00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 #ifndef _PTELNETSOCKET
00104 #define _PTELNETSOCKET
00105
00106 #ifdef P_USE_PRAGMA
00107 #pragma interface
00108 #endif
00109
00110 #include <ptlib/sockets.h>
00111
00112
00115 class PTelnetSocket : public PTCPSocket
00116 {
00117 PCLASSINFO(PTelnetSocket, PTCPSocket)
00118
00119 public:
00120 PTelnetSocket();
00121
00122
00123 PTelnetSocket(
00124 const PString & address
00125 );
00126
00127
00128
00129
00145 BOOL Read(
00146 void * buf,
00147 PINDEX len
00148 );
00149
00163 BOOL Write(
00164 const void * buf,
00165 PINDEX len
00166 );
00167
00168
00180 virtual BOOL Connect(
00181 const PString & address
00182 );
00183
00184
00199 virtual BOOL Accept(
00200 PSocket & socket
00201 );
00202
00203
00210 virtual void OnOutOfBand(
00211 const void * buf,
00212 PINDEX len
00213 );
00214
00215
00216
00217 enum Command {
00218 IAC = 255,
00219 DONT = 254,
00220 DO = 253,
00221 WONT = 252,
00222 WILL = 251,
00223 SB = 250,
00224 GoAhead = 249,
00225 EraseLine = 248,
00226 EraseChar = 247,
00227 AreYouThere = 246,
00228 AbortOutput = 245,
00229 InterruptProcess = 244,
00230 Break = 243,
00231 DataMark = 242,
00232 NOP = 241,
00233 SE = 240,
00234 EndOfReccord = 239,
00235 AbortProcess = 238,
00236 SuspendProcess= 237,
00237 EndOfFile = 236
00238 };
00239
00240
00261 BOOL SendCommand(
00262 Command cmd,
00263 int opt = 0
00264 );
00265
00266
00267 enum Options {
00268 TransmitBinary = 0,
00269 EchoOption = 1,
00270 ReconnectOption = 2,
00271 SuppressGoAhead = 3,
00272 MessageSizeOption = 4,
00273 StatusOption = 5,
00274 TimingMark = 6,
00275 RCTEOption = 7,
00276 OutputLineWidth = 8,
00277 OutputPageSize = 9,
00278 CRDisposition = 10,
00279 HorizontalTabsStops = 11,
00280 HorizTabDisposition = 12,
00281 FormFeedDisposition = 13,
00282 VerticalTabStops = 14,
00283 VertTabDisposition = 15,
00284 LineFeedDisposition = 16,
00285 ExtendedASCII = 17,
00286 ForceLogout = 18,
00287 ByteMacroOption = 19,
00288 DataEntryTerminal = 20,
00289 SupDupProtocol = 21,
00290 SupDupOutput = 22,
00291 SendLocation = 23,
00292 TerminalType = 24,
00293 EndOfRecordOption = 25,
00294 TACACSUID = 26,
00295 OutputMark = 27,
00296 TerminalLocation = 28,
00297 Use3270RegimeOption = 29,
00298 UseX3PADOption = 30,
00299 WindowSize = 31,
00300 TerminalSpeed = 32,
00301 FlowControl = 33,
00302 LineModeOption = 34,
00303 XDisplayLocation = 35,
00304 EnvironmentOption = 36,
00305 AuthenticateOption = 37,
00306 EncriptionOption = 38,
00307 EncryptionOption = 38,
00308 ExtendedOptionsList = 255,
00309 MaxOptions
00310 };
00311
00312
00313
00319 virtual BOOL SendDo(
00320 BYTE option
00321 );
00322
00328 virtual BOOL SendDont(
00329 BYTE option
00330 );
00331
00337 virtual BOOL SendWill(
00338 BYTE option
00339 );
00340
00346 virtual BOOL SendWont(
00347 BYTE option
00348 );
00349
00350 enum SubOptionCodes {
00351 SubOptionIs = 0,
00352 SubOptionSend = 1,
00353 };
00354
00355
00361 BOOL SendSubOption(
00362 BYTE code,
00363 const BYTE * info,
00364 PINDEX len,
00365 int subCode = -1
00366 );
00367
00371 void SetOurOption(
00372 BYTE code,
00373 BOOL state = TRUE
00374 ) { option[code].weCan = state; }
00375
00379 void SetTheirOption(
00380 BYTE code,
00381 BOOL state = TRUE
00382 ) { option[code].theyShould = state; }
00383
00389 BOOL IsOurOption(
00390 BYTE code
00391 ) const { return option[code].ourState == OptionInfo::IsYes; }
00392
00398 BOOL IsTheirOption(
00399 BYTE code
00400 ) const { return option[code].theirState == OptionInfo::IsYes; }
00401
00402 void SetTerminalType(
00403 const PString & newType
00404 );
00405
00406
00407 const PString & GetTerminalType() const { return terminalType; }
00408
00409
00410 void SetWindowSize(
00411 WORD width,
00412 WORD height
00413 );
00414
00415
00416 void GetWindowSize(
00417 WORD & width,
00418 WORD & height
00419 ) const;
00420
00421
00422
00423 protected:
00424 void Construct();
00425
00426
00436 virtual void OnDo(
00437 BYTE option
00438 );
00439
00446 virtual void OnDont(
00447 BYTE option
00448 );
00449
00456 virtual void OnWill(
00457 BYTE option
00458 );
00459
00466 virtual void OnWont(
00467 BYTE option
00468 );
00469
00473 virtual void OnSubOption(
00474 BYTE code,
00475 const BYTE * info,
00476 PINDEX len
00477 );
00478
00479
00489 virtual BOOL OnCommand(
00490 BYTE code
00491 );
00492
00493
00494
00495 struct OptionInfo {
00496 enum {
00497 IsNo, IsYes, WantNo, WantNoQueued, WantYes, WantYesQueued
00498 };
00499 unsigned weCan:1;
00500 unsigned ourState:3;
00501 unsigned theyShould:1;
00502 unsigned theirState:3;
00503 };
00504
00505 OptionInfo option[MaxOptions];
00506
00507
00508 PString terminalType;
00509
00510
00511 WORD windowWidth, windowHeight;
00512
00513
00514 BOOL debug;
00515
00516
00517
00518 private:
00519 enum State {
00520 StateNormal,
00521 StateCarriageReturn,
00522 StateIAC,
00523 StateDo,
00524 StateDont,
00525 StateWill,
00526 StateWont,
00527 StateSubNegotiations,
00528 StateEndNegotiations
00529 };
00530
00531
00532 State state;
00533
00534
00535 PBYTEArray subOption;
00536
00537
00538 unsigned synchronising;
00539
00540 BOOL StartSend(const char * which, BYTE code);
00541 };
00542
00543
00544 #endif
00545
00546
00547
00548