1 16 package org.apache.commons.net.telnet; 17 18 import java.io.BufferedInputStream ; 19 import java.io.BufferedOutputStream ; 20 import java.io.OutputStream ; 21 import java.io.IOException ; 22 import org.apache.commons.net.SocketClient; 23 24 28 29 class Telnet extends SocketClient 30 { 31 static final boolean debug = false; 32 33 static final boolean debugoptions = false; 34 35 static final byte[] _COMMAND_DO = { 36 (byte)TelnetCommand.IAC, (byte)TelnetCommand.DO 37 }; 38 39 static final byte[] _COMMAND_DONT = { 40 (byte)TelnetCommand.IAC, (byte)TelnetCommand.DONT 41 }; 42 43 static final byte[] _COMMAND_WILL = { 44 (byte)TelnetCommand.IAC, (byte)TelnetCommand.WILL 45 }; 46 47 static final byte[] _COMMAND_WONT = { 48 (byte)TelnetCommand.IAC, (byte)TelnetCommand.WONT 49 }; 50 51 static final byte[] _COMMAND_SB = { 52 (byte)TelnetCommand.IAC, (byte)TelnetCommand.SB 53 }; 54 55 static final byte[] _COMMAND_SE = { 56 (byte)TelnetCommand.IAC, (byte)TelnetCommand.SE 57 }; 58 59 static final int _WILL_MASK = 0x01, _DO_MASK = 0x02, 60 _REQUESTED_WILL_MASK = 0x04, _REQUESTED_DO_MASK = 0x08; 61 62 63 static final int DEFAULT_PORT = 23; 64 65 int[] _doResponse, _willResponse, _options; 66 67 68 71 protected static final int TERMINAL_TYPE = 24; 72 73 76 protected static final int TERMINAL_TYPE_SEND = 1; 77 78 81 protected static final int TERMINAL_TYPE_IS = 0; 82 83 86 static final byte[] _COMMAND_IS = { 87 (byte) TERMINAL_TYPE, (byte) TERMINAL_TYPE_IS 88 }; 89 90 93 private String terminalType = null; 94 95 96 97 100 private TelnetOptionHandler optionHandlers[]; 101 102 103 104 105 108 static final byte[] _COMMAND_AYT = { 109 (byte) TelnetCommand.IAC, (byte) TelnetCommand.AYT 110 }; 111 112 115 private Object aytMonitor = new Object (); 116 117 120 private boolean aytFlag = true; 121 122 123 126 private OutputStream spyStream = null; 127 128 131 private TelnetNotificationHandler __notifhand = null; 132 135 Telnet() 136 { 137 setDefaultPort(DEFAULT_PORT); 138 _doResponse = new int[TelnetOption.MAX_OPTION_VALUE + 1]; 139 _willResponse = new int[TelnetOption.MAX_OPTION_VALUE + 1]; 140 _options = new int[TelnetOption.MAX_OPTION_VALUE + 1]; 141 optionHandlers = 142 new TelnetOptionHandler[TelnetOption.MAX_OPTION_VALUE + 1]; 143 } 144 145 146 151 Telnet(String termtype) 152 { 153 setDefaultPort(DEFAULT_PORT); 154 _doResponse = new int[TelnetOption.MAX_OPTION_VALUE + 1]; 155 _willResponse = new int[TelnetOption.MAX_OPTION_VALUE + 1]; 156 _options = new int[TelnetOption.MAX_OPTION_VALUE + 1]; 157 terminalType = termtype; 158 optionHandlers = 159 new TelnetOptionHandler[TelnetOption.MAX_OPTION_VALUE + 1]; 160 } 161 162 163 170 boolean _stateIsWill(int option) 171 { 172 return ((_options[option] & _WILL_MASK) != 0); 173 } 174 175 182 boolean _stateIsWont(int option) 183 { 184 return !_stateIsWill(option); 185 } 186 187 194 boolean _stateIsDo(int option) 195 { 196 return ((_options[option] & _DO_MASK) != 0); 197 } 198 199 206 boolean _stateIsDont(int option) 207 { 208 return !_stateIsDo(option); 209 } 210 211 218 boolean _requestedWill(int option) 219 { 220 return ((_options[option] & _REQUESTED_WILL_MASK) != 0); 221 } 222 223 230 boolean _requestedWont(int option) 231 { 232 return !_requestedWill(option); 233 } 234 235 242 boolean _requestedDo(int option) 243 { 244 return ((_options[option] & _REQUESTED_DO_MASK) != 0); 245 } 246 247 254 boolean _requestedDont(int option) 255 { 256 return !_requestedDo(option); 257 } 258 259 264 void _setWill(int option) 265 { 266 _options[option] |= _WILL_MASK; 267 268 269 if (_requestedWill(option)) 270 { 271 if (optionHandlers[option] != null) 272 { 273 optionHandlers[option].setWill(true); 274 275 int subneg[] = 276 optionHandlers[option].startSubnegotiationLocal(); 277 278 if (subneg != null) 279 { 280 try 281 { 282 _sendSubnegotiation(subneg); 283 } 284 catch (Exception e) 285 { 286 System.err.println( 287 "Exception in option subnegotiation" 288 + e.getMessage()); 289 } 290 } 291 } 292 } 293 294 } 295 296 301 void _setDo(int option) 302 { 303 _options[option] |= _DO_MASK; 304 305 306 if (_requestedDo(option)) 307 { 308 if (optionHandlers[option] != null) 309 { 310 optionHandlers[option].setDo(true); 311 312 int subneg[] = 313 optionHandlers[option].startSubnegotiationRemote(); 314 315 if (subneg != null) 316 { 317 try 318 { 319 _sendSubnegotiation(subneg); 320 } 321 catch (Exception e) 322 { 323 System.err.println("Exception in option subnegotiation" 324 + e.getMessage()); 325 } 326 } 327 } 328 } 329 330 } 331 332 337 void _setWantWill(int option) 338 { 339 _options[option] |= _REQUESTED_WILL_MASK; 340 } 341 342 347 void _setWantDo(int option) 348 { 349 _options[option] |= _REQUESTED_DO_MASK; 350 } 351 352 357 void _setWont(int option) 358 { 359 _options[option] &= ~_WILL_MASK; 360 361 362 if (optionHandlers[option] != null) 363 { 364 optionHandlers[option].setWill(false); 365 } 366 367 } 368 369 374 void _setDont(int option) 375 { 376 _options[option] &= ~_DO_MASK; 377 378 379 if (optionHandlers[option] != null) 380 { 381 optionHandlers[option].setDo(false); 382 } 383 384 } 385 386 391 void _setWantWont(int option) 392 { 393 _options[option] &= ~_REQUESTED_WILL_MASK; 394 } 395 396 401 void _setWantDont(int option) 402 { 403 _options[option] &= ~_REQUESTED_DO_MASK; 404 } 405 406 413 void _processDo(int option) throws IOException 414 { 415 if (debugoptions) 416 { 417 System.err.println("RECEIVED DO: " 418 + TelnetOption.getOption(option)); 419 } 420 421 if (__notifhand != null) 422 { 423 __notifhand.receivedNegotiation( 424 TelnetNotificationHandler.RECEIVED_DO, 425 option); 426 } 427 428 boolean acceptNewState = false; 429 430 431 432 if (optionHandlers[option] != null) 433 { 434 acceptNewState = optionHandlers[option].getAcceptLocal(); 435 } 436 else 437 { 438 439 440 if (option == TERMINAL_TYPE) 441 { 442 if ((terminalType != null) && (terminalType.length() > 0)) 443 { 444 acceptNewState = true; 445 } 446 } 447 448 449 } 450 451 452 if (_willResponse[option] > 0) 453 { 454 --_willResponse[option]; 455 if (_willResponse[option] > 0 && _stateIsWill(option)) 456 { 457 --_willResponse[option]; 458 } 459 } 460 461 if (_willResponse[option] == 0) 462 { 463 if (_requestedWont(option)) 464 { 465 466 switch (option) 467 { 468 469 default: 470 break; 471 472 } 473 474 475 if (acceptNewState) 476 { 477 _setWantWill(option); 478 _sendWill(option); 479 } 480 else 481 { 482 ++_willResponse[option]; 483 _sendWont(option); 484 } 485 } 486 else 487 { 488 490 switch (option) 491 { 492 493 default: 494 break; 495 496 } 497 498 } 499 } 500 501 _setWill(option); 502 } 503 504 511 void _processDont(int option) throws IOException 512 { 513 if (debugoptions) 514 { 515 System.err.println("RECEIVED DONT: " 516 + TelnetOption.getOption(option)); 517 } 518 if (__notifhand != null) 519 { 520 __notifhand.receivedNegotiation( 521 TelnetNotificationHandler.RECEIVED_DONT, 522 option); 523 } 524 if (_willResponse[option] > 0) 525 { 526 --_willResponse[option]; 527 if (_willResponse[option] > 0 && _stateIsWont(option)) 528 { 529 --_willResponse[option]; 530 } 531 } 532 533 if (_willResponse[option] == 0 && _requestedWill(option)) 534 { 535 536 switch (option) 537 { 538 539 default: 540 break; 541 542 } 543 544 545 if ((_stateIsWill(option)) || (_requestedWill(option))) 546 { 547 _sendWont(option); 548 } 549 550 _setWantWont(option); 551 552 } 553 554 _setWont(option); 555 } 556 557 558 565 void _processWill(int option) throws IOException 566 { 567 if (debugoptions) 568 { 569 System.err.println("RECEIVED WILL: " 570 + TelnetOption.getOption(option)); 571 } 572 573 if (__notifhand != null) 574 { 575 __notifhand.receivedNegotiation( 576 TelnetNotificationHandler.RECEIVED_WILL, 577 option); 578 } 579 580 boolean acceptNewState = false; 581 582 583 if (optionHandlers[option] != null) 584 { 585 acceptNewState = optionHandlers[option].getAcceptRemote(); 586 } 587 588 589 if (_doResponse[option] > 0) 590 { 591 --_doResponse[option]; 592 if (_doResponse[option] > 0 && _stateIsDo(option)) 593 { 594 --_doResponse[option]; 595 } 596 } 597 598 if (_doResponse[option] == 0 && _requestedDont(option)) 599 { 600 601 switch (option) 602 { 603 604 default: 605 break; 606 607 } 608 609 610 if (acceptNewState) 611 { 612 _setWantDo(option); 613 _sendDo(option); 614 } 615 else 616 { 617 ++_doResponse[option]; 618 _sendDont(option); 619 } 620 } 621 622 _setDo(option); 623 } 624 625 632 void _processWont(int option) throws IOException 633 { 634 if (debugoptions) 635 { 636 System.err.println("RECEIVED WONT: " 637 + TelnetOption.getOption(option)); 638 } 639 640 if (__notifhand != null) 641 { 642 __notifhand.receivedNegotiation( 643 TelnetNotificationHandler.RECEIVED_WONT, 644 option); 645 } 646 647 if (_doResponse[option] > 0) 648 { 649 --_doResponse[option]; 650 if (_doResponse[option] > 0 && _stateIsDont(option)) 651 { 652 --_doResponse[option]; 653 } 654 } 655 656 if (_doResponse[option] == 0 && _requestedDo(option)) 657 { 658 659 switch (option) 660 { 661 662 default: 663 break; 664 665 } 666 667 668 if ((_stateIsDo(option)) || (_requestedDo(option))) 669 { 670 _sendDont(option); 671 } 672 673 _setWantDont(option); 674 675 } 676 677 _setDont(option); 678 } 679 680 681 689 void _processSuboption(int suboption[], int suboptionLength) 690 throws IOException 691 { 692 if (debug) 693 { 694 System.err.println("PROCESS SUBOPTION."); 695 } 696 697 698 if (suboptionLength > 0) 699 { 700 if (optionHandlers[suboption[0]] != null) 701 { 702 int responseSuboption[] = 703 optionHandlers[suboption[0]].answerSubnegotiation(suboption, 704 suboptionLength); 705 _sendSubnegotiation(responseSuboption); 706 } 707 else 708 { 709 if (suboptionLength > 1) 710 { 711 if (debug) 712 { 713 for (int ii = 0; ii < suboptionLength; ii++) 714 { 715 System.err.println("SUB[" + ii + "]: " 716 + suboption[ii]); 717 } 718 } 719 if ((suboption[0] == TERMINAL_TYPE) 720 && (suboption[1] == TERMINAL_TYPE_SEND)) 721 { 722 _sendTerminalType(); 723 } 724 } 725 } 726 } 727 728 } 729 730 735 final synchronized void _sendTerminalType() 736 throws IOException 737 { 738 if (debug) 739 { 740 System.err.println("SEND TERMINAL-TYPE: " + terminalType); 741 } 742 if (terminalType != null) 743 { 744 _output_.write(_COMMAND_SB); 745 _output_.write(_COMMAND_IS); 746 _output_.write(terminalType.getBytes()); 747 _output_.write(_COMMAND_SE); 748 _output_.flush(); 749 } 750 } 751 752 753 754 755 762 final synchronized void _sendSubnegotiation(int subn[]) 763 throws IOException 764 { 765 if (debug) 766 { 767 System.err.println("SEND SUBNEGOTIATION: "); 768 if (subn != null) 769 { 770 for (int ii = 0; ii < subn.length; ii++) 771 { 772 System.err.println("subn[" + ii + "]=" + subn[ii]); 773 } 774 } 775 } 776 if (subn != null) 777 { 778 byte byteresp[] = new byte[subn.length]; 779 for (int ii = 0; ii < subn.length; ii++) 780 { 781 byteresp[ii] = (byte) subn[ii]; 782 } 783 784 _output_.write(_COMMAND_SB); 785 _output_.write(byteresp); 786 _output_.write(_COMMAND_SE); 787 788 789 _output_.flush(); 790 791 } 792 } 793 794 795 796 799 final synchronized void _processAYTResponse() 800 { 801 if (!aytFlag) 802 { 803 synchronized (aytMonitor) 804 { 805 aytFlag = true; 806 try 807 { 808 aytMonitor.notifyAll(); 809 } 810 catch (Exception e) 811 { 812 System.err.println("Exception notifying:" + e.getMessage()); 813 } 814 } 815 } 816 } 817 818 819 824 protected void _connectAction_() throws IOException 825 { 826 827 for (int ii = 0; ii < TelnetOption.MAX_OPTION_VALUE + 1; ii++) 828 { 829 _doResponse[ii] = 0; 830 _willResponse[ii] = 0; 831 _options[ii] = 0; 832 if (optionHandlers[ii] != null) 833 { 834 optionHandlers[ii].setDo(false); 835 optionHandlers[ii].setWill(false); 836 } 837 } 838 839 840 super._connectAction_(); 841 _input_ = new BufferedInputStream (_input_); 842 _output_ = new BufferedOutputStream (_output_); 843 844 845 for (int ii = 0; ii < TelnetOption.MAX_OPTION_VALUE + 1; ii++) 846 { 847 if (optionHandlers[ii] != null) 848 { 849 if (optionHandlers[ii].getInitLocal()) 850 { 851 try 852 { 853 _requestWill(optionHandlers[ii].getOptionCode()); 854 } 855 catch (IOException e) 856 { 857 System.err.println( 858 "Exception while initializing option: " 859 + e.getMessage()); 860 } 861 } 862 863 if (optionHandlers[ii].getInitRemote()) 864 { 865 try 866 { 867 _requestDo(optionHandlers[ii].getOptionCode()); 868 } 869 catch (IOException e) 870 { 871 System.err.println( 872 "Exception while initializing option: " 873 + e.getMessage()); 874 } 875 } 876 } 877 } 878 879 } 880 881 888 final synchronized void _sendDo(int option) 889 throws IOException 890 { 891 if (debug || debugoptions) 892 { 893 System.err.println("DO: " + TelnetOption.getOption(option)); 894 } 895 _output_.write(_COMMAND_DO); 896 _output_.write(option); 897 898 899 _output_.flush(); 900 901 } 902 903 910 final synchronized void _requestDo(int option) 911 throws IOException 912 { 913 if ((_doResponse[option] == 0 && _stateIsDo(option)) 914 || _requestedDo(option)) 915 { 916 return ; 917 } 918 _setWantDo(option); 919 ++_doResponse[option]; 920 _sendDo(option); 921 } 922 923 930 final synchronized void _sendDont(int option) 931 throws IOException 932 { 933 if (debug || debugoptions) 934 { 935 System.err.println("DONT: " + TelnetOption.getOption(option)); 936 } 937 _output_.write(_COMMAND_DONT); 938 _output_.write(option); 939 940 941 _output_.flush(); 942 943 } 944 945 952 final synchronized void _requestDont(int option) 953 throws IOException 954 { 955 if ((_doResponse[option] == 0 && _stateIsDont(option)) 956 || _requestedDont(option)) 957 { 958 return ; 959 } 960 _setWantDont(option); 961 ++_doResponse[option]; 962 _sendDont(option); 963 } 964 965 966 973 final synchronized void _sendWill(int option) 974 throws IOException 975 { 976 if (debug || debugoptions) 977 { 978 System.err.println("WILL: " + TelnetOption.getOption(option)); 979 } 980 _output_.write(_COMMAND_WILL); 981 _output_.write(option); 982 983 984 _output_.flush(); 985 986 } 987 988 995 final synchronized void _requestWill(int option) 996 throws IOException 997 { 998 if ((_willResponse[option] == 0 && _stateIsWill(option)) 999 || _requestedWill(option)) 1000 { 1001 return ; 1002 } 1003 _setWantWill(option); 1004 ++_doResponse[option]; 1005 _sendWill(option); 1006 } 1007 1008 1015 final synchronized void _sendWont(int option) 1016 throws IOException 1017 { 1018 if (debug || debugoptions) 1019 { 1020 System.err.println("WONT: " + TelnetOption.getOption(option)); 1021 } 1022 _output_.write(_COMMAND_WONT); 1023 _output_.write(option); 1024 1025 1026 _output_.flush(); 1027 1028 } 1029 1030 1037 final synchronized void _requestWont(int option) 1038 throws IOException 1039 { 1040 if ((_willResponse[option] == 0 && _stateIsWont(option)) 1041 || _requestedWont(option)) 1042 { 1043 return ; 1044 } 1045 _setWantWont(option); 1046 ++_doResponse[option]; 1047 _sendWont(option); 1048 } 1049 1050 1057 final synchronized void _sendByte(int b) 1058 throws IOException 1059 { 1060 _output_.write(b); 1061 1062 1063 _spyWrite(b); 1064 1065 1066 } 1067 1068 1069 1080 final boolean _sendAYT(long timeout) 1081 throws IOException , IllegalArgumentException , InterruptedException 1082 { 1083 boolean retValue = false; 1084 synchronized (aytMonitor) 1085 { 1086 synchronized (this) 1087 { 1088 aytFlag = false; 1089 _output_.write(_COMMAND_AYT); 1090 _output_.flush(); 1091 } 1092 1093 try 1094 { 1095 aytMonitor.wait(timeout); 1096 if (aytFlag == false) 1097 { 1098 retValue = false; 1099 aytFlag = true; 1100 } 1101 else 1102 { 1103 retValue = true; 1104 } 1105 } 1106 catch (IllegalMonitorStateException e) 1107 { 1108 System.err.println("Exception processing AYT:" 1109 + e.getMessage()); 1110 } 1111 } 1112 1113 return (retValue); 1114 } 1115 1116 1117 1118 1119 1126 void addOptionHandler(TelnetOptionHandler opthand) 1127 throws InvalidTelnetOptionException 1128 { 1129 int optcode = opthand.getOptionCode(); 1130 if (TelnetOption.isValidOption(optcode)) 1131 { 1132 if (optionHandlers[optcode] == null) 1133 { 1134 optionHandlers[optcode] = opthand; 1135 if (isConnected()) 1136 { 1137 if (opthand.getInitLocal()) 1138 { 1139 try 1140 { 1141 _requestWill(optcode); 1142 } 1143 catch (IOException e) 1144 { 1145 System.err.println( 1146 "Exception while initializing option: " 1147 + e.getMessage()); 1148 } 1149 } 1150 1151 if (opthand.getInitRemote()) 1152 { 1153 try 1154 { 1155 _requestDo(optcode); 1156 } 1157 catch (IOException e) 1158 { 1159 System.err.println( 1160 "Exception while initializing option: " 1161 + e.getMessage()); 1162 } 1163 } 1164 } 1165 } 1166 else 1167 { 1168 throw (new InvalidTelnetOptionException( 1169 "Already registered option", optcode)); 1170 } 1171 } 1172 else 1173 { 1174 throw (new InvalidTelnetOptionException( 1175 "Invalid Option Code", optcode)); 1176 } 1177 } 1178 1179 1186 void deleteOptionHandler(int optcode) 1187 throws InvalidTelnetOptionException 1188 { 1189 if (TelnetOption.isValidOption(optcode)) 1190 { 1191 if (optionHandlers[optcode] == null) 1192 { 1193 throw (new InvalidTelnetOptionException( 1194 "Unregistered option", optcode)); 1195 } 1196 else 1197 { 1198 TelnetOptionHandler opthand = optionHandlers[optcode]; 1199 optionHandlers[optcode] = null; 1200 1201 if (opthand.getWill()) 1202 { 1203 try 1204 { 1205 _requestWont(optcode); 1206 } 1207 catch (IOException e) 1208 { 1209 System.err.println( 1210 "Exception while turning off option: " 1211 + e.getMessage()); 1212 } 1213 } 1214 1215 if (opthand.getDo()) 1216 { 1217 try 1218 { 1219 _requestDont(optcode); 1220 } 1221 catch (IOException e) 1222 { 1223 System.err.println( 1224 "Exception while turning off option: " 1225 + e.getMessage()); 1226 } 1227 } 1228 } 1229 } 1230 else 1231 { 1232 throw (new InvalidTelnetOptionException( 1233 "Invalid Option Code", optcode)); 1234 } 1235 } 1236 1237 1238 1239 1246 void _registerSpyStream(OutputStream spystream) 1247 { 1248 spyStream = spystream; 1249 } 1250 1251 1255 void _stopSpyStream() 1256 { 1257 spyStream = null; 1258 } 1259 1260 1265 void _spyRead(int ch) 1266 { 1267 if (spyStream != null) 1268 { 1269 try 1270 { 1271 if (ch != (int) '\r') 1272 { 1273 spyStream.write(ch); 1274 if (ch == (int) '\n') 1275 { 1276 spyStream.write((int) '\r'); 1277 } 1278 spyStream.flush(); 1279 } 1280 } 1281 catch (Exception e) 1282 { 1283 spyStream = null; 1284 } 1285 } 1286 } 1287 1288 1293 void _spyWrite(int ch) 1294 { 1295 if (!(_stateIsDo(TelnetOption.ECHO) 1296 && _requestedDo(TelnetOption.ECHO))) 1297 { 1298 if (spyStream != null) 1299 { 1300 try 1301 { 1302 spyStream.write(ch); 1303 spyStream.flush(); 1304 } 1305 catch (Exception e) 1306 { 1307 spyStream = null; 1308 } 1309 } 1310 } 1311 } 1312 1313 1314 1320 public void registerNotifHandler(TelnetNotificationHandler notifhand) 1321 { 1322 __notifhand = notifhand; 1323 } 1324 1325 1329 public void unregisterNotifHandler() 1330 { 1331 __notifhand = null; 1332 } 1333} 1334 | Popular Tags |