aboutsummaryrefslogtreecommitdiff
path: root/src/protocoltelnet.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/protocoltelnet.h151
1 files changed, 135 insertions, 16 deletions
diff --git a/src/protocoltelnet.h b/src/protocoltelnet.h
index 3a606b5..f773f1e 100644
--- a/src/protocoltelnet.h
+++ b/src/protocoltelnet.h
@@ -3,35 +3,131 @@
3 3
4#include "bu/protocol.h" 4#include "bu/protocol.h"
5#include "bu/hash.h" 5#include "bu/hash.h"
6#include "bu/fstring.h"
7
8// #define __TELNET_DEBUG
6 9
7namespace Bu 10namespace Bu
8{ 11{
12 /**
13 * Telnet Protocol handler. This attempts to provide useful and general
14 * support for most of the most commonly used Telnet extensions in a simple
15 * and easy to use way. The Option variables control the settings that can
16 * be used on the line, and control which virtual "callbacks" will be called
17 * when different events happen.
18 *
19 * To setup initial values and to disable any options you wish override the
20 * onNewConnection function in your own class, like this:
21 *@code
22 class MyTelnet : public Bu::ProtocolTelnet
23 {
24 public:
25 ...
26
27 virtual void onNewConnection( class Bu::Client *pClient )
28 {
29 // Call the parent class' onNewConnection to get everything all
30 // set up.
31 Bu::ProtocolTelnet::onNewConnection( pClient );
32
33 // These functions disable the option to send files via telnet,
34 // disabling the remote option means that we won't accept this
35 // option (binary data being sent to us) from the client.
36 //
37 // Disabling the local option means that the client cannot ask us
38 // to send them binary data.
39 oBinary.enableRemote( false );
40 oBinary.enableLocal( false );
41
42 // This requests that the client send us window size updates
43 // whenever the size of their window changes, and an initial set to
44 // boot.
45 //
46 // To see if this option is set later, try oNAWS.isRemoteSet(), but
47 // wait a little while, asking immediatly will always return false,
48 // since the remote side has yet to receive our request.
49 oNAWS.remoteSet();
50 }
51 }
52 @endcode
53 *
54 */
9 class ProtocolTelnet : public Protocol 55 class ProtocolTelnet : public Protocol
10 { 56 {
11 public: 57 public:
12 ProtocolTelnet(); 58 ProtocolTelnet();
13 virtual ~ProtocolTelnet(); 59 virtual ~ProtocolTelnet();
14 60
61 /**
62 * If you override this function in a child class, make sure to call
63 * this version of it as the very first thing that you do, before you
64 * set any options. See the example in the class docs.
65 */
15 virtual void onNewConnection( class Bu::Client *pClient ); 66 virtual void onNewConnection( class Bu::Client *pClient );
67
68 /**
69 * You should never override this function unless you really, really
70 * know what you're doing. If you want to get data after each line
71 * entered (in canonical mode) or after any data arrives (non canonical
72 * mode) then override the gotLine and gotData functions, respectively.
73 */
16 virtual void onNewData( class Bu::Client *pClient ); 74 virtual void onNewData( class Bu::Client *pClient );
17 75
18 enum OptMode 76 /**
19 { 77 * Override this function to be notified of lines being submitted by
20 optOff, 78 * the client. This function is only called in canonical mode, after
21 optOn, 79 * all edits are performed on the data. In this mode weather you use
22 optDesire, 80 * the line or not, the data will be cleared from the buffer when this
23 optRefuse 81 * function returns, any changes made to the buffer will be destroyed.
24 }; 82 */
83 virtual void gotLine( Bu::FString &sLine ){};
25 84
26 OptMode getLocalOptBinary(); 85 /**
27 void setLocalOptBinary( OptMode eMode ); 86 * Override this function to be notified of any new data that comes in
28 OptMode getRemoteOptBinary(); 87 * from the client. This function is only called in non-canonical mode,
29 void setRemoteOptBinary( OptMode eMode ); 88 * and includes all raw data minus telnet control codes and ansi
89 * escape sequences. In this mode control of the buffer is up to the
90 * child class in this function, the buffer will never be cleared unless
91 * it happens in this function's override.
92 */
93 virtual void gotData( Bu::FString &sData ){};
30 94
31 OptMode getLocalOptEcho(); 95 /**
32 void setLocalOptEcho( OptMode eMode ); 96 * Using this function to enable or disable canonical mode only affects
33 OptMode getRemoteOptEcho(); 97 * the way the data is processed and which virtual functions are called
34 void setRemoteOptEcho( OptMode eMode ); 98 * during processing. It does not affect options set locally or
99 * remotely. Setting this to false will enable char-at-a-time mode,
100 * effectively disabling internal line-editing code. Characters
101 * such as backspace that are detected will not be handled and will be
102 * sent to the user override. The subclass will also be notified every
103 * time new data is available, not just whole lines.
104 *
105 * When set to true (the default), line editing control codes will be
106 * interpreted and used, and the subclass will only be notified when
107 * complete lines are available in the buffer.
108 */
109 void setCanonical( bool bCon=true );
110 bool isCanonical();
111
112 void write( const Bu::FString &sData );
113 void write( char *pData, int iSize );
114 void write( char cData );
115
116 public:
117 /**
118 * If you wish to know the current dimensions of the client window,
119 * override this function, it will be called whenever the size changes.
120 */
121 virtual void onSubNAWS( uint16_t iWidth, uint16_t iHeight ){};
122
123 /**
124 * This function is called whenever an unknown sub negotiation option is
125 * sent over the line. This doesn't mean that it's malformatted, it
126 * just means that this class doesn't support that option yet, but you
127 * can handle it yourself if you'd like. Feel free to change the
128 * sSubBuf, it will be cleared as soon as this function returns anyway.
129 */
130 virtual void onSubUnknown( char cSubOpt, Bu::FString &sSubBuf ){};
35 131
36 private: 132 private:
37 /** 133 /**
@@ -75,15 +171,38 @@ namespace Bu
75 char fOpts; 171 char fOpts;
76 char cCode; 172 char cCode;
77 }; 173 };
174 friend class Bu::ProtocolTelnet::Option;
78 175
79 Hash<char, Option *> hOpts; 176 Hash<char, Option *> hOpts;
80 177
178 public:
81 Option oBinary; 179 Option oBinary;
82 Option oEcho; 180 Option oEcho;
181 Option oNAWS;
182 Option oSuppressGA;
83 183
184 private:
185 void onWill( char cCode );
186 void onWont( char cCode );
187 void onDo( char cCode );
188 void onDont( char cCode );
189 void onSubOpt();
190 void onCtlChar( char cChr );
191
192#ifdef __TELNET_DEBUG
193 void printCode( char cCode );
194 void printOpt( char cOpt );
195#endif
196
197 private:
84 Client *pClient; 198 Client *pClient;
85 199
86 friend class Bu::ProtocolTelnet::Option; 200 Bu::FString sDataBuf; /**< Buffer for regular line data. */
201 Bu::FString sSubBuf; /**< Buffer for subnegotiation data. */
202 char cSubOpt; /**< Which suboption are we processing. */
203
204 bool bCanonical; /**< Are we canonicalizing incoming data? */
205 bool bSubOpt; /**< Are we processing a suboption right now? */
87 }; 206 };
88} 207}
89 208