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
109
110
111
112
113
114
115
116
|
using System;
using System.Diagnostics;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace com.clusterrr.clovershell
{
internal class ShellConnection : IDisposable
{
public readonly ClovershellConnection connection;
internal Socket socket;
internal int id;
internal Thread shellConnectionThread;
public ShellConnection(ClovershellConnection connection, Socket socket)
{
this.connection = connection;
this.socket = socket;
id = -1;
socket.Send(new byte[] { 0xFF, 0xFD, 0x03 }); // Do Suppress Go Ahead
socket.Send(new byte[] { 0xFF, 0xFB, 0x03 }); // Will Suppress Go Ahead
socket.Send(new byte[] { 0xFF, 0xFB, 0x01 }); // Will Echo
}
internal void shellConnectionLoop()
{
try
{
var buff = new byte[1024];
while (socket.Connected)
{
var l = socket.Receive(buff);
if (l > 0)
{
int start = 0;
int pos = 0;
do
{
if ((pos + 1 < l) && (buff[pos] == '\r') && (buff[pos + 1] == '\n')) // New line?
{
// Hey, dot not send \r\n! I'll cut it to \n
buff[pos] = (byte)'\n';
connection.writeUsb(ClovershellConnection.ClovershellCommand.CMD_SHELL_IN, (byte)id, buff, start, pos - start + 1);
pos += 2;
start = pos;
}
else if ((pos + 1 < l) && (buff[pos] == 0xFF)) // Telnet command?
{
if (buff[pos + 1] == 0xFF) // Or just 0xFF...
{
connection.writeUsb(ClovershellConnection.ClovershellCommand.CMD_SHELL_IN, (byte)id, buff, start, pos - start + 1);
pos += 2;
start = pos;
}
else if (pos + 2 < l)
{
if (pos - start > 0)
connection.writeUsb(ClovershellConnection.ClovershellCommand.CMD_SHELL_IN, (byte)id, buff, start, pos - start);
var cmd = buff[pos + 1]; // Telnet command code
var opt = buff[pos + 2]; // Telnet option code
#if VERY_DEBUG
Debug.WriteLine(string.Format("Telnet command: CMD={0:X2} ARG={1:X2}", cmd, opt));
#endif
pos += 3;
start = pos;
}
}
else pos++; // No, moving to next character
if ((pos == l) && (l - start > 0)) // End of packet
{
connection.writeUsb(ClovershellConnection.ClovershellCommand.CMD_SHELL_IN, (byte)id, buff, start, l - start);
}
} while (pos < l);
}
else
break;
}
}
catch (ThreadAbortException)
{
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message + ex.StackTrace);
if (socket.Connected)
socket.Send(Encoding.ASCII.GetBytes("Error: " + ex.Message));
}
finally
{
shellConnectionThread = null;
Debug.WriteLine(string.Format("Shell client {0} disconnected", id));
if (socket != null)
socket.Close();
connection.shellConnections[id] = null;
}
}
public void Dispose()
{
if (shellConnectionThread != null)
shellConnectionThread.Abort();
if (socket != null)
socket.Close();
socket = null;
if (id > 0)
connection.shellConnections[id] = null;
}
internal void Send(byte[] data, int pos, int len)
{
socket.Send(data, pos, len, SocketFlags.None);
}
}
}
|