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 6841 - (hide annotations) (download) (as text)
Tue Jul 4 15:02:28 2017 UTC (6 years, 9 months ago) by doda
File MIME type: text/x-csrc
File size: 17321 byte(s)
TeraTerm Project としてのライセンス表記を追加

・Tera Term 本体分を横 80 桁に収まるように改行位置を調整
・ttssh 関連の分を追加
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     BYTE TmpStr[51];
253     int i;
254    
255     if (tr.SubOptIAC)
256     {
257     tr.SubOptIAC = FALSE;
258     switch (b) {
259     case SE:
260     if ((tr.MyOpt[TERMTYPE].Status == Yes) &&
261     (tr.SubOptCount >= 2) &&
262     (tr.SubOptBuff[0] == TERMTYPE) &&
263     (tr.SubOptBuff[1] == 1))
264     {
265     #if 1
266     _snprintf_s(TmpStr, sizeof(TmpStr), _TRUNCATE, "%c%c%c%c%s%c%c", IAC, SB, TERMTYPE, 0, ts.TermType, IAC, SE);
267     // 4 �o�C�g���� 0 �����������A������������������
268     i = strlen(TmpStr + 4) + 4;
269     #else
270     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     #endif
281     CommRawOut(&cv,TmpStr,i);
282    
283     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+
291     tr.SubOptBuff[2];
292     tr.WinSize.y = tr.SubOptBuff[3]*256+
293     tr.SubOptBuff[4];
294     tr.ChangeWinSize = TRUE;
295     }
296     tr.SubOptCount = 0;
297     TelStatus = TelIdle;
298     return ;
299     /* case IAC: braek; */
300     default:
301     if (tr.SubOptCount >= sizeof(tr.SubOptBuff)-1)
302     {
303     tr.SubOptCount = 0;
304     TelStatus = TelIdle;
305     return;
306     }
307     else {
308     tr.SubOptBuff[tr.SubOptCount] = IAC;
309     tr.SubOptCount++;
310     if (b==IAC)
311     {
312     tr.SubOptIAC = TRUE;
313     return;
314     }
315     }
316     }
317     }
318     else
319     if (b==IAC)
320     {
321     tr.SubOptIAC = TRUE;
322     return;
323     }
324    
325     if (tr.SubOptCount >= sizeof(tr.SubOptBuff)-1)
326     {
327     tr.SubOptCount = 0;
328     tr.SubOptIAC = FALSE;
329     TelStatus = TelIdle;
330     }
331     else {
332     tr.SubOptBuff[tr.SubOptCount] = b;
333     tr.SubOptCount++;
334     }
335     }
336    
337     void ParseTelWill(BYTE b)
338     {
339     if (b <= MaxTelOpt)
340     {
341     switch (tr.HisOpt[b].Status) {
342     case No:
343     if (tr.HisOpt[b].Accept)
344     {
345     SendBack(DOTEL,b);
346     tr.HisOpt[b].Status = Yes;
347     }
348     else
349     SendBack(DONTTEL,b);
350     break;
351 doda 6435
352 maya 3227 case WantNo:
353     switch (tr.HisOpt[b].Que) {
354     case Empty:
355     tr.HisOpt[b].Status = No;
356     break;
357     case Opposite:
358     tr.HisOpt[b].Status = Yes;
359     break;
360     }
361     break;
362    
363     case WantYes:
364     switch (tr.HisOpt[b].Que) {
365     case Empty:
366     tr.HisOpt[b].Status = Yes;
367     break;
368     case Opposite:
369     tr.HisOpt[b].Status = WantNo;
370     tr.HisOpt[b].Que = Empty;
371     SendBack(DONTTEL,b);
372     break;
373     }
374     break;
375     }
376     }
377     else
378     SendBack(DONTTEL,b);
379    
380     switch (b) {
381     case ECHO:
382     if (ts.TelEcho>0)
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 doda 3531 if (tr.HisOpt[ECHO].Status == Yes) {
392     cv.TelLineMode = FALSE;
393     }
394 maya 3227 break;
395 doda 3530 case SGA:
396     if (tr.HisOpt[SGA].Status == Yes) {
397     cv.TelLineMode = FALSE;
398     }
399     break;
400 maya 3227 case BINARY:
401     switch (tr.HisOpt[BINARY].Status) {
402     case Yes:
403     cv.TelBinRecv = TRUE;
404     break;
405     case No:
406     cv.TelBinRecv = FALSE;
407     break;
408     }
409     break;
410     }
411     TelStatus = TelIdle;
412     }
413    
414     void ParseTelWont(BYTE b)
415     {
416     if (b <= MaxTelOpt)
417     {
418     switch (tr.HisOpt[b].Status) {
419     case Yes:
420     tr.HisOpt[b].Status = No;
421     SendBack(DONTTEL,b);
422     break;
423    
424     case WantNo:
425     switch (tr.HisOpt[b].Que) {
426     case Empty:
427     tr.HisOpt[b].Status = No;
428     break;
429     case Opposite:
430     tr.HisOpt[b].Status = WantYes;
431     tr.HisOpt[b].Que = Empty;
432     SendBack(DOTEL,b);
433     break;
434     }
435     break;
436    
437     case WantYes:
438     switch (tr.HisOpt[b].Que) {
439     case Empty:
440     tr.HisOpt[b].Status = No;
441     break;
442     case Opposite:
443     tr.HisOpt[b].Status = No;
444     tr.HisOpt[b].Que = Empty;
445     break;
446     }
447     break;
448     }
449     }
450     else
451     SendBack(DONTTEL,b);
452    
453     switch (b) {
454     case ECHO:
455     if (ts.TelEcho>0)
456     switch (tr.HisOpt[ECHO].Status) {
457     case Yes:
458     ts.LocalEcho = 0;
459     break;
460     case No:
461     ts.LocalEcho = 1;
462     break;
463     }
464     break;
465 doda 3531 if (tr.HisOpt[ECHO].Status == Yes) {
466     cv.TelLineMode = FALSE;
467     }
468 maya 3227 case BINARY:
469     switch (tr.HisOpt[BINARY].Status) {
470     case Yes:
471     cv.TelBinRecv = TRUE;
472     break;
473     case No:
474     cv.TelBinRecv = FALSE;
475     break;
476     }
477     break;
478     }
479     TelStatus = TelIdle;
480     }
481    
482     void ParseTelDo(BYTE b)
483     {
484     if (b <= MaxTelOpt)
485     {
486     switch (tr.MyOpt[b].Status) {
487     case No:
488     if (tr.MyOpt[b].Accept)
489     {
490     tr.MyOpt[b].Status = Yes;
491     SendBack(WILLTEL,b);
492     }
493     else
494     SendBack(WONTTEL,b);
495     break;
496    
497     case WantNo:
498     switch (tr.MyOpt[b].Que) {
499     case Empty:
500     tr.MyOpt[b].Status = No;
501     break;
502     case Opposite:
503     tr.MyOpt[b].Status = Yes;
504     break;
505     }
506     break;
507    
508     case WantYes:
509     switch (tr.MyOpt[b].Que) {
510     case Empty:
511     tr.MyOpt[b].Status = Yes;
512     break;
513     case Opposite:
514     tr.MyOpt[b].Status = WantNo;
515     tr.MyOpt[b].Que = Empty;
516     SendBack(WONTTEL,b);
517     break;
518     }
519     break;
520     }
521     }
522     else
523     SendBack(WONTTEL,b);
524    
525     switch (b) {
526     case BINARY:
527     switch (tr.MyOpt[BINARY].Status) {
528     case Yes:
529     cv.TelBinSend = TRUE;
530     break;
531     case No:
532     cv.TelBinSend = FALSE;
533     break;
534     }
535     break;
536     case NAWS:
537     if (tr.MyOpt[NAWS].Status==Yes)
538     SendWinSize();
539     break;
540 doda 3494 case SGA:
541     if (tr.MyOpt[SGA].Status==Yes)
542     cv.TelLineMode = FALSE;
543     break;
544 maya 3227 }
545     TelStatus = TelIdle;
546     }
547    
548     void ParseTelDont(BYTE b)
549     {
550     if (b <= MaxTelOpt)
551     {
552     switch (tr.MyOpt[b].Status) {
553     case Yes:
554     tr.MyOpt[b].Status = No;
555     SendBack(WONTTEL,b);
556     break;
557    
558     case WantNo:
559     switch (tr.MyOpt[b].Que) {
560     case Empty:
561     tr.MyOpt[b].Status = No;
562     break;
563     case Opposite:
564     tr.MyOpt[b].Status = WantYes;
565     tr.MyOpt[b].Que = Empty;
566     SendBack(WILLTEL,b);
567     break;
568     }
569     break;
570    
571     case WantYes:
572     switch (tr.MyOpt[b].Que) {
573     case Empty:
574     tr.MyOpt[b].Status = No;
575     break;
576     case Opposite:
577     tr.MyOpt[b].Status = No;
578     tr.MyOpt[b].Que = Empty;
579     break;
580     }
581     break;
582     }
583     }
584     else
585     SendBack(WONTTEL,b);
586    
587     switch (b) {
588     case BINARY:
589     switch (tr.MyOpt[BINARY].Status) {
590     case Yes:
591     cv.TelBinSend = TRUE;
592     break;
593     case No:
594     cv.TelBinSend = FALSE;
595     break;
596     }
597     break;
598     }
599     TelStatus = TelIdle;
600     }
601    
602     void ParseTel(BOOL *Size, int *nx, int *ny)
603     {
604     BYTE b;
605     int c;
606    
607     c = CommReadRawByte(&cv,&b);
608    
609     while ((c>0) && (cv.TelMode))
610     {
611     if (tr.LogFile!=0)
612     {
613     if (TelStatus==TelIAC)
614     {
615     _lwrite(tr.LogFile,"\015\012<",3);
616     TelWriteLog1(0xff);
617     }
618     TelWriteLog1(b);
619     }
620    
621     tr.ChangeWinSize = FALSE;
622    
623     switch (TelStatus) {
624     case TelIAC: ParseTelIAC(b); break;
625     case TelSB: ParseTelSB(b); break;
626     case TelWill: ParseTelWill(b); break;
627     case TelWont: ParseTelWont(b); break;
628     case TelDo: ParseTelDo(b); break;
629     case TelDont: ParseTelDont(b); break;
630     case TelNop: TelStatus = TelIdle; break;
631     }
632     if (TelStatus == TelIdle) cv.TelMode = FALSE;
633    
634     if (cv.TelMode) c = CommReadRawByte(&cv,&b);
635     }
636    
637     *Size = tr.ChangeWinSize;
638     *nx = tr.WinSize.x;
639     *ny = tr.WinSize.x;
640     }
641    
642     void TelEnableHisOpt(BYTE b)
643     {
644     if (b <= MaxTelOpt)
645     {
646     switch (tr.HisOpt[b].Status) {
647     case No:
648     tr.HisOpt[b].Status = WantYes;
649     SendBack(DOTEL,b);
650     break;
651    
652     case WantNo:
653     if (tr.HisOpt[b].Que==Empty)
654     tr.HisOpt[b].Que = Opposite;
655     break;
656    
657     case WantYes:
658     if (tr.HisOpt[b].Que==Opposite)
659     tr.HisOpt[b].Que = Empty;
660     break;
661     }
662     }
663     }
664    
665     void TelDisableHisOpt(BYTE b)
666     {
667     if (b <= MaxTelOpt)
668     {
669     switch (tr.HisOpt[b].Status) {
670     case Yes:
671     tr.HisOpt[b].Status = WantNo;
672     SendBack(DONTTEL,b);
673     break;
674    
675     case WantNo:
676     if (tr.HisOpt[b].Que==Opposite)
677     tr.HisOpt[b].Que = Empty;
678     break;
679    
680     case WantYes:
681     if (tr.HisOpt[b].Que==Empty)
682     tr.HisOpt[b].Que = Opposite;
683     break;
684     }
685     }
686     }
687    
688     void TelEnableMyOpt(BYTE b)
689     {
690     if (b <= MaxTelOpt)
691     {
692     switch (tr.MyOpt[b].Status) {
693     case No:
694     tr.MyOpt[b].Status = WantYes;
695     SendBack(WILLTEL,b);
696     break;
697    
698     case WantNo:
699     if (tr.MyOpt[b].Que==Empty)
700     tr.MyOpt[b].Que = Opposite;
701     break;
702    
703     case WantYes:
704     if (tr.MyOpt[b].Que==Opposite)
705     tr.MyOpt[b].Que = Empty;
706     break;
707     }
708     }
709     }
710    
711     void TelDisableMyOpt(BYTE b)
712     {
713     if (b <= MaxTelOpt)
714     {
715     switch (tr.MyOpt[b].Status) {
716     case Yes:
717     tr.MyOpt[b].Status = WantNo;
718     SendBack(WONTTEL,b);
719     break;
720    
721     case WantNo:
722     if (tr.MyOpt[b].Que==Opposite)
723     tr.MyOpt[b].Que = Empty;
724     break;
725    
726     case WantYes:
727     if (tr.MyOpt[b].Que==Empty)
728     tr.MyOpt[b].Que = Opposite;
729     break;
730     }
731     }
732     }
733    
734     void TelInformWinSize(int nx, int ny)
735     {
736     if ((tr.MyOpt[NAWS].Status==Yes) &&
737     ((nx!=tr.WinSize.x) ||
738     (ny!=tr.WinSize.y)))
739     {
740     tr.WinSize.x = nx;
741     tr.WinSize.y = ny;
742     SendWinSize();
743     }
744     }
745    
746     void TelSendAYT()
747     {
748     BYTE Str[2];
749    
750     Str[0] = IAC;
751     Str[1] = AYT;
752     CommRawOut(&cv,Str,2);
753     CommSend(&cv);
754     if (tr.LogFile!=0)
755     TelWriteLog(Str,2);
756     }
757    
758     void TelSendBreak()
759     {
760     BYTE Str[2];
761    
762     Str[0] = IAC;
763     Str[1] = BREAK;
764     CommRawOut(&cv,Str,2);
765     CommSend(&cv);
766     if (tr.LogFile!=0)
767     TelWriteLog(Str,2);
768     }
769    
770     void TelChangeEcho()
771     {
772     if (ts.LocalEcho==0)
773     TelEnableHisOpt(ECHO);
774     else
775     TelDisableHisOpt(ECHO);
776     }
777    
778     void TelSendNOP()
779     {
780     BYTE Str[2];
781    
782     Str[0] = IAC;
783     Str[1] = NOP;
784     CommRawOut(&cv,Str,2);
785     CommSend(&cv);
786     if (tr.LogFile!=0)
787     TelWriteLog(Str,2);
788     }
789    
790     #define WM_SEND_HEARTBEAT (WM_USER + 1)
791    
792     static LRESULT CALLBACK telnet_heartbeat_dlg_proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
793     {
794    
795     switch (msg) {
796     case WM_INITDIALOG:
797     return FALSE;
798    
799     case WM_SEND_HEARTBEAT:
800     TelSendNOP();
801     return TRUE;
802     break;
803    
804     case WM_COMMAND:
805     switch (wp) {
806     }
807    
808     switch (LOWORD(wp)) {
809     case IDOK:
810     {
811     return TRUE;
812     }
813    
814     case IDCANCEL:
815     EndDialog(hWnd, 0);
816     return TRUE;
817     default:
818     return FALSE;
819     }
820     break;
821    
822     case WM_CLOSE:
823     // close�{�^���������������� window ���������������������B
824     return TRUE;
825    
826     case WM_DESTROY:
827     return TRUE;
828    
829     default:
830     return FALSE;
831     }
832     return TRUE;
833     }
834    
835    
836     static unsigned _stdcall TelKeepAliveThread(void *dummy) {
837     static int instance = 0;
838    
839     if (instance > 0)
840     return 0;
841     instance++;
842    
843     while (cv.Open && nop_interval > 0) {
844     if (time(NULL) >= cv.LastSendTime + nop_interval) {
845     SendMessage(keepalive_dialog, WM_SEND_HEARTBEAT, 0, 0);
846     }
847    
848     Sleep(100);
849     }
850     instance--;
851     return 0;
852     }
853    
854     void TelStartKeepAliveThread() {
855     unsigned tid;
856    
857     if (ts.TelKeepAliveInterval > 0) {
858     nop_interval = ts.TelKeepAliveInterval;
859    
860     // ���[�h���X�_�C�A���O������ (2007.12.26 yutaka)
861     keepalive_dialog = CreateDialog(hInst, MAKEINTRESOURCE(IDD_BROADCAST_DIALOG),
862     HVTWin, (DLGPROC)telnet_heartbeat_dlg_proc);
863    
864     keepalive_thread = (HANDLE)_beginthreadex(NULL, 0, TelKeepAliveThread, NULL, 0, &tid);
865     if (keepalive_thread == (HANDLE)-1) {
866     nop_interval = 0;
867     }
868     }
869     }
870    
871     void TelStopKeepAliveThread() {
872     if (keepalive_thread != (HANDLE)-1L) {
873     nop_interval = 0;
874     WaitForSingleObject(keepalive_thread, INFINITE);
875     CloseHandle(keepalive_thread);
876     keepalive_thread = (HANDLE)-1L;
877    
878     DestroyWindow(keepalive_dialog);
879     }
880     }
881    
882     void TelUpdateKeepAliveInterval() {
883     if (cv.Open && cv.TelFlag && ts.TCPPort==ts.TelPort) {
884     if (ts.TelKeepAliveInterval > 0 && keepalive_thread == (HANDLE)-1)
885     TelStartKeepAliveThread();
886     else if (ts.TelKeepAliveInterval == 0 && keepalive_thread != (HANDLE)-1)
887     TelStopKeepAliveThread();
888     else
889     nop_interval = ts.TelKeepAliveInterval;
890     }
891     }

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