Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/teraterm/teraterm/telnet.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6963 - (hide annotations) (download) (as text)
Fri Oct 27 09:40:53 2017 UTC (6 years, 5 months ago) by doda
File MIME type: text/x-csrc
File size: 17149 byte(s)
telnet 接続時、端末の幅/高さが 255 の時に端末サイズがサーバに伝わらないのを修正 #37605

telnet サブオプションで値に 255 を使う時は 255(IAC) を二つ連続で送る必要がある。

RFC 855:
|   Finally, if parameters in an option "subnegotiation" include a byte
|   with a value of 255, it is necessary to double this byte in
|   accordance the general TELNET rules.

HIBYTE の方が 255 になる事はないだろうが、念の為対応しておく。
1 doda 6806 /*
2     * Copyright (C) 1994-1998 T. Teranishi
3     * (C) 2007-2017 TeraTerm Project
4     * All rights reserved.
5     *
6 doda 6841 * Redistribution and use in source and binary forms, with or without
7     * modification, are permitted provided that the following conditions
8     * are met:
9 doda 6806 *
10 doda 6841 * 1. Redistributions of source code must retain the above copyright
11     * notice, this list of conditions and the following disclaimer.
12     * 2. Redistributions in binary form must reproduce the above copyright
13     * notice, this list of conditions and the following disclaimer in the
14     * documentation and/or other materials provided with the distribution.
15     * 3. The name of the author may not be used to endorse or promote products
16     * derived from this software without specific prior written permission.
17 doda 6806 *
18 doda 6841 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
19     * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21     * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23     * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27     * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 doda 6806 */
29 maya 3227
30     /* TERATERM.EXE, TELNET routines */
31    
32     #include "teraterm.h"
33     #include "tttypes.h"
34     #include <stdio.h>
35     #include <string.h>
36     #include "ttcommon.h"
37     #include "ttwinman.h"
38     #include "commlib.h"
39     #include <time.h>
40     #include <process.h>
41    
42     #include "telnet.h"
43     #include "tt_res.h"
44    
45     int TelStatus;
46    
47     enum OptStatus {No, Yes, WantNo, WantYes};
48     enum OptQue {Empty, Opposite};
49    
50     typedef struct {
51 doda 6961 BOOL Accept;
52     enum OptStatus Status;
53     enum OptQue Que;
54 maya 3227 } TelOpt;
55     typedef TelOpt *PTelOpt;
56    
57     typedef struct {
58 doda 6961 TelOpt MyOpt[MaxTelOpt+1];
59     TelOpt HisOpt[MaxTelOpt+1];
60     BYTE SubOptBuff[51];
61     int SubOptCount;
62     BOOL SubOptIAC;
63     BOOL ChangeWinSize;
64     POINT WinSize;
65     int LogFile;
66 maya 3227 } TelRec;
67     typedef TelRec *PTelRec;
68    
69     static TelRec tr;
70    
71     static HANDLE keepalive_thread = (HANDLE)-1L;
72 doda 6435 static HWND keepalive_dialog = NULL;
73 maya 3227 int nop_interval = 0;
74    
75     void DefaultTelRec()
76     {
77 doda 6961 int i;
78 maya 3227
79 doda 6961 for (i=0 ; i <= MaxTelOpt ; i++) {
80     tr.MyOpt[i].Accept = FALSE;
81     tr.MyOpt[i].Status = No;
82     tr.MyOpt[i].Que = Empty;
83     tr.HisOpt[i].Accept = FALSE;
84     tr.HisOpt[i].Status = No;
85     tr.HisOpt[i].Que = Empty;
86     }
87 maya 3227
88 doda 6961 tr.SubOptCount = 0;
89     tr.SubOptIAC = FALSE;
90     tr.ChangeWinSize = FALSE;
91 maya 3227 }
92    
93     void InitTelnet()
94     {
95 doda 6961 TelStatus = TelIdle;
96 maya 3227
97 doda 6961 DefaultTelRec();
98     tr.MyOpt[BINARY].Accept = TRUE;
99     tr.HisOpt[BINARY].Accept = TRUE;
100     tr.MyOpt[SGA].Accept = TRUE;
101     tr.HisOpt[SGA].Accept = TRUE;
102     tr.HisOpt[ECHO].Accept = TRUE;
103     tr.MyOpt[TERMTYPE].Accept = TRUE;
104     tr.MyOpt[TERMSPEED].Accept = TRUE;
105     tr.MyOpt[NAWS].Accept = TRUE;
106     tr.HisOpt[NAWS].Accept = TRUE;
107     tr.WinSize.x = ts.TerminalWidth;
108     tr.WinSize.y = ts.TerminalHeight;
109 maya 3227
110 doda 6961 if ((ts.LogFlag & LOG_TEL) != 0)
111     tr.LogFile = _lcreat("TELNET.LOG", 0);
112     else
113     tr.LogFile = 0;
114 maya 3227 }
115    
116     void EndTelnet()
117     {
118 doda 6961 if (tr.LogFile) {
119     tr.LogFile = 0;
120     _lclose(tr.LogFile);
121     }
122 maya 3227
123 doda 6961 TelStopKeepAliveThread();
124 maya 3227 }
125    
126     void TelWriteLog1(BYTE b)
127     {
128 doda 6961 BYTE Temp[3];
129     BYTE Ch;
130 maya 3227
131 doda 6961 Temp[0] = 0x20;
132     Ch = b / 16;
133     if (Ch <= 9)
134     Ch = Ch + 0x30;
135     else
136     Ch = Ch + 0x37;
137     Temp[1] = Ch;
138 maya 3227
139 doda 6961 Ch = b & 15;
140     if (Ch <= 9)
141     Ch = Ch + 0x30;
142     else
143     Ch = Ch + 0x37;
144     Temp[2] = Ch;
145     _lwrite(tr.LogFile, Temp, 3);
146 maya 3227 }
147    
148     void TelWriteLog(PCHAR Buf, int C)
149     {
150 doda 6961 int i;
151 maya 3227
152 doda 6961 _lwrite(tr.LogFile, "\015\012>", 3);
153     for (i = 0 ; i<= C-1 ; i++)
154     TelWriteLog1(Buf[i]);
155 maya 3227 }
156    
157     void SendBack(BYTE a, BYTE b)
158     {
159 doda 6961 BYTE Str3[3];
160 maya 3227
161 doda 6961 Str3[0] = IAC;
162     Str3[1] = a;
163     Str3[2] = b;
164     CommRawOut(&cv, Str3, 3);
165     if (tr.LogFile)
166     TelWriteLog(Str3, 3);
167 maya 3227 }
168    
169     void SendWinSize()
170     {
171 doda 6961 int i;
172     BYTE TmpBuff[21];
173 maya 3227
174 doda 6961 i = 0;
175 maya 3227
176 doda 6961 TmpBuff[i++] = IAC;
177     TmpBuff[i++] = SB;
178     TmpBuff[i++] = NAWS;
179 doda 6963
180     if (HIBYTE(tr.WinSize.x) == IAC) {
181     TmpBuff[i++] = IAC;
182     }
183 doda 6961 TmpBuff[i++] = HIBYTE(tr.WinSize.x);
184 doda 6963
185     if (LOBYTE(tr.WinSize.x) == IAC) {
186     TmpBuff[i++] = IAC;
187     }
188 doda 6961 TmpBuff[i++] = LOBYTE(tr.WinSize.x);
189 doda 6963
190     if (HIBYTE(tr.WinSize.y) == IAC) {
191     TmpBuff[i++] = IAC;
192     }
193 doda 6961 TmpBuff[i++] = HIBYTE(tr.WinSize.y);
194 doda 6963
195     if (LOBYTE(tr.WinSize.y) == IAC) {
196     TmpBuff[i++] = IAC;
197     }
198 doda 6961 TmpBuff[i++] = LOBYTE(tr.WinSize.y);
199 doda 6963
200 doda 6961 TmpBuff[i++] = IAC;
201     TmpBuff[i++] = SE;
202 maya 3227
203 doda 6961 CommRawOut(&cv, TmpBuff, i);
204     if (tr.LogFile)
205     TelWriteLog(TmpBuff, i);
206 maya 3227 }
207    
208     void ParseTelIAC(BYTE b)
209     {
210 doda 6961 switch (b) {
211     case SE: break;
212     case NOP:
213     case DM:
214     case BREAK:
215     case IP:
216     case AO:
217     case AYT:
218     case EC:
219     case EL:
220     case GOAHEAD:
221     TelStatus = TelIdle;
222     break;
223     case SB:
224     TelStatus = TelSB;
225     tr.SubOptCount = 0;
226     break;
227     case WILLTEL:
228     TelStatus = TelWill;
229     break;
230     case WONTTEL:
231     TelStatus = TelWont;
232     break;
233     case DOTEL:
234     TelStatus = TelDo;
235     break;
236     case DONTTEL:
237     TelStatus = TelDont;
238     break;
239     case IAC:
240     TelStatus = TelIdle;
241     break;
242     default:
243     TelStatus = TelIdle;
244     }
245 maya 3227 }
246    
247     void ParseTelSB(BYTE b)
248     {
249 doda 6959 BYTE TmpStr[51];
250     int i;
251 maya 3227
252 doda 6959 if (tr.SubOptIAC) {
253     tr.SubOptIAC = FALSE;
254     switch (b) {
255     case SE:
256 doda 6962 if (tr.SubOptCount <= 1) {
257     // �p�����[�^������ Sub Option ���������v����������������������
258     tr.SubOptCount = 0;
259     TelStatus = TelIdle;
260     return ;
261     }
262 maya 3227
263 doda 6962 switch (tr.SubOptBuff[0]) {
264     case TERMTYPE:
265     if ((tr.MyOpt[TERMTYPE].Status == Yes) && (tr.SubOptBuff[1] == 1)) {
266     _snprintf_s(TmpStr, sizeof(TmpStr), _TRUNCATE, "%c%c%c%c%s%c%c",
267     IAC, SB, TERMTYPE, 0, ts.TermType, IAC, SE);
268     // 4 �o�C�g���� 0 �����������A������������������
269     i = strlen(TmpStr + 4) + 4;
270     CommRawOut(&cv, TmpStr, i);
271    
272     if (tr.LogFile)
273     TelWriteLog(TmpStr, i);
274     }
275     break;
276    
277     case NAWS:
278     if ( /* (tr.HisOpt[NAWS].Status == Yes) && */ (tr.SubOptCount >= 5)) {
279     tr.WinSize.x = tr.SubOptBuff[1]*256 + tr.SubOptBuff[2];
280     tr.WinSize.y = tr.SubOptBuff[3]*256 + tr.SubOptBuff[4];
281     tr.ChangeWinSize = TRUE;
282     }
283     break;
284    
285     case TERMSPEED:
286     if ((tr.MyOpt[TERMSPEED].Status == Yes) && (tr.SubOptBuff[1] == 1)) {
287     _snprintf_s(TmpStr, sizeof(TmpStr), _TRUNCATE,
288     "%c%c%c%c%d,%d%c%c", IAC, SB, TERMSPEED, 0,
289     ts.TerminalInputSpeed, ts.TerminalOutputSpeed, IAC, SE);
290     // 4 �o�C�g���� 0 �����������A������������������
291     i = strlen(TmpStr + 4) + 4;
292     CommRawOut(&cv, TmpStr, i);
293    
294     if (tr.LogFile)
295     TelWriteLog(TmpStr, i);
296     }
297     break;
298 doda 6959 }
299 doda 6960
300 doda 6959 tr.SubOptCount = 0;
301     TelStatus = TelIdle;
302     return ;
303 doda 6962
304 doda 6959 /* case IAC: braek; */
305     default:
306     if (tr.SubOptCount >= sizeof(tr.SubOptBuff)-1) {
307     tr.SubOptCount = 0;
308     TelStatus = TelIdle;
309     return;
310     }
311     else {
312     tr.SubOptBuff[tr.SubOptCount] = IAC;
313     tr.SubOptCount++;
314     if (b==IAC) {
315     tr.SubOptIAC = TRUE;
316     return;
317     }
318     }
319     }
320 maya 3227 }
321 doda 6959 else if (b==IAC) {
322     tr.SubOptIAC = TRUE;
323     return;
324 maya 3227 }
325 doda 6959
326     if (tr.SubOptCount >= sizeof(tr.SubOptBuff)-1) {
327     tr.SubOptCount = 0;
328     tr.SubOptIAC = FALSE;
329     TelStatus = TelIdle;
330 maya 3227 }
331     else {
332 doda 6959 tr.SubOptBuff[tr.SubOptCount] = b;
333     tr.SubOptCount++;
334 maya 3227 }
335     }
336    
337     void ParseTelWill(BYTE b)
338     {
339 doda 6961 if (b <= MaxTelOpt) {
340     switch (tr.HisOpt[b].Status) {
341     case No:
342     if (tr.HisOpt[b].Accept) {
343     SendBack(DOTEL, b);
344     tr.HisOpt[b].Status = Yes;
345     }
346     else {
347     SendBack(DONTTEL, b);
348     }
349     break;
350 doda 6435
351 doda 6961 case WantNo:
352     switch (tr.HisOpt[b].Que) {
353     case Empty:
354     tr.HisOpt[b].Status = No;
355     break;
356     case Opposite:
357     tr.HisOpt[b].Status = Yes;
358     break;
359     }
360     break;
361 maya 3227
362 doda 6961 case WantYes:
363     switch (tr.HisOpt[b].Que) {
364     case Empty:
365     tr.HisOpt[b].Status = Yes;
366     break;
367     case Opposite:
368     tr.HisOpt[b].Status = WantNo;
369     tr.HisOpt[b].Que = Empty;
370     SendBack(DONTTEL, b);
371     break;
372     }
373     break;
374     }
375 maya 3227 }
376 doda 6961 else {
377     SendBack(DONTTEL, b);
378     }
379 maya 3227
380 doda 6961 switch (b) {
381     case ECHO:
382     if (ts.TelEcho) {
383     switch (tr.HisOpt[ECHO].Status) {
384     case Yes:
385     ts.LocalEcho = 0;
386     break;
387     case No:
388     ts.LocalEcho = 1;
389     break;
390     }
391     }
392     if (tr.HisOpt[ECHO].Status == Yes) {
393     cv.TelLineMode = FALSE;
394     }
395     break;
396    
397     case SGA:
398     if (tr.HisOpt[SGA].Status == Yes) {
399     cv.TelLineMode = FALSE;
400     }
401     break;
402    
403     case BINARY:
404     switch (tr.HisOpt[BINARY].Status) {
405     case Yes:
406     cv.TelBinRecv = TRUE;
407     break;
408     case No:
409     cv.TelBinRecv = FALSE;
410     break;
411     }
412     break;
413 maya 3227 }
414 doda 6961 TelStatus = TelIdle;
415 maya 3227 }
416    
417     void ParseTelWont(BYTE b)
418     {
419 doda 6961 if (b <= MaxTelOpt) {
420     switch (tr.HisOpt[b].Status) {
421     case Yes:
422     tr.HisOpt[b].Status = No;
423     SendBack(DONTTEL, b);
424     break;
425 maya 3227
426 doda 6961 case WantNo:
427     switch (tr.HisOpt[b].Que) {
428     case Empty:
429     tr.HisOpt[b].Status = No;
430     break;
431     case Opposite:
432     tr.HisOpt[b].Status = WantYes;
433     tr.HisOpt[b].Que = Empty;
434     SendBack(DOTEL, b);
435     break;
436     }
437     break;
438 maya 3227
439 doda 6961 case WantYes:
440     switch (tr.HisOpt[b].Que) {
441     case Empty:
442     tr.HisOpt[b].Status = No;
443     break;
444     case Opposite:
445     tr.HisOpt[b].Status = No;
446     tr.HisOpt[b].Que = Empty;
447     break;
448     }
449     break;
450     }
451 maya 3227 }
452 doda 6961 else {
453     SendBack(DONTTEL, b);
454     }
455 maya 3227
456 doda 6961 switch (b) {
457     case ECHO:
458     if (ts.TelEcho) {
459     switch (tr.HisOpt[ECHO].Status) {
460     case Yes:
461     ts.LocalEcho = 0;
462     break;
463     case No:
464     ts.LocalEcho = 1;
465     break;
466     }
467     }
468     if (tr.HisOpt[ECHO].Status == Yes) {
469     cv.TelLineMode = FALSE;
470     }
471     break;
472    
473     case BINARY:
474     switch (tr.HisOpt[BINARY].Status) {
475     case Yes:
476     cv.TelBinRecv = TRUE;
477     break;
478     case No:
479     cv.TelBinRecv = FALSE;
480     break;
481     }
482     break;
483 maya 3227 }
484 doda 6961 TelStatus = TelIdle;
485 maya 3227 }
486    
487     void ParseTelDo(BYTE b)
488     {
489 doda 6961 if (b <= MaxTelOpt) {
490     switch (tr.MyOpt[b].Status) {
491     case No:
492     if (tr.MyOpt[b].Accept) {
493     tr.MyOpt[b].Status = Yes;
494     SendBack(WILLTEL, b);
495     }
496     else {
497     SendBack(WONTTEL, b);
498     }
499     break;
500 maya 3227
501 doda 6961 case WantNo:
502     switch (tr.MyOpt[b].Que) {
503     case Empty:
504     tr.MyOpt[b].Status = No;
505     break;
506     case Opposite:
507     tr.MyOpt[b].Status = Yes;
508     break;
509     }
510     break;
511    
512     case WantYes:
513     switch (tr.MyOpt[b].Que) {
514     case Empty:
515     tr.MyOpt[b].Status = Yes;
516     break;
517     case Opposite:
518     tr.MyOpt[b].Status = WantNo;
519     tr.MyOpt[b].Que = Empty;
520     SendBack(WONTTEL, b);
521     break;
522     }
523     break;
524     }
525 maya 3227 }
526 doda 6961 else {
527     SendBack(WONTTEL, b);
528     }
529 maya 3227
530 doda 6961 switch (b) {
531     case BINARY:
532     switch (tr.MyOpt[BINARY].Status) {
533     case Yes:
534     cv.TelBinSend = TRUE;
535     break;
536     case No:
537     cv.TelBinSend = FALSE;
538     break;
539     }
540     break;
541    
542     case NAWS:
543     if (tr.MyOpt[NAWS].Status==Yes)
544     SendWinSize();
545     break;
546    
547     case SGA:
548     if (tr.MyOpt[SGA].Status==Yes)
549     cv.TelLineMode = FALSE;
550     break;
551 maya 3227 }
552 doda 6961 TelStatus = TelIdle;
553 maya 3227 }
554    
555     void ParseTelDont(BYTE b)
556     {
557 doda 6961 if (b <= MaxTelOpt) {
558     switch (tr.MyOpt[b].Status) {
559     case Yes:
560     tr.MyOpt[b].Status = No;
561     SendBack(WONTTEL, b);
562     break;
563 maya 3227
564 doda 6961 case WantNo:
565     switch (tr.MyOpt[b].Que) {
566     case Empty:
567     tr.MyOpt[b].Status = No;
568     break;
569     case Opposite:
570     tr.MyOpt[b].Status = WantYes;
571     tr.MyOpt[b].Que = Empty;
572     SendBack(WILLTEL, b);
573     break;
574     }
575     break;
576    
577     case WantYes:
578     switch (tr.MyOpt[b].Que) {
579     case Empty:
580     tr.MyOpt[b].Status = No;
581     break;
582     case Opposite:
583     tr.MyOpt[b].Status = No;
584     tr.MyOpt[b].Que = Empty;
585     break;
586     }
587     break;
588     }
589 maya 3227 }
590 doda 6961 else {
591     SendBack(WONTTEL, b);
592     }
593 maya 3227
594 doda 6961 switch (b) {
595     case BINARY:
596     switch (tr.MyOpt[BINARY].Status) {
597     case Yes:
598     cv.TelBinSend = TRUE;
599     break;
600     case No:
601     cv.TelBinSend = FALSE;
602     break;
603     }
604     break;
605 maya 3227 }
606 doda 6961 TelStatus = TelIdle;
607 maya 3227 }
608    
609     void ParseTel(BOOL *Size, int *nx, int *ny)
610     {
611 doda 6961 BYTE b;
612     int c;
613 maya 3227
614 doda 6961 c = CommReadRawByte(&cv, &b);
615 maya 3227
616 doda 6961 while ((c>0) && (cv.TelMode)) {
617     if (tr.LogFile) {
618     if (TelStatus==TelIAC) {
619     _lwrite(tr.LogFile, "\015\012<", 3);
620     TelWriteLog1(0xff);
621     }
622     TelWriteLog1(b);
623     }
624 maya 3227
625 doda 6961 tr.ChangeWinSize = FALSE;
626 maya 3227
627 doda 6961 switch (TelStatus) {
628     case TelIAC: ParseTelIAC(b); break;
629     case TelSB: ParseTelSB(b); break;
630     case TelWill: ParseTelWill(b); break;
631     case TelWont: ParseTelWont(b); break;
632     case TelDo: ParseTelDo(b); break;
633     case TelDont: ParseTelDont(b); break;
634     case TelNop: TelStatus = TelIdle; break;
635     }
636     if (TelStatus == TelIdle) cv.TelMode = FALSE;
637 maya 3227
638 doda 6961 if (cv.TelMode) c = CommReadRawByte(&cv, &b);
639     }
640 maya 3227
641 doda 6961 *Size = tr.ChangeWinSize;
642     *nx = tr.WinSize.x;
643     *ny = tr.WinSize.x;
644 maya 3227 }
645    
646     void TelEnableHisOpt(BYTE b)
647     {
648 doda 6961 if (b <= MaxTelOpt) {
649     switch (tr.HisOpt[b].Status) {
650     case No:
651     tr.HisOpt[b].Status = WantYes;
652     SendBack(DOTEL, b);
653     break;
654 maya 3227
655 doda 6961 case WantNo:
656     if (tr.HisOpt[b].Que==Empty)
657     tr.HisOpt[b].Que = Opposite;
658     break;
659 maya 3227
660 doda 6961 case WantYes:
661     if (tr.HisOpt[b].Que==Opposite)
662     tr.HisOpt[b].Que = Empty;
663     break;
664     }
665     }
666 maya 3227 }
667    
668     void TelDisableHisOpt(BYTE b)
669     {
670 doda 6961 if (b <= MaxTelOpt) {
671     switch (tr.HisOpt[b].Status) {
672     case Yes:
673     tr.HisOpt[b].Status = WantNo;
674     SendBack(DONTTEL, b);
675     break;
676 maya 3227
677 doda 6961 case WantNo:
678     if (tr.HisOpt[b].Que==Opposite)
679     tr.HisOpt[b].Que = Empty;
680     break;
681 maya 3227
682 doda 6961 case WantYes:
683     if (tr.HisOpt[b].Que==Empty)
684     tr.HisOpt[b].Que = Opposite;
685     break;
686     }
687     }
688 maya 3227 }
689    
690     void TelEnableMyOpt(BYTE b)
691     {
692 doda 6961 if (b <= MaxTelOpt) {
693     switch (tr.MyOpt[b].Status) {
694     case No:
695     tr.MyOpt[b].Status = WantYes;
696     SendBack(WILLTEL, b);
697     break;
698 maya 3227
699 doda 6961 case WantNo:
700     if (tr.MyOpt[b].Que==Empty)
701     tr.MyOpt[b].Que = Opposite;
702     break;
703 maya 3227
704 doda 6961 case WantYes:
705     if (tr.MyOpt[b].Que==Opposite)
706     tr.MyOpt[b].Que = Empty;
707     break;
708     }
709     }
710 maya 3227 }
711    
712     void TelDisableMyOpt(BYTE b)
713     {
714 doda 6961 if (b <= MaxTelOpt) {
715     switch (tr.MyOpt[b].Status) {
716     case Yes:
717     tr.MyOpt[b].Status = WantNo;
718     SendBack(WONTTEL, b);
719     break;
720 maya 3227
721 doda 6961 case WantNo:
722     if (tr.MyOpt[b].Que==Opposite)
723     tr.MyOpt[b].Que = Empty;
724     break;
725 maya 3227
726 doda 6961 case WantYes:
727     if (tr.MyOpt[b].Que==Empty)
728     tr.MyOpt[b].Que = Opposite;
729     break;
730     }
731     }
732 maya 3227 }
733    
734     void TelInformWinSize(int nx, int ny)
735     {
736 doda 6961 if ((tr.MyOpt[NAWS].Status==Yes) &&
737     (nx != tr.WinSize.x || ny != tr.WinSize.y))
738     {
739     tr.WinSize.x = nx;
740     tr.WinSize.y = ny;
741     SendWinSize();
742     }
743 maya 3227 }
744    
745     void TelSendAYT()
746     {
747 doda 6961 BYTE Str[2];
748 maya 3227
749 doda 6961 Str[0] = IAC;
750     Str[1] = AYT;
751     CommRawOut(&cv, Str, 2);
752     CommSend(&cv);
753     if (tr.LogFile)
754     TelWriteLog(Str, 2);
755 maya 3227 }
756    
757     void TelSendBreak()
758     {
759 doda 6961 BYTE Str[2];
760 maya 3227
761 doda 6961 Str[0] = IAC;
762     Str[1] = BREAK;
763     CommRawOut(&cv, Str, 2);
764     CommSend(&cv);
765     if (tr.LogFile)
766     TelWriteLog(Str, 2);
767 maya 3227 }
768    
769     void TelChangeEcho()
770     {
771 doda 6961 if (ts.LocalEcho==0)
772     TelEnableHisOpt(ECHO);
773     else
774     TelDisableHisOpt(ECHO);
775 maya 3227 }
776    
777     void TelSendNOP()
778     {
779 doda 6961 BYTE Str[2];
780 maya 3227
781 doda 6961 Str[0] = IAC;
782     Str[1] = NOP;
783     CommRawOut(&cv, Str, 2);
784     CommSend(&cv);
785     if (tr.LogFile)
786     TelWriteLog(Str, 2);
787 maya 3227 }
788    
789     #define WM_SEND_HEARTBEAT (WM_USER + 1)
790    
791     static LRESULT CALLBACK telnet_heartbeat_dlg_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
792     {
793     switch (msg) {
794 doda 6961 case WM_INITDIALOG:
795     return FALSE;
796 maya 3227
797 doda 6961 case WM_SEND_HEARTBEAT:
798     TelSendNOP();
799     return TRUE;
800     break;
801 maya 3227
802 doda 6961 case WM_COMMAND:
803     switch (LOWORD(wp)) {
804     case IDOK:
805 maya 3227 return TRUE;
806 doda 6961 case IDCANCEL:
807     EndDialog(hWnd, 0);
808 maya 3227 return TRUE;
809     default:
810     return FALSE;
811 doda 6961 }
812     break;
813    
814     case WM_CLOSE:
815     // close�{�^���������������� window ���������������������B
816     return TRUE;
817    
818     case WM_DESTROY:
819     return TRUE;
820    
821     default:
822     return FALSE;
823 maya 3227 }
824     return TRUE;
825     }
826    
827    
828     static unsigned _stdcall TelKeepAliveThread(void *dummy) {
829 doda 6961 static int instance = 0;
830 maya 3227
831 doda 6961 if (instance > 0)
832     return 0;
833     instance++;
834 maya 3227
835 doda 6961 while (cv.Open && nop_interval > 0) {
836     if (time(NULL) >= cv.LastSendTime + nop_interval) {
837     SendMessage(keepalive_dialog, WM_SEND_HEARTBEAT, 0, 0);
838     }
839 maya 3227
840 doda 6961 Sleep(100);
841     }
842     instance--;
843     return 0;
844 maya 3227 }
845    
846     void TelStartKeepAliveThread() {
847 doda 6961 unsigned tid;
848 maya 3227
849 doda 6961 if (ts.TelKeepAliveInterval > 0) {
850     nop_interval = ts.TelKeepAliveInterval;
851 maya 3227
852     // ���[�h���X�_�C�A���O������ (2007.12.26 yutaka)
853     keepalive_dialog = CreateDialog(hInst, MAKEINTRESOURCE(IDD_BROADCAST_DIALOG),
854 doda 6961 HVTWin, (DLGPROC)telnet_heartbeat_dlg_proc);
855 maya 3227
856 doda 6961 keepalive_thread = (HANDLE)_beginthreadex(NULL, 0, TelKeepAliveThread, NULL, 0, &tid);
857     if (keepalive_thread == (HANDLE)-1) {
858     nop_interval = 0;
859     }
860     }
861 maya 3227 }
862    
863     void TelStopKeepAliveThread() {
864 doda 6961 if (keepalive_thread != (HANDLE)-1L) {
865     nop_interval = 0;
866     WaitForSingleObject(keepalive_thread, INFINITE);
867     CloseHandle(keepalive_thread);
868     keepalive_thread = (HANDLE)-1L;
869 maya 3227
870 doda 6961 DestroyWindow(keepalive_dialog);
871     }
872 maya 3227 }
873    
874     void TelUpdateKeepAliveInterval() {
875 doda 6961 if (cv.Open && cv.TelFlag && ts.TCPPort==ts.TelPort) {
876     if (ts.TelKeepAliveInterval > 0 && keepalive_thread == (HANDLE)-1)
877     TelStartKeepAliveThread();
878     else if (ts.TelKeepAliveInterval == 0 && keepalive_thread != (HANDLE)-1)
879     TelStopKeepAliveThread();
880     else
881     nop_interval = ts.TelKeepAliveInterval;
882     }
883 maya 3227 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26