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 6959 - (hide annotations) (download) (as text)
Tue Oct 24 17:53:30 2017 UTC (6 years, 5 months ago) by doda
File MIME type: text/x-csrc
File size: 17331 byte(s)
インデント修正
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     BOOL Accept;
52     enum OptStatus Status;
53     enum OptQue Que;
54     } TelOpt;
55     typedef TelOpt *PTelOpt;
56    
57     typedef struct {
58     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     } 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     int i;
78    
79     for (i=0 ; i <= MaxTelOpt ; i++)
80     {
81     tr.MyOpt[i].Accept = FALSE;
82     tr.MyOpt[i].Status = No;
83     tr.MyOpt[i].Que = Empty;
84     tr.HisOpt[i].Accept = FALSE;
85     tr.HisOpt[i].Status = No;
86     tr.HisOpt[i].Que = Empty;
87     }
88    
89     tr.SubOptCount = 0;
90     tr.SubOptIAC = FALSE;
91     tr.ChangeWinSize = FALSE;
92     }
93    
94     void InitTelnet()
95     {
96     TelStatus = TelIdle;
97    
98     DefaultTelRec();
99     tr.MyOpt[BINARY].Accept = TRUE;
100     tr.HisOpt[BINARY].Accept = TRUE;
101     tr.MyOpt[SGA].Accept = TRUE;
102     tr.HisOpt[SGA].Accept = TRUE;
103     tr.HisOpt[ECHO].Accept = TRUE;
104     tr.MyOpt[TERMTYPE].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    
110     if ((ts.LogFlag & LOG_TEL) != 0)
111     tr.LogFile = _lcreat("TELNET.LOG",0);
112     else
113     tr.LogFile = 0;
114     }
115    
116     void EndTelnet()
117     {
118     if (tr.LogFile != 0)
119     {
120     tr.LogFile = 0;
121     _lclose(tr.LogFile);
122     }
123    
124     TelStopKeepAliveThread();
125     }
126    
127     void TelWriteLog1(BYTE b)
128     {
129     BYTE Temp[3];
130     BYTE Ch;
131    
132     Temp[0] = 0x20;
133     Ch = b / 16;
134     if (Ch <= 9)
135     Ch = Ch + 0x30;
136     else
137     Ch = Ch + 0x37;
138     Temp[1] = Ch;
139    
140     Ch = b & 15;
141     if (Ch <= 9)
142     Ch = Ch + 0x30;
143     else
144     Ch = Ch + 0x37;
145     Temp[2] = Ch;
146     _lwrite(tr.LogFile,Temp,3);
147     }
148    
149     void TelWriteLog(PCHAR Buf, int C)
150     {
151     int i;
152    
153     _lwrite(tr.LogFile,"\015\012>",3);
154     for (i = 0 ; i<= C-1 ; i++)
155     TelWriteLog1(Buf[i]);
156     }
157    
158     void SendBack(BYTE a, BYTE b)
159     {
160     BYTE Str3[3];
161    
162     Str3[0] = IAC;
163     Str3[1] = a;
164     Str3[2] = b;
165     CommRawOut(&cv,Str3,3);
166     if (tr.LogFile!=0)
167     TelWriteLog(Str3,3);
168     }
169    
170     void SendWinSize()
171     {
172     int i;
173     BYTE TmpBuff[21];
174    
175     i = 0;
176    
177     TmpBuff[i] = IAC;
178     i++;
179     TmpBuff[i] = SB;
180     i++;
181     TmpBuff[i] = NAWS;
182     i++;
183     TmpBuff[i] = HIBYTE(tr.WinSize.x);
184     i++;
185     /* if (LOBYTE(tr.WinSize.x) == IAC)
186     {
187     tr.SendBackBuff[i] = IAC;
188     i++;
189     } */
190     TmpBuff[i] = LOBYTE(tr.WinSize.x);
191     i++;
192     TmpBuff[i] = HIBYTE(tr.WinSize.y);
193     i++;
194     /* if (LOBYTE(tr.WinSize.y) == IAC)
195     {
196     tr.SendBackBuff[i] = IAC;
197     i++;
198     } */
199     TmpBuff[i] = LOBYTE(tr.WinSize.y);
200     i++;
201     TmpBuff[i] = IAC;
202     i++;
203     TmpBuff[i]= SE;
204     i++;
205    
206     CommRawOut(&cv,TmpBuff,i);
207     if (tr.LogFile!=0)
208     TelWriteLog(TmpBuff,i);
209     }
210    
211     void ParseTelIAC(BYTE b)
212     {
213     switch (b) {
214     case SE: break;
215     case NOP:
216     case DM:
217     case BREAK:
218     case IP:
219     case AO:
220     case AYT:
221     case EC:
222     case EL:
223     case GOAHEAD:
224     TelStatus = TelIdle;
225     break;
226     case SB:
227     TelStatus = TelSB;
228     tr.SubOptCount = 0;
229     break;
230     case WILLTEL:
231     TelStatus = TelWill;
232     break;
233     case WONTTEL:
234     TelStatus = TelWont;
235     break;
236     case DOTEL:
237     TelStatus = TelDo;
238     break;
239     case DONTTEL:
240     TelStatus = TelDont;
241     break;
242     case IAC:
243     TelStatus = TelIdle;
244     break;
245     default:
246     TelStatus = TelIdle;
247     }
248     }
249    
250     void ParseTelSB(BYTE b)
251     {
252 doda 6959 BYTE TmpStr[51];
253     int i;
254 maya 3227
255 doda 6959 if (tr.SubOptIAC) {
256     tr.SubOptIAC = FALSE;
257     switch (b) {
258     case SE:
259     if ((tr.MyOpt[TERMTYPE].Status == Yes) &&
260     (tr.SubOptCount >= 2) &&
261     (tr.SubOptBuff[0] == TERMTYPE) &&
262     (tr.SubOptBuff[1] == 1))
263     {
264 maya 3227 #if 1
265 doda 6959 _snprintf_s(TmpStr, sizeof(TmpStr), _TRUNCATE, "%c%c%c%c%s%c%c",
266     IAC, SB, TERMTYPE, 0, ts.TermType, IAC, SE);
267     // 4 �o�C�g���� 0 �����������A������������������
268     i = strlen(TmpStr + 4) + 4;
269 maya 3227 #else
270 doda 6959 TmpStr[0] = IAC;
271     TmpStr[1] = SB;
272     TmpStr[2] = TERMTYPE;
273     TmpStr[3] = 0;
274     strcpy(&TmpStr[4],ts.TermType);
275     i = 4 + strlen(ts.TermType);
276     TmpStr[i] = IAC;
277     i++;
278     TmpStr[i] = SE;
279     i++;
280 maya 3227 #endif
281 doda 6959 CommRawOut(&cv,TmpStr,i);
282 maya 3227
283 doda 6959 if (tr.LogFile!=0)
284     TelWriteLog(TmpStr,i);
285     }
286     else if ( /* (tr.HisOpt[NAWS].Status == Yes) && */
287     (tr.SubOptCount >= 5) &&
288     (tr.SubOptBuff[0] == NAWS))
289     {
290     tr.WinSize.x = tr.SubOptBuff[1]*256+ tr.SubOptBuff[2];
291     tr.WinSize.y = tr.SubOptBuff[3]*256+ 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     tr.SubOptCount = 0;
301     TelStatus = TelIdle;
302     return;
303     }
304     else {
305     tr.SubOptBuff[tr.SubOptCount] = IAC;
306     tr.SubOptCount++;
307     if (b==IAC) {
308     tr.SubOptIAC = TRUE;
309     return;
310     }
311     }
312     }
313 maya 3227 }
314 doda 6959 else if (b==IAC) {
315     tr.SubOptIAC = TRUE;
316     return;
317 maya 3227 }
318 doda 6959
319     if (tr.SubOptCount >= sizeof(tr.SubOptBuff)-1) {
320     tr.SubOptCount = 0;
321     tr.SubOptIAC = FALSE;
322     TelStatus = TelIdle;
323 maya 3227 }
324     else {
325 doda 6959 tr.SubOptBuff[tr.SubOptCount] = b;
326     tr.SubOptCount++;
327 maya 3227 }
328     }
329    
330     void ParseTelWill(BYTE b)
331     {
332     if (b <= MaxTelOpt)
333     {
334     switch (tr.HisOpt[b].Status) {
335     case No:
336     if (tr.HisOpt[b].Accept)
337     {
338     SendBack(DOTEL,b);
339     tr.HisOpt[b].Status = Yes;
340     }
341     else
342     SendBack(DONTTEL,b);
343     break;
344 doda 6435
345 maya 3227 case WantNo:
346     switch (tr.HisOpt[b].Que) {
347     case Empty:
348     tr.HisOpt[b].Status = No;
349     break;
350     case Opposite:
351     tr.HisOpt[b].Status = Yes;
352     break;
353     }
354     break;
355    
356     case WantYes:
357     switch (tr.HisOpt[b].Que) {
358     case Empty:
359     tr.HisOpt[b].Status = Yes;
360     break;
361     case Opposite:
362     tr.HisOpt[b].Status = WantNo;
363     tr.HisOpt[b].Que = Empty;
364     SendBack(DONTTEL,b);
365     break;
366     }
367     break;
368     }
369     }
370     else
371     SendBack(DONTTEL,b);
372    
373     switch (b) {
374     case ECHO:
375     if (ts.TelEcho>0)
376     switch (tr.HisOpt[ECHO].Status) {
377     case Yes:
378     ts.LocalEcho = 0;
379     break;
380     case No:
381     ts.LocalEcho = 1;
382     break;
383     }
384 doda 3531 if (tr.HisOpt[ECHO].Status == Yes) {
385     cv.TelLineMode = FALSE;
386     }
387 maya 3227 break;
388 doda 3530 case SGA:
389     if (tr.HisOpt[SGA].Status == Yes) {
390     cv.TelLineMode = FALSE;
391     }
392     break;
393 maya 3227 case BINARY:
394     switch (tr.HisOpt[BINARY].Status) {
395     case Yes:
396     cv.TelBinRecv = TRUE;
397     break;
398     case No:
399     cv.TelBinRecv = FALSE;
400     break;
401     }
402     break;
403     }
404     TelStatus = TelIdle;
405     }
406    
407     void ParseTelWont(BYTE b)
408     {
409     if (b <= MaxTelOpt)
410     {
411     switch (tr.HisOpt[b].Status) {
412     case Yes:
413     tr.HisOpt[b].Status = No;
414     SendBack(DONTTEL,b);
415     break;
416    
417     case WantNo:
418     switch (tr.HisOpt[b].Que) {
419     case Empty:
420     tr.HisOpt[b].Status = No;
421     break;
422     case Opposite:
423     tr.HisOpt[b].Status = WantYes;
424     tr.HisOpt[b].Que = Empty;
425     SendBack(DOTEL,b);
426     break;
427     }
428     break;
429    
430     case WantYes:
431     switch (tr.HisOpt[b].Que) {
432     case Empty:
433     tr.HisOpt[b].Status = No;
434     break;
435     case Opposite:
436     tr.HisOpt[b].Status = No;
437     tr.HisOpt[b].Que = Empty;
438     break;
439     }
440     break;
441     }
442     }
443     else
444     SendBack(DONTTEL,b);
445    
446     switch (b) {
447     case ECHO:
448     if (ts.TelEcho>0)
449     switch (tr.HisOpt[ECHO].Status) {
450     case Yes:
451     ts.LocalEcho = 0;
452     break;
453     case No:
454     ts.LocalEcho = 1;
455     break;
456     }
457     break;
458 doda 3531 if (tr.HisOpt[ECHO].Status == Yes) {
459     cv.TelLineMode = FALSE;
460     }
461 maya 3227 case BINARY:
462     switch (tr.HisOpt[BINARY].Status) {
463     case Yes:
464     cv.TelBinRecv = TRUE;
465     break;
466     case No:
467     cv.TelBinRecv = FALSE;
468     break;
469     }
470     break;
471     }
472     TelStatus = TelIdle;
473     }
474    
475     void ParseTelDo(BYTE b)
476     {
477     if (b <= MaxTelOpt)
478     {
479     switch (tr.MyOpt[b].Status) {
480     case No:
481     if (tr.MyOpt[b].Accept)
482     {
483     tr.MyOpt[b].Status = Yes;
484     SendBack(WILLTEL,b);
485     }
486     else
487     SendBack(WONTTEL,b);
488     break;
489    
490     case WantNo:
491     switch (tr.MyOpt[b].Que) {
492     case Empty:
493     tr.MyOpt[b].Status = No;
494     break;
495     case Opposite:
496     tr.MyOpt[b].Status = Yes;
497     break;
498     }
499     break;
500    
501     case WantYes:
502     switch (tr.MyOpt[b].Que) {
503     case Empty:
504     tr.MyOpt[b].Status = Yes;
505     break;
506     case Opposite:
507     tr.MyOpt[b].Status = WantNo;
508     tr.MyOpt[b].Que = Empty;
509     SendBack(WONTTEL,b);
510     break;
511     }
512     break;
513     }
514     }
515     else
516     SendBack(WONTTEL,b);
517    
518     switch (b) {
519     case BINARY:
520     switch (tr.MyOpt[BINARY].Status) {
521     case Yes:
522     cv.TelBinSend = TRUE;
523     break;
524     case No:
525     cv.TelBinSend = FALSE;
526     break;
527     }
528     break;
529     case NAWS:
530     if (tr.MyOpt[NAWS].Status==Yes)
531     SendWinSize();
532     break;
533 doda 3494 case SGA:
534     if (tr.MyOpt[SGA].Status==Yes)
535     cv.TelLineMode = FALSE;
536     break;
537 maya 3227 }
538     TelStatus = TelIdle;
539     }
540    
541     void ParseTelDont(BYTE b)
542     {
543     if (b <= MaxTelOpt)
544     {
545     switch (tr.MyOpt[b].Status) {
546     case Yes:
547     tr.MyOpt[b].Status = No;
548     SendBack(WONTTEL,b);
549     break;
550    
551     case WantNo:
552     switch (tr.MyOpt[b].Que) {
553     case Empty:
554     tr.MyOpt[b].Status = No;
555     break;
556     case Opposite:
557     tr.MyOpt[b].Status = WantYes;
558     tr.MyOpt[b].Que = Empty;
559     SendBack(WILLTEL,b);
560     break;
561     }
562     break;
563    
564     case WantYes:
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 = No;
571     tr.MyOpt[b].Que = Empty;
572     break;
573     }
574     break;
575     }
576     }
577     else
578     SendBack(WONTTEL,b);
579    
580     switch (b) {
581     case BINARY:
582     switch (tr.MyOpt[BINARY].Status) {
583     case Yes:
584     cv.TelBinSend = TRUE;
585     break;
586     case No:
587     cv.TelBinSend = FALSE;
588     break;
589     }
590     break;
591     }
592     TelStatus = TelIdle;
593     }
594    
595     void ParseTel(BOOL *Size, int *nx, int *ny)
596     {
597     BYTE b;
598     int c;
599    
600     c = CommReadRawByte(&cv,&b);
601    
602     while ((c>0) && (cv.TelMode))
603     {
604     if (tr.LogFile!=0)
605     {
606     if (TelStatus==TelIAC)
607     {
608     _lwrite(tr.LogFile,"\015\012<",3);
609     TelWriteLog1(0xff);
610     }
611     TelWriteLog1(b);
612     }
613    
614     tr.ChangeWinSize = FALSE;
615    
616     switch (TelStatus) {
617     case TelIAC: ParseTelIAC(b); break;
618     case TelSB: ParseTelSB(b); break;
619     case TelWill: ParseTelWill(b); break;
620     case TelWont: ParseTelWont(b); break;
621     case TelDo: ParseTelDo(b); break;
622     case TelDont: ParseTelDont(b); break;
623     case TelNop: TelStatus = TelIdle; break;
624     }
625     if (TelStatus == TelIdle) cv.TelMode = FALSE;
626    
627     if (cv.TelMode) c = CommReadRawByte(&cv,&b);
628     }
629    
630     *Size = tr.ChangeWinSize;
631     *nx = tr.WinSize.x;
632     *ny = tr.WinSize.x;
633     }
634    
635     void TelEnableHisOpt(BYTE b)
636     {
637     if (b <= MaxTelOpt)
638     {
639     switch (tr.HisOpt[b].Status) {
640     case No:
641     tr.HisOpt[b].Status = WantYes;
642     SendBack(DOTEL,b);
643     break;
644    
645     case WantNo:
646     if (tr.HisOpt[b].Que==Empty)
647     tr.HisOpt[b].Que = Opposite;
648     break;
649    
650     case WantYes:
651     if (tr.HisOpt[b].Que==Opposite)
652     tr.HisOpt[b].Que = Empty;
653     break;
654     }
655     }
656     }
657    
658     void TelDisableHisOpt(BYTE b)
659     {
660     if (b <= MaxTelOpt)
661     {
662     switch (tr.HisOpt[b].Status) {
663     case Yes:
664     tr.HisOpt[b].Status = WantNo;
665     SendBack(DONTTEL,b);
666     break;
667    
668     case WantNo:
669     if (tr.HisOpt[b].Que==Opposite)
670     tr.HisOpt[b].Que = Empty;
671     break;
672    
673     case WantYes:
674     if (tr.HisOpt[b].Que==Empty)
675     tr.HisOpt[b].Que = Opposite;
676     break;
677     }
678     }
679     }
680    
681     void TelEnableMyOpt(BYTE b)
682     {
683     if (b <= MaxTelOpt)
684     {
685     switch (tr.MyOpt[b].Status) {
686     case No:
687     tr.MyOpt[b].Status = WantYes;
688     SendBack(WILLTEL,b);
689     break;
690    
691     case WantNo:
692     if (tr.MyOpt[b].Que==Empty)
693     tr.MyOpt[b].Que = Opposite;
694     break;
695    
696     case WantYes:
697     if (tr.MyOpt[b].Que==Opposite)
698     tr.MyOpt[b].Que = Empty;
699     break;
700     }
701     }
702     }
703    
704     void TelDisableMyOpt(BYTE b)
705     {
706     if (b <= MaxTelOpt)
707     {
708     switch (tr.MyOpt[b].Status) {
709     case Yes:
710     tr.MyOpt[b].Status = WantNo;
711     SendBack(WONTTEL,b);
712     break;
713    
714     case WantNo:
715     if (tr.MyOpt[b].Que==Opposite)
716     tr.MyOpt[b].Que = Empty;
717     break;
718    
719     case WantYes:
720     if (tr.MyOpt[b].Que==Empty)
721     tr.MyOpt[b].Que = Opposite;
722     break;
723     }
724     }
725     }
726    
727     void TelInformWinSize(int nx, int ny)
728     {
729     if ((tr.MyOpt[NAWS].Status==Yes) &&
730     ((nx!=tr.WinSize.x) ||
731     (ny!=tr.WinSize.y)))
732     {
733     tr.WinSize.x = nx;
734     tr.WinSize.y = ny;
735     SendWinSize();
736     }
737     }
738    
739     void TelSendAYT()
740     {
741     BYTE Str[2];
742    
743     Str[0] = IAC;
744     Str[1] = AYT;
745     CommRawOut(&cv,Str,2);
746     CommSend(&cv);
747     if (tr.LogFile!=0)
748     TelWriteLog(Str,2);
749     }
750    
751     void TelSendBreak()
752     {
753     BYTE Str[2];
754    
755     Str[0] = IAC;
756     Str[1] = BREAK;
757     CommRawOut(&cv,Str,2);
758     CommSend(&cv);
759     if (tr.LogFile!=0)
760     TelWriteLog(Str,2);
761     }
762    
763     void TelChangeEcho()
764     {
765     if (ts.LocalEcho==0)
766     TelEnableHisOpt(ECHO);
767     else
768     TelDisableHisOpt(ECHO);
769     }
770    
771     void TelSendNOP()
772     {
773     BYTE Str[2];
774    
775     Str[0] = IAC;
776     Str[1] = NOP;
777     CommRawOut(&cv,Str,2);
778     CommSend(&cv);
779     if (tr.LogFile!=0)
780     TelWriteLog(Str,2);
781     }
782    
783     #define WM_SEND_HEARTBEAT (WM_USER + 1)
784    
785     static LRESULT CALLBACK telnet_heartbeat_dlg_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
786     {
787    
788     switch (msg) {
789     case WM_INITDIALOG:
790     return FALSE;
791    
792     case WM_SEND_HEARTBEAT:
793     TelSendNOP();
794     return TRUE;
795     break;
796    
797     case WM_COMMAND:
798     switch (wp) {
799     }
800    
801     switch (LOWORD(wp)) {
802     case IDOK:
803     {
804     return TRUE;
805     }
806    
807     case IDCANCEL:
808     EndDialog(hWnd, 0);
809     return TRUE;
810     default:
811     return FALSE;
812     }
813     break;
814    
815     case WM_CLOSE:
816     // close�{�^���������������� window ���������������������B
817     return TRUE;
818    
819     case WM_DESTROY:
820     return TRUE;
821    
822     default:
823     return FALSE;
824     }
825     return TRUE;
826     }
827    
828    
829     static unsigned _stdcall TelKeepAliveThread(void *dummy) {
830     static int instance = 0;
831    
832     if (instance > 0)
833     return 0;
834     instance++;
835    
836     while (cv.Open && nop_interval > 0) {
837     if (time(NULL) >= cv.LastSendTime + nop_interval) {
838     SendMessage(keepalive_dialog, WM_SEND_HEARTBEAT, 0, 0);
839     }
840    
841     Sleep(100);
842     }
843     instance--;
844     return 0;
845     }
846    
847     void TelStartKeepAliveThread() {
848     unsigned tid;
849    
850     if (ts.TelKeepAliveInterval > 0) {
851     nop_interval = ts.TelKeepAliveInterval;
852    
853     // ���[�h���X�_�C�A���O������ (2007.12.26 yutaka)
854     keepalive_dialog = CreateDialog(hInst, MAKEINTRESOURCE(IDD_BROADCAST_DIALOG),
855     HVTWin, (DLGPROC)telnet_heartbeat_dlg_proc);
856    
857     keepalive_thread = (HANDLE)_beginthreadex(NULL, 0, TelKeepAliveThread, NULL, 0, &tid);
858     if (keepalive_thread == (HANDLE)-1) {
859     nop_interval = 0;
860     }
861     }
862     }
863    
864     void TelStopKeepAliveThread() {
865     if (keepalive_thread != (HANDLE)-1L) {
866     nop_interval = 0;
867     WaitForSingleObject(keepalive_thread, INFINITE);
868     CloseHandle(keepalive_thread);
869     keepalive_thread = (HANDLE)-1L;
870    
871     DestroyWindow(keepalive_dialog);
872     }
873     }
874    
875     void TelUpdateKeepAliveInterval() {
876     if (cv.Open && cv.TelFlag && ts.TCPPort==ts.TelPort) {
877     if (ts.TelKeepAliveInterval > 0 && keepalive_thread == (HANDLE)-1)
878     TelStartKeepAliveThread();
879     else if (ts.TelKeepAliveInterval == 0 && keepalive_thread != (HANDLE)-1)
880     TelStopKeepAliveThread();
881     else
882     nop_interval = ts.TelKeepAliveInterval;
883     }
884     }

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