1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 /**
25 * @author Daniel F. Savarese
26 * @author Bruno D'Avanzo
27 */
28
29 class Telnet extends SocketClient
30 {
31 static final boolean debug =
32
33 static final boolean debugoptions =
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 /***
69 * Terminal type option
70 ***/
71 protected static final int TERMINAL_TYPE = 24;
72
73 /***
74 * Send (for subnegotiation)
75 ***/
76 protected static final int TERMINAL_TYPE_SEND = 1;
77
78 /***
79 * Is (for subnegotiation)
80 ***/
81 protected static final int TERMINAL_TYPE_IS = 0;
82
83 /***
84 * Is sequence (for subnegotiation)
85 ***/
86 static final byte[] _COMMAND_IS = {
87 (byte) TERMINAL_TYPE, (byte) TERMINAL_TYPE_IS
88 };
89
90 /***
91 * Terminal type
92 ***/
93 private String terminalType = null;
94
95
96
97 /***
98 * Array of option handlers
99 ***/
100 private TelnetOptionHandler optionHandlers[];
101
102
103
104
105 /***
106 * AYT sequence
107 ***/
108 static final byte[] _COMMAND_AYT = {
109 (byte) TelnetCommand.IAC, (byte) TelnetCommand.AYT
110 };
111
112 /***
113 * monitor to wait for AYT
114 ***/
115 private Object aytMonitor = new Object();
116
117 /***
118 * flag for AYT
119 ***/
120 private boolean aytFlag = true;
121
122
123 /***
124 * The stream on which to spy
125 ***/
126 private OutputStream spyStream = null;
127
128 /***
129 * The notification handler
130 ***/
131 private TelnetNotificationHandler __notifhand = null;
132 /***
133 * Empty Constructor
134 ***/
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 /***
147 * This constructor lets you specify the terminal type.
148 * <p>
149 * @param termtype - terminal type to be negotiated (ej. VT100)
150 ***/
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 /***
164 * Looks for the state of the option.
165 * <p>
166 * @return returns true if a will has been acknowledged
167 * <p>
168 * @param option - option code to be looked up.
169 ***/
170 boolean _stateIsWill(int option)
171 {
172 return ((_options[option] & _WILL_MASK) != 0);
173 }
174
175 /***
176 * Looks for the state of the option.
177 * <p>
178 * @return returns true if a wont has been acknowledged
179 * <p>
180 * @param option - option code to be looked up.
181 ***/
182 boolean _stateIsWont(int option)
183 {
184 return !_stateIsWill(option);
185 }
186
187 /***
188 * Looks for the state of the option.
189 * <p>
190 * @return returns true if a do has been acknowledged
191 * <p>
192 * @param option - option code to be looked up.
193 ***/
194 boolean _stateIsDo(int option)
195 {
196 return ((_options[option] & _DO_MASK) != 0);
197 }
198
199 /***
200 * Looks for the state of the option.
201 * <p>
202 * @return returns true if a dont has been acknowledged
203 * <p>
204 * @param option - option code to be looked up.
205 ***/
206 boolean _stateIsDont(int option)
207 {
208 return !_stateIsDo(option);
209 }
210
211 /***
212 * Looks for the state of the option.
213 * <p>
214 * @return returns true if a will has been reuqested
215 * <p>
216 * @param option - option code to be looked up.
217 ***/
218 boolean _requestedWill(int option)
219 {
220 return ((_options[option] & _REQUESTED_WILL_MASK) != 0);
221 }
222
223 /***
224 * Looks for the state of the option.
225 * <p>
226 * @return returns true if a wont has been reuqested
227 * <p>
228 * @param option - option code to be looked up.
229 ***/
230 boolean _requestedWont(int option)
231 {
232 return !_requestedWill(option);
233 }
234
235 /***
236 * Looks for the state of the option.
237 * <p>
238 * @return returns true if a do has been reuqested
239 * <p>
240 * @param option - option code to be looked up.
241 ***/
242 boolean _requestedDo(int option)
243 {
244 return ((_options[option] & _REQUESTED_DO_MASK) != 0);
245 }
246
247 /***
248 * Looks for the state of the option.
249 * <p>
250 * @return returns true if a dont has been reuqested
251 * <p>
252 * @param option - option code to be looked up.
253 ***/
254 boolean _requestedDont(int option)
255 {
256 return !_requestedDo(option);
257 }
258
259 /***
260 * Sets the state of the option.
261 * <p>
262 * @param option - option code to be set.
263 ***/
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 /***
297 * Sets the state of the option.
298 * <p>
299 * @param option - option code to be set.
300 ***/
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 /***
333 * Sets the state of the option.
334 * <p>
335 * @param option - option code to be set.
336 ***/
337 void _setWantWill(int option)
338 {
339 _options[option] |= _REQUESTED_WILL_MASK;
340 }
341
342 /***
343 * Sets the state of the option.
344 * <p>
345 * @param option - option code to be set.
346 ***/
347 void _setWantDo(int option)
348 {
349 _options[option] |= _REQUESTED_DO_MASK;
350 }
351
352 /***
353 * Sets the state of the option.
354 * <p>
355 * @param option - option code to be set.
356 ***/
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 /***
370 * Sets the state of the option.
371 * <p>
372 * @param option - option code to be set.
373 ***/
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 /***
387 * Sets the state of the option.
388 * <p>
389 * @param option - option code to be set.
390 ***/
391 void _setWantWont(int option)
392 {
393 _options[option] &= ~_REQUESTED_WILL_MASK;
394 }
395
396 /***
397 * Sets the state of the option.
398 * <p>
399 * @param option - option code to be set.
400 ***/
401 void _setWantDont(int option)
402 {
403 _options[option] &= ~_REQUESTED_DO_MASK;
404 }
405
406 /***
407 * Processes a DO request.
408 * <p>
409 * @throws IOException - Exception in I/O.
410 * <p>
411 * @param option - option code to be set.
412 ***/
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
489
490 switch (option)
491 {
492
493 default:
494 break;
495
496 }
497
498 }
499 }
500
501 _setWill(option);
502 }
503
504 /***
505 * Processes a DONT request.
506 * <p>
507 * @throws IOException - Exception in I/O.
508 * <p>
509 * @param option - option code to be set.
510 ***/
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 /***
559 * Processes a WILL request.
560 * <p>
561 * @throws IOException - Exception in I/O.
562 * <p>
563 * @param option - option code to be set.
564 ***/
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 /***
626 * Processes a WONT request.
627 * <p>
628 * @throws IOException - Exception in I/O.
629 * <p>
630 * @param option - option code to be set.
631 ***/
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 /***
682 * Processes a suboption negotiation.
683 * <p>
684 * @throws IOException - Exception in I/O.
685 * <p>
686 * @param suboption - subnegotiation data received
687 * @param suboptionLength - length of data received
688 ***/
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 /***
731 * Sends terminal type information.
732 * <p>
733 * @throws IOException - Exception in I/O.
734 ***/
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 /***
756 * Manages subnegotiation for Terminal Type.
757 * <p>
758 * @throws IOException - Exception in I/O.
759 * <p>
760 * @param subn - subnegotiation data to be sent
761 ***/
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 /***
797 * Processes the response of an AYT
798 ***/
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 /***
820 * Called upon connection.
821 * <p>
822 * @throws IOException - Exception in I/O.
823 ***/
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 /***
882 * Sends a DO.
883 * <p>
884 * @throws IOException - Exception in I/O.
885 * <p>
886 * @param option - Option code.
887 ***/
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 /***
904 * Requests a DO.
905 * <p>
906 * @throws IOException - Exception in I/O.
907 * <p>
908 * @param option - Option code.
909 ***/
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 /***
924 * Sends a DONT.
925 * <p>
926 * @throws IOException - Exception in I/O.
927 * <p>
928 * @param option - Option code.
929 ***/
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 /***
946 * Requests a DONT.
947 * <p>
948 * @throws IOException - Exception in I/O.
949 * <p>
950 * @param option - Option code.
951 ***/
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 /***
967 * Sends a WILL.
968 * <p>
969 * @throws IOException - Exception in I/O.
970 * <p>
971 * @param option - Option code.
972 ***/
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 /***
989 * Requests a WILL.
990 * <p>
991 * @throws IOException - Exception in I/O.
992 * <p>
993 * @param option - Option code.
994 ***/
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 /***
1009 * Sends a WONT.
1010 * <p>
1011 * @throws IOException - Exception in I/O.
1012 * <p>
1013 * @param option - Option code.
1014 ***/
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 /***
1031 * Requests a WONT.
1032 * <p>
1033 * @throws IOException - Exception in I/O.
1034 * <p>
1035 * @param option - Option code.
1036 ***/
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 /***
1051 * Sends a byte.
1052 * <p>
1053 * @throws IOException - Exception in I/O.
1054 * <p>
1055 * @param b - byte to send
1056 ***/
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 /***
1070 * Sends an Are You There sequence and waits for the result.
1071 * <p>
1072 * @throws IOException - Exception in I/O.
1073 * @throws IllegalArgumentException - Illegal argument
1074 * @throws InterruptedException - Interrupted during wait.
1075 * <p>
1076 * @param timeout - Time to wait for a response (millis.)
1077 * <p>
1078 * @return true if AYT received a response, false otherwise
1079 ***/
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 /***
1120 * Registers a new TelnetOptionHandler for this telnet to use.
1121 * <p>
1122 * @throws InvalidTelnetOptionException - The option code is invalid.
1123 * <p>
1124 * @param opthand - option handler to be registered.
1125 ***/
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 /***
1180 * Unregisters a TelnetOptionHandler.
1181 * <p>
1182 * @throws InvalidTelnetOptionException - The option code is invalid.
1183 * <p>
1184 * @param optcode - Code of the option to be unregistered.
1185 ***/
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 /***
1240 * Registers an OutputStream for spying what's going on in
1241 * the Telnet session.
1242 * <p>
1243 * @param spystream - OutputStream on which session activity
1244 * will be echoed.
1245 ***/
1246 void _registerSpyStream(OutputStream spystream)
1247 {
1248 spyStream = spystream;
1249 }
1250
1251 /***
1252 * Stops spying this Telnet.
1253 * <p>
1254 ***/
1255 void _stopSpyStream()
1256 {
1257 spyStream = null;
1258 }
1259
1260 /***
1261 * Sends a read char on the spy stream.
1262 * <p>
1263 * @param ch - character read from the session
1264 ***/
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 /***
1289 * Sends a written char on the spy stream.
1290 * <p>
1291 * @param ch - character written to the session
1292 ***/
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 /***
1315 * Registers a notification handler to which will be sent
1316 * notifications of received telnet option negotiation commands.
1317 * <p>
1318 * @param notifhand - TelnetNotificationHandler to be registered
1319 ***/
1320 public void registerNotifHandler(TelnetNotificationHandler notifhand)
1321 {
1322 __notifhand = notifhand;
1323 }
1324
1325 /***
1326 * Unregisters the current notification handler.
1327 * <p>
1328 ***/
1329 public void unregisterNotifHandler()
1330 {
1331 __notifhand = null;
1332 }
1333 }