1 |
#include <stdlib.h> |
2 |
#include <stdio.h> |
3 |
#include <string.h> |
4 |
#include "teraterm.h" |
5 |
#include "tttypes.h" |
6 |
#include "ttplugin.h" |
7 |
#include "tt_res.h" |
8 |
|
9 |
#ifndef NO_INET6 |
10 |
#include <winsock2.h> |
11 |
#include <ws2tcpip.h> |
12 |
#else |
13 |
#include <winsock.h> |
14 |
#endif /* NO_INET6 */ |
15 |
|
16 |
#include "compat_w95.h" |
17 |
|
18 |
#define ORDER 4800 |
19 |
|
20 |
#define IdModeFirst 0 |
21 |
#define IdModeESC 1 |
22 |
#define IdModeOSC 2 |
23 |
#define IdModeESC2 3 |
24 |
#define IdModeProc 4 |
25 |
|
26 |
static HANDLE hInst; /* Instance handle of TTX*.DLL */ |
27 |
|
28 |
typedef struct { |
29 |
PTTSet ts; |
30 |
PComVar cv; |
31 |
Trecv origPrecv; |
32 |
Tsend origPsend; |
33 |
TReadFile origPReadFile; |
34 |
TWriteFile origPWriteFile; |
35 |
} TInstVar; |
36 |
|
37 |
static TInstVar FAR * pvar; |
38 |
static TInstVar InstVar; |
39 |
|
40 |
static void PASCAL FAR TTXInit(PTTSet ts, PComVar cv) { |
41 |
pvar->ts = ts; |
42 |
pvar->cv = cv; |
43 |
pvar->origPrecv = NULL; |
44 |
pvar->origPsend = NULL; |
45 |
pvar->origPReadFile = NULL; |
46 |
pvar->origPWriteFile = NULL; |
47 |
} |
48 |
|
49 |
void CommOut(char *str, int len) { |
50 |
int outlen, c; |
51 |
char *p; |
52 |
|
53 |
if (len > OutBuffSize - pvar->cv->OutBuffCount) |
54 |
outlen = OutBuffSize - pvar->cv->OutBuffCount; |
55 |
else |
56 |
outlen = len; |
57 |
|
58 |
if (pvar->cv->OutPtr > 0) { |
59 |
memmove(pvar->cv->OutBuff, &(pvar->cv->OutBuff[pvar->cv->OutPtr]), pvar->cv->OutBuffCount); |
60 |
pvar->cv->OutPtr = 0; |
61 |
} |
62 |
|
63 |
c = pvar->cv->OutBuffCount; |
64 |
for (p = str; outlen>0; p++, outlen--) { |
65 |
switch (*p) { |
66 |
case 0x0d: |
67 |
switch (pvar->cv->CRSend) { |
68 |
case IdCR: |
69 |
pvar->cv->OutBuff[c++] = 0x0d; |
70 |
if (c < OutBuffSize && pvar->cv->TelFlag && ! pvar->cv->TelBinSend) { |
71 |
pvar->cv->OutBuff[c++] = 0; |
72 |
} |
73 |
break; |
74 |
case IdLF: |
75 |
pvar->cv->OutBuff[c++] = 0x0a; |
76 |
break; |
77 |
case IdCRLF: |
78 |
pvar->cv->OutBuff[c++] = 0x0d; |
79 |
if (c < OutBuffSize) { |
80 |
pvar->cv->OutBuff[c++] = 0x0a; |
81 |
} |
82 |
break; |
83 |
} |
84 |
if (c + outlen > OutBuffSize) { |
85 |
outlen--; |
86 |
} |
87 |
break; |
88 |
case 0xff: |
89 |
if (pvar->cv->TelFlag) { |
90 |
if (c < OutBuffSize - 1) { |
91 |
pvar->cv->OutBuff[c++] = 0xff; |
92 |
pvar->cv->OutBuff[c++] = 0xff; |
93 |
} |
94 |
} |
95 |
else { |
96 |
pvar->cv->OutBuff[c++] = 0xff; |
97 |
} |
98 |
if (c + outlen > OutBuffSize) { |
99 |
outlen--; |
100 |
} |
101 |
break; |
102 |
default: |
103 |
pvar->cv->OutBuff[c++] = *p; |
104 |
} |
105 |
} |
106 |
|
107 |
pvar->cv->OutBuffCount = c; |
108 |
} |
109 |
|
110 |
void ParseInputStr(char *rstr, int rcount) { |
111 |
static WORD mode = IdModeFirst; |
112 |
static char buff[InBuffSize]; |
113 |
static unsigned int blen; |
114 |
char *p, *p2; |
115 |
int i; |
116 |
unsigned int func; |
117 |
|
118 |
#define AcceptC1Control \ |
119 |
((pvar->cv->KanjiCodeEcho == IdEUC || pvar->cv->KanjiCodeEcho == IdJIS) && \ |
120 |
pvar->ts->TerminalID >= IdVT220J && (pvar->ts->TermFlag & TF_ACCEPT8BITCTRL) != 0) |
121 |
|
122 |
for (i=0; i<rcount; i++) { |
123 |
switch (mode) { |
124 |
case IdModeFirst: |
125 |
if (rstr[i] == ESC) { |
126 |
mode = IdModeESC; |
127 |
} |
128 |
else if (rstr[i] == OSC && AcceptC1Control) { |
129 |
mode = IdModeOSC; |
130 |
} |
131 |
break; |
132 |
case IdModeESC: |
133 |
if (rstr[i] == ']') { |
134 |
mode = IdModeOSC; |
135 |
} |
136 |
else { |
137 |
mode = IdModeFirst; |
138 |
} |
139 |
break; |
140 |
case IdModeOSC: |
141 |
if (rstr[i] == ESC) { |
142 |
mode = IdModeESC2; |
143 |
} |
144 |
else if (rstr[i] == '\a' || rstr[i] == ST && AcceptC1Control) { |
145 |
mode = IdModeProc; |
146 |
i--; |
147 |
} |
148 |
else if (blen < InBuffSize - 1) { |
149 |
buff[blen++] = rstr[i]; |
150 |
} |
151 |
if (blen >= InBuffSize - 1) { |
152 |
mode = IdModeProc; |
153 |
i--; |
154 |
} |
155 |
break; |
156 |
case IdModeESC2: |
157 |
if (rstr[i] == '\\') { |
158 |
mode = IdModeProc; |
159 |
i--; |
160 |
} |
161 |
else { |
162 |
if (blen < InBuffSize - 1) { |
163 |
buff[blen++] = ESC; |
164 |
buff[blen++] = rstr[i]; |
165 |
} |
166 |
if (blen >= InBuffSize - 1) { |
167 |
mode = IdModeProc; |
168 |
i--; |
169 |
} |
170 |
else { |
171 |
mode = IdModeOSC; |
172 |
} |
173 |
} |
174 |
break; |
175 |
case IdModeProc: |
176 |
i++; |
177 |
buff[(blen<InBuffSize)?blen:InBuffSize-1] = '\0'; |
178 |
p = buff; |
179 |
|
180 |
for (p=buff, func=0; isdigit(*p); p++) { |
181 |
func = func * 10 + *p - '0'; |
182 |
} |
183 |
if (*p != ';' || p == buff) { |
184 |
blen = 0; |
185 |
mode = IdModeFirst; |
186 |
break; |
187 |
} |
188 |
p++; |
189 |
switch (func) { |
190 |
case 5963: |
191 |
while (p && *p) { |
192 |
if ((p2 = strchr(p, ';')) != NULL) |
193 |
*p2++ = '\0'; |
194 |
if (_strnicmp(p, "kt=", 3) == 0) { |
195 |
p+= 3; |
196 |
if (_stricmp(p, "SJIS") == 0) |
197 |
pvar->cv->KanjiCodeSend = pvar->ts->KanjiCodeSend = IdSJIS; |
198 |
else if (_stricmp(p, "EUC") == 0) |
199 |
pvar->cv->KanjiCodeSend = pvar->ts->KanjiCodeSend = IdEUC; |
200 |
else if (_stricmp(p, "JIS") == 0) |
201 |
pvar->cv->KanjiCodeSend = pvar->ts->KanjiCodeSend = IdJIS; |
202 |
else if (_stricmp(p, "UTF8") == 0 || _stricmp(p, "UTF-8") == 0) |
203 |
pvar->cv->KanjiCodeSend = pvar->ts->KanjiCodeSend = IdUTF8; |
204 |
} |
205 |
else if (_strnicmp(p, "kr=", 3) == 0) { |
206 |
p += 3; |
207 |
if (_stricmp(p, "SJIS") == 0) |
208 |
pvar->cv->KanjiCodeEcho = pvar->ts->KanjiCode = IdSJIS; |
209 |
else if (_stricmp(p, "EUC") == 0) |
210 |
pvar->cv->KanjiCodeEcho = pvar->ts->KanjiCode = IdEUC; |
211 |
else if (_stricmp(p, "JIS") == 0) |
212 |
pvar->cv->KanjiCodeEcho = pvar->ts->KanjiCode = IdJIS; |
213 |
else if (_stricmp(p, "UTF8") == 0 || _stricmp(p, "UTF-8") == 0) |
214 |
pvar->cv->KanjiCodeEcho = pvar->ts->KanjiCode = IdUTF8; |
215 |
else if (_stricmp(p, "UTF8m") == 0 || _stricmp(p, "UTF-8m") == 0) |
216 |
pvar->cv->KanjiCodeEcho = pvar->ts->KanjiCode = IdUTF8m; |
217 |
} |
218 |
p = p2; |
219 |
} |
220 |
break; |
221 |
case 5964: |
222 |
while (p && *p) { |
223 |
if ((p2 = strchr(p, ';')) != NULL) |
224 |
*p2++ = '\0'; |
225 |
if (_stricmp(p, "kt") == 0) { |
226 |
switch (pvar->cv->KanjiCodeSend) { |
227 |
case IdSJIS: |
228 |
CommOut("kt=SJIS;", 8); |
229 |
break; |
230 |
case IdEUC: |
231 |
CommOut("kt=EUC;", 7); |
232 |
break; |
233 |
case IdJIS: |
234 |
CommOut("kt=JIS;", 7); |
235 |
break; |
236 |
case IdUTF8: |
237 |
CommOut("kt=UTF8;", 8); |
238 |
break; |
239 |
} |
240 |
} |
241 |
else if (_stricmp(p, "kr") == 0) { |
242 |
switch (pvar->cv->KanjiCodeEcho) { |
243 |
case IdSJIS: |
244 |
CommOut("kr=SJIS;", 8); |
245 |
break; |
246 |
case IdEUC: |
247 |
CommOut("kr=EUC;", 7); |
248 |
break; |
249 |
case IdJIS: |
250 |
CommOut("kr=JIS;", 7); |
251 |
break; |
252 |
case IdUTF8: |
253 |
CommOut("kr=UTF8;", 8); |
254 |
break; |
255 |
case IdUTF8m: |
256 |
CommOut("kr=UTF8m;", 9); |
257 |
break; |
258 |
} |
259 |
} |
260 |
p = p2; |
261 |
} |
262 |
CommOut("\r", 1); |
263 |
break; |
264 |
default: |
265 |
; /* nothing to do */ |
266 |
} |
267 |
blen = 0; |
268 |
mode = IdModeFirst; |
269 |
default: |
270 |
; /* not reached */ |
271 |
} |
272 |
} |
273 |
} |
274 |
|
275 |
int PASCAL FAR TTXrecv(SOCKET s, char FAR *buff, int len, int flags) { |
276 |
int rlen; |
277 |
|
278 |
if ((rlen = pvar->origPrecv(s, buff, len, flags)) > 0) { |
279 |
ParseInputStr(buff, rlen); |
280 |
} |
281 |
return rlen; |
282 |
} |
283 |
|
284 |
BOOL PASCAL FAR TTXReadFile(HANDLE fh, LPVOID buff, DWORD len, LPDWORD rbytes, LPOVERLAPPED rol) { |
285 |
BOOL result; |
286 |
|
287 |
if ((result = pvar->origPReadFile(fh, buff, len, rbytes, rol)) != FALSE) |
288 |
ParseInputStr(buff, *rbytes); |
289 |
return result; |
290 |
} |
291 |
|
292 |
static void PASCAL FAR TTXOpenTCP(TTXSockHooks FAR * hooks) { |
293 |
pvar->origPrecv = *hooks->Precv; |
294 |
*hooks->Precv = TTXrecv; |
295 |
} |
296 |
|
297 |
static void PASCAL FAR TTXCloseTCP(TTXSockHooks FAR * hooks) { |
298 |
if (pvar->origPrecv) { |
299 |
*hooks->Precv = pvar->origPrecv; |
300 |
} |
301 |
} |
302 |
|
303 |
static void PASCAL FAR TTXOpenFile(TTXFileHooks FAR * hooks) { |
304 |
pvar->origPReadFile = *hooks->PReadFile; |
305 |
*hooks->PReadFile = TTXReadFile; |
306 |
} |
307 |
|
308 |
static void PASCAL FAR TTXCloseFile(TTXFileHooks FAR * hooks) { |
309 |
if (pvar->origPReadFile) { |
310 |
*hooks->PReadFile = pvar->origPReadFile; |
311 |
} |
312 |
} |
313 |
|
314 |
static TTXExports Exports = { |
315 |
sizeof(TTXExports), |
316 |
ORDER, |
317 |
|
318 |
TTXInit, |
319 |
NULL, // TTXGetUIHooks, |
320 |
NULL, // TTXGetSetupHooks, |
321 |
TTXOpenTCP, |
322 |
TTXCloseTCP, |
323 |
NULL, // TTXSetWinSize, |
324 |
NULL, // TTXModifyMenu, |
325 |
NULL, // TTXModifyPopupMenu, |
326 |
NULL, // TTXProcessCommand, |
327 |
NULL, // TTXEnd, |
328 |
NULL, // TTXSetCommandLine, |
329 |
TTXOpenFile, |
330 |
TTXCloseFile |
331 |
}; |
332 |
|
333 |
BOOL __declspec(dllexport) PASCAL FAR TTXBind(WORD Version, TTXExports FAR * exports) { |
334 |
int size = sizeof(Exports) - sizeof(exports->size); |
335 |
|
336 |
if (size > exports->size) { |
337 |
size = exports->size; |
338 |
} |
339 |
memcpy((char FAR *)exports + sizeof(exports->size), |
340 |
(char FAR *)&Exports + sizeof(exports->size), |
341 |
size); |
342 |
return TRUE; |
343 |
} |
344 |
|
345 |
BOOL WINAPI DllMain(HANDLE hInstance, |
346 |
ULONG ul_reason_for_call, |
347 |
LPVOID lpReserved) |
348 |
{ |
349 |
switch( ul_reason_for_call ) { |
350 |
case DLL_THREAD_ATTACH: |
351 |
/* do thread initialization */ |
352 |
break; |
353 |
case DLL_THREAD_DETACH: |
354 |
/* do thread cleanup */ |
355 |
break; |
356 |
case DLL_PROCESS_ATTACH: |
357 |
/* do process initialization */ |
358 |
DoCover_IsDebuggerPresent(); |
359 |
hInst = hInstance; |
360 |
pvar = &InstVar; |
361 |
break; |
362 |
case DLL_PROCESS_DETACH: |
363 |
/* do process cleanup */ |
364 |
break; |
365 |
} |
366 |
return TRUE; |
367 |
} |