Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /branches/ttcomtester/teraterm/teraterm/telnet.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6806 - (hide annotations) (download) (as text)
Thu Jun 15 00:37:01 2017 UTC (6 years, 9 months ago) by doda
Original Path: trunk/teraterm/teraterm/telnet.c
File MIME type: text/x-csrc
File size: 17325 byte(s)
TeraTerm Project としてのライセンス表記を追加

とりあえず Tera Term 本体分。
TeraTerm Project としての copyright 表記の年部分はコミットログを確認して書いたつもりだけど、ミスってたらすみません。

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

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