diff options
Diffstat (limited to 'src/protocoltelnet.cpp')
-rw-r--r-- | src/protocoltelnet.cpp | 620 |
1 files changed, 0 insertions, 620 deletions
diff --git a/src/protocoltelnet.cpp b/src/protocoltelnet.cpp deleted file mode 100644 index 7e37cca..0000000 --- a/src/protocoltelnet.cpp +++ /dev/null | |||
@@ -1,620 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2011 Xagasoft, All rights reserved. | ||
3 | * | ||
4 | * This file is part of the libbu++ library and is released under the | ||
5 | * terms of the license contained in the file LICENSE. | ||
6 | */ | ||
7 | |||
8 | #include "bu/protocoltelnet.h" | ||
9 | #include "bu/client.h" | ||
10 | |||
11 | /* We apparently at least want defs for the lower 13, not sure we care about | ||
12 | * the rest of the chars, maybe escape. | ||
13 | */ | ||
14 | #define CH_NUL '\x00' /* NUL */ | ||
15 | #define CH_SOH '\x01' /* Start Of Heading */ | ||
16 | #define CH_STX '\x02' /* Start of Text */ | ||
17 | #define CH_ETX '\x03' /* End of Text */ | ||
18 | #define CH_EOT '\x04' /* End of transmission */ | ||
19 | #define CH_ENQ '\x05' /* Enquiery */ | ||
20 | #define CH_ACK '\x06' /* Acknowledge */ | ||
21 | #define CH_BEL '\x07' /* Bell */ | ||
22 | #define CH_BS '\x08' /* Backspace */ | ||
23 | #define CH_TAB '\x09' /* Horizontal Tab */ | ||
24 | #define CH_LF '\x0A' /* NL Line feed, new line */ | ||
25 | #define CH_VT '\x0B' /* Vertical Tab */ | ||
26 | #define CH_FF '\x0C' /* Form feed, new page */ | ||
27 | #define CH_CR '\x0D' /* Carriage return */ | ||
28 | #define CH_ESC '\x1B' /* Escape */ | ||
29 | #define CH_DEL '\x7F' /* Delete */ | ||
30 | |||
31 | #define CODE_SE '\xf0' /* End of subnegotiation params. */ | ||
32 | #define CODE_NOP '\xf1' /* No operation (keep-alive). */ | ||
33 | #define CODE_DM '\xf2' /* Datastream side of a Synch. */ | ||
34 | #define CODE_BRK '\xf3' /* Break character. */ | ||
35 | #define CODE_IP '\xf4' /* Interrupt Process character. */ | ||
36 | #define CODE_AO '\xf5' /* Abort Output character. */ | ||
37 | #define CODE_AYT '\xf6' /* Are You There? character. */ | ||
38 | #define CODE_EC '\xf7' /* Erase Character character. */ | ||
39 | #define CODE_EL '\xf8' /* Erase Line character. */ | ||
40 | #define CODE_GA '\xf9' /* Go Ahead signal. */ | ||
41 | #define CODE_SB '\xfa' /* Begin subnegotiation options. */ | ||
42 | #define CODE_WILL '\xfb' /* Desire to do something. */ | ||
43 | #define CODE_WONT '\xfc' /* Refuse to perform. */ | ||
44 | #define CODE_DO '\xfd' /* Request option. */ | ||
45 | #define CODE_DONT '\xfe' /* Demand a stop. */ | ||
46 | |||
47 | #define CODE_IAC '\xff' /* Interpret-As-Command. */ | ||
48 | |||
49 | #define OPT_BINARY '\x00' /* Binary mode (file transfers?). */ | ||
50 | #define OPT_ECHO '\x01' /* (local) Echo mode. */ | ||
51 | #define OPT_SUPGA '\x03' /* Suppress Go Ahead signals. */ | ||
52 | #define OPT_STATUS '\x05' /* Allow status messages. */ | ||
53 | #define OPT_TIMING '\x06' /* Place a timing mark in the code. */ | ||
54 | #define OPT_EXASCII '\x11' /* Extended ASCII. */ | ||
55 | #define OPT_LOGOUT '\x12' /* Logout. */ | ||
56 | #define OPT_TTYPE '\x18' /* Terminal Type. */ | ||
57 | #define OPT_NAWS '\x1f' /* Negotiate about window size. */ | ||
58 | #define OPT_TSPEED '\x20' /* Terminal Speed. */ | ||
59 | #define OPT_NEWENV '\x27' /* New Environment Option. */ | ||
60 | #define OPT_EXOPL '\xff' /* Can we, will we, handle extended options. */ | ||
61 | |||
62 | #ifndef __TELNET_DEBUG | ||
63 | # define printCode( a ) (void)0 | ||
64 | # define printOpt( a ) (void)0 | ||
65 | #endif | ||
66 | |||
67 | Bu::ProtocolTelnet::ProtocolTelnet() : | ||
68 | oBinary( *this, OPT_BINARY ), | ||
69 | oEcho( *this, OPT_ECHO ), | ||
70 | oNAWS( *this, OPT_NAWS ), | ||
71 | oSuppressGA(*this, OPT_SUPGA ), | ||
72 | bCanonical( true ), | ||
73 | bSubOpt( false ) | ||
74 | { | ||
75 | } | ||
76 | |||
77 | Bu::ProtocolTelnet::~ProtocolTelnet() | ||
78 | { | ||
79 | } | ||
80 | |||
81 | void Bu::ProtocolTelnet::onNewConnection( Bu::Client *pClient ) | ||
82 | { | ||
83 | this->pClient = pClient; | ||
84 | } | ||
85 | |||
86 | void Bu::ProtocolTelnet::onNewData( Bu::Client *pClient ) | ||
87 | { | ||
88 | char bc; | ||
89 | int iLeft; | ||
90 | while( (iLeft = pClient->getInputSize()) ) | ||
91 | { | ||
92 | if( bSubOpt ) | ||
93 | { | ||
94 | pClient->peek( &bc, 1 ); | ||
95 | if( bc == CODE_IAC ) | ||
96 | { | ||
97 | if( iLeft <= 1 ) return; | ||
98 | char bc2; | ||
99 | printCode( CODE_IAC ); | ||
100 | pClient->peek( &bc2, 1, 1 ); | ||
101 | printCode( bc2 ); | ||
102 | if( bc2 == CODE_SE ) | ||
103 | { | ||
104 | bSubOpt = false; | ||
105 | onSubOpt(); | ||
106 | } | ||
107 | else if( bc2 == CODE_IAC ) | ||
108 | { | ||
109 | sSubBuf += CODE_IAC; | ||
110 | } | ||
111 | else | ||
112 | { | ||
113 | // Error of some sort. | ||
114 | } | ||
115 | pClient->seek( 1 ); | ||
116 | } | ||
117 | else | ||
118 | { | ||
119 | sSubBuf += bc; | ||
120 | } | ||
121 | pClient->seek( 1 ); | ||
122 | } | ||
123 | else | ||
124 | { | ||
125 | pClient->peek( &bc, 1 ); | ||
126 | if( bc == CODE_IAC ) | ||
127 | { | ||
128 | if( iLeft <= 1 ) return; | ||
129 | char bc2; | ||
130 | pClient->peek( &bc2, 1, 1 ); | ||
131 | printCode( bc ); | ||
132 | printCode( bc2 ); | ||
133 | |||
134 | switch( bc2 ) | ||
135 | { | ||
136 | case CODE_WILL: | ||
137 | if( iLeft <= 2 ) return; | ||
138 | { | ||
139 | char bc3; | ||
140 | pClient->peek( &bc3, 1, 2 ); | ||
141 | pClient->seek( 1 ); | ||
142 | printOpt( bc3 ); | ||
143 | onWill( bc3 ); | ||
144 | } | ||
145 | break; | ||
146 | |||
147 | case CODE_WONT: | ||
148 | if( iLeft <= 2 ) return; | ||
149 | { | ||
150 | char bc3; | ||
151 | pClient->peek( &bc3, 1, 2 ); | ||
152 | pClient->seek( 1 ); | ||
153 | printOpt( bc3 ); | ||
154 | onWont( bc3 ); | ||
155 | } | ||
156 | break; | ||
157 | |||
158 | case CODE_DO: | ||
159 | if( iLeft <= 2 ) return; | ||
160 | { | ||
161 | char bc3; | ||
162 | pClient->peek( &bc3, 1, 2 ); | ||
163 | pClient->seek( 1 ); | ||
164 | printOpt( bc3 ); | ||
165 | onDo( bc3 ); | ||
166 | } | ||
167 | break; | ||
168 | |||
169 | case CODE_DONT: | ||
170 | if( iLeft <= 2 ) return; | ||
171 | { | ||
172 | char bc3; | ||
173 | pClient->peek( &bc3, 1, 2 ); | ||
174 | pClient->seek( 1 ); | ||
175 | printOpt( bc3 ); | ||
176 | onDont( bc3 ); | ||
177 | } | ||
178 | break; | ||
179 | |||
180 | case CODE_SB: | ||
181 | if( iLeft <= 2 ) return; | ||
182 | { | ||
183 | pClient->peek( &cSubOpt, 1, 2 ); | ||
184 | pClient->seek( 1 ); | ||
185 | printOpt( cSubOpt ); | ||
186 | bSubOpt = true; | ||
187 | } | ||
188 | break; | ||
189 | |||
190 | case CODE_IAC: | ||
191 | sDataBuf += CODE_IAC; | ||
192 | printCode( CODE_IAC ); | ||
193 | break; | ||
194 | } | ||
195 | pClient->seek( 1 ); | ||
196 | #ifdef __TELNET_DEBUG | ||
197 | printf("\n"); | ||
198 | #endif | ||
199 | } | ||
200 | else if( bc == CODE_SB ) | ||
201 | { | ||
202 | } | ||
203 | else | ||
204 | { | ||
205 | // This is where control code handling goes | ||
206 | // Also, possibly, character code conversion, although I'm not | ||
207 | // sure that really matters anymore, go ASCII/UTF-8 | ||
208 | if( bCanonical ) | ||
209 | { | ||
210 | if( bc < 0x20 || bc >= CH_DEL ) | ||
211 | { | ||
212 | if( bc == CH_CR ) | ||
213 | { | ||
214 | if( iLeft <= 1 ) return; | ||
215 | char bc2; | ||
216 | pClient->peek( &bc2, 1, 1 ); | ||
217 | if( bc2 == CH_NUL || bc2 == CH_LF ) | ||
218 | { | ||
219 | onCtlChar( bc ); | ||
220 | gotLine( sDataBuf ); | ||
221 | sDataBuf.clear(); | ||
222 | } | ||
223 | pClient->seek( 1 ); | ||
224 | } | ||
225 | else | ||
226 | { | ||
227 | onCtlChar( bc ); | ||
228 | } | ||
229 | } | ||
230 | else | ||
231 | { | ||
232 | sDataBuf += bc; | ||
233 | if( oEcho.isLocalSet() ) | ||
234 | { | ||
235 | pClient->write( &bc, 1 ); | ||
236 | #ifdef __TELNET_DEBUG | ||
237 | printf("%c", bc ); | ||
238 | fflush( stdout ); | ||
239 | #endif | ||
240 | } | ||
241 | } | ||
242 | } | ||
243 | else | ||
244 | { | ||
245 | sDataBuf += bc; | ||
246 | if( oEcho.isLocalSet() ) | ||
247 | { | ||
248 | pClient->write( &bc, 1 ); | ||
249 | } | ||
250 | } | ||
251 | } | ||
252 | pClient->seek( 1 ); | ||
253 | } | ||
254 | } | ||
255 | |||
256 | // It's true, this code will not be executed if we only have half of an | ||
257 | // IAC code or multibyte escape sequence or something, but then again, it | ||
258 | // shouldn't be called then, and really, shouldn't be, it'll be called soon | ||
259 | // enough, when we get the rest of that code. | ||
260 | if( !bCanonical ) | ||
261 | { | ||
262 | gotData( sDataBuf ); | ||
263 | } | ||
264 | } | ||
265 | |||
266 | void Bu::ProtocolTelnet::setCanonical( bool bCon ) | ||
267 | { | ||
268 | bCanonical = bCon; | ||
269 | } | ||
270 | |||
271 | bool Bu::ProtocolTelnet::isCanonical() | ||
272 | { | ||
273 | return bCanonical; | ||
274 | } | ||
275 | |||
276 | void Bu::ProtocolTelnet::write( const Bu::String &sData ) | ||
277 | { | ||
278 | write( sData.getStr(), sData.getSize() ); | ||
279 | } | ||
280 | |||
281 | void Bu::ProtocolTelnet::write( const char *pData, int iSize ) | ||
282 | { | ||
283 | int iLast = 0, j; | ||
284 | for( j = iLast; j < iSize; j++ ) | ||
285 | { | ||
286 | if( pData[j] == '\n' ) | ||
287 | { | ||
288 | if( j+1 >= iSize || | ||
289 | (pData[j+1] != '\r' && pData[j+1] != '\0') ) | ||
290 | { | ||
291 | pClient->write( pData+iLast, j-iLast ); | ||
292 | pClient->write( "\n\r", 2 ); | ||
293 | iLast = j+1; | ||
294 | } | ||
295 | else | ||
296 | { | ||
297 | j++; | ||
298 | } | ||
299 | } | ||
300 | } | ||
301 | if( j > iLast ) | ||
302 | { | ||
303 | pClient->write( pData+iLast, iSize-iLast ); | ||
304 | } | ||
305 | //pClient->write( pData, iSize ); | ||
306 | } | ||
307 | |||
308 | void Bu::ProtocolTelnet::write( char cData ) | ||
309 | { | ||
310 | write( &cData, 1 ); | ||
311 | } | ||
312 | |||
313 | void Bu::ProtocolTelnet::onWill( char cCode ) | ||
314 | { | ||
315 | try | ||
316 | { | ||
317 | Option *pOpt = hOpts[cCode]; | ||
318 | if( pOpt->isRemoteEnabled() ) | ||
319 | { | ||
320 | pOpt->fOpts |= Option::fRemoteIs; | ||
321 | char buf[3] = { CODE_IAC, CODE_DO, cCode }; | ||
322 | pClient->write( buf, 3 ); | ||
323 | } | ||
324 | else | ||
325 | { | ||
326 | char buf[3] = { CODE_IAC, CODE_DONT, cCode }; | ||
327 | pClient->write( buf, 3 ); | ||
328 | } | ||
329 | |||
330 | } | ||
331 | catch( Bu::HashException &e ) | ||
332 | { | ||
333 | char buf[3] = { CODE_IAC, CODE_DONT, cCode }; | ||
334 | pClient->write( buf, 3 ); | ||
335 | } | ||
336 | } | ||
337 | |||
338 | void Bu::ProtocolTelnet::onWont( char cCode ) | ||
339 | { | ||
340 | try | ||
341 | { | ||
342 | Option *pOpt = hOpts[cCode]; | ||
343 | |||
344 | pOpt->fOpts &= ~Option::fRemoteIs; | ||
345 | char buf[3] = { CODE_IAC, CODE_DONT, cCode }; | ||
346 | pClient->write( buf, 3 ); | ||
347 | } | ||
348 | catch( Bu::HashException &e ) | ||
349 | { | ||
350 | char buf[3] = { CODE_IAC, CODE_DONT, cCode }; | ||
351 | pClient->write( buf, 3 ); | ||
352 | } | ||
353 | } | ||
354 | |||
355 | void Bu::ProtocolTelnet::onDo( char cCode ) | ||
356 | { | ||
357 | try | ||
358 | { | ||
359 | Option *pOpt = hOpts[cCode]; | ||
360 | if( pOpt->isLocalEnabled() ) | ||
361 | { | ||
362 | pOpt->fOpts |= Option::fLocalIs; | ||
363 | char buf[3] = { CODE_IAC, CODE_WILL, cCode }; | ||
364 | pClient->write( buf, 3 ); | ||
365 | } | ||
366 | else | ||
367 | { | ||
368 | char buf[3] = { CODE_IAC, CODE_WONT, cCode }; | ||
369 | pClient->write( buf, 3 ); | ||
370 | } | ||
371 | |||
372 | } | ||
373 | catch( Bu::HashException &e ) | ||
374 | { | ||
375 | char buf[3] = { CODE_IAC, CODE_WONT, cCode }; | ||
376 | pClient->write( buf, 3 ); | ||
377 | } | ||
378 | } | ||
379 | |||
380 | void Bu::ProtocolTelnet::onDont( char cCode ) | ||
381 | { | ||
382 | try | ||
383 | { | ||
384 | Option *pOpt = hOpts[cCode]; | ||
385 | |||
386 | pOpt->fOpts &= ~Option::fLocalIs; | ||
387 | char buf[3] = { CODE_IAC, CODE_DONT, cCode }; | ||
388 | pClient->write( buf, 3 ); | ||
389 | } | ||
390 | catch( Bu::HashException &e ) | ||
391 | { | ||
392 | char buf[3] = { CODE_IAC, CODE_DONT, cCode }; | ||
393 | pClient->write( buf, 3 ); | ||
394 | } | ||
395 | } | ||
396 | |||
397 | void Bu::ProtocolTelnet::onSubOpt() | ||
398 | { | ||
399 | switch( cSubOpt ) | ||
400 | { | ||
401 | case OPT_NAWS: | ||
402 | { | ||
403 | uint16_t iWidth, iHeight; | ||
404 | ((char *)&iWidth)[1] = sSubBuf[0]; | ||
405 | ((char *)&iWidth)[0] = sSubBuf[1]; | ||
406 | ((char *)&iHeight)[1] = sSubBuf[2]; | ||
407 | ((char *)&iHeight)[0] = sSubBuf[3]; | ||
408 | onSubNAWS( iWidth, iHeight ); | ||
409 | } | ||
410 | break; | ||
411 | |||
412 | default: | ||
413 | onSubUnknown( cSubOpt, sSubBuf ); | ||
414 | break; | ||
415 | } | ||
416 | |||
417 | sSubBuf.clear(); | ||
418 | } | ||
419 | |||
420 | void Bu::ProtocolTelnet::onCtlChar( char cChr ) | ||
421 | { | ||
422 | #ifdef __TELNET_DEBUG | ||
423 | switch( cChr ) | ||
424 | { | ||
425 | case CH_NUL: printf("NUL "); break; | ||
426 | case CH_SOH: printf("SOH "); break; | ||
427 | case CH_STX: printf("STX "); break; | ||
428 | case CH_ETX: printf("ETX "); break; | ||
429 | case CH_EOT: printf("EOT "); break; | ||
430 | case CH_ENQ: printf("ENQ "); break; | ||
431 | case CH_ACK: printf("ACK "); break; | ||
432 | case CH_BEL: printf("BEL "); break; | ||
433 | case CH_BS: printf("BS "); break; | ||
434 | case CH_TAB: printf("TAB "); break; | ||
435 | case CH_LF: printf("LF "); break; | ||
436 | case CH_VT: printf("VT "); break; | ||
437 | case CH_FF: printf("FF "); break; | ||
438 | case CH_CR: printf("CR "); break; | ||
439 | case CH_ESC: printf("ESC "); break; | ||
440 | case CH_DEL: printf("DEL "); break; | ||
441 | default: printf("!![%02x] ", cChr ); break; | ||
442 | } | ||
443 | fflush( stdout ); | ||
444 | #endif | ||
445 | |||
446 | switch( cChr ) | ||
447 | { | ||
448 | case CH_DEL: | ||
449 | { | ||
450 | if( sDataBuf.getSize() > 0 ) | ||
451 | { | ||
452 | sDataBuf.resize( sDataBuf.getSize()-1 ); | ||
453 | char buf[3] = { CH_BS, ' ', CH_BS }; | ||
454 | pClient->write( buf, 3 ); | ||
455 | } | ||
456 | } | ||
457 | break; | ||
458 | |||
459 | } | ||
460 | } | ||
461 | |||
462 | #ifdef __TELNET_DEBUG | ||
463 | void Bu::ProtocolTelnet::printCode( char cCode ) | ||
464 | { | ||
465 | switch( cCode ) | ||
466 | { | ||
467 | case CODE_SE: printf("SE "); break; | ||
468 | case CODE_NOP: printf("NOP "); break; | ||
469 | case CODE_DM: printf("DM "); break; | ||
470 | case CODE_BRK: printf("BRK "); break; | ||
471 | case CODE_IP: printf("IP "); break; | ||
472 | case CODE_AO: printf("AO "); break; | ||
473 | case CODE_AYT: printf("AYT "); break; | ||
474 | case CODE_EC: printf("EC "); break; | ||
475 | case CODE_EL: printf("EL "); break; | ||
476 | case CODE_GA: printf("GA "); break; | ||
477 | case CODE_SB: printf("SB "); break; | ||
478 | case CODE_WILL: printf("WILL "); break; | ||
479 | case CODE_WONT: printf("WONT "); break; | ||
480 | case CODE_DO: printf("DO "); break; | ||
481 | case CODE_DONT: printf("DONT "); break; | ||
482 | case CODE_IAC: printf("IAC "); break; | ||
483 | default: printf("??%02x ", cCode ); break; | ||
484 | } | ||
485 | fflush( stdout ); | ||
486 | } | ||
487 | |||
488 | void Bu::ProtocolTelnet::printOpt( char cOpt ) | ||
489 | { | ||
490 | switch( cOpt ) | ||
491 | { | ||
492 | case OPT_BINARY: printf("BINARY "); break; | ||
493 | case OPT_ECHO: printf("ECHO "); break; | ||
494 | case OPT_SUPGA: printf("SUPGA "); break; | ||
495 | case OPT_STATUS: printf("STATUS "); break; | ||
496 | case OPT_TIMING: printf("TIMING "); break; | ||
497 | case OPT_EXASCII: printf("EXASCII "); break; | ||
498 | case OPT_LOGOUT: printf("LOGOUT "); break; | ||
499 | case OPT_TTYPE: printf("TTYPE "); break; | ||
500 | case OPT_NAWS: printf("NAWS "); break; | ||
501 | case OPT_TSPEED: printf("TSPEED "); break; | ||
502 | case OPT_NEWENV: printf("NEWENV "); break; | ||
503 | case OPT_EXOPL: printf("EXOPL "); break; | ||
504 | default: printf("??%02x ", cOpt); break; | ||
505 | } | ||
506 | fflush( stdout ); | ||
507 | } | ||
508 | #endif | ||
509 | |||
510 | Bu::ProtocolTelnet::Option::Option( Bu::ProtocolTelnet &rPT, char cCode ) : | ||
511 | rPT( rPT ), | ||
512 | fOpts( 0 ), | ||
513 | cCode( cCode ) | ||
514 | { | ||
515 | rPT.hOpts.insert( cCode, this ); | ||
516 | } | ||
517 | |||
518 | Bu::ProtocolTelnet::Option::~Option() | ||
519 | { | ||
520 | } | ||
521 | |||
522 | void Bu::ProtocolTelnet::Option::localEnable( bool bSet ) | ||
523 | { | ||
524 | if( bSet == (bool)(!(fOpts&fLocalCant)) ) return; | ||
525 | |||
526 | if( bSet ) | ||
527 | fOpts &= ~fLocalCant; | ||
528 | else | ||
529 | fOpts |= fLocalCant; | ||
530 | } | ||
531 | |||
532 | void Bu::ProtocolTelnet::Option::localSet( bool bSet ) | ||
533 | { | ||
534 | if( bSet == (bool)(fOpts&fLocalIs) ) return; | ||
535 | |||
536 | char buf[3] = { CODE_IAC, 0, cCode }; | ||
537 | |||
538 | if( bSet ) | ||
539 | { | ||
540 | buf[1] = CODE_WILL; | ||
541 | rPT.pClient->write( buf, 3 ); | ||
542 | #ifdef __TELNET_DEBUG | ||
543 | printf("<= "); | ||
544 | rPT.printCode( buf[0] ); | ||
545 | rPT.printCode( buf[1] ); | ||
546 | rPT.printOpt( buf[2] ); | ||
547 | printf("\n"); | ||
548 | #endif | ||
549 | } | ||
550 | else | ||
551 | { | ||
552 | buf[1] = CODE_WONT; | ||
553 | rPT.pClient->write( buf, 3 ); | ||
554 | #ifdef __TELNET_DEBUG | ||
555 | printf("<= "); | ||
556 | rPT.printCode( buf[0] ); | ||
557 | rPT.printCode( buf[1] ); | ||
558 | rPT.printOpt( buf[2] ); | ||
559 | printf("\n"); | ||
560 | #endif | ||
561 | } | ||
562 | } | ||
563 | |||
564 | bool Bu::ProtocolTelnet::Option::isLocalEnabled() | ||
565 | { | ||
566 | return (bool)(!(fOpts&fLocalCant)); | ||
567 | } | ||
568 | |||
569 | bool Bu::ProtocolTelnet::Option::isLocalSet() | ||
570 | { | ||
571 | return (bool)(fOpts&fLocalIs); | ||
572 | } | ||
573 | |||
574 | void Bu::ProtocolTelnet::Option::remoteEnable( bool /*bSet*/ ) | ||
575 | { | ||
576 | return; | ||
577 | } | ||
578 | |||
579 | void Bu::ProtocolTelnet::Option::remoteSet( bool bSet ) | ||
580 | { | ||
581 | //if( bSet == (bool)(fOpts&fRemoteIs) ) return; | ||
582 | |||
583 | char buf[3] = { CODE_IAC, 0, cCode }; | ||
584 | |||
585 | if( bSet ) | ||
586 | { | ||
587 | buf[1] = CODE_DO; | ||
588 | rPT.pClient->write( buf, 3 ); | ||
589 | #ifdef __TELNET_DEBUG | ||
590 | printf("<= "); | ||
591 | rPT.printCode( buf[0] ); | ||
592 | rPT.printCode( buf[1] ); | ||
593 | rPT.printOpt( buf[2] ); | ||
594 | printf("\n"); | ||
595 | #endif | ||
596 | } | ||
597 | else | ||
598 | { | ||
599 | buf[1] = CODE_DONT; | ||
600 | rPT.pClient->write( buf, 3 ); | ||
601 | #ifdef __TELNET_DEBUG | ||
602 | printf("<= "); | ||
603 | rPT.printCode( buf[0] ); | ||
604 | rPT.printCode( buf[1] ); | ||
605 | rPT.printOpt( buf[2] ); | ||
606 | printf("\n"); | ||
607 | #endif | ||
608 | } | ||
609 | } | ||
610 | |||
611 | bool Bu::ProtocolTelnet::Option::isRemoteEnabled() | ||
612 | { | ||
613 | return (bool)(!(fOpts&fRemoteCant)); | ||
614 | } | ||
615 | |||
616 | bool Bu::ProtocolTelnet::Option::isRemoteSet() | ||
617 | { | ||
618 | return (bool)(fOpts&fRemoteIs); | ||
619 | } | ||
620 | |||