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 6964 - (hide annotations) (download) (as text)
Fri Oct 27 09:40:55 2017 UTC (6 years, 5 months ago) by doda
Original Path: trunk/teraterm/teraterm/telnet.c
File MIME type: text/x-csrc
File size: 17378 byte(s)
相手から送られて来たサブオプション中の連続した IAC を正しく扱えていなかったのを修正。

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

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