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

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