Welcome to mirror list, hosted at ThFree Co, Russian Federation.

ShellConnection.cs « Clovershell - github.com/ClusterM/hakchi2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: ff97a5ec47edc702dc5b46df2928fe3367b9f73f (plain)
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);
        }
    }

}