├── BUILDING.txt
├── CHANGES.txt
├── COPYRIGHT.txt
├── README.txt
├── RFCs.txt
├── build-awt.xml
├── build-blackberry-enterprise.properties
├── build-blackberry-midp1.properties
├── build-blackberry-midp2.properties
├── build-blackberry.properties
├── build-blackberry.xml
├── build-kindle.xml
├── build-package.xml
├── build-ssh1-lite.properties
├── build-ssh1.properties
├── build-ssh2-lite.properties
├── build-ssh2.properties
├── build.properties
├── build.xml
├── conf
├── KindleTERM.manifest
├── developer.keystore
├── httpserver-manifest.txt
├── log4j.properties
├── midpssh.alx
└── session.properties
├── excludes.cfg
├── lib
├── antenna-bin-1.2.1-beta.jar
├── kdk.jar
└── proguard.jar
├── res
├── font
├── font3x6lcd.png
├── font4x6lcd.png
├── font4x6lcdV.png
├── font4x7lcd.png
├── font5x9lcd.png
├── font8x13lcd.png
├── large.png
└── small.png
└── src
├── httpserver
└── midpssh
│ ├── ChunkedInputStream.java
│ ├── FiniteInputStream.java
│ ├── HttpFields.java
│ ├── HttpInputStream.java
│ ├── HttpOutputStream.java
│ ├── ParseException.java
│ ├── Server.java
│ └── Session.java
├── j2me
├── app
│ ├── LineInputStream.java
│ ├── Main.java
│ ├── MyRecordStore.java
│ ├── SessionManager.java
│ ├── SessionSpec.java
│ ├── Settings.java
│ └── session
│ │ ├── HttpInboundStream.java
│ │ ├── HttpOutboundStream.java
│ │ ├── ISshSession.java
│ │ ├── MacroSetManager.java
│ │ ├── Session.java
│ │ ├── SessionIOHandler.java
│ │ ├── SshSession.java
│ │ └── TelnetSession.java
├── awt
│ ├── AwtMain.java
│ ├── AwtSession.java
│ ├── AwtSshSession.java
│ └── AwtTerminal.java
├── gui
│ ├── Activatable.java
│ ├── EditableForm.java
│ ├── EditableMenu.java
│ ├── ImportSessionsForm.java
│ ├── MainMenu.java
│ ├── Redrawable.java
│ ├── SessionForm.java
│ ├── SessionsMenu.java
│ ├── session
│ │ ├── SpecialMenu.java
│ │ └── macros
│ │ │ ├── MacroForm.java
│ │ │ ├── MacroSet.java
│ │ │ └── MacrosMenu.java
│ └── settings
│ │ ├── SettingsForm.java
│ │ └── SettingsMenu.java
├── kindle
│ ├── FlashPanel.java
│ ├── KindleTerminal.java
│ ├── ProxyKeyEvent.java
│ ├── RemoteKbdReceiver.java
│ ├── RemoteKeyboard.java
│ └── TermKindlet.java
├── ssh
│ ├── SshIO.java
│ ├── SshPacket.java
│ ├── v1
│ │ ├── BigInteger.java
│ │ ├── Blowfish.java
│ │ ├── Cipher.java
│ │ ├── DES.java
│ │ ├── DES3.java
│ │ ├── IDEA.java
│ │ ├── MD5.java
│ │ ├── NONE.java
│ │ ├── SshCrypto.java
│ │ └── SshPacket1.java
│ └── v2
│ │ ├── BigInteger.java
│ │ ├── BufferedDESedeCBC.java
│ │ ├── DHKeyExchange.java
│ │ ├── HMACSHA1.java
│ │ ├── PublicKeyAuthentication.java
│ │ ├── SHA1Digest.java
│ │ ├── SshCrypto2.java
│ │ └── SshPacket2.java
├── telnet
│ ├── Dimension.java
│ └── TelnetProtocolHandler.java
└── terminal
│ ├── LCDFont.java
│ ├── Terminal.java
│ └── VT320.java
└── tasks
├── FileLength.java
└── RewriteBlackberryJAD.java
/BUILDING.txt:
--------------------------------------------------------------------------------
1 | To build MidpSSH you need to have the following software installed:
2 |
3 | * Apache Ant (ant.apache.org)
4 | * J2ME Wireless Toolkit (java.sun.com/j2me)
5 |
6 | MidpSSH uses an Ant pluggin called Antenna (antenna.sourceforge.net). Antenna must
7 | be installed in your Ant classpath. For more information please see the Antenna
8 | website.
9 |
10 |
--------------------------------------------------------------------------------
/CHANGES.txt:
--------------------------------------------------------------------------------
1 | 1.7.3
2 | Fix SSH protocol error that caused connection drop on ScreenOS firewall - thanks Stefan Brunner
3 | Improve security of SSH implementation by simple state tracking - thanks to Aleksy Schubert for bringing this to my attention
4 |
5 | 1.7.2
6 | Add BB Wi-fi support
7 |
8 | 1.7.1
9 | Attempt to fix BB OTA JAD files
10 | Upgrade to Antenna 1.0.0
11 | Upgrade to WTK2.5.2
12 | Upgrade to Proguard 4.1
13 |
14 | 1.7.0
15 | Proguard upgrade from 3.3.2 to 3.8. Reduces lite build sizes by 13 and 24 bytes respectively.
16 | Antenna upgrade from 0.9.13 to 0.9.14. No significant improvements. Just the latest.
17 | Upgrade to WTK2.5
18 | BlackBerry JDE upgrade to 4.2.0
19 | Settings forms no longer have an OK and Back option. They just have a back option, no longer any way to cancel changes.
20 | Fix Blackberry Pearl ChoiceGroup bug by changing from EXCLUSIVE to POPUP ChoiceGroups for MIDP2.
21 |
22 | 1.5.8 becomes 1.6.0
23 | Release version.
24 | Testing support for avoiding InputStream.available() method
25 | Improved build process - now deploys each new version into a separate URL so that old versions can be maintained
26 | Updated to BB 4.0.2
27 | Checksums created for all files
28 | Field access permissions tightened as per recommendations in the paper by Erik Poll and Aleksy Schubert (http://zls.mimuw.edu.pl/~alx/papers/wits.pdf)
29 |
30 | 1.5.4
31 | Keyboard-interactive support
32 |
33 | 1.5.3
34 | Released HTTP proxy support
35 |
36 | 1.4.20
37 | Changed lcdfont8x16 to lcdfont8x13
38 |
39 | 1.4.19
40 | Added lcdfont8x16
41 |
42 | 1.4.18
43 | Fixes for BB bad packets (due to noiosync issue)
44 | Fix for bad packet type 0 on SSH 1 keep-alive
45 | Check for accumulated data waiting to send upon ready to send
46 |
47 | 1.4.12
48 | Fix for devices that AIOOB on LCD fonts
49 | BB MIDP2 version
50 |
51 | 1.4.11
52 | Added more LCD font sizes
53 | Added BGR mode for LCD fonts
54 | Added vertical LCD font
55 | Bug fix for Siemens full screen and rotated view (thanks to DarkBear)
56 |
57 | 1.4.10
58 | Public key authentication added
59 | Special menu refactored
60 | Source code overhaul to reduce file size for lite versions
61 |
62 | 1.4.9
63 | Added settings menu for SSH2 Lite (as a result of size savings elsewhere)
64 | Username & Password now optional on sessions and both will be prompted for at connect
65 | Roar font test
66 |
67 | 1.4.8
68 | Fix for BitVise SSH (and maybe others) which sends KEX_INIT immediately after its id string
69 | Support for typing control chars and newlines in macros
70 |
71 | 1.4.7
72 | Setting for polling I/O
73 | Keep-alive sending re-added for Blackberry (and other no-io-sync).
74 | Code tidy and shrinkage, especially in SSH2 code
75 | SSH2 lite version now <64KB
76 | Predictive text usage is now a setting
77 | Settings renamed and slighly reorganised
78 |
79 | 1.4.6
80 | Function keys and insert keys now work on Blackberry and some other builds where they didn't work before.
81 | Connection type option for session import on Blackberries
82 | Sorting of sessions and macro sets fixed
83 | IOOBException on BB better fixed
84 |
85 | 1.4.5
86 | Blackberry type mode freeze fix
87 | Blackberry enterprise version added (for MDS only to avoid split-pipe security constraint)
88 | More text fields non-predictive
89 |
90 | 1.4.4
91 | Setting for ssh2 private key strength
92 | Setting to pregenerate ssh2 private and public key on phone and store
93 | Patch for BigInteger.modPow improved performance (http://www.bouncycastle.org/devmailarchive/msg03877.html)
94 | Changed default ssh2 key size from 32 to 512 (recommended minimum, http://www.bouncycastle.org/devmailarchive/msg03877.html)
95 | Display host key fingerprint
96 |
97 | 1.4.3
98 |
99 | Added password prompt if no password provided in session spec
100 | Added session list download
101 | Blackberry IOOB fix when using menus
102 | Choose preferred SSH version for connecting to 1.99 hosts
103 | Properly implemented ANSI colours, including bold
104 |
105 | 1.4.2
106 |
107 | Vibrate on beep
108 | INSERT & DELETE special keys added
109 | Trial removing sync on I/O for Blackberry
110 | Fixed SSH2 broken in 1.4.1
111 | Turn off predictive text in input boxes
112 | Fixed < in tiny font - thanks Goetz Schwandtner
113 |
114 | 1.4.1
115 |
116 | Fixed AraryIndexOutOfBoundsException when connecting to a host with a large key.
117 | Added Blackberry OTA
118 |
119 | 1.3.12
120 |
121 | Application error on Motorola (and others) fixed - problem in javac target
122 | Session report no longer displayed if a crash closes the connection, to enable the user to view the error message.
123 |
124 | 1.3.11
125 |
126 | Fixed magenta colour - thanks GeniusOne2
127 | Added connection type option for Blackberry (default of BES)
128 |
129 | 1.3.10
130 |
131 | Fixed problems introduced in 1.3.9 for Motorola phones due to rolling of SshMisc into SshIO.
132 |
133 | 1.3.9
134 |
135 | Back button added to Key Bindings popup
136 | Input dialog changed to not blank content if you use the Back button
137 | Fixed cols/rows, broken in 1.3.8
138 |
139 | 1.3.8
140 |
141 | Fix fullscreen on some devices.
142 | Reduction in file size.
143 | Improved functionality on lite builds.
144 | Added program icon
145 |
146 | 1.3.7
147 |
148 | Settings reorganisation
149 | "Use" option on macros
150 | Default macro set when none exist
151 |
152 | 1.3.6
153 |
154 | Fixed game actions interfering in connected mode
155 | Added home and end keys
156 | Fixed back-to-main-menu on resume
157 |
158 | 1.3.5
159 |
160 | Disconnect menu item changed so not default on some phones
161 | Fullscreen option added
162 | Page up / Page down added
163 |
164 | 1.3.4
165 |
166 | Newlines changed from \n to \r\n then back to \r with fix for telnet
167 | Interactive typing mode fixed (some phones were interpreting keypresses as game actions - and thus as cursor movements)
168 |
169 | 1.3.3
170 |
171 | Font size options
172 | Added Midlet-Permission tag to JAD - does this help siemens phones?
173 | Additional rotation option
174 |
175 | 1.3.2
176 |
177 | terminal type preference, eg. vt320 etc
178 | joystick operates the cursor all the time rather than just in cursor mode
179 | FAILED Ssh2 lite < 64KB?
180 | rotated version - so it could be wider than tall
181 | Find and fix disconnection on blackberry using ssh2 when pressing backspace in typing mode
182 | Fixed 1.3.1 bug where you could no longer connect on MIDP 1.0 phones!
183 |
184 | 1.3.1
185 |
186 | Changed select command code so that it shouldn't appear twice on the Blackberry,
187 | and may work better on midp 1.0 phones.
188 | Fixed SSH1 lite size so that it will work better on 64KB limited phones.
189 | Fixed SSH2 idle disconnect problem
190 |
191 | 1.2.2
192 | Fixed exceptions when using edit/delete etc on empty lists (session menu, macros menu)
193 |
194 | 1.2.1
195 | Reinstated special midp2 enhancements; preprocess symbol wasn't being set correctly
196 |
197 | 1.2
198 | SSH2 support
199 |
--------------------------------------------------------------------------------
/README.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vdp/KindleTERM/e3f55e2f5745a43f52b64c854e3ee911e71bef5c/README.txt
--------------------------------------------------------------------------------
/RFCs.txt:
--------------------------------------------------------------------------------
1 | The Secure Shell (SSH) Protocol Architecture
2 | http://www.ietf.org/rfc/rfc4251.txt
3 |
4 | The Secure Shell (SSH) Authentication Protocol
5 | http://www.ietf.org/rfc/rfc4252.txt
6 |
7 | The Secure Shell (SSH) Transport Layer Protocol
8 | http://www.ietf.org/rfc/rfc4253.txt
9 |
10 | The Secure Shell (SSH) Connection Protocol
11 | http://www.ietf.org/rfc/rfc4254.txt
12 |
13 | Generic Message Exchange Authentication for
14 | the Secure Shell Protocol (SSH)
15 | http://www.ietf.org/rfc/rfc4256.txt
16 |
--------------------------------------------------------------------------------
/build-awt.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
63 |
64 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/build-blackberry-enterprise.properties:
--------------------------------------------------------------------------------
1 | preprocess.symbols=ssh2,blackberry,simplevt320,noiosync,nopaintsync,blackberryenterprise
2 | jad.icon=large.png
3 | obfuscate-blackberry=true
4 |
--------------------------------------------------------------------------------
/build-blackberry-midp1.properties:
--------------------------------------------------------------------------------
1 | # Blackberry JDE
2 | bb.home=c:/Program Files/Research In Motion/BlackBerry JDE 3.7
3 | #bb.home=C:/Program Files/Research In Motion/BlackBerry JDE Component Package 4.3.0
4 | bb.buildjars.home=${bb.home}/bin
5 | bb.lib.home=${bb.home}/lib
6 |
7 | # BB simulator
8 | bb.simulator=${bb.home}/simulator
9 | bb.simulator.run=${bb.home}/bin/run.bat
10 |
11 | # BB 7500 simulator
12 | #bb.simulator=${bb.home}/simulator2
13 | #bb.simulator.run=${bb.home}/simulator2/runOs7500.bat
14 |
15 | # BB 7700 simulator
16 | #bb.simulator=${bb.home}/simulator3
17 | #bb.simulator.run=${bb.home}/simulator3/runOs7700.bat
18 |
19 | bb.ota=true
--------------------------------------------------------------------------------
/build-blackberry-midp2.properties:
--------------------------------------------------------------------------------
1 | # Blackberry JDE
2 | bb.home=C:/Program Files/Research In Motion/BlackBerry JDE Component Package 4.3.0
3 | bb.buildjars.home=${bb.home}/bin
4 | bb.lib.home=${bb.home}/lib
5 |
6 | # BB simulator
7 | bb.simulator=${bb.home}/simulator
8 | bb.simulator.run=${bb.home}/simulator/8100.bat
9 |
10 | bb.ota=true
11 |
--------------------------------------------------------------------------------
/build-blackberry.properties:
--------------------------------------------------------------------------------
1 | preprocess.symbols=ssh2,blackberry,noiosync,nopaintsync,blackberryconntypes,keybrdinteractive
2 | jad.icon=large.png
3 | obfuscate-blackberry=true
4 |
--------------------------------------------------------------------------------
/build-blackberry.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
--------------------------------------------------------------------------------
/build-kindle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
66 |
67 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
88 |
89 |
90 |
91 |
93 |
97 |
101 |
105 |
106 |
107 |
108 |
109 |
110 |
112 |
113 |
114 |
115 |
119 |
120 |
122 |
123 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
--------------------------------------------------------------------------------
/build-ssh1-lite.properties:
--------------------------------------------------------------------------------
1 | #preprocess.symbols=nosettings,nodocs,notelnet,simplevt320,small,notyping,nospecialmenu,nocursororscroll
2 | preprocess.symbols=nodocs,notelnet,simplevt320,small,noinstructions,nosessionimport,nofonts
3 |
4 | obfuscate-lite=true
5 |
--------------------------------------------------------------------------------
/build-ssh1.properties:
--------------------------------------------------------------------------------
1 | preprocess.symbols=NONE
2 | jad.icon=small.png
3 | obfuscate-normal=true
4 |
--------------------------------------------------------------------------------
/build-ssh2-lite.properties:
--------------------------------------------------------------------------------
1 | preprocess.symbols=nodocs,notelnet,simplevt320,ssh2,nossh1,small,noinstructions,nosessionimport,nofonts,nocursororscroll,nospecialmenu
2 | # to reduce size by 500 bytes - nocursororscroll
3 | obfuscate-lite-nossh1=true
4 |
--------------------------------------------------------------------------------
/build-ssh2.properties:
--------------------------------------------------------------------------------
1 | preprocess.symbols=ssh2,keybrdinteractive
2 | jad.icon=small.png
3 | obfuscate-normal=true
4 |
--------------------------------------------------------------------------------
/build.properties:
--------------------------------------------------------------------------------
1 | # MidpSSH build properties
2 | version=1.7.3
3 | jad.target=http://www.xk72.com/midpssh/v${version}
4 |
5 | name=MidpSSH
6 |
7 | #wtk.home=c:/WTK21
8 | #deviceName=DefaultColorPhone
9 |
10 | #wtk.home=c:/WTK22
11 | #deviceName=DefaultColorPhone
12 |
13 | wtk.home=../../../../WTK-2.5.1
14 | deviceName=DefaultColorPhone
15 |
16 | #wtk.home=c:/SonyEricsson/J2ME_SDK/PC_Emulation/WTK2
17 | #deviceName=SonyEricsson_K700
18 |
19 | build.dir=build
20 | dist.dir=dist
21 | zip.file=midpssh.zip
22 |
23 | #preprocess.symbols.global=debug
24 | #preprocess.symbols.global=io.no_available
25 | preprocess.symbols.global=NONE
26 |
27 | jad.vendor=XK72
28 |
--------------------------------------------------------------------------------
/conf/KindleTERM.manifest:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Main-Class: kindle.TermKindlet
3 | Implementation-Title: KindleTERM
4 | Implementation-Version: 1
5 | Implementation-Vendor: VDP
6 |
--------------------------------------------------------------------------------
/conf/developer.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vdp/KindleTERM/e3f55e2f5745a43f52b64c854e3ee911e71bef5c/conf/developer.keystore
--------------------------------------------------------------------------------
/conf/httpserver-manifest.txt:
--------------------------------------------------------------------------------
1 | Main-Class: midpssh.Server
2 |
--------------------------------------------------------------------------------
/conf/log4j.properties:
--------------------------------------------------------------------------------
1 | log4j.rootLogger=debug, R
2 |
3 | log4j.category.kindle.KindleTerminal=info
4 | log4j.category.kindle.KindleTerminal$Redrawer=warn
5 |
6 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender
7 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
8 |
9 | # Pattern to output the caller's file name and line number.
10 | log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
11 |
12 | log4j.appender.R=org.apache.log4j.RollingFileAppender
13 | log4j.appender.R.File=/mnt/us/developer/KindleTERM/work/kterm.log
14 |
15 | log4j.appender.R.MaxFileSize=100KB
16 | # Keep one backup file
17 | log4j.appender.R.MaxBackupIndex=1
18 |
19 | log4j.appender.R.layout=org.apache.log4j.PatternLayout
20 | log4j.appender.R.layout.ConversionPattern=%d{dd MMM HH:mm:ss} %5p [%t] (%F:%L) - %m%n
21 |
--------------------------------------------------------------------------------
/conf/midpssh.alx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | @NAME@
5 |
6 |
7 | Telnet and SSH application for Java compatible phone and other mobile devices.
8 | Please visit the project website for more information:
9 | http://www.xk72.com/midpssh/
10 |
11 |
12 | @VERSION@
13 |
14 |
15 | Developed by Karl von Randow, based upon FloydSSH and Telnet Floyd by Radek Polak
16 |
17 |
18 | Distributed under the GPL License.
19 |
20 |
21 |
22 |
23 |
24 |
25 | @CODNAME@.cod
26 | @CODNAME@-1.cod
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/conf/session.properties:
--------------------------------------------------------------------------------
1 | host localhost
2 | port 22
3 | user root
4 | pass pass
--------------------------------------------------------------------------------
/excludes.cfg:
--------------------------------------------------------------------------------
1 | app/SessionSpec.java
2 | app/Main.java
3 | app/SessionManager.java
4 | app/MyRecordStore.java
5 | app/session/HttpOutboundStream.java
6 | app/session/SshSession.java
7 | app/session/Session.java
8 | app/session/MacroSetManager.java
9 | app/session/TelnetSession.java
10 | app/session/HttpInboundStream.java
11 | app/Settings.java
12 | app/LineInputStream.java
13 | gui/MainMenu.java
14 | gui/settings
15 | gui/settings/SettingsForm.java
16 | gui/settings/SettingsMenu.java
17 | gui/EditableMenu.java
18 | gui/SessionForm.java
19 | gui/SessionsMenu.java
20 | gui/session
21 | gui/session/SpecialMenu.java
22 | gui/session/macros
23 | gui/session/macros/MacroSet.java
24 | gui/session/macros/MacroForm.java
25 | gui/session/macros/MacrosMenu.java
26 | gui/ImportSessionsForm.java
27 | gui/Activatable.java
28 | gui/EditableForm.java
29 | terminal/LCDFont.java
30 | terminal/Terminal.java
--------------------------------------------------------------------------------
/lib/antenna-bin-1.2.1-beta.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vdp/KindleTERM/e3f55e2f5745a43f52b64c854e3ee911e71bef5c/lib/antenna-bin-1.2.1-beta.jar
--------------------------------------------------------------------------------
/lib/kdk.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vdp/KindleTERM/e3f55e2f5745a43f52b64c854e3ee911e71bef5c/lib/kdk.jar
--------------------------------------------------------------------------------
/lib/proguard.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vdp/KindleTERM/e3f55e2f5745a43f52b64c854e3ee911e71bef5c/lib/proguard.jar
--------------------------------------------------------------------------------
/res/font:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vdp/KindleTERM/e3f55e2f5745a43f52b64c854e3ee911e71bef5c/res/font
--------------------------------------------------------------------------------
/res/font3x6lcd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vdp/KindleTERM/e3f55e2f5745a43f52b64c854e3ee911e71bef5c/res/font3x6lcd.png
--------------------------------------------------------------------------------
/res/font4x6lcd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vdp/KindleTERM/e3f55e2f5745a43f52b64c854e3ee911e71bef5c/res/font4x6lcd.png
--------------------------------------------------------------------------------
/res/font4x6lcdV.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vdp/KindleTERM/e3f55e2f5745a43f52b64c854e3ee911e71bef5c/res/font4x6lcdV.png
--------------------------------------------------------------------------------
/res/font4x7lcd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vdp/KindleTERM/e3f55e2f5745a43f52b64c854e3ee911e71bef5c/res/font4x7lcd.png
--------------------------------------------------------------------------------
/res/font5x9lcd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vdp/KindleTERM/e3f55e2f5745a43f52b64c854e3ee911e71bef5c/res/font5x9lcd.png
--------------------------------------------------------------------------------
/res/font8x13lcd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vdp/KindleTERM/e3f55e2f5745a43f52b64c854e3ee911e71bef5c/res/font8x13lcd.png
--------------------------------------------------------------------------------
/res/large.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vdp/KindleTERM/e3f55e2f5745a43f52b64c854e3ee911e71bef5c/res/large.png
--------------------------------------------------------------------------------
/res/small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vdp/KindleTERM/e3f55e2f5745a43f52b64c854e3ee911e71bef5c/res/small.png
--------------------------------------------------------------------------------
/src/httpserver/midpssh/ChunkedInputStream.java:
--------------------------------------------------------------------------------
1 | /*
2 | * @(#)ChunkedInputStream.java 0.3-3 06/05/2001
3 | *
4 | * This file is part of the HTTPClient package
5 | * Copyright (C) 1996-2001 Ronald Tschal�r
6 | *
7 | * This library is free software; you can redistribute it and/or
8 | * modify it under the terms of the GNU Lesser General Public
9 | * License as published by the Free Software Foundation; either
10 | * version 2 of the License, or (at your option) any later version.
11 | *
12 | * This library is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public
18 | * License along with this library; if not, write to the Free
19 | * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 | * MA 02111-1307, USA
21 | *
22 | * For questions, suggestions, bug-reports, enhancement-requests etc.
23 | * I may be contacted at:
24 | *
25 | * ronald@innovation.ch
26 | *
27 | * The HTTPClient's home page is located at:
28 | *
29 | * http://www.innovation.ch/java/HTTPClient/
30 | *
31 | */
32 |
33 | package midpssh;
34 |
35 | import java.io.EOFException;
36 | import java.io.FilterInputStream;
37 | import java.io.IOException;
38 | import java.io.InputStream;
39 |
40 | /**
41 | * This class de-chunks an input stream.
42 | *
43 | * @version 0.3-3 06/05/2001
44 | * @author Ronald Tschal�r
45 | */
46 | public class ChunkedInputStream extends FilterInputStream {
47 | /**
48 | * @param is
49 | * the input stream to dechunk
50 | */
51 | public ChunkedInputStream(InputStream is) {
52 | super(is);
53 | }
54 |
55 | byte[] one = new byte[1];
56 |
57 | public synchronized int read() throws IOException {
58 | int b = read(one, 0, 1);
59 | if (b == 1)
60 | return (one[0] & 0xff);
61 | else
62 | return -1;
63 | }
64 |
65 | private long chunk_len = -1;
66 |
67 | private boolean eof = false;
68 |
69 | public synchronized int read(byte[] buf, int off, int len) throws IOException {
70 | if (eof)
71 | return -1;
72 |
73 | if (chunk_len == -1) // it's a new chunk
74 | {
75 | try {
76 | chunk_len = getChunkLength(in);
77 | } catch (ParseException pe) {
78 | throw new IOException(pe.toString());
79 | }
80 | }
81 |
82 | if (chunk_len > 0) // it's data
83 | {
84 | if (len > chunk_len)
85 | len = (int) chunk_len;
86 | int rcvd = in.read(buf, off, len);
87 | if (rcvd == -1)
88 | throw new EOFException("Premature EOF encountered");
89 |
90 | chunk_len -= rcvd;
91 | if (chunk_len == 0) // got the whole chunk
92 | {
93 | in.read(); // CR
94 | in.read(); // LF
95 | chunk_len = -1;
96 | }
97 |
98 | return rcvd;
99 | } else // the footers (trailers)
100 | {
101 | // discard
102 | /*
103 | * try { readLines(); } catch ( IOException e ) {}
104 | */
105 |
106 | eof = true;
107 | return -1;
108 | }
109 | }
110 |
111 | /**
112 | * Gets the length of the chunk.
113 | *
114 | * @param input
115 | * the stream from which to read the next chunk.
116 | * @return the length of chunk to follow (w/o trailing CR LF).
117 | * @exception ParseException
118 | * If any exception during parsing occured.
119 | * @exception IOException
120 | * If any exception during reading occured.
121 | */
122 | final static long getChunkLength(InputStream input) throws ParseException, IOException {
123 | byte[] hex_len = new byte[16]; // if they send more than 8EB chunks...
124 | int off = 0, ch;
125 |
126 | // read chunk length
127 |
128 | while ((ch = input.read()) > 0 && (ch == ' ' || ch == '\t'))
129 | ;
130 | if (ch < 0)
131 | throw new EOFException("Premature EOF while reading chunk length");
132 | hex_len[off++] = (byte) ch;
133 | while ((ch = input.read()) > 0 && ch != '\r' && ch != '\n' && ch != ' ' && ch != '\t' && ch != ';' && off < hex_len.length)
134 | hex_len[off++] = (byte) ch;
135 |
136 | while ((ch == ' ' || ch == '\t') && (ch = input.read()) > 0)
137 | ;
138 | if (ch == ';') // chunk-ext (ignore it)
139 | while ((ch = input.read()) > 0 && ch != '\r' && ch != '\n')
140 | ;
141 |
142 | if (ch < 0)
143 | throw new EOFException("Premature EOF while reading chunk length");
144 | if (ch != '\n' && (ch != '\r' || input.read() != '\n'))
145 | throw new ParseException("Didn't find valid chunk length: " + new String(hex_len, 0, off, "8859_1"));
146 |
147 | // parse chunk length
148 |
149 | try {
150 | return Long.parseLong(new String(hex_len, 0, off, "8859_1").trim(), 16);
151 | } catch (NumberFormatException nfe) {
152 | throw new ParseException("Didn't find valid chunk length: " + new String(hex_len, 0, off, "8859_1"));
153 | }
154 | }
155 |
156 | // private void readLines() throws IOException {
157 | // /* This loop is a merge of readLine() from DataInputStream and
158 | // * the necessary header logic to merge continued lines and terminate
159 | // * after an empty line. The reason this is explicit is because of
160 | // * the need to handle InterruptedIOExceptions.
161 | // */
162 | // loop: while ( true ) {
163 | // boolean got_cr = false, bol = false;
164 | // int b = super.read();
165 | // switch ( b ) {
166 | // case -1:
167 | // throw new EOFException( "Encountered premature EOF while reading
168 | // trailers" );
169 | // case '\r':
170 | // got_cr = true;
171 | // break;
172 | // case '\n':
173 | // if ( bol ) break loop; // all headers read
174 | // bol = true;
175 | // got_cr = false;
176 | // break;
177 | // case ' ':
178 | // case '\t':
179 | // if ( bol ) // a continued line
180 | // {
181 | // // replace previous \n with SP
182 | // bol = false;
183 | // break;
184 | // }
185 | // default:
186 | // if ( got_cr ) {
187 | // got_cr = false;
188 | // }
189 | // bol = false;
190 | // break;
191 | // }
192 | // }
193 | // }
194 |
195 | public synchronized long skip(long num) throws IOException {
196 | byte[] tmp = new byte[(int) num];
197 | int got = read(tmp, 0, (int) num);
198 |
199 | if (got > 0)
200 | return (long) got;
201 | else
202 | return 0L;
203 | }
204 |
205 | public synchronized int available() throws IOException {
206 | if (eof)
207 | return 0;
208 |
209 | if (chunk_len != -1)
210 | return (int) chunk_len + in.available();
211 | else
212 | return in.available();
213 | }
214 | }
215 |
--------------------------------------------------------------------------------
/src/httpserver/midpssh/FiniteInputStream.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2006 Karl von Randow.
3 | *
4 | * --LICENSE NOTICE--
5 | * This program is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU General Public License
7 | * as published by the Free Software Foundation; either version 2
8 | * of the License, or (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 | * --LICENSE NOTICE--
19 | *
20 | */
21 |
22 | package midpssh;
23 |
24 | import java.io.FilterInputStream;
25 | import java.io.IOException;
26 | import java.io.InputStream;
27 |
28 | /**
29 | * FiniteInputStream is a FilterInputStream implementation that takes a limit on
30 | * the number of bytes that can be read from the stream.
31 | */
32 | public class FiniteInputStream extends FilterInputStream {
33 | private long size;
34 |
35 | private long counter;
36 |
37 | public FiniteInputStream(InputStream in, long size) {
38 | super(in);
39 | this.size = size;
40 | counter = 0;
41 | }
42 |
43 | public int read() throws IOException {
44 | if (counter < size) {
45 | int c = in.read();
46 | if (c != -1) {
47 | counter++;
48 | return c;
49 | } else {
50 | return -1;
51 | }
52 | } else {
53 | return -1;
54 | }
55 | }
56 |
57 | public int read(byte b[]) throws IOException {
58 | return read(b, 0, b.length);
59 | }
60 |
61 | public int read(byte b[], int off, int len) throws IOException {
62 | if (counter + len >= size) {
63 | len = (int) (size - counter);
64 | if (len <= 0)
65 | return -1;
66 | }
67 | int n = in.read(b, off, len);
68 | if (n > 0) {
69 | counter += n;
70 | }
71 | return n;
72 | }
73 |
74 | public long skip(long n) throws IOException {
75 | if (counter + n >= size) {
76 | n = size - counter;
77 | }
78 | long skipped = in.skip(n);
79 | counter += skipped;
80 | return skipped;
81 | }
82 |
83 | public int available() throws IOException {
84 | int n = in.available();
85 | if (counter + n >= size) {
86 | n = (int) (size - counter);
87 | }
88 | return n;
89 | }
90 |
91 | public long getCounter() {
92 | return counter;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/httpserver/midpssh/HttpFields.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2006 Karl von Randow.
3 | *
4 | * --LICENSE NOTICE--
5 | * This program is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU General Public License
7 | * as published by the Free Software Foundation; either version 2
8 | * of the License, or (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 | * --LICENSE NOTICE--
19 | *
20 | */
21 |
22 | package midpssh;
23 |
24 | import java.io.EOFException;
25 | import java.io.IOException;
26 | import java.io.Serializable;
27 | import java.util.ArrayList;
28 |
29 | /**
30 | *
31 | * @author karl
32 | * @version
33 | */
34 | public class HttpFields extends Object implements Serializable, Cloneable {
35 |
36 | private ArrayList fieldNames = new ArrayList();
37 |
38 | private ArrayList fieldValues = new ArrayList();
39 |
40 | /** Holds value of property firstLine. */
41 | private String firstLine;
42 |
43 | /** Creates new HttpFields */
44 | public HttpFields() {
45 | }
46 |
47 | public boolean read(HttpInputStream in) throws IOException {
48 | firstLine = in.readLineInclusive();
49 | if (firstLine == null)
50 | throw new EOFException("EOF reading HTTP headers");
51 | String trimmedFirstLine = HttpInputStream.trimNewline(firstLine);
52 | if (trimmedFirstLine.length() == 0) {
53 | firstLine = "";
54 | return false;
55 | }
56 |
57 | // Sanity check, some servers don't return headers they just return body
58 | // straight away (eg. images on Tucows.com)
59 | if (firstLine.indexOf("HTTP/") == -1) {
60 | in.unreadLine(firstLine);
61 | firstLine = null;
62 | return true;
63 | }
64 |
65 | // Trim the newline characters
66 | firstLine = trimmedFirstLine;
67 |
68 | String line = in.readLine();
69 | String key = null;
70 | StringBuffer value = null;
71 |
72 | // System.out.println();
73 | // System.out.println( firstLine );
74 | while (line != null && line.length() != 0) {
75 | // System.out.println( line );
76 | if (line.startsWith(" ")) {
77 | if (value == null) {
78 | throw new IOException("Found header field continuation before a header field!: \"" + line + "\"");
79 | }
80 | // value.append( " " );
81 | value.append(line); // .trim()
82 | } else {
83 | int colon = line.indexOf(":");
84 | if (colon == -1) {
85 | if (value != null) {
86 | value.append(' ');
87 | value.append(line);
88 | }
89 | } else {
90 | if (key != null) {
91 | addField(key, value.toString().trim());
92 | }
93 | key = line.substring(0, colon);
94 | value = new StringBuffer();
95 | if (colon + 2 < line.length()) {
96 | value.append(line.substring(colon + 2)); // .trim()
97 | }
98 | }
99 | }
100 |
101 | line = in.readLine();
102 | }
103 |
104 | if (key != null) {
105 | addField(key, value.toString().trim());
106 | }
107 |
108 | if (line == null)
109 | throw new EOFException("EOF reading HTTP headers");
110 | return true;
111 | }
112 |
113 | public String get(String fieldName) {
114 | return getField(fieldName);
115 | }
116 |
117 | public String getField(String fieldName) {
118 | int n = fieldNames.size();
119 |
120 | for (int i = 0; i < n; i++) {
121 | String key = (String) fieldNames.get(i);
122 | if (key.equalsIgnoreCase(fieldName)) {
123 | return (String) fieldValues.get(i);
124 | }
125 | }
126 |
127 | return null;
128 | }
129 |
130 | public int getIntField(String fieldName) throws NumberFormatException {
131 | return getIntField(fieldName, -1);
132 | }
133 |
134 | public int getIntField(String fieldName, int defaultValue) throws NumberFormatException {
135 | String value = getField(fieldName);
136 | if (value != null) {
137 | value = value.trim();
138 | try {
139 | return Integer.parseInt(value);
140 | } catch (NumberFormatException e) {
141 | // Try to get some numbers from the front as some spastic web
142 | // servers return something after the number,
143 | /*
144 | * eg. from
145 | * http://ad.nz.doubleclick.net/viewad/622507/asb_matrix_home_tile_260x80.gif
146 | * HTTP/1.0 200 OK Server: DCLK-HttpSvr Content-Type: image/gif
147 | * Content-Length: 7996Wed, 13 Aug 2003 04:51:35 GMT
148 | */
149 | int iValue = -1;
150 | for (int i = 1; i <= value.length(); i++) {
151 | try {
152 | iValue = Integer.parseInt(value.substring(0, i));
153 | } catch (NumberFormatException f) {
154 | // If possible return the last number that was valid
155 | if (i > 1)
156 | return iValue;
157 | // Otherwise throw the original exception
158 | break;
159 | }
160 | }
161 | throw e;
162 | }
163 | } else {
164 | return defaultValue;
165 | }
166 | }
167 |
168 | /**
169 | */
170 | public void addField(String key, String value) {
171 | fieldNames.add(key);
172 | fieldValues.add(value);
173 | }
174 |
175 | /**
176 | * Getter for property firstLine.
177 | *
178 | * @return Value of property firstLine.
179 | */
180 | public String getFirstLine() {
181 | return firstLine;
182 | }
183 |
184 | }
185 |
--------------------------------------------------------------------------------
/src/httpserver/midpssh/HttpInputStream.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2006 Karl von Randow.
3 | *
4 | * --LICENSE NOTICE--
5 | * This program is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU General Public License
7 | * as published by the Free Software Foundation; either version 2
8 | * of the License, or (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 | * --LICENSE NOTICE--
19 | *
20 | */
21 |
22 | package midpssh;
23 |
24 | import java.io.IOException;
25 | import java.io.InputStream;
26 | import java.io.PushbackInputStream;
27 |
28 | /**
29 | *
30 | * @author karl
31 | * @version
32 | */
33 | public class HttpInputStream extends PushbackInputStream {
34 |
35 | public static final String CHARSET = "ISO-8859-1";
36 |
37 | /** Creates new HttpInputStream */
38 | public HttpInputStream(InputStream in) {
39 | super(in, 8192);
40 | }
41 |
42 | public void waitForData() throws IOException {
43 | int c = read();
44 | unread(c);
45 | }
46 |
47 | /**
48 | * The String contains a line of text read from the stream, not including
49 | * the EOL character(s). The string is converted from bytes using ISO-8859-1
50 | * encoding - in the hope that ISO-8859-1 is 8-bit safe. That is, the bytes
51 | * can be converted to a String and back to bytes without changing the
52 | * bytes.
53 | *
54 | * @return
55 | * @throws IOException
56 | */
57 | public String readLine() throws IOException {
58 | if (buf == null) {
59 | buf = new byte[128];
60 | }
61 |
62 | int c = read();
63 | if (c == -1)
64 | return null;
65 | int i = 0;
66 | while (c != -1) {
67 | if (c == '\r') {
68 | int d = read();
69 | if (d == '\n') {
70 | break;
71 | }
72 | unread(d);
73 | break;
74 | } else if (c == '\n') {
75 | break;
76 | }
77 |
78 | addByteToBuffer(i++, c);
79 | c = read();
80 | }
81 | return new String(buf, 0, i, CHARSET);
82 | }
83 |
84 | public String readLineInclusive() throws IOException {
85 | if (buf == null) {
86 | buf = new byte[128];
87 | }
88 |
89 | int c = read();
90 | if (c == -1)
91 | return null;
92 | int i = 0;
93 | while (c != -1) {
94 | // First put the byte in the buffer
95 | addByteToBuffer(i++, c);
96 |
97 | if (c == '\r') {
98 | int d = read();
99 | if (d == '\n') {
100 | addByteToBuffer(i++, d);
101 | break;
102 | }
103 | unread(d);
104 | break;
105 | } else if (c == '\n') {
106 | break;
107 | }
108 |
109 | c = read();
110 | }
111 | return new String(buf, 0, i, CHARSET);
112 | }
113 |
114 | public static String trimNewline(String line) {
115 | if (line.endsWith("\r\n")) {
116 | return line.substring(0, line.length() - 2);
117 | } else if (line.endsWith("\r") || line.endsWith("\n")) {
118 | return line.substring(0, line.length() - 1);
119 | } else {
120 | return line;
121 | }
122 | }
123 |
124 | private void addByteToBuffer(int i, int c) {
125 | if (i >= buf.length) {
126 | // Extend the buffer
127 | byte[] buf = new byte[this.buf.length + 128];
128 | System.arraycopy(this.buf, 0, buf, 0, this.buf.length);
129 | this.buf = buf;
130 | }
131 |
132 | buf[i] = (byte) (c & 0xff);
133 | }
134 |
135 | public void unreadLine(String line) throws IOException {
136 | byte[] buf = line.getBytes(CHARSET);
137 | unread(buf);
138 | }
139 |
140 | private byte[] buf;
141 | }
142 |
--------------------------------------------------------------------------------
/src/httpserver/midpssh/HttpOutputStream.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2006 Karl von Randow.
3 | *
4 | * --LICENSE NOTICE--
5 | * This program is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU General Public License
7 | * as published by the Free Software Foundation; either version 2
8 | * of the License, or (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 | * --LICENSE NOTICE--
19 | *
20 | */
21 |
22 | package midpssh;
23 |
24 | import java.io.FilterOutputStream;
25 | import java.io.IOException;
26 | import java.io.OutputStream;
27 |
28 | /**
29 | *
30 | * @author karl
31 | * @version
32 | */
33 | public class HttpOutputStream extends FilterOutputStream {
34 |
35 | /** Creates new HttpOutputStream */
36 | public HttpOutputStream(OutputStream out) {
37 | super(out);
38 | }
39 |
40 | public void write(String str) throws IOException {
41 | out.write(str.getBytes());
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/httpserver/midpssh/ParseException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * @(#)ParseException.java 0.3-3 06/05/2001
3 | *
4 | * This file is part of the HTTPClient package
5 | * Copyright (C) 1996-2001 Ronald Tschal�r
6 | *
7 | * This library is free software; you can redistribute it and/or
8 | * modify it under the terms of the GNU Lesser General Public
9 | * License as published by the Free Software Foundation; either
10 | * version 2 of the License, or (at your option) any later version.
11 | *
12 | * This library is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU Lesser General Public
18 | * License along with this library; if not, write to the Free
19 | * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 | * MA 02111-1307, USA
21 | *
22 | * For questions, suggestions, bug-reports, enhancement-requests etc.
23 | * I may be contacted at:
24 | *
25 | * ronald@innovation.ch
26 | *
27 | * The HTTPClient's home page is located at:
28 | *
29 | * http://www.innovation.ch/java/HTTPClient/
30 | *
31 | */
32 |
33 | package midpssh;
34 |
35 | /**
36 | * Signals that something went wrong while parsing data. Usually means the input
37 | * data was invalid.
38 | *
39 | * @version 0.3-3 06/05/2001
40 | * @author Ronald Tschal�r
41 | */
42 | public class ParseException extends Exception {
43 |
44 | /**
45 | * Constructs an ParseException with no detail message. A detail message is
46 | * a String that describes this particular exception.
47 | */
48 | public ParseException() {
49 | super();
50 | }
51 |
52 | /**
53 | * Constructs an ParseException class with the specified detail message. A
54 | * detail message is a String that describes this particular exception.
55 | *
56 | * @param s
57 | * the String containing a detail message
58 | */
59 | public ParseException(String s) {
60 | super(s);
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/src/httpserver/midpssh/Server.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2006 Karl von Randow.
3 | *
4 | * --LICENSE NOTICE--
5 | * This program is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU General Public License
7 | * as published by the Free Software Foundation; either version 2
8 | * of the License, or (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 | * --LICENSE NOTICE--
19 | *
20 | */
21 |
22 | package midpssh;
23 |
24 | import java.io.EOFException;
25 | import java.io.IOException;
26 | import java.io.InputStream;
27 | import java.io.OutputStream;
28 | import java.net.ServerSocket;
29 | import java.net.Socket;
30 | import java.util.HashMap;
31 | import java.util.Map;
32 | import java.util.StringTokenizer;
33 |
34 | public class Server implements Runnable {
35 |
36 | private static final String HTTP_HEADERS = "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-type: application/octet-stream\r\n";
37 |
38 | private static final String CRLF = "\r\n";
39 |
40 | private static Map current;
41 |
42 | private Socket clientSocket;
43 |
44 | private HttpInputStream in;
45 |
46 | private HttpOutputStream out;
47 |
48 | private Session session;
49 |
50 | private String key;
51 |
52 | private String host;
53 |
54 | private int port;
55 |
56 | /**
57 | * The application's main method. Starts listening on a socket and creates a new instance
58 | * of the Server class for each socket connection accepted.
59 | */
60 | public static void main(String[] args) throws Exception {
61 | current = new HashMap();
62 |
63 | int port = 8088;
64 |
65 | if (args.length > 0) {
66 | port = Integer.parseInt(args[0]);
67 | }
68 |
69 | System.out.println("Starting MidpSSH HTTP Proxy on port " + port);
70 |
71 | ServerSocket ss = new ServerSocket(port);
72 |
73 | while (true) {
74 | Socket s = ss.accept();
75 | new Server(s);
76 | }
77 | }
78 |
79 | public Server(Socket socket) {
80 | this.clientSocket = socket;
81 | new Thread(this).start();
82 | }
83 |
84 | /**
85 | * The main server loop. A new thread is created for each socket handled by the server. This
86 | * method handles that socket and exists until the socket is closed.
87 | */
88 | public void run() {
89 | debug("Connection from " + clientSocket);
90 | try {
91 | in = new HttpInputStream(clientSocket.getInputStream());
92 | out = new HttpOutputStream(clientSocket.getOutputStream());
93 |
94 | // boolean keptAlive = false;
95 | while (true) {
96 | // if (keptAlive) {
97 | // System.out.println("trying a keep alive read");
98 | // }
99 | HttpFields fields = new HttpFields();
100 | fields.read(in);
101 | // if (keptAlive) {
102 | // System.out.println("kept alive!");
103 | // }
104 |
105 | String firstLine = fields.getFirstLine();
106 | if (firstLine != null) {
107 | StringTokenizer tok = new StringTokenizer(firstLine, " ");
108 | String method = tok.nextToken();
109 | String path = tok.nextToken();
110 |
111 | /* Determine the key that uniquely identifies the connection */
112 | key = path;
113 | int i = key.indexOf('/', 1);
114 | host = key.substring(i + 1);
115 |
116 | i = host.indexOf(':');
117 | port = Integer.parseInt(host.substring(i + 1));
118 | host = host.substring(0, i);
119 |
120 | /* Look for that connection in our current list and use that if possible. Otherwise this
121 | * is a new connection.
122 | */
123 | synchronized (current) {
124 | if (current.containsKey(key)) {
125 | session = (Session) current.get(key);
126 | session.setLastAccessed(System.currentTimeMillis());
127 | } else {
128 | session = new Session();
129 | current.put(key, session);
130 | }
131 | }
132 |
133 | synchronized (session) {
134 | if (!session.isConnected()) {
135 | session.connect(host, port);
136 | }
137 | }
138 |
139 | try {
140 | if (method.equalsIgnoreCase("POST")) {
141 | doClientOutbound(fields);
142 | } else {
143 | doClientInbound(fields);
144 | }
145 | }
146 | catch (IOException e) {
147 | /* Remove this connection from the current list */
148 | current.remove(key);
149 | session.close();
150 | throw e;
151 | }
152 |
153 | // keptAlive = true;
154 | break;
155 | } else {
156 | break;
157 | }
158 | }
159 |
160 | in.close();
161 | out.close();
162 | } catch (IOException e) {
163 | System.out.println(e);
164 | }
165 |
166 | try {
167 | clientSocket.close();
168 | } catch (IOException e) {
169 | System.out.println(e);
170 | }
171 | }
172 |
173 | /**
174 | * Handle the outbound stream from MidpSSH. Can support chunked POST data, in which case MidpSSH may
175 | * be able to send all outbound data over a single chunked POST. Otherwise multiple and separate POSTs
176 | * are sent.
177 | *
178 | * We read all the data from the post and write it out to the destination server.
179 | * @param fields
180 | * @throws IOException
181 | */
182 | public void doClientOutbound(HttpFields fields) throws IOException {
183 | OutputStream destout = session.getSocket().getOutputStream();
184 |
185 | InputStream in = this.in;
186 | boolean chunking = fields.getField("Transfer-Encoding") != null && fields.getField("Transfer-Encoding").equalsIgnoreCase("chunked");
187 | if (chunking) {
188 | in = new ChunkedInputStream(in);
189 | } else {
190 | int contentLength = fields.getIntField("Content-length");
191 | in = new FiniteInputStream(in, contentLength);
192 | }
193 |
194 | byte[] buf = new byte[8192];
195 | int read = in.read(buf);
196 | while (read != -1) {
197 | destout.write(buf, 0, read);
198 | destout.flush();
199 |
200 | read = in.read(buf);
201 | }
202 |
203 | out.write(HTTP_HEADERS + CRLF);
204 | out.flush();
205 | }
206 |
207 | /**
208 | * Handle the inbound stream to MidpSSH. Can support persistent connection to MidpSSH if the phone + network
209 | * can support it: the entire inbound stream is sent during one connection. Otherwise we send back what we have
210 | * and then close the connection.
211 | * @param fields
212 | * @throws IOException
213 | */
214 | public void doClientInbound(HttpFields fields) throws IOException {
215 | InputStream destin = session.getSocket().getInputStream();
216 |
217 | boolean persistent = fields.get("X-MidpSSH-Persistent") != null;
218 | boolean headers = false;
219 |
220 | byte[] buf = new byte[8192];
221 | int read = destin.read(buf);
222 | while (read != -1) {
223 | if (!headers) {
224 | if (persistent) {
225 | out.write(HTTP_HEADERS + CRLF);
226 | } else {
227 | out.write(HTTP_HEADERS + "Content-length: " + read + CRLF + CRLF);
228 | }
229 | out.flush();
230 | headers = true;
231 | }
232 | out.write(buf, 0, read);
233 | out.flush();
234 | if (persistent) {
235 | read = destin.read(buf);
236 | } else {
237 | break;
238 | }
239 | }
240 |
241 | if (read == -1) {
242 | throw new EOFException("Remote server has closed connection");
243 | }
244 | }
245 |
246 | // private String toHex(byte[] ray, int offset, int length) {
247 | // StringBuffer buf = new StringBuffer();
248 | // for (int i = offset; i < offset + length; i++) {
249 | // buf.append("0x");
250 | // buf.append(Integer.toHexString(ray[i]));
251 | // buf.append(' ');
252 | // }
253 | // buf.append('\n');
254 | // buf.append(new String(ray, offset, length));
255 | // return buf.toString();
256 | // }
257 |
258 | private void debug(String message) {
259 | System.out.println(message);
260 | }
261 |
262 | }
263 |
--------------------------------------------------------------------------------
/src/httpserver/midpssh/Session.java:
--------------------------------------------------------------------------------
1 | package midpssh;
2 |
3 | import java.io.IOException;
4 | import java.net.Socket;
5 | import java.net.UnknownHostException;
6 |
7 | public class Session {
8 |
9 | private Socket socket;
10 |
11 | private long lastAccessed;
12 |
13 | public Session() {
14 | lastAccessed = System.currentTimeMillis();
15 | }
16 |
17 | public Socket getSocket() {
18 | return socket;
19 | }
20 |
21 | public void setSocket(Socket socket) {
22 | this.socket = socket;
23 | }
24 |
25 | public long getLastAccessed() {
26 | return lastAccessed;
27 | }
28 |
29 | public void setLastAccessed(long lastAccessed) {
30 | this.lastAccessed = lastAccessed;
31 | }
32 |
33 | public void close() throws IOException {
34 | socket.close();
35 | }
36 |
37 | public void connect(String host, int port) throws UnknownHostException, IOException {
38 | socket = new Socket(host, port);
39 | }
40 |
41 | public boolean isConnected() {
42 | return socket != null;
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/j2me/app/LineInputStream.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2005 Karl von Randow.
3 | *
4 | * --LICENSE NOTICE--
5 | * This program is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU General Public License
7 | * as published by the Free Software Foundation; either version 2
8 | * of the License, or (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 | * --LICENSE NOTICE--
19 | *
20 | */
21 | package app;
22 |
23 | import java.io.IOException;
24 | import java.io.InputStream;
25 |
26 | /**
27 | * @author Karl
28 | *
29 | */
30 | public class LineInputStream extends InputStream {
31 |
32 | private static final int BUFSIZ = 8192;
33 |
34 | private InputStream in;
35 |
36 | private byte[] buf = new byte[BUFSIZ];
37 |
38 | private int index = 0;
39 |
40 | public LineInputStream(InputStream in) {
41 | this.in = in;
42 | }
43 |
44 | public int read() throws IOException {
45 | return in.read();
46 | }
47 |
48 | public void close() throws IOException {
49 | in.close();
50 | }
51 |
52 | public String readLine() throws IOException {
53 | while (true) {
54 | /* Read into buffer */
55 | int read;
56 | if (index < BUFSIZ) {
57 | read = in.read(buf, index, BUFSIZ - index);
58 | if (read > 0 ) {
59 | index += read;
60 | }
61 | }
62 | else {
63 | read = -1;
64 | }
65 |
66 | /* Look for EOL */
67 | int eol = -1;
68 | int next = -1;
69 |
70 | for (int i = 0; i < index; i++) {
71 | if (buf[i] == '\r') {
72 | if (i + 1 < index && buf[i+1] == '\n') {
73 | eol = i;
74 | next = i + 2;
75 | }
76 | else {
77 | eol = i;
78 | next = i + 1;
79 | }
80 | break;
81 | }
82 | else if (buf[i] == '\n') {
83 | eol = i;
84 | next = i + 1;
85 | break;
86 | }
87 | }
88 |
89 | if (eol != -1) {
90 | String str = new String(buf, 0, eol);
91 | index = index - next;
92 | System.arraycopy(buf, next, buf, 0, index);
93 | return str;
94 | }
95 | else if (read == -1) {
96 | /* EOF */
97 | if (index > 0) {
98 | String str = new String(buf, 0, index);
99 | index = 0;
100 | return str;
101 | }
102 | else {
103 | return null;
104 | }
105 | }
106 | }
107 | }
108 |
109 | }
110 |
--------------------------------------------------------------------------------
/src/j2me/app/Main.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2004 Karl von Randow.
3 | *
4 | * MidpSSH is based upon Telnet Floyd and FloydSSH by Radek Polak.
5 | *
6 | * --LICENSE NOTICE--
7 | * This program is free software; you can redistribute it and/or
8 | * modify it under the terms of the GNU General Public License
9 | * as published by the Free Software Foundation; either version 2
10 | * of the License, or (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program; if not, write to the Free Software
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 | * --LICENSE NOTICE--
21 | *
22 | */
23 |
24 | package app;
25 |
26 | import gui.MainMenu;
27 |
28 | import javax.microedition.midlet.MIDlet;
29 |
30 | public class Main extends MIDlet {
31 |
32 | public static Main instance;
33 |
34 | private static MainMenu mainMenu;
35 |
36 | private static boolean paused;
37 |
38 | /** Constructor */
39 | public Main() {
40 | Main.instance = this;
41 | mainMenu = new MainMenu();
42 | System.out.println("Test\n");
43 | Settings.init();
44 | }
45 |
46 | /** Main method */
47 | protected void startApp() {
48 | if ( !paused ) {
49 | mainMenu.activate();
50 | }
51 | paused = false;
52 | }
53 |
54 | /** Handle pausing the MIDlet */
55 | protected void pauseApp() {
56 | paused = true;
57 | }
58 |
59 | /** Handle destroying the MIDlet */
60 | protected void destroyApp( boolean unconditional ) {
61 | paused = false;
62 | }
63 |
64 | /** Quit the MIDlet */
65 | public static void quitApp() {
66 | instance.destroyApp( true );
67 | instance.notifyDestroyed();
68 | instance = null;
69 | }
70 |
71 | public static void printStack(String msg, long pause) {
72 | msg += " (wait " + pause + "sec)";
73 | try {
74 | throw new IllegalArgumentException(msg);
75 | } catch (IllegalArgumentException iae) {
76 | iae.printStackTrace();
77 | }
78 |
79 | if (pause > 0) {
80 | try {
81 | Thread.sleep(pause * 1000);
82 | }
83 | catch(InterruptedException ie) {
84 | }
85 | }
86 | }
87 |
88 | /*
89 | public static void debug(String msg) {
90 | Alert alert = new Alert("DEBUG");
91 | alert.setString(msg);
92 | alert.setTimeout(Alert.FOREVER);
93 | alert(alert, getDisplay().getCurrent());
94 | }
95 | */
96 | }
--------------------------------------------------------------------------------
/src/j2me/app/MyRecordStore.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2005 Karl von Randow.
3 | *
4 | * --LICENSE NOTICE--
5 | * This program is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU General Public License
7 | * as published by the Free Software Foundation; either version 2
8 | * of the License, or (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 | * --LICENSE NOTICE--
19 | *
20 | */
21 | package app;
22 |
23 | import java.io.ByteArrayInputStream;
24 | import java.io.ByteArrayOutputStream;
25 | import java.io.DataInputStream;
26 | import java.io.DataOutputStream;
27 | import java.io.IOException;
28 | import java.util.Vector;
29 |
30 | import javax.microedition.rms.RecordEnumeration;
31 | import javax.microedition.rms.RecordStore;
32 |
33 | /**
34 | * @author Karl
35 | *
36 | */
37 | public abstract class MyRecordStore {
38 |
39 | protected Vector load(String rmsName, boolean sort) {
40 | try {
41 | RecordStore rec = RecordStore.openRecordStore(rmsName, false);
42 |
43 | RecordEnumeration recs = rec.enumerateRecords(null, null, false);
44 | Vector vector = new Vector();
45 |
46 | while (recs.hasNextElement()) {
47 | byte[] data = recs.nextRecord();
48 | DataInputStream in = new DataInputStream(new ByteArrayInputStream(data));
49 | try {
50 | vector.addElement(read(in));
51 | } catch (IOException e) {
52 |
53 | }
54 | in.close();
55 | }
56 | rec.closeRecordStore();
57 |
58 | //#ifndef small
59 | if (sort) {
60 | insertSort(vector);
61 | }
62 | //#endif
63 | return vector;
64 | } catch (Exception e) {
65 |
66 | }
67 | return new Vector();
68 | }
69 |
70 | protected void insertSort(Vector v) {
71 | int in, out;
72 | int n = v.size();
73 |
74 | for (out = 1; out < n; out++) // out is dividing line
75 | {
76 | Object temp = v.elementAt(out);
77 | in = out;
78 | while (in > 0 && compare(v.elementAt(in - 1), temp) >= 0) {
79 | v.setElementAt(v.elementAt(in - 1), in);
80 | --in;
81 | }
82 | v.setElementAt(temp, in);
83 | }
84 | }
85 |
86 | protected int compare(Object a, Object b) {
87 | return 0;
88 | }
89 |
90 | protected void save(String rmsName, Vector vector) {
91 | if (vector != null) {
92 | try {
93 | try {
94 | RecordStore.deleteRecordStore(rmsName);
95 | } catch (Exception e) {
96 |
97 | }
98 |
99 | RecordStore rec = RecordStore.openRecordStore(rmsName, true);
100 | for (int i = 0; i < vector.size(); i++) {
101 | Object ob = vector.elementAt(i);
102 | ByteArrayOutputStream out = new ByteArrayOutputStream();
103 | DataOutputStream dout = new DataOutputStream(out);
104 | try {
105 | write(dout, ob);
106 | dout.close();
107 |
108 | byte[] data = out.toByteArray();
109 | rec.addRecord(data, 0, data.length);
110 | } catch (IOException e) {
111 |
112 | }
113 | }
114 |
115 | rec.closeRecordStore();
116 | } catch (Exception e) {
117 |
118 | }
119 | }
120 | }
121 |
122 | protected abstract Object read(DataInputStream in) throws IOException;
123 |
124 | protected abstract void write(DataOutputStream out, Object ob) throws IOException;
125 | }
126 |
--------------------------------------------------------------------------------
/src/j2me/app/SessionManager.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2004 Karl von Randow.
3 | *
4 | * MidpSSH is based upon Telnet Floyd and FloydSSH by Radek Polak.
5 | *
6 | * --LICENSE NOTICE--
7 | * This program is free software; you can redistribute it and/or
8 | * modify it under the terms of the GNU General Public License
9 | * as published by the Free Software Foundation; either version 2
10 | * of the License, or (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program; if not, write to the Free Software
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 | * --LICENSE NOTICE--
21 | *
22 | */
23 | package app;
24 |
25 | import java.io.DataInputStream;
26 | import java.io.DataOutputStream;
27 | import java.io.EOFException;
28 | import java.io.IOException;
29 | import java.util.Vector;
30 |
31 | /**
32 | * @author Karl von Randow
33 | *
34 | */
35 | public class SessionManager extends MyRecordStore {
36 |
37 | private static final String RMS_NAME = "sessions";
38 |
39 | private static Vector sessions;
40 |
41 | private static SessionManager me = new SessionManager();
42 |
43 | protected int compare(Object a, Object b) {
44 | return ((SessionSpec) a).alias.compareTo(((SessionSpec) b).alias);
45 | }
46 |
47 | public static Vector getSessions() {
48 | if ( sessions == null ) {
49 | SessionManager.sessions = me.load( RMS_NAME, true );
50 | }
51 | return sessions;
52 | }
53 |
54 | private static void saveSessions() {
55 | me.save( RMS_NAME, sessions );
56 | }
57 |
58 | /**
59 | * @param conn
60 | */
61 | public static void addSession( SessionSpec conn ) {
62 | Vector connections = getSessions();
63 | connections.addElement( conn );
64 | saveSessions();
65 | }
66 |
67 | /**
68 | * @param i
69 | * @return
70 | */
71 | public static SessionSpec getSession( int i ) {
72 | Vector connections = getSessions();
73 | return (i >= connections.size() ? null : (SessionSpec) connections.elementAt( i ));
74 | }
75 |
76 | /**
77 | * @param i
78 | */
79 | public static void deleteSession( int i ) {
80 | Vector connections = getSessions();
81 | if (i < connections.size()) {
82 | connections.removeElementAt( i );
83 | saveSessions();
84 | }
85 | }
86 |
87 | /**
88 | * @param connectionIndex
89 | * @param conn
90 | */
91 | public static void replaceSession( int i, SessionSpec conn ) {
92 | Vector connections = getSessions();
93 | if ( i >= connections.size() ) {
94 | connections.addElement( conn );
95 | }
96 | else {
97 | connections.setElementAt( conn, i );
98 | }
99 | saveSessions();
100 | }
101 | /* (non-Javadoc)
102 | * @see app.MyRecordStore#read(java.io.DataInputStream)
103 | */
104 | protected Object read(DataInputStream in) throws IOException {
105 | SessionSpec spec = new SessionSpec();
106 | try {
107 | spec.read( in );
108 | }
109 | catch (EOFException e) {
110 | /* ignore EOFExceptions as they result from us adding more fields to the end of the spec */
111 | }
112 | return spec;
113 | }
114 | /* (non-Javadoc)
115 | * @see app.MyRecordStore#write(java.io.DataOutputStream, java.lang.Object)
116 | */
117 | protected void write(DataOutputStream out, Object ob) throws IOException {
118 | SessionSpec spec = (SessionSpec) ob;
119 | spec.write( out );
120 | }
121 |
122 | }
--------------------------------------------------------------------------------
/src/j2me/app/SessionSpec.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2004 Karl von Randow.
3 | *
4 | * MidpSSH is based upon Telnet Floyd and FloydSSH by Radek Polak.
5 | *
6 | * --LICENSE NOTICE--
7 | * This program is free software; you can redistribute it and/or
8 | * modify it under the terms of the GNU General Public License
9 | * as published by the Free Software Foundation; either version 2
10 | * of the License, or (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program; if not, write to the Free Software
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 | * --LICENSE NOTICE--
21 | *
22 | */
23 | package app;
24 |
25 | import java.io.DataInputStream;
26 | import java.io.DataOutputStream;
27 | import java.io.IOException;
28 |
29 | /**
30 | * @author Karl von Randow
31 | *
32 | */
33 | public class SessionSpec {
34 | public static final String TYPE_SSH = "ssh";
35 |
36 | public static final String TYPE_TELNET = "telnet";
37 |
38 | public String alias, type, host, username, password;
39 |
40 | public boolean usepublickey;
41 |
42 | //#ifdef blackberryconntypes
43 | public static final int BLACKBERRY_CONN_TYPE_DEFAULT = 0;
44 | public static final int BLACKBERRY_CONN_TYPE_DEVICESIDE = 1;
45 | public static final int BLACKBERRY_CONN_TYPE_PROXY = 2;
46 | public static final int BLACKBERRY_CONN_TYPE_WIFI = 3;
47 |
48 | public int blackberryConnType;
49 | //#endif
50 |
51 | public void read( DataInputStream in ) throws IOException {
52 | alias = in.readUTF();
53 | type = in.readUTF();
54 | host = in.readUTF();
55 | username = in.readUTF();
56 | password = in.readUTF();
57 | //#ifdef blackberryconntypes
58 | blackberryConnType = in.readInt();
59 | //#endif
60 | usepublickey = in.readBoolean();
61 | }
62 |
63 | public void write( DataOutputStream out ) throws IOException {
64 | out.writeUTF( alias );
65 | out.writeUTF( type );
66 | out.writeUTF( host );
67 | out.writeUTF( username );
68 | out.writeUTF( password );
69 | //#ifdef blackberryconntypes
70 | out.writeInt(blackberryConnType);
71 | //#endif
72 | out.writeBoolean(usepublickey);
73 | }
74 | }
--------------------------------------------------------------------------------
/src/j2me/app/Settings.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2004 Karl von Randow.
3 | *
4 | * MidpSSH is based upon Telnet Floyd and FloydSSH by Radek Polak.
5 | *
6 | * --LICENSE NOTICE--
7 | * This program is free software; you can redistribute it and/or
8 | * modify it under the terms of the GNU General Public License
9 | * as published by the Free Software Foundation; either version 2
10 | * of the License, or (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program; if not, write to the Free Software
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 | * --LICENSE NOTICE--
21 | *
22 | */
23 | package app;
24 |
25 | import java.io.DataInputStream;
26 | import java.io.DataOutputStream;
27 | import java.io.IOException;
28 | import java.util.Vector;
29 |
30 | /**
31 | * @author Karl von Randow
32 | */
33 | public class Settings extends MyRecordStore {
34 |
35 | public static final int DEFAULT_BGCOLOR = 0x000000,
36 | DEFAULT_FGCOLOR = 0xffffff;
37 |
38 | public static final int ROT_NORMAL = 0;
39 |
40 | public static final int ROT_270 = 1;
41 |
42 | public static final int ROT_90 = 2;
43 |
44 | public static final int FONT_NORMAL = 0;
45 |
46 | public static final int FONT_DEVICE = 1;
47 |
48 | private static final String RMS_NAME = "settings";
49 |
50 | public static int bgcolor, fgcolor;
51 |
52 | public static int terminalCols, terminalRows;
53 |
54 | public static String terminalType;
55 |
56 | //#ifdef midp2
57 | public static int terminalRotated;
58 | //#endif
59 |
60 | public static int fontMode;
61 |
62 | //#ifndef nofonts
63 | //#ifdef midp2
64 | public static byte lcdFontMode;
65 | //#endif
66 | //#endif
67 |
68 | private static Settings me = new Settings();
69 |
70 | //#ifdef midp2
71 | public static boolean terminalFullscreen;
72 | //#endif
73 |
74 | public static String sessionsImportUrl;
75 |
76 | //#ifdef ssh2
77 | public static int sshVersionPreferred;
78 |
79 | public static boolean ssh2StoreKey;
80 |
81 | public static byte[] ssh2x, ssh2y;
82 |
83 | public static byte[] x, y;
84 |
85 | public static int ssh2KeySize;
86 | //#endif
87 |
88 | public static boolean pollingIO;
89 |
90 | //#ifdef midp2
91 | public static boolean predictiveText;
92 | //#endif
93 |
94 | public static String httpProxy;
95 |
96 | public static int httpProxyMode;
97 |
98 | public static void print() {}
99 |
100 | public static void init() {
101 | defaults();
102 | me.load(RMS_NAME, false);
103 | }
104 |
105 | /**
106 | * @param settings2
107 | */
108 | public static void saveSettings() {
109 | Vector v = new Vector();
110 | v.addElement(null); // doesn't matter what we pass through, it just
111 | // calls write()
112 | me.save(RMS_NAME, v);
113 | }
114 |
115 | public static void defaults() {
116 | bgcolor = DEFAULT_BGCOLOR;
117 | fgcolor = DEFAULT_FGCOLOR;
118 | terminalCols = 0;
119 | terminalRows = 0;
120 | terminalType = "";
121 | //#ifdef midp2
122 | terminalRotated = ROT_NORMAL;
123 | //#endif
124 | fontMode = FONT_NORMAL;
125 | //#ifdef midp2
126 | terminalFullscreen = false;
127 | //#endif
128 | //#ifdef ssh2
129 | sshVersionPreferred = 1;
130 | //#endif
131 | sessionsImportUrl = "http://";
132 | //#ifdef ssh2
133 | ssh2StoreKey = true;
134 | ssh2x = null;
135 | ssh2y = null;
136 | ssh2KeySize = 512;
137 | //#endif
138 | pollingIO = false;
139 | //#ifdef midp2
140 | predictiveText = true;
141 | //#endif
142 | //#ifdef ssh2
143 | x = null;
144 | y = null;
145 | //#endif
146 | //#ifndef nofonts
147 | //#ifdef midp2
148 | lcdFontMode = 0;
149 | //#endif
150 | //#endif
151 | httpProxy = "";
152 | httpProxyMode = 0;
153 | }
154 |
155 | /*
156 | * (non-Javadoc)
157 | *
158 | * @see app.MyRecordStore#read(java.io.DataInputStream)
159 | */
160 | protected Object read(DataInputStream in) throws IOException {
161 | fgcolor = in.readInt();
162 | bgcolor = in.readInt();
163 | terminalCols = in.readInt();
164 | terminalRows = in.readInt();
165 | terminalType = in.readUTF();
166 | //#ifdef midp2
167 | terminalRotated = in.readInt();
168 | //#endif
169 | fontMode = in.readInt();
170 | //#ifdef midp2
171 | terminalFullscreen = in.readBoolean();
172 | //#endif
173 | //#ifdef ssh2
174 | sshVersionPreferred = in.readInt();
175 | //#endif
176 | sessionsImportUrl = in.readUTF();
177 | //#ifdef ssh2
178 | ssh2StoreKey = in.readBoolean();
179 | ssh2x = readByteArray(in);
180 | ssh2y = readByteArray(in);
181 | ssh2KeySize = in.readInt();
182 | //#endif
183 | pollingIO = in.readBoolean();
184 | //#ifdef midp2
185 | predictiveText = in.readBoolean();
186 | //#endif
187 | //#ifdef ssh2
188 | x = readByteArray(in);
189 | y = readByteArray(in);
190 | //#endif
191 | //#ifndef nofonts
192 | //#ifdef midp2
193 | lcdFontMode = in.readByte();
194 | //#endif
195 | //#endif
196 | httpProxy = in.readUTF();
197 | httpProxyMode = in.readByte();
198 | return null;
199 | }
200 |
201 | /*
202 | * (non-Javadoc)
203 | *
204 | * @see app.MyRecordStore#write(java.io.DataOutputStream, java.lang.Object)
205 | */
206 | protected void write(DataOutputStream out, Object ob) throws IOException {
207 | out.writeInt(fgcolor);
208 | out.writeInt(bgcolor);
209 | out.writeInt(terminalCols);
210 | out.writeInt(terminalRows);
211 | out.writeUTF(terminalType);
212 | //#ifdef midp2
213 | out.writeInt(terminalRotated);
214 | //#endif
215 | out.writeInt(fontMode);
216 | //#ifdef midp2
217 | out.writeBoolean(terminalFullscreen);
218 | //#endif
219 | //#ifdef ssh2
220 | out.writeInt(sshVersionPreferred);
221 | //#endif
222 | out.writeUTF(sessionsImportUrl);
223 | //#ifdef ssh2
224 | out.writeBoolean(ssh2StoreKey);
225 | writeByteArray(out, ssh2x);
226 | writeByteArray(out, ssh2y);
227 | out.writeInt(ssh2KeySize);
228 | //#endif
229 | out.writeBoolean(pollingIO);
230 | //#ifdef midp2
231 | out.writeBoolean(predictiveText);
232 | //#endif
233 | //#ifdef ssh2
234 | writeByteArray(out, x);
235 | writeByteArray(out, y);
236 | //#endif
237 | //#ifndef nofonts
238 | //#ifdef midp2
239 | out.writeByte(lcdFontMode);
240 | //#endif
241 | //#endif
242 | out.writeUTF(httpProxy);
243 | out.writeByte(httpProxyMode);
244 | }
245 |
246 | //#ifdef ssh2
247 | private byte[] readByteArray(DataInputStream in) throws IOException {
248 | int length = in.readInt();
249 | if (length == 0) {
250 | return null;
251 | } else {
252 | byte[] buf = new byte[length];
253 | in.readFully(buf);
254 | return buf;
255 | }
256 | }
257 |
258 | private void writeByteArray(DataOutputStream out, byte[] ray)
259 | throws IOException {
260 | if (ray != null) {
261 | out.writeInt(ray.length);
262 | out.write(ray);
263 | } else {
264 | out.writeInt(0);
265 | }
266 | }
267 | //#endif
268 | }
269 |
--------------------------------------------------------------------------------
/src/j2me/app/session/HttpInboundStream.java:
--------------------------------------------------------------------------------
1 | package app.session;
2 |
3 | import java.io.EOFException;
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 |
7 | import javax.microedition.io.Connector;
8 | import javax.microedition.io.HttpConnection;
9 |
10 | public class HttpInboundStream extends InputStream {
11 |
12 | private String url;
13 |
14 | private byte[] buf;
15 |
16 | private int offset, length;
17 |
18 | public HttpInboundStream(String url) {
19 | this.url = url;
20 | this.buf = new byte[10240];
21 | this.offset = 0;
22 | this.length = 0;
23 | }
24 |
25 | public int read() throws IOException {
26 | if (length - offset <= 0) {
27 | fillBuffer();
28 | }
29 |
30 | if (length - offset <= 0) {
31 | return -1;
32 | }
33 |
34 | return buf[offset++];
35 | }
36 |
37 | public int read(byte[] destbuf, int destoffset, int destlength) throws IOException {
38 | if (length - offset <= 0) {
39 | fillBuffer();
40 | }
41 |
42 | if (length - offset <= 0) {
43 | throw new EOFException();
44 | }
45 |
46 | int readlength = Math.min(length - offset, destlength - destoffset);
47 | System.arraycopy(buf, offset, destbuf, destoffset, readlength);
48 | offset += readlength;
49 | return readlength;
50 | }
51 |
52 | public int read(byte[] buf) throws IOException {
53 | return read(buf, 0, buf.length);
54 | }
55 |
56 | private void fillBuffer() throws IOException {
57 | /* Note that we assume that the server will never send responses larger than our buffer size. If the server
58 | * does we'll probably go into an infinite loop.
59 | */
60 | HttpConnection conn = (HttpConnection) Connector.open(url, Connector.READ_WRITE, false);
61 | InputStream in = conn.openInputStream();
62 | int offset = 0;
63 | int read = in.read(buf, offset, buf.length - offset);
64 | while (read != -1) {
65 | offset += read;
66 | read = in.read(buf, offset, buf.length - offset);
67 | }
68 |
69 | length = offset;
70 | this.offset = 0;
71 | in.close();
72 | }
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/src/j2me/app/session/HttpOutboundStream.java:
--------------------------------------------------------------------------------
1 | package app.session;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.IOException;
5 | import java.io.OutputStream;
6 |
7 | import javax.microedition.io.Connector;
8 | import javax.microedition.io.HttpConnection;
9 |
10 | public class HttpOutboundStream extends ByteArrayOutputStream {
11 |
12 | private String url;
13 |
14 | public HttpOutboundStream(String url) {
15 | this.url = url;
16 | }
17 |
18 | public synchronized void close() throws IOException {
19 | flush();
20 | super.close();
21 | }
22 |
23 | public void flush() throws IOException {
24 | super.flush();
25 |
26 | HttpConnection outbound = (HttpConnection) Connector.open(url, Connector.READ_WRITE, false);
27 | outbound.setRequestMethod(HttpConnection.POST);
28 | OutputStream out = outbound.openOutputStream();
29 | out.write(toByteArray());
30 | out.close();
31 | outbound.openInputStream().close();
32 |
33 | reset();
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/j2me/app/session/ISshSession.java:
--------------------------------------------------------------------------------
1 | /*
2 | * ISshSession.java
3 | *
4 | * Copyright (c) 2010 VDP .
5 | *
6 | * This file is part of MidpSSH.
7 | *
8 | * MidpSSH is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * MidpSSH is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with MidpSSH. If not, see .
20 | */
21 |
22 | package app.session;
23 |
24 | import java.io.IOException;
25 |
26 | /**
27 | *
28 | * @author VDP
29 | */
30 | public interface ISshSession {
31 | public void sendData( byte [] data ) throws IOException;
32 | public void prompt(String name, String instruction,
33 | String[] prompts, boolean[] echos) throws IOException;
34 | public String getTerminalID();
35 | public int getTerminalHeight();
36 | public int getTerminalWidth();
37 | }
38 |
--------------------------------------------------------------------------------
/src/j2me/app/session/MacroSetManager.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2004 Karl von Randow.
3 | *
4 | * MidpSSH is based upon Telnet Floyd and FloydSSH by Radek Polak.
5 | *
6 | * --LICENSE NOTICE--
7 | * This program is free software; you can redistribute it and/or
8 | * modify it under the terms of the GNU General Public License
9 | * as published by the Free Software Foundation; either version 2
10 | * of the License, or (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program; if not, write to the Free Software
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 | * --LICENSE NOTICE--
21 | *
22 | */
23 | package app.session;
24 |
25 | import gui.session.macros.MacroSet;
26 |
27 | import java.io.DataInputStream;
28 | import java.io.DataOutputStream;
29 | import java.io.IOException;
30 | import java.util.Vector;
31 |
32 | import app.MyRecordStore;
33 |
34 | /**
35 | * @author Karl von Randow
36 | *
37 | */
38 | public class MacroSetManager extends MyRecordStore {
39 |
40 | private static final String RMS_NAME = "macros";
41 |
42 | private static Vector macroSets;
43 |
44 | private static MacroSetManager me = new MacroSetManager();
45 |
46 | protected int compare(Object a, Object b) {
47 | MacroSet aa = (MacroSet) a;
48 | MacroSet bb = (MacroSet) b;
49 | return aa.name.compareTo(bb.name);
50 | }
51 |
52 | public static Vector getMacroSets() {
53 | if ( macroSets == null ) {
54 | MacroSetManager.macroSets = me.load( RMS_NAME, true );
55 | if ( macroSets.isEmpty() ) {
56 | MacroSet macroSet = new MacroSet();
57 | macroSet.name = "Untitled Set";
58 | macroSets.addElement( macroSet );
59 | saveMacroSets();
60 | }
61 | }
62 | return macroSets;
63 | }
64 |
65 | public static void saveMacroSets() {
66 | me.save( RMS_NAME, macroSets );
67 | }
68 |
69 | /**
70 | * @param i
71 | * @return
72 | */
73 | public static MacroSet getMacroSet( int i ) {
74 | Vector macroSets = getMacroSets();
75 | return ( macroSets == null || i >= macroSets.size() ? null : (MacroSet) macroSets.elementAt( i ));
76 | }
77 |
78 | /**
79 | * @param conn
80 | */
81 | public static void addMacroSet( MacroSet macroSet ) {
82 | Vector macroSets = getMacroSets();
83 | macroSets.addElement( macroSet );
84 | saveMacroSets();
85 | }
86 |
87 | /**
88 | * @param i
89 | */
90 | public static void deleteMacroSet( int i ) {
91 | Vector macroSets = getMacroSets();
92 | if (i < macroSets.size() ) {
93 | macroSets.removeElementAt( i );
94 | saveMacroSets();
95 | }
96 | }
97 |
98 | /**
99 | * @param connectionIndex
100 | * @param conn
101 | */
102 | public static void replaceMacroSet( int i, MacroSet macroSet ) {
103 | Vector macroSets = getMacroSets();
104 | if ( i >= macroSets.size() ) {
105 | macroSets.addElement( macroSet );
106 | }
107 | else {
108 | macroSets.setElementAt( macroSet, i );
109 | }
110 | saveMacroSets();
111 | }
112 | /* (non-Javadoc)
113 | * @see app.MyRecordStore#read(java.io.DataInputStream)
114 | */
115 | protected Object read(DataInputStream in) throws IOException {
116 | MacroSet macroSet = new MacroSet();
117 | macroSet.read( in );
118 | return macroSet;
119 | }
120 | /* (non-Javadoc)
121 | * @see app.MyRecordStore#write(java.io.DataOutputStream, java.lang.Object)
122 | */
123 | protected void write(DataOutputStream out, Object ob) throws IOException {
124 | MacroSet macroSet = (MacroSet) ob;
125 | macroSet.write( out );
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/src/j2me/app/session/SessionIOHandler.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2004 Karl von Randow.
3 | *
4 | * MidpSSH is based upon Telnet Floyd and FloydSSH by Radek Polak.
5 | *
6 | * --LICENSE NOTICE--
7 | * This program is free software; you can redistribute it and/or
8 | * modify it under the terms of the GNU General Public License
9 | * as published by the Free Software Foundation; either version 2
10 | * of the License, or (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program; if not, write to the Free Software
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 | * --LICENSE NOTICE--
21 | *
22 | */
23 | package app.session;
24 |
25 | import java.io.IOException;
26 |
27 | /**
28 | * @author Karl von Randow
29 | *
30 | */
31 | public interface SessionIOHandler {
32 | public void handleSendData( byte[] data, int offset, int length ) throws IOException;
33 |
34 | public void handleReceiveData( byte[] data, int offset, int length ) throws IOException;
35 | }
--------------------------------------------------------------------------------
/src/j2me/app/session/SshSession.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2004 Karl von Randow.
3 | *
4 | * MidpSSH is based upon Telnet Floyd and FloydSSH by Radek Polak.
5 | *
6 | * --LICENSE NOTICE--
7 | * This program is free software; you can redistribute it and/or
8 | * modify it under the terms of the GNU General Public License
9 | * as published by the Free Software Foundation; either version 2
10 | * of the License, or (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program; if not, write to the Free Software
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 | * --LICENSE NOTICE--
21 | *
22 | */
23 | package app.session;
24 |
25 | import gui.MainMenu;
26 |
27 | import java.io.IOException;
28 |
29 | import javax.microedition.lcdui.Command;
30 | import javax.microedition.lcdui.CommandListener;
31 | import javax.microedition.lcdui.Displayable;
32 | import javax.microedition.lcdui.Form;
33 | import javax.microedition.lcdui.StringItem;
34 | import javax.microedition.lcdui.TextField;
35 |
36 | import ssh.SshIO;
37 | import app.SessionSpec;
38 | import app.Settings;
39 |
40 | /**
41 | * @author Karl von Randow
42 | *
43 | */
44 | public class SshSession extends Session
45 | implements SessionIOHandler, ISshSession
46 | //#ifdef keybrdinteractive
47 | , CommandListener
48 | //#endif
49 | {
50 |
51 |
52 | private SshIO sshIO;
53 |
54 | public void connect(SessionSpec spec, String username, String password) {
55 | sshIO = new SshIO( this );
56 | sshIO.login = username != null ? username : spec.username;
57 | sshIO.password = password != null ? password : spec.password;
58 | sshIO.usepublickey = spec.usepublickey;
59 | super.connect( spec, this );
60 | }
61 |
62 | /*
63 | * (non-Javadoc)
64 | *
65 | * @see telnet.Session#defaultPort()
66 | */
67 | protected int defaultPort() {
68 | return 22;
69 | }
70 | /*
71 | * (non-Javadoc)
72 | *
73 | * @see app.session.SessionIOListener#receiveData(byte[], int, int)
74 | */
75 | public void handleReceiveData( byte[] data, int offset, int length ) throws IOException {
76 | byte[] result;
77 | result = sshIO.handleSSH( data, offset, length );
78 | super.receiveData( result, 0, result.length );
79 | }
80 |
81 | /*
82 | * (non-Javadoc)
83 | *
84 | * @see app.session.SessionIOListener#sendData(byte[], int, int)
85 | */
86 | public void handleSendData( byte[] data, int offset, int length ) throws IOException {
87 | if ( length > 0 ) {
88 | sshIO.sendData( data, offset, length );
89 | }
90 | else {
91 | sshIO.Send_SSH_NOOP();
92 | }
93 | }
94 |
95 | /*
96 | * Receive data send back by SshIO and send it out onto the network
97 | */
98 | public void sendData( byte [] data ) throws IOException {
99 | super.sendData( data, 0, data.length );
100 | }
101 |
102 | public String getTerminalID() {
103 | if ( Settings.terminalType.length() > 0 ) {
104 | return Settings.terminalType;
105 | }
106 | else {
107 | return emulation.getTerminalID();
108 | }
109 | }
110 |
111 | public int getTerminalWidth() {
112 | return emulation.width;
113 | }
114 |
115 | public int getTerminalHeight() {
116 | return emulation.height;
117 | }
118 |
119 | //#ifdef keybrdinteractive
120 | public void prompt(String name, String instruction, String[] prompts, boolean[] echos) throws IOException {
121 | if (prompts.length > 0) {
122 | /* Show prompt */
123 | if (name.length() == 0) {
124 | name = "Authenticate";
125 | }
126 | Form form = new Form(name);
127 |
128 | if (instruction.length() > 0) {
129 | form.append(new StringItem("Instructions", instruction));
130 | }
131 | promptFields = new TextField[prompts.length];
132 | for (int i = 0; i < prompts.length; i++) {
133 | promptFields[i] = new TextField(prompts[i], "", 255, TextField.ANY | (echos[i] ? 0 : TextField.PASSWORD));
134 | if (prompts[i].toLowerCase().startsWith("password:")) {
135 | promptFields[i].setString(sshIO.password);
136 | }
137 | form.append(promptFields[i]);
138 | }
139 | form.addCommand(MainMenu.okCommand);
140 | form.addCommand(MainMenu.backCommand);
141 | form.setCommandListener(this);
142 | MainMenu.setDisplay(form);
143 | }
144 | else {
145 | sshIO.sendUserauthInfoResponse(new String[0]);
146 | }
147 | }
148 |
149 | private TextField[] promptFields;
150 |
151 | public void commandAction(Command cmd, Displayable displayable) {
152 | try {
153 | if (cmd == MainMenu.okCommand) {
154 | String[] responses = new String[promptFields.length];
155 | for (int i = 0; i < responses.length; i++) {
156 | responses[i] = promptFields[i].getString();
157 | }
158 | sshIO.sendUserauthInfoResponse(responses);
159 | }
160 | else {
161 | sshIO.sendUserauthInfoResponse(new String[0]);
162 | }
163 | }
164 | catch (IOException e) {
165 |
166 | }
167 |
168 | promptFields = null;
169 | activate();
170 | }
171 | //#endif
172 | }
--------------------------------------------------------------------------------
/src/j2me/app/session/TelnetSession.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2004 Karl von Randow.
3 | *
4 | * MidpSSH is based upon Telnet Floyd and FloydSSH by Radek Polak.
5 | *
6 | * --LICENSE NOTICE--
7 | * This program is free software; you can redistribute it and/or
8 | * modify it under the terms of the GNU General Public License
9 | * as published by the Free Software Foundation; either version 2
10 | * of the License, or (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program; if not, write to the Free Software
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 | * --LICENSE NOTICE--
21 | *
22 | */
23 | package app.session;
24 |
25 | import java.io.IOException;
26 |
27 | import telnet.Dimension;
28 | import telnet.TelnetProtocolHandler;
29 | import app.SessionSpec;
30 | import app.Settings;
31 |
32 | /**
33 | * @author Karl von Randow
34 | *
35 | */
36 | public class TelnetSession extends Session implements SessionIOHandler {
37 | public TelnetSession() {
38 | super();
39 |
40 | // Default to true in telnet and then turn off when told to
41 | emulation.setLocalEcho( true );
42 | }
43 |
44 | public void connect( SessionSpec spec ) {
45 | telnet = new TelnetProtocolHandler() {
46 | /** get the current terminal type */
47 | public String getTerminalType() {
48 | if ( Settings.terminalType.length() > 0 ) {
49 | return Settings.terminalType;
50 | }
51 | else {
52 | return emulation.getTerminalID();
53 | }
54 | }
55 |
56 | /** get the current window size */
57 | public Dimension getWindowSize() {
58 | return new Dimension( emulation.width, emulation.height );
59 | }
60 |
61 | /** notify about local echo */
62 | public void setLocalEcho( boolean echo ) {
63 | emulation.localecho = echo;
64 | }
65 |
66 | /** notify about EOR end of record */
67 | public void notifyEndOfRecord() {
68 | // only used when EOR needed, like for line mode
69 | }
70 |
71 | /** write data to our back end */
72 | public void write( byte[] b ) throws IOException {
73 | /*for ( int i = 0; i < b.length; i++ ) {
74 | System.out.println( "SEND " + b[i] + "=" + (char) b[i] );
75 | }*/
76 | TelnetSession.this.sendData( b, 0, b.length );
77 | }
78 | };
79 |
80 | super.connect( spec, this );
81 | }
82 |
83 | /*
84 | * (non-Javadoc)
85 | *
86 | * @see telnet.Session#defaultPort()
87 | */
88 | protected int defaultPort() {
89 | return 23;
90 | }
91 |
92 | private TelnetProtocolHandler telnet;
93 |
94 | /*
95 | * (non-Javadoc)
96 | *
97 | * @see terminal.TerminalIOListener#receiveData(byte[])
98 | */
99 | public void handleReceiveData( byte[] data, int offset, int length ) throws IOException {
100 | telnet.inputfeed( data, offset, length );
101 | int n;
102 | do {
103 | n = telnet.negotiate( data, offset, length );
104 | if ( n > 0 ) {
105 | /*for ( int i = offset; i < offset + n; i++ ) {
106 | System.out.println( "RECV " + data[i] + "=" + (char) data[i] );
107 | }*/
108 | TelnetSession.this.receiveData( data, offset, n );
109 | }
110 | }
111 | while ( n != -1 );
112 | }
113 |
114 | /*
115 | * (non-Javadoc)
116 | *
117 | * @see terminal.TerminalIOListener#sendData(byte[])
118 | */
119 | public void handleSendData( byte[] data, int offset, int length ) throws IOException {
120 | if ( length > 0 ) {
121 | telnet.transpose( data, offset, length );
122 | }
123 | else {
124 | telnet.sendTelnetNOP();
125 | }
126 | }
127 | }
--------------------------------------------------------------------------------
/src/j2me/awt/AwtMain.java:
--------------------------------------------------------------------------------
1 | /*
2 | * AwtMain.java
3 | *
4 | * Copyright (c) 2010 VDP .
5 | *
6 | * This file is part of MidpSSH.
7 | *
8 | * MidpSSH is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * MidpSSH is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with MidpSSH. If not, see .
20 | */
21 |
22 | package awt;
23 |
24 | import java.awt.BorderLayout;
25 | import java.awt.Button;
26 | import java.awt.Dimension;
27 | import java.awt.Frame;
28 | import java.awt.Panel;
29 | import java.awt.event.WindowAdapter;
30 | import java.awt.event.WindowEvent;
31 | import kindle.RemoteKbdReceiver;
32 | import org.apache.log4j.Logger;
33 | import org.apache.log4j.PropertyConfigurator;
34 | import terminal.VT320;
35 |
36 | /**
37 | * AWT interface on top of MidpSSH infrastructure
38 | *
39 | * @author VDP
40 | */
41 | public class AwtMain {
42 |
43 | private Frame root;
44 | private AwtSshSession session;
45 | private Logger log;
46 |
47 | private void configLog() {
48 | PropertyConfigurator.configure("conf/log4j.properties");
49 | }
50 |
51 | public AwtMain(String title) {
52 | configLog();
53 | this.log = Logger.getLogger(AwtMain.class.getName());
54 | log.debug("Log started");
55 | //System.out.println("Work dir:" + System.getProperty("user.dir"));
56 | root = new Frame(title);
57 | root.setSize(800, 600);
58 | root.addWindowListener(
59 | new WindowAdapter() {
60 | public void windowClosing(WindowEvent e) {
61 | System.exit(0);
62 | }
63 | }
64 | );
65 | Panel panel = new Panel();
66 | Button b1 = new Button("Does nothing");
67 | panel.add(b1);
68 | //root.add(panel, BorderLayout.NORTH);
69 | //Settings.defaults();
70 | this.session = new AwtSshSession();
71 | AwtTerminal term = new AwtTerminal(session.getEmulation(), session);
72 |
73 | RemoteKbdReceiver rk = new RemoteKbdReceiver(3333, term, term);
74 | rk.start();
75 |
76 | root.add(term, BorderLayout.CENTER);
77 | session.connect("localhost", 22, "user", "pass");
78 | //System.out.print("Connect ...\n");
79 | term.setFocusable(true);
80 | term.setFocusTraversalKeysEnabled(false);
81 | term.setPreferredSize(new Dimension(1200, 950));
82 |
83 | root.pack();
84 | root.setVisible(true);
85 | //printTerminal(session.getTerminal().buffer);
86 | }
87 |
88 | public void printTerminal(VT320 buf) {
89 | for (int i = 0; i < buf.charArray.length; i++){
90 | String line = new String(buf.charArray[i]);
91 | System.out.println(line + "\n");
92 | }
93 |
94 | }
95 |
96 | public static void main(String[] args) {
97 | AwtMain am = new AwtMain("Test");
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/j2me/awt/AwtSshSession.java:
--------------------------------------------------------------------------------
1 | /*
2 | * AwtSshSession.java
3 | *
4 | * Copyright (c) 2010 VDP .
5 | *
6 | * This file is part of MidpSSH.
7 | *
8 | * MidpSSH is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * MidpSSH is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with MidpSSH. If not, see .
20 | */
21 |
22 | package awt;
23 |
24 | import app.session.ISshSession;
25 | import app.session.SessionIOHandler;
26 | import java.io.IOException;
27 | import ssh.SshIO;
28 |
29 | /**
30 | *
31 | * @author VDP
32 | */
33 | public class AwtSshSession extends AwtSession
34 | implements SessionIOHandler, ISshSession {
35 |
36 | private SshIO sshIO;
37 |
38 | public void connect(String host, int port,
39 | String username, String password) {
40 | sshIO = new SshIO(this);
41 | sshIO.login = username;
42 | sshIO.password = password;
43 | //sshIO.usepublickey = spec.usepublickey;
44 | super.connect(host, port, username, password, this);
45 | }
46 |
47 | /*
48 | * (non-Javadoc)
49 | *
50 | * @see telnet.Session#defaultPort()
51 | */
52 | protected int defaultPort() {
53 | return 22;
54 | }
55 | /*
56 | * (non-Javadoc)
57 | *
58 | * @see app.session.SessionIOListener#receiveData(byte[], int, int)
59 | */
60 | public void handleReceiveData( byte[] data, int offset, int length ) throws IOException {
61 | byte[] result;
62 | //System.out.println("Handle received data: " + new String(data) + "\n");
63 | result = sshIO.handleSSH( data, offset, length );
64 | super.receiveData( result, 0, result.length );
65 | }
66 |
67 | /*
68 | * (non-Javadoc)
69 | *
70 | * @see app.session.SessionIOListener#sendData(byte[], int, int)
71 | */
72 | public void handleSendData( byte[] data, int offset, int length ) throws IOException {
73 | if ( length > 0 ) {
74 | sshIO.sendData( data, offset, length );
75 | }
76 | else {
77 | sshIO.Send_SSH_NOOP();
78 | }
79 | }
80 |
81 | /*
82 | * Receive data send back by SshIO and send it out onto the network
83 | */
84 | public void sendData( byte [] data ) throws IOException {
85 | super.sendData( data, 0, data.length );
86 | }
87 |
88 | public String getTerminalID() {
89 | return emulation.getTerminalID();
90 | }
91 |
92 | public int getTerminalWidth() {
93 | return emulation.width;
94 | }
95 |
96 | public int getTerminalHeight() {
97 | return emulation.height;
98 | }
99 |
100 | public void prompt(String name, String instruction, String[] prompts, boolean[] echos) throws IOException {
101 | System.out.println("PROMPT");
102 | throw new UnsupportedOperationException("AWT SSH Session prompt()");
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/src/j2me/gui/Activatable.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2004 Karl von Randow.
3 | *
4 | * MidpSSH is based upon Telnet Floyd and FloydSSH by Radek Polak.
5 | *
6 | * --LICENSE NOTICE--
7 | * This program is free software; you can redistribute it and/or
8 | * modify it under the terms of the GNU General Public License
9 | * as published by the Free Software Foundation; either version 2
10 | * of the License, or (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program; if not, write to the Free Software
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 | * --LICENSE NOTICE--
21 | *
22 | */
23 | package gui;
24 |
25 |
26 | /**
27 | * @author Karl von Randow
28 | *
29 | */
30 | public interface Activatable {
31 |
32 | public void activate();
33 |
34 | public void activate( Activatable back );
35 | }
--------------------------------------------------------------------------------
/src/j2me/gui/EditableForm.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2004 Karl von Randow.
3 | *
4 | * MidpSSH is based upon Telnet Floyd and FloydSSH by Radek Polak.
5 | *
6 | * --LICENSE NOTICE--
7 | * This program is free software; you can redistribute it and/or
8 | * modify it under the terms of the GNU General Public License
9 | * as published by the Free Software Foundation; either version 2
10 | * of the License, or (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program; if not, write to the Free Software
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 | * --LICENSE NOTICE--
21 | *
22 | */
23 | package gui;
24 |
25 | import javax.microedition.lcdui.Command;
26 | import javax.microedition.lcdui.CommandListener;
27 | import javax.microedition.lcdui.Displayable;
28 | import javax.microedition.lcdui.Form;
29 |
30 | /**
31 | * @author Karl von Randow
32 | */
33 | public abstract class EditableForm extends Form implements CommandListener, Activatable {
34 |
35 | private Activatable back;
36 |
37 | public EditableForm( String title ) {
38 | super( title );
39 |
40 | addCommand( MainMenu.backCommand );
41 | setCommandListener( this );
42 | }
43 |
44 | /*
45 | * (non-Javadoc)
46 | *
47 | * @see javax.microedition.lcdui.CommandListener#commandAction(javax.microedition.lcdui.Command,
48 | * javax.microedition.lcdui.Displayable)
49 | */
50 | public void commandAction( Command command, Displayable displayed ) {
51 | if ( command == MainMenu.backCommand ) {
52 | doBack();
53 | } else if (command == MainMenu.okCommand) {
54 | doOK();
55 | }
56 | }
57 |
58 | protected void addOKCommand() {
59 | addCommand(MainMenu.okCommand);
60 | }
61 |
62 | protected void doBack() {
63 | back.activate();
64 | }
65 |
66 | protected void doOK() {
67 | back.activate();
68 | }
69 |
70 | /* (non-Javadoc)
71 | * @see gui.Activatable#activate()
72 | */
73 | public void activate() {
74 | MainMenu.setDisplay( this );
75 | }
76 | /* (non-Javadoc)
77 | * @see gui.Activatable#activate(gui.Activatable)
78 | */
79 | public void activate( Activatable back ) {
80 | this.back = back;
81 | activate();
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/j2me/gui/EditableMenu.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2004 Karl von Randow.
3 | *
4 | * MidpSSH is based upon Telnet Floyd and FloydSSH by Radek Polak.
5 | *
6 | * --LICENSE NOTICE--
7 | * This program is free software; you can redistribute it and/or
8 | * modify it under the terms of the GNU General Public License
9 | * as published by the Free Software Foundation; either version 2
10 | * of the License, or (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program; if not, write to the Free Software
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 | * --LICENSE NOTICE--
21 | *
22 | */
23 | package gui;
24 |
25 | import javax.microedition.lcdui.Command;
26 | import javax.microedition.lcdui.CommandListener;
27 | import javax.microedition.lcdui.Displayable;
28 | import javax.microedition.lcdui.List;
29 |
30 | /**
31 | * @author Karl von Randow
32 | *
33 | */
34 | public abstract class EditableMenu extends List implements CommandListener, Activatable {
35 |
36 | protected static Command newCommand = new Command( "New", Command.SCREEN, 8 );
37 |
38 | protected static Command editCommand = new Command( "Edit", Command.ITEM, 9 );
39 |
40 | protected static Command deleteCommand = new Command( "Delete", Command.ITEM, 10 );
41 |
42 | protected Command selectCommand = List.SELECT_COMMAND;
43 |
44 | private Activatable back;
45 |
46 | public EditableMenu( String title ) {
47 | super( title, List.IMPLICIT );
48 |
49 | //addCommand( selectCommand );
50 | addCommand( newCommand );
51 | addCommand( editCommand );
52 | addCommand( deleteCommand );
53 | addCommand( MainMenu.backCommand );
54 |
55 | setCommandListener( this );
56 | }
57 |
58 | protected void replaceSelectCommand( Command selectCommand ) {
59 | //removeCommand( this.selectCommand );
60 | this.selectCommand = selectCommand;
61 |
62 | //#ifdef midp2
63 | super.setSelectCommand( selectCommand );
64 | //#else
65 | //#ifndef blackberry
66 | // On the blackberry we don't require the command to be added as the implicit command is also listed in
67 | // the menu.
68 | addCommand( selectCommand );
69 | //#endif
70 | //#endif
71 | }
72 |
73 | //#ifndef midp2
74 | public void deleteAll() {
75 | while ( size() > 0 ) {
76 | delete(0);
77 | }
78 | }
79 | //#endif
80 |
81 | protected abstract void addItems();
82 |
83 | /* (non-Javadoc)
84 | * @see javax.microedition.lcdui.CommandListener#commandAction(javax.microedition.lcdui.Command, javax.microedition.lcdui.Displayable)
85 | */
86 | public void commandAction( Command command, Displayable displayable ) {
87 | if ( command == List.SELECT_COMMAND || command == selectCommand ) {
88 | int i = getSelectedIndex();
89 | if ( i >= 0 && i < size() ) {
90 | doSelect( getSelectedIndex() );
91 | }
92 | }
93 | else if ( command == newCommand ) {
94 | doNew();
95 | }
96 | else if ( command == editCommand ) {
97 | int i = getSelectedIndex();
98 | if ( i >= 0 && i < size() ) {
99 | doEdit( i );
100 | }
101 | }
102 | else if ( command == deleteCommand ) {
103 | int i = getSelectedIndex();
104 | if ( i >= 0 && i < size() ) {
105 | doDelete( i );
106 | }
107 | }
108 | else if ( command == MainMenu.backCommand ) {
109 | doBack();
110 | }
111 | }
112 |
113 | /* (non-Javadoc)
114 | * @see app.Activatable#activate()
115 | */
116 | public void activate() {
117 | addItems();
118 | MainMenu.setDisplay( this );
119 | }
120 |
121 | public void activate( Activatable back ) {
122 | this.back = back;
123 | activate();
124 | }
125 |
126 | protected abstract void doSelect( int i );
127 |
128 | protected abstract void doEdit( int i );
129 |
130 | protected abstract void doDelete( int i );
131 |
132 | protected abstract void doNew();
133 |
134 | protected void doBack() {
135 | back.activate();
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/src/j2me/gui/MainMenu.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2004 Karl von Randow.
3 | *
4 | * MidpSSH is based upon Telnet Floyd and FloydSSH by Radek Polak.
5 | *
6 | * --LICENSE NOTICE--
7 | * This program is free software; you can redistribute it and/or
8 | * modify it under the terms of the GNU General Public License
9 | * as published by the Free Software Foundation; either version 2
10 | * of the License, or (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program; if not, write to the Free Software
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 | * --LICENSE NOTICE--
21 | *
22 | */
23 | package gui;
24 |
25 | import gui.session.macros.MacrosMenu;
26 | import gui.settings.SettingsMenu;
27 |
28 | import javax.microedition.lcdui.Alert;
29 | import javax.microedition.lcdui.AlertType;
30 | import javax.microedition.lcdui.Command;
31 | import javax.microedition.lcdui.CommandListener;
32 | import javax.microedition.lcdui.Display;
33 | import javax.microedition.lcdui.Displayable;
34 | import javax.microedition.lcdui.Form;
35 | import javax.microedition.lcdui.List;
36 | import javax.microedition.lcdui.StringItem;
37 |
38 | import app.Main;
39 | import app.session.Session;
40 |
41 | /**
42 | * @author Karl von Randow
43 | */
44 | public class MainMenu extends List implements CommandListener, Activatable {
45 |
46 | public static final Command okCommand = new Command( "OK", Command.OK, 1 );
47 |
48 | public static final Command backCommand = new Command( "Back", Command.BACK, 99 );
49 |
50 | private static Command quitCommand = new Command( "Quit", Command.EXIT, 2 );
51 |
52 | private static MainMenu instance;
53 |
54 | public static boolean useColors;
55 |
56 | private static Session currentSession;
57 |
58 | private SessionsMenu sessionsMenu;
59 |
60 | //#ifndef nomacros
61 | private static MacrosMenu macrosMenu;
62 | //#endif
63 | private static Activatable settingsMenu;
64 |
65 | private static final String ITEM_SESSIONS = "Sessions";
66 | //#ifndef nomacros
67 | private static final String ITEM_MACROS = "Macros";
68 | //#endif
69 | //#ifndef nosettings
70 | private static final String ITEM_SETTINGS = "Settings";
71 | //#endif
72 | //#ifndef nodocs
73 | private static final String ITEM_ABOUT = "About MidpSSH";
74 | private static final String ITEM_HELP = "Help";
75 | //#endif
76 | private static final String ITEM_QUIT = "Quit";
77 |
78 | /**
79 | * @param arg0
80 | * @param arg1
81 | */
82 | public MainMenu() {
83 | super( "MidpSSH", List.IMPLICIT );
84 |
85 | MainMenu.instance = this;
86 |
87 | useColors = getDisplay().isColor();
88 |
89 | append( ITEM_SESSIONS, null );
90 | //#ifndef nomacros
91 | append( ITEM_MACROS, null );
92 | //#endif
93 | //#ifndef nosettings
94 | append( ITEM_SETTINGS, null );
95 | //#endif
96 | //#ifndef nodocs
97 | append( ITEM_ABOUT, null );
98 | append( ITEM_HELP, null );
99 | //#endif
100 | append( ITEM_QUIT, null );
101 |
102 | //setSelectCommand( selectCommand );
103 | addCommand( quitCommand );
104 |
105 | setCommandListener( this );
106 | }
107 |
108 | /*
109 | * (non-Javadoc)
110 | *
111 | * @see javax.microedition.lcdui.CommandListener#commandAction(javax.microedition.lcdui.Command,
112 | * javax.microedition.lcdui.Displayable)
113 | */
114 | public void commandAction( Command com, Displayable displayable ) {
115 | if ( com == List.SELECT_COMMAND /*|| com == selectCommand*/ ) {
116 | String command = getString( getSelectedIndex() );
117 | if ( command.equals( ITEM_SESSIONS ) ) {
118 | doSessions();
119 | }
120 | //#ifndef nomacros
121 | else if ( command.equals( ITEM_MACROS ) ) {
122 | doMacros( this );
123 | }
124 | //#endif
125 | //#ifndef nosettings
126 | else if ( command.equals( ITEM_SETTINGS ) ) {
127 | doSettings();
128 | }
129 | //#endif
130 | //#ifndef nodocs
131 | else if ( command.equals( ITEM_ABOUT ) ) {
132 | doAbout();
133 | }
134 | else if ( command.equals( ITEM_HELP ) ) {
135 | doHelp();
136 | }
137 | //#endif
138 | else if ( command.equals( ITEM_QUIT ) ) {
139 | Main.quitApp();
140 | }
141 | }
142 | else if (com == okCommand) {
143 | goMainMenu();
144 | }
145 | else if ( com == quitCommand ) {
146 | Main.quitApp();
147 | }
148 | }
149 |
150 | private void doSessions() {
151 | if ( sessionsMenu == null ) {
152 | sessionsMenu = new SessionsMenu();
153 | }
154 | sessionsMenu.activate( this );
155 | }
156 |
157 | //#ifndef nomacros
158 | public static void doMacros( Activatable back ) {
159 | if ( macrosMenu == null ) {
160 | macrosMenu = new MacrosMenu();
161 | }
162 | macrosMenu.activate( back );
163 | }
164 | //#endif
165 |
166 | //#ifndef nosettings
167 | private void doSettings() {
168 | if ( settingsMenu == null ) {
169 | settingsMenu = new SettingsMenu();
170 | }
171 | settingsMenu.activate( this );
172 | }
173 | //#endif
174 |
175 | public static Form showMessage(String title, String msg, CommandListener commandListener) {
176 | Form form = new Form(title);
177 | form.append( new StringItem( null, msg ) );
178 | form.addCommand(okCommand);
179 | form.setCommandListener(commandListener);
180 | setDisplay(form);
181 | return form;
182 | }
183 |
184 | private void doAbout() {
185 | showMessage( "About MidpSSH",
186 | "Version @VERSION@\n\n" +
187 | "MidpSSH is a Telnet and SSH application for Java compatible phones and other mobile devices.\n\n" +
188 | "Please visit the project website for more information:\n" +
189 | "http://www.xk72.com/midpssh/\n\n" +
190 | "MidpSSH is developed by Karl von Randow. MidpSSH is based upon " +
191 | "FloydSSH and Telnet Floyd by Radek Polak.\n\n" +
192 | "MidpSSH is distributed under the GPL licence. For more information please " +
193 | "visit the website.",
194 | this);
195 | }
196 |
197 | private void doHelp() {
198 | showMessage( "MidpSSH Help",
199 | "Connecting\n\n" +
200 | "To connect to a remote server choose the Sessions option " +
201 | "from the main menu - create a new session, entering in the host and other details. " +
202 | "You can then connect to that server by choosing the new session.\n\n" +
203 |
204 | "More Information\n\n" +
205 | "For more information please visit the project website http://www.xk72.com/midpssh/",
206 | this);
207 | }
208 |
209 | /* (non-Javadoc)
210 | * @see app.Activatable#activate()
211 | */
212 | public void activate() {
213 | setDisplay( this );
214 | }
215 | /* (non-Javadoc)
216 | * @see gui.Activatable#activate(gui.Activatable)
217 | */
218 | public void activate( Activatable back ) {
219 | activate();
220 | }
221 |
222 | public static void setDisplay( Displayable display ) {
223 | getDisplay().setCurrent( display );
224 | }
225 |
226 | public static void alert( Alert alert, Displayable back ) {
227 | getDisplay().setCurrent( alert, back );
228 | }
229 |
230 | public static Display getDisplay() {
231 | return Display.getDisplay(Main.instance);
232 | }
233 |
234 | public static void goMainMenu() {
235 | setDisplay(instance);
236 | }
237 |
238 | public static void alertBackToMain( Alert alert ) {
239 | getDisplay().setCurrent(alert, instance);
240 | }
241 |
242 | public static void openSession( Session session ) {
243 | currentSession = session;
244 | session.activate();
245 | }
246 |
247 | public static Session currentSession() {
248 | return currentSession;
249 | }
250 |
251 | public static void showErrorMessage( String errorMessage ) {
252 | Alert alert = new Alert( "Error" );
253 | alert.setString( errorMessage );
254 | alert.setType( AlertType.ERROR );
255 | MainMenu.setDisplay( alert );
256 | }
257 | }
--------------------------------------------------------------------------------
/src/j2me/gui/Redrawable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Redrawable.java
3 | *
4 | * Copyright (c) 2010 VDP .
5 | *
6 | * This file is part of MidpSSH.
7 | *
8 | * MidpSSH is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * MidpSSH is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with MidpSSH. If not, see .
20 | */
21 |
22 | package gui;
23 |
24 | import terminal.VT320;
25 |
26 | /**
27 | * A common interface to be implemented by all classes
28 | * that are used as terminals within the {@link terminal.VT320}.
29 | *
30 | * @author VDP
31 | */
32 | public interface Redrawable {
33 |
34 | /**
35 | * Invoked when screen refresh is needed
36 | */
37 | public void redraw();
38 | }
39 |
--------------------------------------------------------------------------------
/src/j2me/gui/SessionsMenu.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2004 Karl von Randow.
3 | *
4 | * MidpSSH is based upon Telnet Floyd and FloydSSH by Radek Polak.
5 | *
6 | * --LICENSE NOTICE--
7 | * This program is free software; you can redistribute it and/or
8 | * modify it under the terms of the GNU General Public License
9 | * as published by the Free Software Foundation; either version 2
10 | * of the License, or (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program; if not, write to the Free Software
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 | * --LICENSE NOTICE--
21 | *
22 | */
23 | package gui;
24 |
25 | import app.Main;
26 | import java.util.Vector;
27 |
28 | //import java.util.logging.Level;
29 | //import java.util.logging.Logger;
30 | import javax.microedition.lcdui.Command;
31 | import javax.microedition.lcdui.Displayable;
32 | import javax.microedition.lcdui.Form;
33 | import javax.microedition.lcdui.TextField;
34 |
35 | import app.SessionManager;
36 | import app.SessionSpec;
37 | import app.session.SshSession;
38 | import app.session.TelnetSession;
39 |
40 | /**
41 | * @author Karl von Randow
42 | *
43 | */
44 | public class SessionsMenu extends EditableMenu {
45 |
46 | private static Command connectCommand = new Command( "Connect", Command.ITEM, 1 );
47 |
48 | private static SessionForm newConnectionForm = new SessionForm( false );
49 |
50 | private static SessionForm editConnectionForm = new SessionForm( true );
51 |
52 | //#ifndef nosessionimport
53 | private static Command importCommand = new Command("Import", Command.SCREEN, 20);
54 |
55 | private ImportSessionsForm importSessionsForm;
56 | //#endif
57 |
58 | private Form authenticationDialog;
59 |
60 | private TextField usernameField, passwordField;
61 |
62 | private SessionSpec conn;
63 |
64 | public SessionsMenu() {
65 | super( "Sessions" );
66 | replaceSelectCommand( connectCommand );
67 |
68 | //#ifndef nosessionimport
69 | addCommand(importCommand);
70 | //#endif
71 | }
72 |
73 | public void commandAction(Command command, Displayable displayable) {
74 | if (displayable == authenticationDialog) {
75 | if (command == MainMenu.okCommand) {
76 | SshSession session = new SshSession();
77 | session.connect(conn, usernameField.getString(), passwordField.getString());
78 | Main.quitApp();
79 | System.out.print("After session.connect()\n");
80 | try {
81 | Thread.sleep(20000);
82 | } catch (InterruptedException ex) {
83 | //Logger.getLogger(SessionsMenu.class.getName()).log(Level.SEVERE, null, ex);
84 | }
85 | MainMenu.openSession( session );
86 | }
87 | else {
88 | activate();
89 | }
90 | }
91 | else {
92 | //#ifndef nosessionimport
93 | if (command == importCommand) {
94 | /* Import */
95 | if (importSessionsForm == null) {
96 | importSessionsForm = new ImportSessionsForm();
97 | }
98 | importSessionsForm.activate(this);
99 | }
100 | else
101 | //#endif
102 | {
103 | System.out.println("Tadaa\n");
104 | super.commandAction(command, displayable);
105 | }
106 | }
107 | }
108 |
109 |
110 | protected void addItems() {
111 | deleteAll();
112 |
113 | Vector connections = SessionManager.getSessions();
114 | if ( connections != null ) {
115 | for ( int i = 0; i < connections.size(); i++ ) {
116 | SessionSpec conn = (SessionSpec) connections.elementAt( i );
117 | append( conn.alias, null );
118 | }
119 | }
120 | }
121 |
122 | protected void doSelect(int i) {
123 | if (i != -1) {
124 | conn = SessionManager.getSession(i);
125 | if (conn != null) {
126 | //#ifndef nossh
127 | if (conn.type.equals(SessionSpec.TYPE_SSH)) {
128 | String username = conn.username;
129 | String password = conn.password;
130 |
131 | if (username.length() == 0 || (password.length() == 0 && !conn.usepublickey)) {
132 | authenticationDialog = new Form("Authentication");
133 | usernameField = new TextField("Username:", username, 255, TextField.ANY);
134 | authenticationDialog.append(usernameField);
135 | if (!conn.usepublickey) {
136 | passwordField = new TextField("Password:", password, 255, TextField.PASSWORD);
137 | authenticationDialog.append(passwordField);
138 | }
139 | authenticationDialog.addCommand(MainMenu.okCommand);
140 | authenticationDialog.addCommand(MainMenu.backCommand);
141 | authenticationDialog.setCommandListener(this);
142 | MainMenu.setDisplay(authenticationDialog);
143 | } else {
144 | SshSession session = new SshSession();
145 | session.connect(conn, null, null);
146 | Main.printStack("After session.connect(conn, null, null)", 0);
147 | MainMenu.openSession(session);
148 | }
149 | }
150 | //#endif
151 | //#ifndef notelnet
152 | if (conn.type.equals(SessionSpec.TYPE_TELNET)) {
153 | TelnetSession session = new TelnetSession();
154 | session.connect(conn);
155 | MainMenu.openSession(session);
156 | }
157 | //#endif
158 | }
159 | }
160 | }
161 |
162 | protected void doEdit( int i ) {
163 | if ( i != -1 ) {
164 | editConnectionForm.setConnectionIndex( i );
165 | editConnectionForm.activate( this );
166 | }
167 | }
168 |
169 | protected void doDelete( int i ) {
170 | if ( i != -1 ) {
171 | SessionManager.deleteSession( i );
172 | delete( i );
173 | }
174 | }
175 |
176 | protected void doNew() {
177 | newConnectionForm.activate( this );
178 | }
179 | }
--------------------------------------------------------------------------------
/src/j2me/gui/session/SpecialMenu.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2005 Karl von Randow.
3 | *
4 | * --LICENSE NOTICE--
5 | * This program is free software; you can redistribute it and/or
6 | * modify it under the terms of the GNU General Public License
7 | * as published by the Free Software Foundation; either version 2
8 | * of the License, or (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program; if not, write to the Free Software
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 | * --LICENSE NOTICE--
19 | *
20 | */
21 | package gui.session;
22 |
23 | import gui.Activatable;
24 | import gui.MainMenu;
25 |
26 | import javax.microedition.lcdui.Command;
27 | import javax.microedition.lcdui.CommandListener;
28 | import javax.microedition.lcdui.Displayable;
29 | import javax.microedition.lcdui.List;
30 |
31 | import ssh.v2.PublicKeyAuthentication;
32 | import terminal.VT320;
33 | import app.Settings;
34 | import app.session.Session;
35 |
36 | /**
37 | * @author Karl
38 | *
39 | */
40 | public class SpecialMenu extends List implements CommandListener, Activatable {
41 |
42 | private Activatable back, done;
43 |
44 | private int index;
45 |
46 | /**
47 | * @param title
48 | * @param mode
49 | */
50 | public SpecialMenu() {
51 | this( "Special", 0 );
52 | }
53 |
54 | public SpecialMenu( String title, int index ) {
55 | super(title, List.IMPLICIT);
56 |
57 | //setSelectCommand( selectCommand );
58 | addCommand( MainMenu.backCommand );
59 | setCommandListener( this );
60 |
61 | String options;
62 | this.index = index;
63 | switch (index) {
64 | case 0:
65 | options = "Keys|Funcs|Symbols|Output|";
66 | break;
67 | case 1:
68 | options = "Bksp|Home|End|PgU|PgD|Del|Ins|";
69 | break;
70 | case 2:
71 | options = "F1|F2|F3|F4|F5|F6|F7|F8|F9|F10|F11|F12|";
72 | break;
73 | case 3:
74 | options = "||\\|~|:|;|'|\"|,|<|.|>|/|?|`|!|@|#|$|%|^|&|*|(|)|-|_|+|=|[|{|]|}|";
75 | break;
76 | default:
77 | //#ifdef ssh2
78 | options = "Public Key|";
79 | //#else
80 | options = "";
81 | //#endif
82 | }
83 |
84 | int start = 0;
85 | int i = options.indexOf('|', 1);
86 | while (i != -1) {
87 | append(options.substring(start, i), null);
88 | start = i + 1;
89 | i = options.indexOf('|', start + 1); // +1 to that we see tokens that are single |
90 | }
91 | }
92 |
93 | public void commandAction( Command command, Displayable displayed ) {
94 | if ( command == List.SELECT_COMMAND ) {
95 | Session session = MainMenu.currentSession();
96 | if ( session != null ) {
97 | int selectedIndex = getSelectedIndex();
98 | String option = null;
99 | int keyCode = 0;
100 | if (index == 0) {
101 | new SpecialMenu(getString(selectedIndex), selectedIndex + 1).activate(this, done);
102 | }
103 | else if (index == 1) {
104 | switch (selectedIndex) {
105 | case 0:
106 | keyCode = VT320.VK_BACK_SPACE;
107 | break;
108 | case 1:
109 | keyCode = VT320.VK_HOME;
110 | break;
111 | case 2:
112 | keyCode = VT320.VK_END;
113 | break;
114 | case 3:
115 | keyCode = VT320.VK_PAGE_UP;
116 | break;
117 | case 4:
118 | keyCode = VT320.VK_PAGE_DOWN;
119 | break;
120 | case 5:
121 | keyCode = VT320.VK_DELETE;
122 | break;
123 | case 6:
124 | keyCode = VT320.VK_INSERT;
125 | break;
126 | }
127 | }
128 | else if (index == 2) {
129 | keyCode = VT320.VK_F1 + selectedIndex;
130 | }
131 | else if (index == 3) {
132 | option = getString(selectedIndex);
133 | }
134 | else if (index == 4) {
135 | //#ifdef ssh2
136 | if (Settings.x != null) {
137 | PublicKeyAuthentication pk = new PublicKeyAuthentication();
138 | option = pk.getPublicKeyText();
139 | }
140 | else {
141 | option = "";
142 | }
143 | //#endif
144 | }
145 |
146 | if (keyCode != 0) {
147 | session.typeKey(keyCode, 0);
148 | done.activate();
149 | }
150 | else if (option != null) {
151 | session.typeString(option);
152 | done.activate();
153 | }
154 | }
155 | }
156 | else if ( command == MainMenu.backCommand ) {
157 | if ( back != null ) {
158 | back.activate();
159 | }
160 | }
161 | }
162 |
163 | public void activate() {
164 | MainMenu.setDisplay( this );
165 | }
166 | public void activate(Activatable back) {
167 | activate( back, back );
168 | }
169 | public void activate(Activatable back, Activatable done) {
170 | this.back = back;
171 | this.done = done;
172 | activate();
173 | }
174 | }
175 |
--------------------------------------------------------------------------------
/src/j2me/gui/session/macros/MacroForm.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2004 Karl von Randow.
3 | *
4 | * MidpSSH is based upon Telnet Floyd and FloydSSH by Radek Polak.
5 | *
6 | * --LICENSE NOTICE--
7 | * This program is free software; you can redistribute it and/or
8 | * modify it under the terms of the GNU General Public License
9 | * as published by the Free Software Foundation; either version 2
10 | * of the License, or (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program; if not, write to the Free Software
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 | * --LICENSE NOTICE--
21 | *
22 | */
23 | package gui.session.macros;
24 |
25 | import gui.EditableForm;
26 | import gui.MainMenu;
27 | import gui.SessionForm;
28 |
29 | import javax.microedition.lcdui.ChoiceGroup;
30 | import javax.microedition.lcdui.TextField;
31 |
32 | import app.Settings;
33 | import app.session.MacroSetManager;
34 |
35 |
36 | /**
37 | * @author Karl von Randow
38 | *
39 | */
40 | public class MacroForm extends EditableForm {
41 |
42 | public static final int MODE_MACRO_SET = 1;
43 | public static final int MODE_MACRO = 2;
44 |
45 | private int macroSetIndex, macroIndex;
46 |
47 | private boolean edit;
48 |
49 | private TextField tfName, tfValue;
50 |
51 | private ChoiceGroup cgType;
52 |
53 | private boolean isMacroSet;
54 |
55 | /**
56 | * @param arg0
57 | */
58 | public MacroForm( boolean edit, boolean isMacroSet ) {
59 | super( ( !isMacroSet ? ( edit ? "Edit Macro" : "New Macro" ) :
60 | ( edit ? "Edit Macro Set" : "New Macro Set" ) ) );
61 |
62 | this.isMacroSet = isMacroSet;
63 |
64 | if ( isMacroSet ) {
65 | tfName = new TextField( "Macro Set Name:", null, 255, TextField.ANY );
66 | append( tfName );
67 | }
68 | else {
69 | tfValue = new TextField( "Value:", null, 255, TextField.ANY );
70 | //#ifdef midp2
71 | if (!Settings.predictiveText) {
72 | tfValue.setConstraints(TextField.ANY | TextField.NON_PREDICTIVE);
73 | }
74 | //#endif
75 |
76 | tfName = new TextField( "Name (Optional):", null, 255, TextField.ANY );
77 | cgType = new ChoiceGroup( "Mode", ChoiceGroup.EXCLUSIVE
78 | //#ifdef midp2
79 | * 0 + ChoiceGroup.POPUP
80 | //#endif
81 | );
82 | cgType.append( "Enter", null );
83 | cgType.append( "Type", null );
84 |
85 | append( tfName );
86 | append( tfValue );
87 | append( cgType );
88 | }
89 |
90 | if (!edit) {
91 | addOKCommand();
92 | }
93 | this.edit = edit;
94 | }
95 |
96 | protected void doBack() {
97 | if (edit) {
98 | if (doSave(false)) {
99 | super.doBack();
100 | }
101 | } else {
102 | super.doBack();
103 | }
104 | }
105 |
106 | protected void doOK() {
107 | if (doSave(true)) {
108 | super.doOK();
109 | }
110 | }
111 |
112 | /* (non-Javadoc)
113 | * @see gui.Activatable#activate()
114 | */
115 | public void activate() {
116 | if ( !edit ) {
117 | tfName.setString( "" );
118 | if ( tfValue != null ) {
119 | tfValue.setString( "" );
120 | }
121 | }
122 | super.activate();
123 | }
124 |
125 | /**
126 | * @param macroSetIndex The macroSetIndex to set.
127 | */
128 | public void setMacroSetIndex( int macroSetIndex ) {
129 | this.macroSetIndex = macroSetIndex;
130 |
131 | if ( isMacroSet ) {
132 | MacroSet macroSet = MacroSetManager.getMacroSet( macroSetIndex );
133 | if ( macroSet != null ) {
134 | tfName.setString( macroSet.name );
135 | }
136 | }
137 | }
138 |
139 | public void setMacroIndices( int macroSetIndex, int macroIndex ) {
140 | this.macroSetIndex = macroSetIndex;
141 | this.macroIndex = macroIndex;
142 |
143 | MacroSet macroSet = MacroSetManager.getMacroSet( macroSetIndex );
144 | MacroSet macro = macroSet.getMacro( macroIndex );
145 | tfName.setString( macro.name );
146 |
147 | String value = macro.value;
148 | if ( value.endsWith( "\n" ) ) {
149 | cgType.setSelectedIndex( 0, true );
150 | value = value.substring( 0, value.length() - 1 );
151 | }
152 | else {
153 | cgType.setSelectedIndex( 1, true );
154 | }
155 | tfValue.setString( value );
156 | }
157 |
158 | private boolean doSave(boolean create) {
159 | if (create || macroSetIndex != -1 ) {
160 | if ( validateForm() ) {
161 | if ( isMacroSet ) {
162 | MacroSet macroSet = create ? new MacroSet() : MacroSetManager.getMacroSet( macroSetIndex );
163 | macroSet.name = tfName.getString();
164 | if (create) {
165 | MacroSetManager.addMacroSet( macroSet );
166 | }
167 | else {
168 | MacroSetManager.replaceMacroSet( macroSetIndex, macroSet );
169 | }
170 | }
171 | else {
172 | MacroSet macroSet = MacroSetManager.getMacroSet( macroSetIndex );
173 | String value = tfValue.getString();
174 | if ( cgType.getSelectedIndex() == 0 ) {
175 | value += "\n";
176 | }
177 | MacroSet macro = new MacroSet( tfName.getString(), value );
178 | if (create) {
179 | macroSet.addMacro( macro );
180 | }
181 | else {
182 | macroSet.replaceMacro( macroIndex, macro );
183 | }
184 | }
185 | return true;
186 | }
187 | }
188 | return false;
189 | }
190 |
191 | protected boolean validateForm() {
192 | if ((isMacroSet && tfName.getString().length() == 0)
193 | || (!isMacroSet && tfValue.getString().length() == 0)) {
194 | MainMenu.showErrorMessage(SessionForm.WARNING_REQUIRED);
195 | return false;
196 | }
197 | else {
198 | return true;
199 | }
200 | }
201 | }
--------------------------------------------------------------------------------
/src/j2me/gui/session/macros/MacroSet.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2004 Karl von Randow.
3 | *
4 | * MidpSSH is based upon Telnet Floyd and FloydSSH by Radek Polak.
5 | *
6 | * --LICENSE NOTICE--
7 | * This program is free software; you can redistribute it and/or
8 | * modify it under the terms of the GNU General Public License
9 | * as published by the Free Software Foundation; either version 2
10 | * of the License, or (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program; if not, write to the Free Software
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 | * --LICENSE NOTICE--
21 | *
22 | */
23 | package gui.session.macros;
24 |
25 | import java.io.DataInputStream;
26 | import java.io.DataOutputStream;
27 | import java.io.IOException;
28 | import java.util.Vector;
29 |
30 | import app.session.MacroSetManager;
31 |
32 | /**
33 | * @author Karl von Randow
34 | *
35 | */
36 | public class MacroSet {
37 |
38 | private static final byte VERSION = 1;
39 |
40 | public String name, value;
41 |
42 | public Vector macros;
43 |
44 | public MacroSet() {
45 | macros = new Vector();
46 | }
47 |
48 | public MacroSet(String name, String value) {
49 | this.name = name;
50 | this.value = value;
51 | }
52 |
53 | /**
54 | * @param in
55 | * @throws IOException
56 | */
57 | public void read( DataInputStream in ) throws IOException {
58 | in.readByte(); // a version byte, for future use
59 | name = in.readUTF();
60 |
61 | int n = in.readByte();
62 | for ( int i = 0; i < n; i++ ) {
63 | String name = in.readUTF();
64 | String value = in.readUTF();
65 |
66 | MacroSet macro = new MacroSet( name, value );
67 | macros.addElement( macro );
68 | }
69 | }
70 | /**
71 | * @param dout
72 | * @throws IOException
73 | */
74 | public void write( DataOutputStream out ) throws IOException {
75 | out.writeByte( VERSION );
76 | out.writeUTF( name );
77 |
78 | out.writeByte( macros.size() );
79 | for ( int i = 0; i < macros.size(); i++ ) {
80 | MacroSet macro = (MacroSet) macros.elementAt( i );
81 | out.writeUTF( macro.name );
82 | out.writeUTF( macro.value );
83 | }
84 | }
85 |
86 | public MacroSet getMacro( int i ) {
87 | return ( i >= macros.size() ? null : (MacroSet) macros.elementAt( i ));
88 | }
89 |
90 | public void addMacro( MacroSet macro ) {
91 | macros.addElement( macro );
92 | MacroSetManager.saveMacroSets();
93 | }
94 |
95 | public void deleteMacro( int i ) {
96 | if ( i < macros.size() ) {
97 | macros.removeElementAt( i );
98 | MacroSetManager.saveMacroSets();
99 | }
100 | }
101 |
102 | public void replaceMacro( int i, MacroSet macro ) {
103 | if ( i >= macros.size() ) {
104 | macros.addElement( macro );
105 | }
106 | else {
107 | macros.setElementAt( macro, i );
108 | }
109 | MacroSetManager.saveMacroSets();
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/j2me/gui/session/macros/MacrosMenu.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2004 Karl von Randow.
3 | *
4 | * MidpSSH is based upon Telnet Floyd and FloydSSH by Radek Polak.
5 | *
6 | * --LICENSE NOTICE--
7 | * This program is free software; you can redistribute it and/or
8 | * modify it under the terms of the GNU General Public License
9 | * as published by the Free Software Foundation; either version 2
10 | * of the License, or (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program; if not, write to the Free Software
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 | * --LICENSE NOTICE--
21 | *
22 | */
23 | package gui.session.macros;
24 |
25 | import gui.EditableMenu;
26 | import gui.MainMenu;
27 |
28 | import java.util.Vector;
29 |
30 | import javax.microedition.lcdui.Command;
31 | import javax.microedition.lcdui.Displayable;
32 |
33 | import terminal.VT320;
34 | import app.session.MacroSetManager;
35 | import app.session.Session;
36 |
37 | /**
38 | * @author Karl von Randow
39 | *
40 | */
41 | public class MacrosMenu extends EditableMenu {
42 |
43 | protected static final Command useCommand = new Command( "Use", Command.ITEM, 1 );
44 |
45 | private MacroSet macroSet;
46 |
47 | private int macroSetIndex;
48 |
49 | private boolean isMacroSets;
50 |
51 | public MacrosMenu() {
52 | super( "Macro Sets" );
53 | isMacroSets = true;
54 | }
55 |
56 | public MacrosMenu( MacroSet macroSet, int macroSetIndex ) {
57 | super( macroSet.name );
58 | isMacroSets = false;
59 | this.macroSet = macroSet;
60 | this.macroSetIndex = macroSetIndex;
61 |
62 | if ( MainMenu.currentSession() != null ) {
63 | addCommand( useCommand );
64 | }
65 | }
66 |
67 | /* (non-Javadoc)
68 | * @see javax.microedition.lcdui.CommandListener#commandAction(javax.microedition.lcdui.Command, javax.microedition.lcdui.Displayable)
69 | */
70 | public void commandAction(Command command, Displayable displayable) {
71 | if ( command == useCommand ) {
72 | int i = getSelectedIndex();
73 | if ( i >= 0 && i < size() ) {
74 | Session session = MainMenu.currentSession();
75 | if ( session != null ) {
76 | MacroSet macro = macroSet.getMacro( i );
77 | if ( macro != null ) {
78 | session.getTerminal().doTextInput(macro.value.trim());
79 | }
80 | }
81 | else {
82 | doEdit( i );
83 | }
84 | }
85 | }
86 | else {
87 | super.commandAction(command, displayable);
88 | }
89 | }
90 | /* (non-Javadoc)
91 | * @see gui.EditableMenu#addItems()
92 | */
93 | protected void addItems() {
94 | deleteAll();
95 |
96 | if ( isMacroSets ) {
97 | Vector macroSets = MacroSetManager.getMacroSets();
98 | for ( int i = 0; i < macroSets.size(); i++ ) {
99 | MacroSet macroSet = (MacroSet) macroSets.elementAt( i );
100 | append( macroSet.name, null );
101 | }
102 | }
103 | else {
104 | Vector macros = macroSet.macros;
105 | for ( int i = 0; i < macros.size(); i++ ) {
106 | MacroSet macro = (MacroSet) macros.elementAt( i );
107 | String name = macro.name;
108 | if (name.length() == 0) {
109 | name = macro.value.trim(); // trim off whitespace as it may end with a newline
110 | }
111 | append( name, null );
112 | }
113 | }
114 | }
115 | /* (non-Javadoc)
116 | * @see gui.EditableMenu#doDelete(int)
117 | */
118 | protected void doDelete( int i ) {
119 | if ( i != -1 ) {
120 | if ( isMacroSets ) {
121 | MacroSetManager.deleteMacroSet( i );
122 | }
123 | else {
124 | macroSet.deleteMacro( i );
125 | }
126 | delete( i );
127 | }
128 | }
129 | /* (non-Javadoc)
130 | * @see gui.EditableMenu#doSelect(int)
131 | */
132 | protected void doSelect( int i ) {
133 | if ( i != -1 ) {
134 | if ( isMacroSets ) {
135 | MacroSet macroSet = MacroSetManager.getMacroSet( i );
136 | MacrosMenu macrosMenu = new MacrosMenu( macroSet, i );
137 | macrosMenu.activate( this );
138 | }
139 | else {
140 | Session session = MainMenu.currentSession();
141 | if ( session != null ) {
142 | MacroSet macro = macroSet.getMacro( i );
143 | if ( macro != null ) {
144 | doMacro(session, macro);
145 | session.activate();
146 | }
147 | }
148 | else {
149 | doEdit( i );
150 | }
151 | }
152 | }
153 | }
154 |
155 | private static final char MACRO_CTRL = '^';
156 |
157 | private static final char MACRO_BACKSLASH = '\\';
158 |
159 | private int indexOfCommand(String value, int start) {
160 | int n = value.length();
161 | for (int i = start; i < n; i++) {
162 | char c = value.charAt(i);
163 | if (c == MACRO_CTRL || c == MACRO_BACKSLASH) {
164 | return i;
165 | }
166 | }
167 | return -1;
168 | }
169 |
170 | private void doMacro(Session session, MacroSet macro) {
171 | String value = macro.value;
172 |
173 | int start = 0;
174 | int i = indexOfCommand(value, 0);
175 | while (i != -1) {
176 | if (i + 1 < value.length()) {
177 | if (i > start) {
178 | /* Output text before the control char */
179 | session.typeString(value.substring(start, i));
180 | }
181 | char com = value.charAt(i);
182 | char arg = value.charAt(i+1);
183 | if (arg == com) {
184 | /* An escaped command char */
185 | session.typeString(value.substring(i, i + 2));
186 | }
187 | else if (com == MACRO_CTRL) {
188 | /* Type control char */
189 | session.typeChar(arg, VT320.KEY_CONTROL);
190 | }
191 | else if (com == MACRO_BACKSLASH) {
192 | if (arg == 'n') {
193 | session.typeChar('\n', 0);
194 | }
195 | else if (arg == 'r') {
196 | session.typeChar('\r', 0);
197 | }
198 | else if (arg == 't') {
199 | session.typeChar('\t', 0);
200 | }
201 | else if (arg == 'e') {
202 | session.typeChar((char)27, 0);
203 | }
204 | else {
205 | session.typeString(value.substring(i, i + 2));
206 | }
207 | }
208 | start = i + 2;
209 | }
210 | else {
211 | start = i + 1;
212 | }
213 | i = indexOfCommand(value, start);
214 | }
215 |
216 | if (start < value.length()) {
217 | session.typeString(value.substring(start));
218 | }
219 | }
220 |
221 | protected void doEdit( int i ) {
222 | if ( i != -1 ) {
223 | MacroForm editMacroForm = new MacroForm( true, isMacroSets );
224 | if ( isMacroSets ) {
225 | editMacroForm.setMacroSetIndex( i );
226 | }
227 | else {
228 | editMacroForm.setMacroIndices( macroSetIndex, i );
229 | }
230 | editMacroForm.activate( this );
231 | }
232 | }
233 |
234 | protected void doNew() {
235 | MacroForm newMacroForm = new MacroForm( false, isMacroSets );
236 | if ( !isMacroSets ) {
237 | newMacroForm.setMacroSetIndex( macroSetIndex );
238 | }
239 | newMacroForm.activate( this );
240 | }
241 | }
242 |
--------------------------------------------------------------------------------
/src/j2me/gui/settings/SettingsMenu.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | * Copyright (c) 2004 Karl von Randow.
3 | *
4 | * MidpSSH is based upon Telnet Floyd and FloydSSH by Radek Polak.
5 | *
6 | * --LICENSE NOTICE--
7 | * This program is free software; you can redistribute it and/or
8 | * modify it under the terms of the GNU General Public License
9 | * as published by the Free Software Foundation; either version 2
10 | * of the License, or (at your option) any later version.
11 | *
12 | * This program is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with this program; if not, write to the Free Software
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 | * --LICENSE NOTICE--
21 | *
22 | */
23 | package gui.settings;
24 |
25 | import gui.Activatable;
26 | import gui.MainMenu;
27 |
28 | import javax.microedition.lcdui.Command;
29 | import javax.microedition.lcdui.CommandListener;
30 | import javax.microedition.lcdui.Displayable;
31 | import javax.microedition.lcdui.List;
32 |
33 | import app.Settings;
34 |
35 | /**
36 | * @author Karl von Randow
37 | */
38 | public class SettingsMenu extends List implements Activatable,
39 | CommandListener {
40 |
41 | private Activatable back;
42 |
43 | protected SettingsMenu(String title) {
44 | super(title, List.IMPLICIT);
45 |
46 | append("Network", null);
47 | append("Interface", null);
48 | //#ifndef nofonts
49 | append("Fonts", null);
50 | //#endif
51 | //#ifdef ssh2
52 | append("SSH", null);
53 | //#endif
54 | append("Restore Defaults", null);
55 |
56 | // setSelectCommand( selectCommand );
57 | addCommand(MainMenu.backCommand);
58 |
59 | setCommandListener(this);
60 | }
61 |
62 | public SettingsMenu() {
63 | this("Settings");
64 | }
65 |
66 | /*
67 | * (non-Javadoc)
68 | *
69 | * @see javax.microedition.lcdui.CommandListener#commandAction(javax.microedition.lcdui.Command,
70 | * javax.microedition.lcdui.Displayable)
71 | */
72 | public void commandAction(Command command, Displayable displayable) {
73 | if (command == List.SELECT_COMMAND) {
74 | doSelect(getSelectedIndex());
75 | } else if (command == MainMenu.backCommand) {
76 | doBack();
77 | }
78 | }
79 |
80 | protected void doSelect(int i) {
81 | int j = 0;
82 | if (j++ == i) {
83 | showSettingsForm(i, SettingsForm.MODE_NETWORK);
84 | } else if (j++ == i) {
85 | showSettingsForm(i, SettingsForm.MODE_INTERFACE);
86 | //#ifndef nofonts
87 | } else if (j++ == i) {
88 | showSettingsForm(i, SettingsForm.MODE_FONTS);
89 | //#endif
90 | }
91 | //#ifdef ssh2
92 | else if (j++ == i) {
93 | showSettingsForm(i, SettingsForm.MODE_SSH);
94 | }
95 | //#endif
96 | else if (j++ == i) {
97 | Settings.defaults();
98 | Settings.saveSettings();
99 | // Main.alertBackToMain(new Alert("Settings",
100 | // "Default settings have been restored.", null,
101 | // AlertType.INFO));
102 | MainMenu.goMainMenu();
103 | }
104 | }
105 |
106 | private void showSettingsForm(int i, int mode) {
107 | SettingsForm f = new SettingsForm(getString(i), mode);
108 | f.activate(this);
109 | }
110 |
111 | private void doBack() {
112 | back.activate();
113 | }
114 |
115 | /*
116 | * (non-Javadoc)
117 | *
118 | * @see gui.Activatable#activate()
119 | */
120 | public void activate() {
121 | MainMenu.setDisplay(this);
122 | }
123 |
124 | /*
125 | * (non-Javadoc)
126 | *
127 | * @see gui.Activatable#activate(gui.Activatable)
128 | */
129 | public void activate(Activatable back) {
130 | this.back = back;
131 | activate();
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/src/j2me/kindle/FlashPanel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * FlashPanel.java
3 | *
4 | * Copyright (c) 2010 VDP .
5 | *
6 | * This file is part of MidpSSH.
7 | *
8 | * MidpSSH is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * MidpSSH is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with MidpSSH. If not, see .
20 | */
21 | package kindle;
22 |
23 | import com.amazon.kindle.kindlet.ui.KPanel;
24 | import com.amazon.kindle.kindlet.ui.KRepaintManager;
25 | import java.awt.Color;
26 | import java.awt.EventQueue;
27 | import java.awt.Graphics;
28 | import java.lang.reflect.InvocationTargetException;
29 | import org.apache.log4j.Logger;
30 |
31 | /**
32 | *
33 | * @author VDP
34 | */
35 | public class FlashPanel extends KPanel {
36 |
37 | /** The object used for logging */
38 | private Logger logger;
39 | /** indicator for flashing panel while repainting */
40 | private boolean m_doFlash;
41 |
42 | public FlashPanel(Logger log) {
43 | super();
44 | this.logger = log;
45 | }
46 |
47 | /**
48 | * {@inheritDoc}
49 | */
50 | public void paint(final Graphics g) {
51 | if (m_doFlash) {
52 | g.setColor(Color.white);
53 | g.clearRect(0, 0, this.getWidth(), this.getHeight());
54 | m_doFlash = false;
55 | }
56 | else {
57 | super.paint(g);
58 | }
59 | }
60 |
61 | /**
62 | * Overloads repaint that flashes the screen by doing two paints.
63 | * It first paints the panel black and then paints the contents again flashing the screen
64 | * @param flashingRepaint sets the repaint to cause a flash or do a regular paint.
65 | */
66 | public void repaint(final boolean flashingRepaint) {
67 | m_doFlash = flashingRepaint;
68 | if (m_doFlash) {
69 | final FlashPanel currentFlashingPanel = this;
70 | EventQueue.invokeLater(new Runnable() {
71 |
72 | /** {@inheritDoc} */
73 | public void run() {
74 | try {
75 | m_doFlash = true;
76 | KRepaintManager.paintImmediately(currentFlashingPanel, true);
77 | } catch (final InterruptedException e1) {
78 | logger.error("Error occured while repainting FlashingPanel", e1);
79 | } catch (final InvocationTargetException e2) {
80 | logger.error("Error occured while repainting FlashingPanel", e2);
81 | }
82 | }
83 | });
84 | }
85 | super.repaint();
86 | }
87 |
88 | /**
89 | * {@inheritDoc}
90 | */
91 | public void repaint() {
92 | repaint(false);
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/j2me/kindle/ProxyKeyEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * ProxyKeyEvent.java
3 | *
4 | * Copyright (c) 2010 VDP .
5 | *
6 | * This file is part of MidpSSH.
7 | *
8 | * MidpSSH is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * MidpSSH is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with MidpSSH. If not, see .
20 | */
21 |
22 | package kindle;
23 |
24 | import java.awt.Component;
25 | import java.awt.event.KeyEvent;
26 | import java.util.StringTokenizer;
27 |
28 | public class ProxyKeyEvent extends KeyEvent {
29 | private final static String HDR_EVENT_ID = "EVENT_ID";
30 | private final static String HDR_MODIFIERS = "MODIFIERS";
31 | private final static String HDR_KEY_CODE = "KEY_CODE";
32 | private final static String HDR_KEY_CHAR = "KEY_CHAR";
33 |
34 | private int id;
35 |
36 | public ProxyKeyEvent(Component source, int id, long when, int modifiers,
37 | int keyCode, char keyChar) {
38 | super(source, id, when, modifiers, keyCode, keyChar);
39 | this.id = id;
40 | }
41 |
42 | public ProxyKeyEvent(KeyEvent ke) {
43 | super(ke.getComponent(), ke.getID(), ke.getWhen(), ke.getModifiers(),
44 | ke.getKeyCode(), ke.getKeyChar());
45 | this.id = ke.getID();
46 | }
47 |
48 | /**
49 | * Event format in text (everything below is of type string)
50 | * EVENT_ID (KEY_PRESSED | KEY_RELEASED | KEY_TYPED)
51 | * MODIFIERS STRING_REPR_OF_INT
52 | * KEY_CODE STRING_REPR_OF_INT
53 | * KEY_CHAR STRING_REPR_OF_CHAR
54 | */
55 | public static ProxyKeyEvent makeEvent(String eventDescr, Component source, long when) {
56 | int id = 0, modifiers = 0, code = 0;
57 | char keyChar = 0;
58 |
59 | StringTokenizer st = new StringTokenizer(eventDescr);
60 | while (st.hasMoreTokens()) {
61 | String token = st.nextToken();
62 |
63 | if (token.equals(HDR_EVENT_ID)) {
64 | id = Integer.parseInt(st.nextToken());
65 | }
66 | else if (token.equals(HDR_MODIFIERS)) {
67 | modifiers = Integer.parseInt(st.nextToken());
68 | }
69 | else if (token.equals(HDR_KEY_CODE)) {
70 | code = Integer.parseInt(st.nextToken());
71 | }
72 | else if (token.equals(HDR_KEY_CHAR)) {
73 | String charString = st.nextToken();
74 | keyChar = charString.charAt(0);
75 | if (keyChar == '\\') {
76 | switch (charString.charAt(1)) {
77 | case 'n':
78 | keyChar = '\n';
79 | break;
80 | case 't':
81 | keyChar = '\t';
82 | break;
83 | case 's':
84 | keyChar = ' ';
85 | break;
86 | }
87 | }
88 | }
89 | else {
90 | //throw new IllegalArgumentException("Unexpected event token: " + token);
91 | }
92 | }
93 |
94 | ProxyKeyEvent theEvent = new ProxyKeyEvent(source, id, when, modifiers, code, keyChar);
95 | return theEvent;
96 | }
97 |
98 | public String toString() {
99 | String keyStr;
100 |
101 | StringBuffer sb = new StringBuffer(200);
102 | sb.append(HDR_EVENT_ID).append(' ').append(getID()).append('\n');
103 | sb.append(HDR_MODIFIERS).append(' ').append(getModifiers()).append('\n');
104 | sb.append(HDR_KEY_CODE).append(' ').append(getKeyCode()).append('\n');
105 | sb.append(HDR_KEY_CHAR).append(' ');
106 |
107 | char kc = getKeyChar();
108 | if (kc == '\n') {
109 | sb.append("\\n");
110 | }
111 | else if (kc == '\t') {
112 | sb.append("\\t");
113 | }
114 | else if (kc == ' ') {
115 | sb.append("\\s");
116 | }
117 | else {
118 | sb.append(kc);
119 | }
120 |
121 | return sb.toString();
122 | }
123 |
124 | public int getID() {
125 | return id;
126 | }
127 |
128 | public void setID(int id) {
129 | this.id = id;
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/src/j2me/kindle/RemoteKbdReceiver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * ProxyKbdReceiver.java
3 | *
4 | * Copyright (c) 2010 VDP .
5 | *
6 | * This file is part of MidpSSH.
7 | *
8 | * MidpSSH is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * MidpSSH is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with MidpSSH. If not, see .
20 | */
21 |
22 | package kindle;
23 |
24 | import java.awt.Component;
25 | import java.awt.event.KeyEvent;
26 | import java.awt.event.KeyListener;
27 | import java.io.IOException;
28 | import java.net.ServerSocket;
29 | import java.net.Socket;
30 | import java.net.SocketException;
31 | import org.apache.log4j.Logger;
32 |
33 | /**
34 | * Listens on a UDP socket for keyboard events
35 | * and forwards them to the terminal window.
36 | */
37 | public class RemoteKbdReceiver extends Thread {
38 |
39 | private boolean stopping;
40 | //private DatagramSocket socket;
41 | //private DatagramPacket packet;
42 | private ServerSocket sockServ;
43 | private Socket sock;
44 | byte[] readBuf = new byte[1024];
45 | private Logger log;
46 | private KeyListener keyListener;
47 | private Component receiver;
48 | private Thread watchdog;
49 | private RKbdStatusListener rkbdListener;
50 |
51 | public RemoteKbdReceiver(int port, KeyListener listener, Component receiver) {
52 | stopping = false;
53 | log = Logger.getLogger(RemoteKbdReceiver.class.getName());
54 | this.keyListener = listener;
55 | this.receiver = receiver;
56 | try {
57 | sockServ = new ServerSocket(port);
58 | } catch (Exception ex) {
59 | log.error(ex.toString());
60 | }
61 |
62 | watchdog = new Thread(new Runnable() {
63 |
64 | public void run() {
65 | long sleepTime = 5 * 1000;
66 | while (!stopping) {
67 | try {
68 | Thread.sleep(sleepTime);
69 | } catch (InterruptedException ie) {
70 | log.debug("Watchdog thread interrupted");
71 | }
72 |
73 | try {
74 | if (sock != null)
75 | sock.getOutputStream().write(1);
76 | } catch (Exception e) {
77 | if (sock != null) {
78 | try {
79 | sock.close();
80 | sock = null;
81 | } catch (IOException ex) {
82 | log.warn(ex.toString());
83 | }
84 | }
85 | log.debug("Remote keyboard probably disconnected ...");
86 | }
87 | }
88 | }
89 | });
90 |
91 | watchdog.start();
92 | }
93 |
94 | public void kill() {
95 | try {
96 | stopping = true;
97 | if (sockServ != null)
98 | sockServ.close();
99 |
100 | if (sock != null && !sock.isClosed()) {
101 | sock.close();
102 | }
103 |
104 | watchdog.interrupt();
105 | } catch (IOException ex) {
106 | log.error(ex.getMessage());
107 | }
108 | }
109 |
110 | public void run() {
111 | try {
112 | while (!stopping) {
113 | if (sock == null) {
114 | log.info("Remote keyboard disconnected");
115 | if (rkbdListener != null) {
116 | rkbdListener.statusChanged(false);
117 | }
118 |
119 | sock = sockServ.accept();
120 |
121 | log.info("New remote keyboard attached");
122 | if (rkbdListener != null) {
123 | rkbdListener.statusChanged(true);
124 | }
125 | }
126 |
127 | int i = 0;
128 | try {
129 | int b = sock.getInputStream().read();
130 | while (b != 0) {
131 | readBuf[i++] = (byte) b;
132 | b = sock.getInputStream().read();
133 | }
134 | }
135 | catch (SocketException se) {
136 | log.info("RKeyboard read() interrupted: " + se.toString());
137 | sock = null;
138 | }
139 | catch (NullPointerException npe) {
140 | log.debug(npe.toString());
141 | }
142 |
143 | String strEvent = new String(readBuf, 0, i);
144 | System.out.println("Received: " + strEvent);
145 | ProxyKeyEvent pe = ProxyKeyEvent.makeEvent(strEvent, receiver, 0);
146 | int id = pe.getID();
147 | if (id == KeyEvent.KEY_PRESSED) {
148 | keyListener.keyPressed(pe);
149 | }
150 | else if (id == KeyEvent.KEY_RELEASED) {
151 | keyListener.keyReleased(pe);
152 | }
153 | else {
154 | keyListener.keyTyped(pe);
155 | }
156 | }
157 | } catch (IOException ex) {
158 | if (!stopping) {
159 | log.error(ex.toString());
160 | }
161 | }
162 | }
163 |
164 | public void setRKbdStatusListener(RKbdStatusListener rkbdListener) {
165 | this.rkbdListener = rkbdListener;
166 | }
167 |
168 | /**
169 | * The objects interested whether a remote keyboard is attached
170 | * should implement this interface and register it with RemoteKbdReceiver
171 | */
172 | public interface RKbdStatusListener {
173 | public void statusChanged(boolean isAttached);
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/src/j2me/kindle/RemoteKeyboard.java:
--------------------------------------------------------------------------------
1 | /*
2 | * RemoteKeyboard.java
3 | *
4 | * Copyright (c) 2010 VDP .
5 | *
6 | * This file is part of MidpSSH.
7 | *
8 | * MidpSSH is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * MidpSSH is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with MidpSSH. If not, see .
20 | */
21 |
22 | package kindle;
23 |
24 | import java.awt.Dimension;
25 | import java.awt.Frame;
26 | import java.awt.GraphicsDevice;
27 | import java.awt.GraphicsEnvironment;
28 | import java.awt.event.KeyEvent;
29 | import java.awt.event.KeyListener;
30 | import java.awt.event.WindowAdapter;
31 | import java.awt.event.WindowEvent;
32 | import java.io.FileInputStream;
33 | import java.io.FileNotFoundException;
34 | import java.io.IOException;
35 | import java.io.OutputStream;
36 | import java.net.DatagramPacket;
37 | import java.net.DatagramSocket;
38 | import java.net.InetSocketAddress;
39 | import java.net.Socket;
40 | import java.net.SocketException;
41 | import java.util.Properties;
42 | import java.util.logging.Level;
43 | import java.util.logging.Logger;
44 |
45 | /**
46 | * Captures the key events on a host machine and relays them
47 | * to the Kindle in plain text format.
48 | *
49 | * @author VDP .
50 | */
51 | public class RemoteKeyboard implements KeyListener {
52 |
53 | public static void main(String[] args) {
54 | // GraphicsDevice device = GraphicsEnvironment.getLocalGraphicsEnvironment().
55 | // getDefaultScreenDevice();
56 | // if (device.isFullScreenSupported()) {
57 | // System.out.println("Fullscreen supported");
58 | // device.setFullScreenWindow(frame);
59 | // }
60 | // else {
61 | // System.err.println("Full screen not supported");
62 | // }
63 | FileInputStream fis = null;
64 | try {
65 | final Frame frame = new Frame("Type here");
66 | frame.setPreferredSize(new Dimension(800, 600));
67 | frame.setSize(new Dimension(800, 600));
68 |
69 | fis = new FileInputStream("remote_keyboard.properties");
70 | Properties props = new Properties();
71 | props.load(fis);
72 | String host = props.getProperty("host");
73 | int port = Integer.parseInt(props.getProperty("port"));
74 |
75 | frame.addWindowListener(new WindowAdapter() {
76 | public void windowClosing(WindowEvent e) {
77 | frame.dispose();
78 | System.exit(0);
79 | }
80 | });
81 |
82 | RemoteKeyboard rk = new RemoteKeyboard(host, port);
83 | frame.addKeyListener(rk);
84 | frame.setFocusTraversalKeysEnabled(false);
85 | frame.setVisible(true);
86 | } catch (Exception ex) {
87 | ex.printStackTrace();
88 | } finally {
89 | try {
90 | fis.close();
91 | } catch (IOException ex) {
92 | ex.printStackTrace();
93 | }
94 | }
95 | }
96 |
97 | private String host;
98 | private int port;
99 |
100 | private Socket socket;
101 | private OutputStream out;
102 |
103 |
104 | public RemoteKeyboard(String targetHost, int targetPort) {
105 | this.host = targetHost;
106 | this.port= targetPort;
107 |
108 | connect();
109 | Thread reader = new Thread(new Runnable() {
110 |
111 | public void run() {
112 | while (true) {
113 | try {
114 | if (socket != null) {
115 | socket.getInputStream().read();
116 | }
117 | } catch (Exception e) {
118 | e.printStackTrace();
119 | }
120 | }
121 | }
122 |
123 | });
124 | }
125 |
126 | private boolean connect() {
127 | boolean ok = true;
128 | try {
129 | System.out.println("Connecting to " + host + ':' + port + " ...");
130 | socket = new Socket(host, port);
131 | out = socket.getOutputStream();
132 | System.out.println("OK");
133 | } catch (Exception ex) {
134 | System.out.println("Failed to connect");
135 | ok = false;
136 | }
137 |
138 | return ok;
139 | }
140 |
141 | private void sendEvent(KeyEvent event) {
142 | try {
143 | ProxyKeyEvent pe = new ProxyKeyEvent(event);
144 | System.out.println("Key Event: " + pe);
145 | //ProxyKeyEvent reconstructed = ProxyKeyEvent.makeEvent(pe.toString(), event.getComponent(), 0);
146 | //System.out.println("Reconstructed: " + reconstructed);
147 | byte[] eventBytes = pe.toString().getBytes();
148 | try {
149 | out.write(eventBytes);
150 | out.write(0);
151 | out.flush();
152 | }
153 | catch (Exception ioe) {
154 | if (socket != null) socket.close();
155 | connect();
156 | }
157 | } catch (Exception ex) {
158 | ex.printStackTrace();
159 | }
160 | }
161 |
162 | public void keyTyped(KeyEvent ke) {
163 | sendEvent(ke);
164 | }
165 |
166 | public void keyPressed(KeyEvent ke) {
167 | sendEvent(ke);
168 | }
169 |
170 | public void keyReleased(KeyEvent ke) {
171 | sendEvent(ke);
172 | }
173 | }
174 |
--------------------------------------------------------------------------------
/src/j2me/ssh/SshPacket.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of "The Java Telnet Application".
3 | *
4 | * (c) Matthias L. Jugel, Marcus Mei�ner 1996-2002. All Rights Reserved.
5 | * The file was changed by Radek Polak to work as midlet in MIDP 1.0
6 | *
7 | * Please visit http://javatelnet.org/ for updates and contact.
8 | *
9 | * --LICENSE NOTICE--
10 | * This program is free software; you can redistribute it and/or
11 | * modify it under the terms of the GNU General Public License
12 | * as published by the Free Software Foundation; either version 2
13 | * of the License, or (at your option) any later version.
14 | *
15 | * This program is distributed in the hope that it will be useful,
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | * GNU General Public License for more details.
19 | *
20 | * You should have received a copy of the GNU General Public License
21 | * along with this program; if not, write to the Free Software
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 | * --LICENSE NOTICE--
24 | */
25 |
26 | package ssh;
27 |
28 | abstract public class SshPacket {
29 | public SshPacket() { /* nothing */
30 | }
31 |
32 | // Data management
33 | protected byte[] byteArray = new byte[0];
34 |
35 | protected int offset;
36 |
37 | private boolean finished;
38 |
39 | public byte[] getData() {
40 | return byteArray;
41 | }
42 |
43 | public void putData(byte[] data) {
44 | byteArray = data;
45 | offset = 0;
46 | finished = true;
47 | }
48 |
49 | public boolean isFinished() {
50 | return finished;
51 | }
52 |
53 | abstract public int addPayload(byte[] buff, int boffset, int length);
54 |
55 | // Type
56 | protected byte packet_type;
57 |
58 | public byte getType() {
59 | return packet_type;
60 | }
61 |
62 | public abstract void putMpInt(byte[] bi);
63 |
64 | public int getInt32() {
65 | short d0 = byteArray[offset++];
66 | short d1 = byteArray[offset++];
67 | short d2 = byteArray[offset++];
68 | short d3 = byteArray[offset++];
69 |
70 | if (d0 < 0)
71 | d0 = (short) (256 + d0);
72 | if (d1 < 0)
73 | d1 = (short) (256 + d1);
74 | if (d2 < 0)
75 | d2 = (short) (256 + d2);
76 | if (d3 < 0)
77 | d3 = (short) (256 + d3);
78 |
79 | return (d0 << 24) + (d1 << 16) + (d2 << 8) + d3;
80 | }
81 |
82 | public int getInt16() {
83 | short d0 = byteArray[offset++];
84 | short d1 = byteArray[offset++];
85 |
86 | if (d0 < 0)
87 | d0 = (short) (256 + d0);
88 | if (d1 < 0)
89 | d1 = (short) (256 + d1);
90 |
91 | return (d0 << 8) + d1;
92 | }
93 |
94 | public String getString() {
95 | int length = getInt32();
96 |
97 | StringBuffer str = new StringBuffer();
98 | for (int i = 0; i < length; i++) {
99 | /*
100 | * if ( byteArray[offset] >= 0 ) str.append( (char) (
101 | * byteArray[offset++] ) ); else str.append( (char) ( 256 +
102 | * byteArray[offset++] ) );
103 | */
104 | str.append((char) byteArray[offset++]);
105 | }
106 | return str.toString();
107 | }
108 |
109 | public byte[] getByteString() {
110 | int length = getInt32();
111 | return getBytes(length);
112 | }
113 |
114 | public byte getByte() {
115 | return byteArray[offset++];
116 | }
117 |
118 | public byte[] getBytes(int cnt) {
119 | byte[] bytes = new byte[cnt];
120 |
121 | System.arraycopy(byteArray, offset, bytes, 0, cnt);
122 | offset += cnt;
123 | return bytes;
124 | }
125 |
126 | private void grow(int howmuch) {
127 | byte[] value = new byte[byteArray.length + howmuch];
128 | System.arraycopy(byteArray, 0, value, 0, byteArray.length);
129 | byteArray = value;
130 | }
131 |
132 | public void putInt16(int xint) {
133 | int boffset = byteArray.length;
134 | grow(2);
135 | byteArray[boffset + 1] = (byte) ((xint) & 0xff);
136 | byteArray[boffset] = (byte) ((xint >> 8) & 0xff);
137 | }
138 |
139 | public void putInt32(int xint) {
140 | int boffset = byteArray.length;
141 | grow(4);
142 | byteArray[boffset + 3] = (byte) ((xint) & 0xff);
143 | byteArray[boffset + 2] = (byte) ((xint >> 8) & 0xff);
144 | byteArray[boffset + 1] = (byte) ((xint >> 16) & 0xff);
145 | byteArray[boffset + 0] = (byte) ((xint >> 24) & 0xff);
146 | }
147 |
148 | public void putByte(byte xbyte) {
149 | grow(1);
150 | byteArray[byteArray.length - 1] = xbyte;
151 | }
152 |
153 | public void putBytes(byte[] bytes) {
154 | int oldlen = byteArray.length;
155 | grow(bytes.length);
156 | System.arraycopy(bytes, 0, byteArray, oldlen, bytes.length);
157 | }
158 |
159 | public void putBytes(byte[] bytes, int offset, int length) {
160 | int oldlen = byteArray.length;
161 | grow(length);
162 | System.arraycopy(bytes, offset, byteArray, oldlen, length);
163 | }
164 |
165 | /**
166 | * Add a SSH String to a packet. The incore representation is a INT32 length
167 | * BYTE[length] data
168 | *
169 | * @param str:
170 | * The string to be added.
171 | */
172 | public void putString(String str) {
173 | putInt32(str.length());
174 | putBytes(str.getBytes());
175 | }
176 |
177 | public void putString(byte[] foo) {
178 | putString(foo, 0, foo.length);
179 | }
180 |
181 | public void putString(byte[] foo, int begin, int length) {
182 | putInt32(length);
183 | putBytes(foo, begin, length);
184 | }
185 | }
--------------------------------------------------------------------------------
/src/j2me/ssh/v1/Blowfish.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vdp/KindleTERM/e3f55e2f5745a43f52b64c854e3ee911e71bef5c/src/j2me/ssh/v1/Blowfish.java
--------------------------------------------------------------------------------
/src/j2me/ssh/v1/Cipher.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vdp/KindleTERM/e3f55e2f5745a43f52b64c854e3ee911e71bef5c/src/j2me/ssh/v1/Cipher.java
--------------------------------------------------------------------------------
/src/j2me/ssh/v1/DES.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vdp/KindleTERM/e3f55e2f5745a43f52b64c854e3ee911e71bef5c/src/j2me/ssh/v1/DES.java
--------------------------------------------------------------------------------
/src/j2me/ssh/v1/DES3.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vdp/KindleTERM/e3f55e2f5745a43f52b64c854e3ee911e71bef5c/src/j2me/ssh/v1/DES3.java
--------------------------------------------------------------------------------
/src/j2me/ssh/v1/IDEA.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vdp/KindleTERM/e3f55e2f5745a43f52b64c854e3ee911e71bef5c/src/j2me/ssh/v1/IDEA.java
--------------------------------------------------------------------------------
/src/j2me/ssh/v1/NONE.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vdp/KindleTERM/e3f55e2f5745a43f52b64c854e3ee911e71bef5c/src/j2me/ssh/v1/NONE.java
--------------------------------------------------------------------------------
/src/j2me/ssh/v1/SshCrypto.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vdp/KindleTERM/e3f55e2f5745a43f52b64c854e3ee911e71bef5c/src/j2me/ssh/v1/SshCrypto.java
--------------------------------------------------------------------------------
/src/j2me/ssh/v2/HMACSHA1.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of "MidpSSH".
3 | *
4 | * This file was adapted from Java Secure Channel (www.jcraft.com/jsch/) for
5 | * MidpSSH by Karl von Randow
6 | *
7 | * Copyright (c) 2002,2003,2004 ymnk, JCraft,Inc. All rights reserved.
8 | *
9 | * Redistribution and use in source and binary forms, with or without
10 | * modification, are permitted provided that the following conditions are met:
11 | *
12 | * 1. Redistributions of source code must retain the above copyright notice,
13 | * this list of conditions and the following disclaimer.
14 | *
15 | * 2. Redistributions in binary form must reproduce the above copyright notice,
16 | * this list of conditions and the following disclaimer in the documentation
17 | * and/or other materials provided with the distribution.
18 | *
19 | * 3. The names of the authors may not be used to endorse or promote products
20 | * derived from this software without specific prior written permission.
21 | *
22 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
23 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
24 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
25 | * INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
28 | * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
31 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 | */
33 | package ssh.v2;
34 |
35 | public class HMACSHA1 {
36 | private String name = "hmac-sha1";
37 |
38 | private int bsize = 20;
39 |
40 | private byte[] tmp = new byte[4];
41 |
42 | private final static int BLOCK_LENGTH = 64;
43 |
44 | private final static byte IPAD = (byte) 0x36;
45 |
46 | private final static byte OPAD = (byte) 0x5C;
47 |
48 | private SHA1Digest digest;
49 |
50 | private int digestSize;
51 |
52 | private byte[] inputPad = new byte[BLOCK_LENGTH];
53 |
54 | private byte[] outputPad = new byte[BLOCK_LENGTH];
55 |
56 | public int getBlockSize() {
57 | return bsize;
58 | };
59 |
60 | public void init(byte[] key) {
61 | if (key.length > bsize) {
62 | byte[] tmp = new byte[bsize];
63 | System.arraycopy(key, 0, tmp, 0, bsize);
64 | key = tmp;
65 | }
66 |
67 | digest = new SHA1Digest();
68 | digestSize = digest.getDigestSize();
69 |
70 | digest.reset();
71 |
72 | if (key.length > BLOCK_LENGTH) {
73 | digest.update(key, 0, key.length);
74 | digest.doFinal(inputPad, 0);
75 | for (int i = digestSize; i < inputPad.length; i++) {
76 | inputPad[i] = 0;
77 | }
78 | } else {
79 | System.arraycopy(key, 0, inputPad, 0, key.length);
80 | for (int i = key.length; i < inputPad.length; i++) {
81 | inputPad[i] = 0;
82 | }
83 | }
84 |
85 | outputPad = new byte[inputPad.length];
86 | System.arraycopy(inputPad, 0, outputPad, 0, inputPad.length);
87 |
88 | for (int i = 0; i < inputPad.length; i++) {
89 | inputPad[i] ^= IPAD;
90 | }
91 |
92 | for (int i = 0; i < outputPad.length; i++) {
93 | outputPad[i] ^= OPAD;
94 | }
95 |
96 | digest.update(inputPad, 0, inputPad.length);
97 | }
98 |
99 | public void update(int i) {
100 | tmp[0] = (byte) (i >>> 24);
101 | tmp[1] = (byte) (i >>> 16);
102 | tmp[2] = (byte) (i >>> 8);
103 | tmp[3] = (byte) i;
104 | update(tmp, 0, 4);
105 | }
106 |
107 | public void update(byte foo[], int s, int l) {
108 | digest.update(foo, s, l);
109 | }
110 |
111 | public byte[] doFinal() {
112 | byte[] out = new byte[digestSize];
113 |
114 | byte[] tmp = new byte[digestSize];
115 | digest.doFinal(tmp, 0);
116 |
117 | digest.update(outputPad, 0, outputPad.length);
118 | digest.update(tmp, 0, tmp.length);
119 |
120 | digest.doFinal(out, 0);
121 |
122 | reset();
123 |
124 | return out;
125 | }
126 |
127 | /**
128 | * Reset the mac generator.
129 | */
130 | public void reset() {
131 | /*
132 | * reset the underlying digest.
133 | */
134 | digest.reset();
135 |
136 | /*
137 | * reinitialize the digest.
138 | */
139 | digest.update(inputPad, 0, inputPad.length);
140 | }
141 |
142 | public String getName() {
143 | return name;
144 | }
145 | }
--------------------------------------------------------------------------------
/src/j2me/ssh/v2/PublicKeyAuthentication.java:
--------------------------------------------------------------------------------
1 | package ssh.v2;
2 |
3 | import java.util.Random;
4 | //#ifndef noj2me
5 | import app.Settings;
6 | //#endif
7 |
8 | public class PublicKeyAuthentication {
9 |
10 | public static final BigInteger p = new BigInteger(
11 | "d1c9009c7f181e9b27ce020e014d72c499f604c8d978a4dd9a8614362b09a74be4004cdd1b6ccf2bb2d2a4d4710be0817a375c85e8b0ce05e92a1f7c0b4886418dc6de84457dfd8dc19efdc0efb5c15bbab7a860b3e95c169d6e8aceef445deddc85ab44a11d5870847b99239011ff7d36a0f52cd11c3a0a33c415cdd58d85a1",
12 | 16),
13 | q = new BigInteger("e691d26b30a8b43081b981d96a8189fe78d04f8f", 16),
14 | g = new BigInteger(
15 | "6ded9dc637ecc98f7ccf5a50839e13354972985cb901ca164fb8174318c84fec50ce84bfef5f4ee4981c239ed7c2bcf0718fcc0f30382df782221f64bfd09c9dc8e098ad10f296eadd9f5650f17414a77d3ff5ca8d103235e2de14a392c9a1156b2a5652d135111858af96d531688d80e962c52c75738f3d48aa09d59ca064a6",
16 | 16);
17 |
18 | public BigInteger x, y;
19 |
20 | //#ifdef ssh2
21 | public PublicKeyAuthentication() {
22 | //#ifndef noj2me
23 | this.x = new BigInteger(Settings.x);
24 | this.y = new BigInteger(Settings.y);
25 | //#else
26 | this.x = null;
27 | this.y = null;
28 | //#endif
29 | }
30 | //#endif
31 |
32 | public byte[] sign(byte[] session_id, byte[] message) {
33 | SshPacket2 buf = new SshPacket2();
34 | buf.putString(session_id);
35 | buf.putByte((byte) 50); // SSH2_MSG_USERAUTH_REQUEST
36 | buf.putBytes(message);
37 |
38 | message = buf.getData();
39 |
40 | SHA1Digest digest = new SHA1Digest();
41 | digest.update(message, 0, message.length);
42 | byte[] hash = new byte[digest.getDigestSize()];
43 | digest.doFinal(hash, 0);
44 |
45 | BigInteger[] rs = generateSignature(hash);
46 |
47 | buf = new SshPacket2();
48 | buf.putString(DHKeyExchange.SSH_DSS);
49 | byte[] r = rs[0].toByteArray();
50 | byte[] s = rs[1].toByteArray();
51 | byte[] sig = new byte[40];
52 | System.arraycopy(r, r.length > 20 ? 1 : 0, sig, r.length > 20 ? 0
53 | : 20 - r.length, r.length > 20 ? 20 : r.length);
54 | System.arraycopy(s, s.length > 20 ? 1 : 0, sig, s.length > 20 ? 20
55 | : 40 - s.length, s.length > 20 ? 20 : s.length);
56 | buf.putString(sig);
57 |
58 | return buf.getData();
59 | }
60 |
61 | /**
62 | * generate a signature for the given message using the key we were
63 | * initialised with. For conventional DSA the message should be a SHA-1 hash
64 | * of the message of interest.
65 | *
66 | * @param message
67 | * the message that will be verified later.
68 | */
69 | public BigInteger[] generateSignature(byte[] message) {
70 | BigInteger m = new BigInteger(1, message);
71 | BigInteger k;
72 | int qBitLength = q.bitLength();
73 |
74 | do {
75 | k = new BigInteger(qBitLength, new Random());
76 | } while (k.compareTo(q) >= 0);
77 |
78 | BigInteger r = g.modPow(k, p).mod(q);
79 |
80 | k = k.modInverse(q).multiply(m.add(x.multiply(r)));
81 |
82 | BigInteger s = k.mod(q);
83 |
84 | BigInteger[] res = new BigInteger[2];
85 |
86 | res[0] = r;
87 | res[1] = s;
88 |
89 | return res;
90 | }
91 |
92 | public String getPublicKeyText() {
93 | byte[] pubblob = getPublicKeyBlob();
94 | byte[] pub = toBase64(pubblob, 0, pubblob.length);
95 | return DHKeyExchange.SSH_DSS + " " + new String(pub);
96 | }
97 |
98 | public byte[] getPublicKeyBlob() {
99 | SshPacket2 buf = new SshPacket2();
100 | buf.putString(DHKeyExchange.SSH_DSS);
101 | buf.putMpInt(p.toByteArray());
102 | buf.putMpInt(q.toByteArray());
103 | buf.putMpInt(g.toByteArray());
104 | buf.putMpInt(y.toByteArray());
105 | return buf.getData();
106 | }
107 |
108 | public static byte[][] generateKeyPair() {
109 | BigInteger x, y;
110 |
111 | do {
112 | x = new BigInteger(160, new Random());
113 | } while (x.equals(BigInteger.ZERO) || x.compareTo(q) >= 0);
114 |
115 | //
116 | // calculate the public key.
117 | //
118 | y = g.modPow(x, p);
119 |
120 | byte[][] res = new byte[2][];
121 | res[0] = x.toByteArray();
122 | res[1] = y.toByteArray();
123 | return res;
124 | }
125 |
126 | private static final byte[] b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
127 | .getBytes();
128 |
129 | private static byte[] toBase64(byte[] buf, int start, int length) {
130 |
131 | byte[] tmp = new byte[length * 2];
132 | int i, j, k;
133 |
134 | int foo = (length / 3) * 3 + start;
135 | i = 0;
136 | for (j = start; j < foo; j += 3) {
137 | k = (buf[j] >>> 2) & 0x3f;
138 | tmp[i++] = b64[k];
139 | k = (buf[j] & 0x03) << 4 | (buf[j + 1] >>> 4) & 0x0f;
140 | tmp[i++] = b64[k];
141 | k = (buf[j + 1] & 0x0f) << 2 | (buf[j + 2] >>> 6) & 0x03;
142 | tmp[i++] = b64[k];
143 | k = buf[j + 2] & 0x3f;
144 | tmp[i++] = b64[k];
145 | }
146 |
147 | foo = (start + length) - foo;
148 | if (foo == 1) {
149 | k = (buf[j] >>> 2) & 0x3f;
150 | tmp[i++] = b64[k];
151 | k = ((buf[j] & 0x03) << 4) & 0x3f;
152 | tmp[i++] = b64[k];
153 | tmp[i++] = (byte) '=';
154 | tmp[i++] = (byte) '=';
155 | } else if (foo == 2) {
156 | k = (buf[j] >>> 2) & 0x3f;
157 | tmp[i++] = b64[k];
158 | k = (buf[j] & 0x03) << 4 | (buf[j + 1] >>> 4) & 0x0f;
159 | tmp[i++] = b64[k];
160 | k = ((buf[j + 1] & 0x0f) << 2) & 0x3f;
161 | tmp[i++] = b64[k];
162 | tmp[i++] = (byte) '=';
163 | }
164 | byte[] bar = new byte[i];
165 | System.arraycopy(tmp, 0, bar, 0, i);
166 | return bar;
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/src/j2me/ssh/v2/SHA1Digest.java:
--------------------------------------------------------------------------------
1 | /* This file is part of "MidpSSH".
2 | *
3 | * This file was adapted from Bouncy Castle JCE (www.bouncycastle.org)
4 | * for MidpSSH by Karl von Randow
5 | */
6 | package ssh.v2;
7 |
8 | /**
9 | * implementation of SHA-1 as outlined in "Handbook of Applied Cryptography",
10 | * pages 346 - 349.
11 | *
12 | * It is interesting to ponder why the, apart from the extra IV, the other
13 | * difference here from MD5 is the "endienness" of the word processing!
14 | */
15 | public class SHA1Digest {
16 | private static final int DIGEST_LENGTH = 20;
17 |
18 | private int H1, H2, H3, H4, H5;
19 |
20 | private int[] X = new int[80];
21 |
22 | private int xOff;
23 |
24 | private byte[] xBuf;
25 |
26 | private int xBufOff;
27 |
28 | private long byteCount;
29 |
30 | /**
31 | * Standard constructor
32 | */
33 | public SHA1Digest() {
34 | xBuf = new byte[4];
35 | xBufOff = 0;
36 |
37 | reset();
38 | }
39 |
40 | public String getAlgorithmName() {
41 | return "SHA-1";
42 | }
43 |
44 | public int getDigestSize() {
45 | return DIGEST_LENGTH;
46 | }
47 |
48 | protected void processWord(byte[] in, int inOff) {
49 | X[xOff++] = ((in[inOff] & 0xff) << 24) | ((in[inOff + 1] & 0xff) << 16)
50 | | ((in[inOff + 2] & 0xff) << 8) | ((in[inOff + 3] & 0xff));
51 |
52 | if (xOff == 16) {
53 | processBlock();
54 | }
55 | }
56 |
57 | private void unpackWord(int word, byte[] out, int outOff) {
58 | out[outOff] = (byte) (word >>> 24);
59 | out[outOff + 1] = (byte) (word >>> 16);
60 | out[outOff + 2] = (byte) (word >>> 8);
61 | out[outOff + 3] = (byte) word;
62 | }
63 |
64 | protected void processLength(long bitLength) {
65 | if (xOff > 14) {
66 | processBlock();
67 | }
68 |
69 | X[14] = (int) (bitLength >>> 32);
70 | X[15] = (int) (bitLength & 0xffffffff);
71 | }
72 |
73 | public int doFinal(byte[] out, int outOff) {
74 | finish();
75 |
76 | unpackWord(H1, out, outOff);
77 | unpackWord(H2, out, outOff + 4);
78 | unpackWord(H3, out, outOff + 8);
79 | unpackWord(H4, out, outOff + 12);
80 | unpackWord(H5, out, outOff + 16);
81 |
82 | reset();
83 |
84 | return DIGEST_LENGTH;
85 | }
86 |
87 | /**
88 | * reset the chaining variables
89 | */
90 | public void reset() {
91 | byteCount = 0;
92 |
93 | xBufOff = 0;
94 | for (int i = 0; i < xBuf.length; i++) {
95 | xBuf[i] = 0;
96 | }
97 |
98 | H1 = 0x67452301;
99 | H2 = 0xefcdab89;
100 | H3 = 0x98badcfe;
101 | H4 = 0x10325476;
102 | H5 = 0xc3d2e1f0;
103 |
104 | xOff = 0;
105 | for (int i = 0; i != X.length; i++) {
106 | X[i] = 0;
107 | }
108 | }
109 |
110 | public void update(byte in) {
111 | xBuf[xBufOff++] = in;
112 |
113 | if (xBufOff == xBuf.length) {
114 | processWord(xBuf, 0);
115 | xBufOff = 0;
116 | }
117 |
118 | byteCount++;
119 | }
120 |
121 | public void update(byte[] in, int inOff, int len) {
122 | //
123 | // fill the current word
124 | //
125 | while ((xBufOff != 0) && (len > 0)) {
126 | update(in[inOff]);
127 |
128 | inOff++;
129 | len--;
130 | }
131 |
132 | //
133 | // process whole words.
134 | //
135 | while (len > xBuf.length) {
136 | processWord(in, inOff);
137 |
138 | inOff += xBuf.length;
139 | len -= xBuf.length;
140 | byteCount += xBuf.length;
141 | }
142 |
143 | //
144 | // load in the remainder.
145 | //
146 | while (len > 0) {
147 | update(in[inOff]);
148 |
149 | inOff++;
150 | len--;
151 | }
152 | }
153 |
154 | public void finish() {
155 | long bitLength = (byteCount << 3);
156 |
157 | //
158 | // add the pad bytes.
159 | //
160 | update((byte) 128);
161 |
162 | while (xBufOff != 0) {
163 | update((byte) 0);
164 | }
165 |
166 | processLength(bitLength);
167 |
168 | processBlock();
169 | }
170 |
171 | //
172 | // Additive constants
173 | //
174 | private static final int Y1 = 0x5a827999;
175 |
176 | private static final int Y2 = 0x6ed9eba1;
177 |
178 | private static final int Y3 = 0x8f1bbcdc;
179 |
180 | private static final int Y4 = 0xca62c1d6;
181 |
182 | private int f(int u, int v, int w) {
183 | return ((u & v) | ((~u) & w));
184 | }
185 |
186 | private int h(int u, int v, int w) {
187 | return (u ^ v ^ w);
188 | }
189 |
190 | private int g(int u, int v, int w) {
191 | return ((u & v) | (u & w) | (v & w));
192 | }
193 |
194 | private int rotateLeft(int x, int n) {
195 | return (x << n) | (x >>> (32 - n));
196 | }
197 |
198 | protected void processBlock() {
199 | //
200 | // expand 16 word block into 80 word block.
201 | //
202 | for (int i = 16; i <= 79; i++) {
203 | X[i] = rotateLeft((X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16]), 1);
204 | }
205 |
206 | //
207 | // set up working variables.
208 | //
209 | int A = H1;
210 | int B = H2;
211 | int C = H3;
212 | int D = H4;
213 | int E = H5;
214 |
215 | //
216 | // round 1
217 | //
218 | for (int j = 0; j <= 19; j++) {
219 | int t = rotateLeft(A, 5) + f(B, C, D) + E + X[j] + Y1;
220 |
221 | E = D;
222 | D = C;
223 | C = rotateLeft(B, 30);
224 | B = A;
225 | A = t;
226 | }
227 |
228 | //
229 | // round 2
230 | //
231 | for (int j = 20; j <= 39; j++) {
232 | int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y2;
233 |
234 | E = D;
235 | D = C;
236 | C = rotateLeft(B, 30);
237 | B = A;
238 | A = t;
239 | }
240 |
241 | //
242 | // round 3
243 | //
244 | for (int j = 40; j <= 59; j++) {
245 | int t = rotateLeft(A, 5) + g(B, C, D) + E + X[j] + Y3;
246 |
247 | E = D;
248 | D = C;
249 | C = rotateLeft(B, 30);
250 | B = A;
251 | A = t;
252 | }
253 |
254 | //
255 | // round 4
256 | //
257 | for (int j = 60; j <= 79; j++) {
258 | int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y4;
259 |
260 | E = D;
261 | D = C;
262 | C = rotateLeft(B, 30);
263 | B = A;
264 | A = t;
265 | }
266 |
267 | H1 += A;
268 | H2 += B;
269 | H3 += C;
270 | H4 += D;
271 | H5 += E;
272 |
273 | //
274 | // reset the offset and clean out the word buffer.
275 | //
276 | xOff = 0;
277 | for (int i = 0; i != X.length; i++) {
278 | X[i] = 0;
279 | }
280 | }
281 | }
--------------------------------------------------------------------------------
/src/j2me/ssh/v2/SshCrypto2.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of "MidpSSH". Copyright (c) 2004 Karl von Randow.
3 | *
4 | * MidpSSH is based upon Telnet Floyd and FloydSSH by Radek Polak.
5 | *
6 | * --LICENSE NOTICE-- This program is free software; you can redistribute it
7 | * and/or modify it under the terms of the GNU General Public License as
8 | * published by the Free Software Foundation; either version 2 of the License,
9 | * or (at your option) any later version.
10 | *
11 | * This program is distributed in the hope that it will be useful, but WITHOUT
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 | * details.
15 | *
16 | * You should have received a copy of the GNU General Public License along with
17 | * this program; if not, write to the Free Software Foundation, Inc., 675 Mass
18 | * Ave, Cambridge, MA 02139, USA. --LICENSE NOTICE--
19 | *
20 | */
21 | package ssh.v2;
22 |
23 |
24 | public class SshCrypto2 {
25 | private BufferedDESedeCBC sndCipher, rcvCipher;
26 |
27 | private HMACSHA1 sndHmac, rcvHmac;
28 |
29 | public SshCrypto2(byte[] IVc2s, byte[] IVs2c, byte[] Ec2s, byte[] Es2c,
30 | byte[] MACc2s, byte[] MACs2c) {
31 | sndCipher = new BufferedDESedeCBC();
32 | sndCipher.init(true, IVc2s, Ec2s);
33 | rcvCipher = new BufferedDESedeCBC();
34 | rcvCipher.init(false, IVs2c, Es2c);
35 |
36 | sndHmac = new HMACSHA1();
37 | sndHmac.init(MACc2s);
38 |
39 | rcvHmac = new HMACSHA1();
40 | rcvHmac.init(MACs2c);
41 | }
42 |
43 | public byte[] encrypt(byte[] src) {
44 | byte[] dest = new byte[src.length];
45 | sndCipher.processBytes(src, 0, src.length, dest, 0);
46 | return dest;
47 | }
48 |
49 | public byte[] decrypt(byte[] src) {
50 | byte[] dest = new byte[src.length];
51 | rcvCipher.processBytes(src, 0, src.length, dest, 0);
52 | return dest;
53 | }
54 |
55 | /**
56 | * @return Returns the rcvHmac.
57 | */
58 | public HMACSHA1 getRcvHmac() {
59 | return rcvHmac;
60 | }
61 |
62 | /**
63 | * @return Returns the sndHmac.
64 | */
65 | public HMACSHA1 getSndHmac() {
66 | return sndHmac;
67 | }
68 | }
--------------------------------------------------------------------------------
/src/j2me/telnet/Dimension.java:
--------------------------------------------------------------------------------
1 | package telnet;
2 |
3 | /* This file is part of "Telnet Floyd".
4 | *
5 | * (c) Radek Polak 2003-2004. All Rights Reserved.
6 | *
7 | * Please visit project homepage at http://phoenix.inf.upol.cz/~polakr
8 | *
9 | * --LICENSE NOTICE--
10 | * This program is free software; you can redistribute it and/or
11 | * modify it under the terms of the GNU General Public License
12 | * as published by the Free Software Foundation; either version 2
13 | * of the License, or (at your option) any later version.
14 | *
15 | * This program is distributed in the hope that it will be useful,
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 | * GNU General Public License for more details.
19 | *
20 | * You should have received a copy of the GNU General Public License
21 | * along with this program; if not, write to the Free Software
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 | * --LICENSE NOTICE--
24 | *
25 | */
26 |
27 | /**
28 | * Class used instead of missing java.awt.Dimension.
29 | */
30 |
31 | public class Dimension {
32 |
33 | public int width, height;
34 |
35 | public Dimension() {
36 | }
37 |
38 | public Dimension( int width, int height ) {
39 | this.width = width;
40 | this.height = height;
41 | }
42 |
43 | }
--------------------------------------------------------------------------------
/src/j2me/telnet/TelnetProtocolHandler.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vdp/KindleTERM/e3f55e2f5745a43f52b64c854e3ee911e71bef5c/src/j2me/telnet/TelnetProtocolHandler.java
--------------------------------------------------------------------------------
/src/j2me/terminal/LCDFont.java:
--------------------------------------------------------------------------------
1 | // LCDFont: Class for using tiny fonts with subpixel antialising
2 | //
3 | // Copyright 2005 Roar Lauritzsen
4 | //
5 | // This class is free software; you can redistribute it and/or modify
6 | // it under the terms of the GNU General Public License as published by
7 | // the Free Software Foundation; either version 2 of the License, or
8 | // (at your option) any later version.
9 | //
10 | // This class is distributed in the hope that it will be useful,
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | // GNU General Public License for more details.
14 | //
15 | // The following link provides a copy of the GNU General Public License:
16 | // http://www.gnu.org/licenses/gpl.txt
17 | // If you are unable to obtain the copy from this address, write to
18 | // the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19 | // Boston, MA 02111-1307 USA
20 |
21 | package terminal;
22 |
23 | import java.io.IOException;
24 |
25 | import javax.microedition.lcdui.Graphics;
26 | import javax.microedition.lcdui.Image;
27 |
28 | public class LCDFont {
29 | //#ifdef midp2
30 |
31 | public final int fontWidth; // Width of one character
32 |
33 | public final int fontHeight; // Height of one character
34 |
35 | private final int imageWidth, imageHeight;
36 |
37 | private int[] bwBuf; // Black-white version of font
38 |
39 | private int[] colorBuf; // Colored version of font
40 |
41 | private int[] currentBuf;
42 |
43 | private long currentColor;
44 |
45 | private long[] cacheColor; // Color of each cached character
46 |
47 | private int FR, FG, FB, BR, BG, BB;
48 |
49 | // Create subpixel-antialiased font based on image resource name.
50 | // If BGR is set to true, subpixel order is reversed (normal is RGB)
51 | public LCDFont(String fontImageName, boolean BGR) {
52 | Image fontImage;
53 | try {
54 | fontImage = Image.createImage(fontImageName);
55 | } catch (IOException e) {
56 | throw new RuntimeException("Cannot load LCDFont: " + e);
57 | }
58 | imageWidth = fontImage.getWidth();
59 | imageHeight = fontImage.getHeight();
60 | fontWidth = imageWidth / 32;
61 | fontHeight = imageHeight / 3;
62 | bwBuf = new int[imageWidth * (imageHeight + 1)];
63 | colorBuf = new int[imageWidth * (imageHeight + 1)];
64 | /* Karl: add 1 to the imageHeight because some device seek beyond the bottom of the array when
65 | * drawing.
66 | */
67 | fontImage.getRGB(bwBuf, 0, imageWidth, 0, 0, imageWidth, imageHeight);
68 | if (BGR) {
69 | // For screens with BGR subpixel ordering, or for ROT_180
70 | for (int i = 0; i < bwBuf.length; i++) {
71 | int c = bwBuf[i];
72 | bwBuf[i] = ((c >> 16) & 0xff) + (c & 0xff00)
73 | + ((c & 0xff) << 16);
74 | }
75 | }
76 | cacheColor = new long[96];
77 | currentBuf = bwBuf;
78 | currentColor = 0;
79 | }
80 |
81 | // Set the foreground and background color of font
82 | // For readability, input font colors will be modified
83 | public void setColor(int fg, int bg) {
84 | if (fg == 0xffffff && bg == 0) {
85 | currentBuf = bwBuf;
86 | } else if (((long) fg << 32) + bg != currentColor) {
87 | currentColor = ((long) fg << 32) + bg;
88 | currentBuf = colorBuf;
89 |
90 | // Because of the subpixel antialising, we cannot use the color
91 | // directly. Instead, we have to select a more "pastel" color,
92 | // and differentiate properly between background and foreground
93 |
94 | FR = (fg >> 16) & 0xff;
95 | FG = (fg >> 8) & 0xff;
96 | FB = fg & 0xff;
97 |
98 | BR = (bg >> 16) & 0xff;
99 | BG = (bg >> 8) & 0xff;
100 | BB = bg & 0xff;
101 |
102 | if (28 * FR + 55 * FG + 17 * FB >= 28 * BR + 55 * BG + 17 * BB) {
103 | // bright on dark
104 | FR = (6 * FR + 10 * 0xff) / 16; // Brighten foreground
105 | FG = (6 * FG + 10 * 0xff) / 16;
106 | FB = (6 * FB + 10 * 0xff) / 16;
107 | BR = (10 * BR) / 16; // Darken background
108 | BG = (10 * BG) / 16;
109 | BB = (10 * BB) / 16;
110 | } else {
111 | // dark on bright
112 | FR = (10 * FR) / 16; // Darken foreground
113 | FG = (10 * FG) / 16;
114 | FB = (10 * FB) / 16;
115 | BR = (6 * BR + 10 * 0xff) / 16; // Brighten background
116 | BG = (6 * BG + 10 * 0xff) / 16;
117 | BB = (6 * BB + 10 * 0xff) / 16;
118 | }
119 | // Scale to range 0-256 for later ">>8" instead of "/255"
120 | FR += FR >> 7;
121 | FG += FG >> 7;
122 | FB += FB >> 7;
123 | BR += BR >> 7;
124 | BG += BG >> 7;
125 | BB += BB >> 7;
126 | }
127 | }
128 |
129 | // Colored characters are cached in colorBuf and rendered as needed
130 | private void renderColorChar(int offset) {
131 | for (int y = 0; y < fontHeight; y++)
132 | for (int x = 0; x < fontWidth; x++) {
133 | int col = bwBuf[offset + y * imageWidth + x];
134 | int R = (col >> 16) & 0xff;
135 | int G = (col >> 8) & 0xff;
136 | int B = col & 0xff;
137 |
138 | R = (FR * R + BR * (255 - R)) >> 8;
139 | G = (FG * G + BG * (255 - G)) >> 8;
140 | B = (FB * B + BB * (255 - B)) >> 8;
141 |
142 | colorBuf[offset + y * imageWidth + x] = (R << 16) + (G << 8)
143 | + B;
144 | }
145 | }
146 |
147 | // Draw one char
148 | public void drawChar(Graphics g, char c, int x, int y) {
149 | if (c <= ' ' || c > '~')
150 | return;
151 | c -= ' ';
152 | int offset = (c >> 5) * fontHeight * imageWidth + (c & 31) * fontWidth;
153 | if (currentBuf == colorBuf && cacheColor[c] != currentColor) {
154 | renderColorChar(offset);
155 | cacheColor[c] = currentColor;
156 | }
157 | g.drawRGB(currentBuf, offset, imageWidth, x, y, fontWidth, fontHeight,
158 | false);
159 | }
160 | //#endif
161 | }
--------------------------------------------------------------------------------
/src/tasks/FileLength.java:
--------------------------------------------------------------------------------
1 | import java.io.File;
2 |
3 | /*
4 | * Created on 15/04/2005
5 | *
6 | */
7 |
8 | /**
9 | * @author Karl
10 | *
11 | */
12 | public class FileLength {
13 | public static void main(String[] argv) {
14 | if (argv.length != 1) {
15 | System.err.println("Usage: filename");
16 | System.exit(1);
17 | }
18 |
19 | File file = new File(argv[0]);
20 | System.out.println(file.length());
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/tasks/RewriteBlackberryJAD.java:
--------------------------------------------------------------------------------
1 | import java.io.BufferedReader;
2 | import java.io.BufferedWriter;
3 | import java.io.DataInputStream;
4 | import java.io.File;
5 | import java.io.FileInputStream;
6 | import java.io.FileReader;
7 | import java.io.FileWriter;
8 | import java.io.IOException;
9 | import java.io.PrintWriter;
10 | import java.security.MessageDigest;
11 | import java.security.NoSuchAlgorithmException;
12 |
13 | /*
14 | * Created on 15/04/2005
15 | *
16 | */
17 |
18 | /**
19 | * @author Karl
20 | *
21 | */
22 | public class RewriteBlackberryJAD {
23 |
24 | public static void main(String[] args) throws IOException, NoSuchAlgorithmException {
25 | File jadIn = new File(args[0]);
26 | File jadOut = new File(args[1]);
27 | String sha1 = sha1(new File(args[2]));
28 | String sha2 = sha1(new File(args[3]));
29 | String cod1 = args[4];
30 | String cod2 = args[5];
31 | long length1 = Long.parseLong(args[6]);
32 | long length2 = Long.parseLong(args[7]);
33 |
34 | BufferedReader in = new BufferedReader(new FileReader(jadIn));
35 | PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(jadOut)));
36 |
37 | String line = in.readLine();
38 | while (line != null) {
39 | if (line.startsWith("RIM-COD-URL") || line.startsWith("RIM-COD-SHA1") || line.startsWith("RIM-COD-Size")) {
40 | /* Ignore these lines */
41 | }
42 | else {
43 | out.println(line);
44 | }
45 | line = in.readLine();
46 | }
47 |
48 | out.println("RIM-COD-URL-1: " + cod1);
49 | out.println("RIM-COD-URL-2: " + cod2);
50 | out.println("RIM-COD-Size-1: " + length1);
51 | out.println("RIM-COD-Size-2: " + length2);
52 | out.println("RIM-COD-SHA1-1: " + sha1);
53 | out.println("RIM-COD-SHA1-2: " + sha2);
54 |
55 | in.close();
56 | out.close();
57 | }
58 |
59 | private static String sha1(File file) throws IOException, NoSuchAlgorithmException {
60 | byte[] data = new byte[(int) file.length()];
61 | DataInputStream in = new DataInputStream(new FileInputStream(file));
62 | in.readFully(data);
63 |
64 | MessageDigest md = MessageDigest.getInstance("SHA-1");
65 | byte[] hash = md.digest(data);
66 |
67 | StringBuffer hashString = new StringBuffer();
68 | for (int i = 0; i < hash.length; i++) {
69 | String hex = Integer.toHexString((int) (hash[i] & 0xff));
70 | if (hex.length() < 2) {
71 | hashString.append('0');
72 | }
73 | hashString.append(hex);
74 | hashString.append(" ");
75 | }
76 |
77 | return hashString.toString().trim();
78 | }
79 | }
80 |
--------------------------------------------------------------------------------