aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2007-10-14 03:36:34 +0000
committerMike Buland <eichlan@xagasoft.com>2007-10-14 03:36:34 +0000
commitfdc3169942c1a9523eb0fca3e2742d14612ca57c (patch)
tree71f4cc059dd08f37be51fd47ad9a1e447a566bb0
parent5a0cd0696dc635551b797445bcc625e8e3b80802 (diff)
downloadlibbu++-fdc3169942c1a9523eb0fca3e2742d14612ca57c.tar.gz
libbu++-fdc3169942c1a9523eb0fca3e2742d14612ca57c.tar.bz2
libbu++-fdc3169942c1a9523eb0fca3e2742d14612ca57c.tar.xz
libbu++-fdc3169942c1a9523eb0fca3e2742d14612ca57c.zip
Beginings of a Telnet Protocol handler, I finally solved the general Option
negotiation issues that plagued the earlier version, now I just have to actually process data.
-rw-r--r--src/protocoltelnet.cpp131
-rw-r--r--src/protocoltelnet.h90
2 files changed, 221 insertions, 0 deletions
diff --git a/src/protocoltelnet.cpp b/src/protocoltelnet.cpp
new file mode 100644
index 0000000..b0209db
--- /dev/null
+++ b/src/protocoltelnet.cpp
@@ -0,0 +1,131 @@
1#include "bu/protocoltelnet.h"
2#include "bu/client.h"
3
4#define CODE_SE '\xf0' /**< End of subnegotiation params. */
5#define CODE_NOP '\xf1' /**< No operation (keep-alive). */
6#define CODE_DM '\xf2' /**< Datastream side of a Synch. */
7#define CODE_BRK '\xf3' /**< Break character. */
8#define CODE_IP '\xf4' /**< Interrupt Process character. */
9#define CODE_AO '\xf5' /**< Abort Output character. */
10#define CODE_AYT '\xf6' /**< Are You There? character. */
11#define CODE_EC '\xf7' /**< Erase Character character. */
12#define CODE_EL '\xf8' /**< Erase Line character. */
13#define CODE_GA '\xf9' /**< Go Ahead signal. */
14#define CODE_SB '\xfa' /**< Begin subnegotiation options. */
15#define CODE_WILL '\xfb' /**< Desire to do something. */
16#define CODE_WONT '\xfc' /**< Refuse to perform. */
17#define CODE_DO '\xfd' /**< Request option. */
18#define CODE_DONT '\xfe' /**< Demand a stop. */
19
20#define CODE_IAC '\xff' /**< Interpret-As-Command. */
21
22#define OPT_BINARY '\x00' /**< Binary mode (file transfers?). */
23#define OPT_ECHO '\x01' /**< (local) Echo mode. */
24
25Bu::ProtocolTelnet::ProtocolTelnet() :
26 oBinary( *this, OPT_BINARY ),
27 oEcho( *this, OPT_ECHO )
28{
29}
30
31Bu::ProtocolTelnet::~ProtocolTelnet()
32{
33}
34
35void Bu::ProtocolTelnet::onNewConnection( Bu::Client *pClient )
36{
37}
38
39void Bu::ProtocolTelnet::onNewData( Bu::Client *pClient )
40{
41}
42
43
44
45Bu::ProtocolTelnet::Option::Option( Bu::ProtocolTelnet &rPT, char cCode ) :
46 rPT( rPT ),
47 fOpts( 0 ),
48 cCode( cCode )
49{
50 rPT.hOpts.insert( cCode, this );
51}
52
53Bu::ProtocolTelnet::Option::~Option()
54{
55}
56
57void Bu::ProtocolTelnet::Option::localEnable( bool bSet )
58{
59 if( bSet == (bool)(!(fOpts&fLocalCant)) ) return;
60
61 if( bSet )
62 fOpts &= ~fLocalCant;
63 else
64 fOpts |= fLocalCant;
65}
66
67void Bu::ProtocolTelnet::Option::localSet( bool bSet )
68{
69 if( bSet == (bool)(fOpts&fLocalIs) ) return;
70
71 char buf[2];
72
73 if( bSet )
74 {
75 buf[0] = CODE_WILL;
76 buf[1] = cCode;
77 rPT.pClient->write( buf, 2 );
78 }
79 else
80 {
81 buf[0] = CODE_WONT;
82 buf[1] = cCode;
83 rPT.pClient->write( buf, 2 );
84 }
85}
86
87bool Bu::ProtocolTelnet::Option::isLocalEnabled()
88{
89 return (bool)(!(fOpts&fLocalCant));
90}
91
92bool Bu::ProtocolTelnet::Option::isLocalSet()
93{
94 return (bool)(fOpts&fLocalIs);
95}
96
97void Bu::ProtocolTelnet::Option::remoteEnable( bool bSet )
98{
99 return;
100}
101
102void Bu::ProtocolTelnet::Option::remoteSet( bool bSet )
103{
104 if( bSet == (bool)(fOpts&fRemoteIs) ) return;
105
106 char buf[2];
107
108 if( bSet )
109 {
110 buf[0] = CODE_DO;
111 buf[1] = cCode;
112 rPT.pClient->write( buf, 2 );
113 }
114 else
115 {
116 buf[0] = CODE_DONT;
117 buf[1] = cCode;
118 rPT.pClient->write( buf, 2 );
119 }
120}
121
122bool Bu::ProtocolTelnet::Option::isRemoteEnabled()
123{
124 return (bool)(!(fOpts&fRemoteCant));
125}
126
127bool Bu::ProtocolTelnet::Option::isRemoteSet()
128{
129 return (bool)(fOpts&fRemoteIs);
130}
131
diff --git a/src/protocoltelnet.h b/src/protocoltelnet.h
new file mode 100644
index 0000000..3a606b5
--- /dev/null
+++ b/src/protocoltelnet.h
@@ -0,0 +1,90 @@
1#ifndef BU_PROTOCOL_TELNET_H
2#define BU_PROTOCOL_TELNET_H
3
4#include "bu/protocol.h"
5#include "bu/hash.h"
6
7namespace Bu
8{
9 class ProtocolTelnet : public Protocol
10 {
11 public:
12 ProtocolTelnet();
13 virtual ~ProtocolTelnet();
14
15 virtual void onNewConnection( class Bu::Client *pClient );
16 virtual void onNewData( class Bu::Client *pClient );
17
18 enum OptMode
19 {
20 optOff,
21 optOn,
22 optDesire,
23 optRefuse
24 };
25
26 OptMode getLocalOptBinary();
27 void setLocalOptBinary( OptMode eMode );
28 OptMode getRemoteOptBinary();
29 void setRemoteOptBinary( OptMode eMode );
30
31 OptMode getLocalOptEcho();
32 void setLocalOptEcho( OptMode eMode );
33 OptMode getRemoteOptEcho();
34 void setRemoteOptEcho( OptMode eMode );
35
36 private:
37 /**
38 * Represents a basic telnet option, either on or off, no parameters.
39 * Each Option can negotiate effectively on it's own, and has two
40 * parameters in each of two classes. Both local and remote can be
41 * enabled/disabled and set/unset. Enabled represents the ability to
42 * set the option, disabling an option should also unset it. Set or
43 * unset represent wether the option is being used, if it is allowed.
44 */
45 class Option
46 {
47 friend class Bu::ProtocolTelnet;
48 private:
49 Option( ProtocolTelnet &rPT, char cCode );
50 virtual ~Option();
51
52 public:
53 void localEnable( bool bSet=true );
54 void localSet( bool bSet=true );
55
56 bool isLocalEnabled();
57 bool isLocalSet();
58
59 void remoteEnable( bool bSet=true );
60 void remoteSet( bool bSet=true );
61
62 bool isRemoteEnabled();
63 bool isRemoteSet();
64
65 private:
66 enum
67 {
68 fLocalCant = 0x01, /**< Local can't/won't allow option. */
69 fLocalIs = 0x02, /**< Local is using option. */
70 fRemoteCant = 0x04, /**< Remote can't/won't allow option. */
71 fRemoteIs = 0x08 /**< Remote is using option. */
72 };
73
74 ProtocolTelnet &rPT;
75 char fOpts;
76 char cCode;
77 };
78
79 Hash<char, Option *> hOpts;
80
81 Option oBinary;
82 Option oEcho;
83
84 Client *pClient;
85
86 friend class Bu::ProtocolTelnet::Option;
87 };
88}
89
90#endif