Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/ttssh2/ttxssh/fwdui.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10618 - (show annotations) (download) (as text)
Fri Mar 3 15:15:16 2023 UTC (13 months, 1 week ago) by zmatsuo
File MIME type: text/x-csrc
File size: 33978 byte(s)
ttxsshで tttset.UIMsg[] ではなく TInstVar.UIMsg[] を使用するよう修正

- lng(i18n)用文字列領域
- ttxssh 以外は tttset.UIMsg[] を使用しなくなった
  - Unicode(wchar_t)版動的な文字列取得に切り替えた
  - tttset.UIMsg[] は ANSI(char) 文字列
- プラグイン用ワーク内に TInstVar.UIMsg[] を新設した
1 /*
2 * Copyright (c) 1998-2001, Robert O'Callahan
3 * (C) 2004- TeraTerm Project
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 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 *
18 * 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 */
29
30 /*
31 This code is copyright (C) 1998-1999 Robert O'Callahan.
32 See LICENSE.TXT for the license.
33 */
34
35 #include "fwdui.h"
36
37 #include "resource.h"
38 #include "x11util.h"
39 #include "util.h"
40 #include "dlglib.h"
41
42 #include "servicenames.h"
43 #include "helpid.h"
44
45 #undef DialogBoxParam
46 #define DialogBoxParam(p1,p2,p3,p4,p5) \
47 TTDialogBoxParam(p1,p2,p3,p4,p5)
48 #undef EndDialog
49 #define EndDialog(p1,p2) \
50 TTEndDialog(p1, p2)
51
52 typedef struct {
53 FWDRequestSpec *spec;
54 PTInstVar pvar;
55 } FWDEditClosure;
56
57 static void make_X_forwarding_spec(FWDRequestSpec *spec, PTInstVar pvar)
58 {
59 spec->type = FWD_REMOTE_X11_TO_LOCAL;
60 spec->from_port = -1;
61 X11_get_DISPLAY_info(pvar, spec->to_host, sizeof(spec->to_host),
62 &spec->to_port, &spec->x11_screen);
63 UTIL_get_lang_msg("MSG_FWD_REMOTE_XSERVER", pvar, "remote X server");
64 strncpy_s(spec->from_port_name, sizeof(spec->from_port_name),
65 pvar->UIMsg, _TRUNCATE);
66 UTIL_get_lang_msg("MSG_FWD_REMOTE_XSCREEN", pvar, "X server (display %d:%d)");
67 _snprintf_s(spec->to_port_name, sizeof(spec->to_port_name), _TRUNCATE,
68 pvar->UIMsg, spec->to_port - 6000, spec->x11_screen);
69 }
70
71 static BOOL parse_request(FWDRequestSpec *request, char *str, PTInstVar pvar)
72 {
73 char *tmp, *ch;
74 int len, i, argc = 0, bracketed = 0;
75 char *argv[4];
76 char hostname[256];
77 int start;
78
79 if ((tmp = strchr(str, ';')) != NULL) {
80 len = tmp - str;
81 }
82 else {
83 len = strlen(str);
84 }
85 tmp = _malloca(sizeof(char) * (len+1));
86 strncpy_s(tmp, sizeof(char) * (len+1), str, _TRUNCATE);
87
88 if (*tmp == 'L' || *tmp == 'l') {
89 request->type = FWD_LOCAL_TO_REMOTE;
90 } else if (*tmp == 'R' || *tmp == 'r') {
91 request->type = FWD_REMOTE_TO_LOCAL;
92 } else if (*tmp == 'D' || *tmp == 'd') {
93 request->type = FWD_LOCAL_DYNAMIC;
94 } else if (*tmp == 'X' || *tmp == 'x') {
95 make_X_forwarding_spec(request, pvar);
96 return TRUE;
97 } else {
98 return FALSE;
99 }
100 tmp++;
101
102 argv[argc++] = tmp;
103 for (i=0; i<len; i++ ) {
104 ch = (tmp+i);
105 if (*ch == ':' && !bracketed) {
106 if (argc >= 4) {
107 argc++;
108 break;
109 }
110 *ch = '\0';
111 argv[argc++] = tmp+i+1;
112 }
113 else if (*ch == '[' && !bracketed) {
114 bracketed = 1;
115 }
116 else if (*ch == ']' && bracketed) {
117 bracketed = 0;
118 }
119 }
120
121 strncpy_s(request->bind_address, sizeof(request->bind_address), "localhost", _TRUNCATE);
122 i=0;
123 switch (argc) {
124 case 4:
125 if (*argv[i] == '\0' || strcmp(argv[i], "*") == 0) {
126 strncpy_s(request->bind_address, sizeof(request->bind_address), "0.0.0.0", _TRUNCATE);
127 }
128 else {
129 // IPv6 �A�h���X�� "[", "]" ������������
130 start = 0;
131 strncpy_s(hostname, sizeof(hostname), argv[i], _TRUNCATE);
132 if (strlen(hostname) > 0 &&
133 hostname[strlen(hostname)-1] == ']') {
134 hostname[strlen(hostname)-1] = '\0';
135 }
136 if (hostname[0] == '[') {
137 start = 1;
138 }
139 strncpy_s(request->bind_address, sizeof(request->bind_address),
140 hostname + start, _TRUNCATE);
141 }
142 i++;
143 /* don't break here */ /* Falls through. */
144
145 case 3:
146 request->from_port = parse_port(argv[i], request->from_port_name,
147 sizeof(request->from_port_name));
148 if (request->from_port < 0) {
149 return FALSE;
150 }
151 i++;
152
153 // IPv6 �A�h���X�� "[", "]" ������������
154 start = 0;
155 strncpy_s(hostname, sizeof(hostname), argv[i], _TRUNCATE);
156 if (strlen(hostname) > 0 &&
157 hostname[strlen(hostname)-1] == ']') {
158 hostname[strlen(hostname)-1] = '\0';
159 }
160 if (hostname[0] == '[') {
161 start = 1;
162 }
163 strncpy_s(request->to_host, sizeof(request->to_host),
164 hostname + start, _TRUNCATE);
165 i++;
166
167 request->to_port = parse_port(argv[i], request->to_port_name,
168 sizeof(request->to_port_name));
169 if (request->to_port < 0) {
170 return FALSE;
171 }
172
173 break;
174
175 case 2:
176 if (request->type != FWD_LOCAL_DYNAMIC) {
177 return FALSE;
178 }
179 if (*argv[i] == '\0' || strcmp(argv[i], "*") == 0) {
180 strncpy_s(request->bind_address, sizeof(request->bind_address),
181 "0.0.0.0", _TRUNCATE);
182 }
183 else {
184 // IPv6 �A�h���X�� "[", "]" ������������
185 start = 0;
186 strncpy_s(hostname, sizeof(hostname), argv[i], _TRUNCATE);
187 if (strlen(hostname) > 0 &&
188 hostname[strlen(hostname)-1] == ']') {
189 hostname[strlen(hostname)-1] = '\0';
190 }
191 if (hostname[0] == '[') {
192 start = 1;
193 }
194 strncpy_s(request->bind_address, sizeof(request->bind_address),
195 hostname + start, _TRUNCATE);
196 }
197 i++;
198 // FALLTHROUGH
199 case 1:
200 if (request->type != FWD_LOCAL_DYNAMIC) {
201 return FALSE;
202 }
203 request->from_port = parse_port(argv[i], request->from_port_name,
204 sizeof(request->from_port_name));
205 if (request->from_port < 0) {
206 return FALSE;
207 }
208 i++;
209
210 request->to_host[0] = '\0';
211 request->to_port = parse_port("0", request->to_port_name,
212 sizeof(request->to_port_name));
213 break;
214
215 default:
216 return FALSE;
217 }
218
219 return TRUE;
220 }
221
222 static void FWDUI_save_settings(PTInstVar pvar)
223 {
224 int num_specs = FWD_get_num_request_specs(pvar);
225 FWDRequestSpec *requests =
226 (FWDRequestSpec *) malloc(sizeof(FWDRequestSpec) * num_specs);
227 int i;
228 char *str = pvar->settings.DefaultForwarding;
229 int str_remaining = sizeof(pvar->settings.DefaultForwarding) - 1;
230 char format[20];
231
232 FWD_get_request_specs(pvar, requests, num_specs);
233
234 *str = 0;
235 str[str_remaining] = 0;
236
237 for (i = 0; i < num_specs; i++) {
238 if (str_remaining > 0 && i > 0) {
239 str[0] = ';';
240 str[1] = 0;
241 str++;
242 str_remaining--;
243 }
244
245 if (str_remaining > 0) {
246 FWDRequestSpec *spec = requests + i;
247 int chars;
248
249 // IPv6 �A�h���X���� "[", "]" ���t��������������
250 switch (spec->type) {
251 case FWD_LOCAL_TO_REMOTE:
252 if (strcmp(spec->bind_address,"localhost") == 0) {
253 if (strchr(spec->to_host, ':') == NULL) {
254 strncpy_s(format, sizeof(format), "L%s:%s:%s", _TRUNCATE);
255 }
256 else {
257 strncpy_s(format, sizeof(format), "L%s:[%s]:%s", _TRUNCATE);
258 }
259 _snprintf_s(str, str_remaining, _TRUNCATE, format,
260 spec->from_port_name, spec->to_host,
261 spec->to_port_name);
262 }
263 else {
264 if (strchr(spec->bind_address, ':') == NULL) {
265 if (strchr(spec->to_host, ':') == NULL) {
266 strncpy_s(format, sizeof(format), "L%s:%s:%s:%s", _TRUNCATE);
267 }
268 else {
269 strncpy_s(format, sizeof(format), "L%s:%s:[%s]:%s", _TRUNCATE);
270 }
271 }
272 else {
273 if (strchr(spec->to_host, ':') == NULL) {
274 strncpy_s(format, sizeof(format), "L[%s]:%s:%s:%s", _TRUNCATE);
275 }
276 else {
277 strncpy_s(format, sizeof(format), "L[%s]:%s:[%s]:%s", _TRUNCATE);
278 }
279 }
280 _snprintf_s(str, str_remaining, _TRUNCATE, format,
281 spec->bind_address, spec->from_port_name,
282 spec->to_host, spec->to_port_name);
283 }
284 break;
285 case FWD_REMOTE_TO_LOCAL:
286 if (strcmp(spec->bind_address,"localhost") == 0) {
287 if (strchr(spec->to_host, ':') == NULL) {
288 strncpy_s(format, sizeof(format), "R%s:%s:%s", _TRUNCATE);
289 }
290 else {
291 strncpy_s(format, sizeof(format), "R%s:[%s]:%s", _TRUNCATE);
292 }
293 _snprintf_s(str, str_remaining, _TRUNCATE, format,
294 spec->from_port_name, spec->to_host,
295 spec->to_port_name);
296 }
297 else {
298 if (strchr(spec->bind_address, ':') == NULL) {
299 if (strchr(spec->to_host, ':') == NULL) {
300 strncpy_s(format, sizeof(format), "R%s:%s:%s:%s", _TRUNCATE);
301 }
302 else {
303 strncpy_s(format, sizeof(format), "R%s:%s:[%s]:%s", _TRUNCATE);
304 }
305 }
306 else {
307 if (strchr(spec->to_host, ':') == NULL) {
308 strncpy_s(format, sizeof(format), "R[%s]:%s:%s:%s", _TRUNCATE);
309 }
310 else {
311 strncpy_s(format, sizeof(format), "R[%s]:%s:[%s]:%s", _TRUNCATE);
312 }
313 }
314 _snprintf_s(str, str_remaining, _TRUNCATE, format,
315 spec->bind_address, spec->from_port_name,
316 spec->to_host, spec->to_port_name);
317 }
318 break;
319 case FWD_REMOTE_X11_TO_LOCAL:
320 _snprintf_s(str, str_remaining, _TRUNCATE, "X");
321 break;
322 case FWD_LOCAL_DYNAMIC:
323 _snprintf_s(str, str_remaining, _TRUNCATE, "D%s:%s",
324 spec->bind_address, spec->from_port_name);
325 }
326
327 chars = strlen(str);
328 str += chars;
329 str_remaining -= chars;
330 }
331 }
332
333 free(requests);
334 }
335
336 void FWDUI_load_settings(PTInstVar pvar)
337 {
338 char *str = pvar->settings.DefaultForwarding;
339
340 if (str[0] != 0) {
341 int i, ch, j;
342 FWDRequestSpec *requests;
343
344 j = 1;
345 for (i = 0; (ch = str[i]) != 0; i++) {
346 if (ch == ';') {
347 j++;
348 }
349 }
350
351 requests =
352 (FWDRequestSpec *) malloc(sizeof(FWDRequestSpec) * j);
353
354 j = 0;
355 if (parse_request(requests, str, pvar)) {
356 j++;
357 }
358 for (i = 0; (ch = str[i]) != 0; i++) {
359 if (ch == ';') {
360 if (parse_request(requests + j, str + i + 1, pvar)) {
361 j++;
362 }
363 }
364 }
365
366 qsort(requests, j, sizeof(FWDRequestSpec), FWD_compare_specs);
367
368 for (i = 0; i < j - 1; i++) {
369 if (FWD_compare_specs(requests + i, requests + i + 1) == 0) {
370 memmove(requests + i, requests + i + 1,
371 sizeof(FWDRequestSpec) * (j - 1 - i));
372 i--;
373 j--;
374 }
375 }
376
377 FWD_set_request_specs(pvar, requests, j);
378 FWDUI_save_settings(pvar);
379
380 free(requests);
381 }
382 }
383
384 void FWDUI_init(PTInstVar pvar)
385 {
386 FWDUI_load_settings(pvar);
387 }
388
389 void FWDUI_end(PTInstVar pvar)
390 {
391 }
392
393 void FWDUI_open(PTInstVar pvar)
394 {
395 }
396
397 static void set_verbose_port(char *buf, int bufsize, int port, char *name)
398 {
399 char *p = name;
400
401 while (*p && isdigit(*p)) {
402 p++;
403 }
404 if (*p == 0) {
405 strncpy_s(buf, bufsize, name, _TRUNCATE);
406 }
407 else {
408 _snprintf_s(buf, bufsize, _TRUNCATE, "%d (%s)", port, name);
409 }
410 }
411
412 static void get_spec_string(FWDRequestSpec *spec, char *buf,
413 int bufsize, PTInstVar pvar)
414 {
415 char verbose_from_port[64];
416 char verbose_to_port[64];
417
418 switch (spec->type) {
419 case FWD_REMOTE_TO_LOCAL:
420 set_verbose_port(verbose_from_port, sizeof(verbose_from_port),
421 spec->from_port, spec->from_port_name);
422 set_verbose_port(verbose_to_port, sizeof(verbose_to_port),
423 spec->to_port, spec->to_port_name);
424 UTIL_get_lang_msg("MSG_FWD_REMOTE", pvar,
425 "Remote \"%s\" port %s to local \"%s\" port %s");
426 _snprintf_s(buf, bufsize, _TRUNCATE, pvar->UIMsg,
427 spec->bind_address, verbose_from_port,
428 spec->to_host, verbose_to_port);
429 break;
430 case FWD_LOCAL_TO_REMOTE:
431 set_verbose_port(verbose_from_port, sizeof(verbose_from_port),
432 spec->from_port, spec->from_port_name);
433 set_verbose_port(verbose_to_port, sizeof(verbose_to_port),
434 spec->to_port, spec->to_port_name);
435 UTIL_get_lang_msg("MSG_FWD_LOCAL", pvar,
436 "Local \"%s\" port %s to remote \"%s\" port %s");
437 _snprintf_s(buf, bufsize, _TRUNCATE, pvar->UIMsg,
438 spec->bind_address, verbose_from_port,
439 spec->to_host, verbose_to_port);
440 break;
441 case FWD_REMOTE_X11_TO_LOCAL:
442 UTIL_get_lang_msg("MSG_FWD_X", pvar,
443 "Remote X applications to local X server");
444 strncpy_s(buf, bufsize, pvar->UIMsg, _TRUNCATE);
445 break;
446 case FWD_LOCAL_DYNAMIC:
447 set_verbose_port(verbose_from_port, sizeof(verbose_from_port),
448 spec->from_port, spec->from_port_name);
449 UTIL_get_lang_msg("MSG_FWD_DYNAMIC", pvar, "Local \"%s\" port %s to remote dynamic");
450 _snprintf_s(buf, bufsize, _TRUNCATE, pvar->UIMsg,
451 spec->bind_address, verbose_from_port);
452 break;
453 }
454 }
455
456 static void update_listbox_selection(HWND dlg)
457 {
458 HWND listbox = GetDlgItem(dlg, IDC_SSHFWDLIST);
459 int cursel = SendMessage(listbox, LB_GETCURSEL, 0, 0);
460
461 EnableWindow(GetDlgItem(dlg, IDC_EDIT), cursel >= 0);
462 EnableWindow(GetDlgItem(dlg, IDC_REMOVE), cursel >= 0);
463 }
464
465 static void init_listbox_selection(HWND dlg)
466 {
467 SendMessage(GetDlgItem(dlg, IDC_SSHFWDLIST), LB_SETCURSEL, 0, 0);
468 update_listbox_selection(dlg);
469 }
470
471 static int add_spec_to_listbox(HWND dlg, FWDRequestSpec *spec, PTInstVar pvar)
472 {
473 char buf[1024];
474 HWND listbox = GetDlgItem(dlg, IDC_SSHFWDLIST);
475 int index;
476
477 get_spec_string(spec, buf, sizeof(buf), pvar);
478
479 index = SendMessage(listbox, LB_ADDSTRING, 0, (LPARAM) buf);
480
481 if (index >= 0) {
482 FWDRequestSpec *listbox_spec = malloc(sizeof(FWDRequestSpec));
483
484 *listbox_spec = *spec;
485 if (SendMessage
486 (listbox, LB_SETITEMDATA, index,
487 (LPARAM) listbox_spec) == LB_ERR) {
488 free(listbox_spec);
489 }
490 }
491
492 return index;
493 }
494
495 static void init_fwd_dlg(PTInstVar pvar, HWND dlg)
496 {
497 int num_specs = FWD_get_num_request_specs(pvar);
498 FWDRequestSpec *requests =
499 (FWDRequestSpec *) malloc(sizeof(FWDRequestSpec) * num_specs);
500 int i;
501 static const DlgTextInfo text_info[] = {
502 { 0, "DLG_FWD_TITLE" },
503 { IDC_PORTFORWARD, "DLG_FWDSETUP_LIST" },
504 { IDC_ADD, "DLG_FWDSETUP_ADD" },
505 { IDC_EDIT, "DLG_FWDSETUP_EDIT" },
506 { IDC_REMOVE, "DLG_FWDSETUP_REMOVE" },
507 { IDC_XFORWARD, "DLG_FWDSETUP_X" },
508 { IDC_SSHFWDX11, "DLG_FWDSETUP_XAPP" },
509 { IDOK, "BTN_OK" },
510 { IDCANCEL, "BTN_CANCEL" },
511 { IDC_SSHFWDSETUP_HELP, "BTN_HELP" },
512 };
513 SetI18nDlgStrsW(dlg, "TTSSH", text_info, _countof(text_info), pvar->ts->UILanguageFileW);
514
515 FWD_get_request_specs(pvar, requests, num_specs);
516
517 for (i = 0; i < num_specs; i++) {
518 if (requests[i].type == FWD_REMOTE_X11_TO_LOCAL) {
519 CheckDlgButton(dlg, IDC_SSHFWDX11, TRUE);
520 } else {
521 add_spec_to_listbox(dlg, requests + i, pvar);
522 }
523 }
524
525 free(requests);
526
527 init_listbox_selection(dlg);
528 }
529
530 static void free_listbox_spec(HWND listbox, int selection)
531 {
532 FWDRequestSpec *spec = (FWDRequestSpec *)
533 SendMessage(listbox, LB_GETITEMDATA, selection, 0);
534
535 if (spec != NULL) {
536 free(spec);
537 }
538 }
539
540 static void free_all_listbox_specs(HWND dlg)
541 {
542 HWND listbox = GetDlgItem(dlg, IDC_SSHFWDLIST);
543 int i;
544
545 for (i = SendMessage(listbox, LB_GETCOUNT, 0, 0) - 1; i >= 0; i--) {
546 free_listbox_spec(listbox, i);
547 }
548 }
549
550 static BOOL end_fwd_dlg(PTInstVar pvar, HWND dlg)
551 {
552 char buf[1024];
553 HWND listbox = GetDlgItem(dlg, IDC_SSHFWDLIST);
554 int num_items = SendMessage(listbox, LB_GETCOUNT, 0, 0);
555 BOOL X_enabled = IsDlgButtonChecked(dlg, IDC_SSHFWDX11);
556 int num_specs = X_enabled ? 1 : 0;
557 FWDRequestSpec *specs =
558 (FWDRequestSpec *) malloc(sizeof(FWDRequestSpec) * (num_specs + num_items));
559 int i;
560 int num_unspecified_forwardings = 0;
561
562 for (i = 0; i < num_items; i++) {
563 FWDRequestSpec *spec = (FWDRequestSpec *)
564 SendMessage(listbox, LB_GETITEMDATA, i, 0);
565
566 if (spec != NULL) {
567 specs[num_specs] = *spec;
568 num_specs++;
569 }
570 }
571
572 if (X_enabled) {
573 make_X_forwarding_spec(specs, pvar);
574 }
575
576 qsort(specs, num_specs, sizeof(FWDRequestSpec), FWD_compare_specs);
577
578 buf[0] = '\0';
579 for (i = 0; i < num_specs; i++) {
580 if (i < num_specs - 1 && FWD_compare_specs(specs + i, specs + i + 1) == 0) {
581 switch (specs[i].type) {
582 case FWD_REMOTE_TO_LOCAL:
583 UTIL_get_lang_msg("MSG_SAME_SERVERPORT_ERROR", pvar,
584 "You cannot have two forwarding from the same server port (%d).");
585 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
586 pvar->UIMsg, specs[i].from_port);
587 break;
588 case FWD_LOCAL_TO_REMOTE:
589 case FWD_LOCAL_DYNAMIC:
590 UTIL_get_lang_msg("MSG_SAME_LOCALPORT_ERROR", pvar,
591 "You cannot have two forwarding from the same local port (%d).");
592 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
593 pvar->UIMsg, specs[i].from_port);
594 break;
595 }
596 notify_nonfatal_error(pvar, buf);
597
598 free(specs);
599 return FALSE;
600 }
601
602 if (!FWD_can_server_listen_for(pvar, specs + i)) {
603 num_unspecified_forwardings++;
604 }
605 }
606
607 if (num_unspecified_forwardings > 0) {
608 UTIL_get_lang_msg("MSG_UNSPECIFIED_FWD_ERROR1", pvar,
609 "The following forwarding was not specified when this SSH session began:\n\n");
610 strncat_s(buf, sizeof(buf), pvar->UIMsg, _TRUNCATE);
611
612 for (i = 0; i < num_specs; i++) {
613 if (!FWD_can_server_listen_for(pvar, specs + i)) {
614 char buf2[1024];
615
616 get_spec_string(specs + i, buf2, sizeof(buf2), pvar);
617
618 strncat_s(buf, sizeof(buf), buf2, _TRUNCATE);
619 strncat_s(buf, sizeof(buf), "\n", _TRUNCATE);
620 }
621 }
622
623 UTIL_get_lang_msg("MSG_UNSPECIFIED_FWD_ERROR2", pvar,
624 "\nDue to a limitation of the SSH protocol, this forwarding will not work in the current SSH session.\n"
625 "If you save these settings and start a new SSH session, the forwarding should work.");
626 strncat_s(buf, sizeof(buf), pvar->UIMsg, _TRUNCATE);
627
628 notify_nonfatal_error(pvar, buf);
629 }
630
631 FWD_set_request_specs(pvar, specs, num_specs);
632 FWDUI_save_settings(pvar);
633 free_all_listbox_specs(dlg);
634 EndDialog(dlg, 1);
635
636 free(specs);
637
638 return TRUE;
639 }
640
641 static void fill_service_names(HWND dlg, WORD item)
642 {
643 HWND cbox = GetDlgItem(dlg, item);
644 int i;
645 char *svc;
646
647 for (i=0; (svc = service_name(i)) != NULL; i++) {
648 SendMessage(cbox, CB_ADDSTRING, 0, (LPARAM) svc);
649 }
650 }
651
652 static void init_input(HWND dlg, FWDType type_to)
653 {
654 HWND dlg_item;
655
656 if (type_to == FWD_REMOTE_TO_LOCAL || type_to == FWD_LOCAL_DYNAMIC) {
657 dlg_item = GetDlgItem(dlg, IDC_SSHLTRFROMPORT);
658 EnableWindow(dlg_item, FALSE);
659 dlg_item = GetDlgItem(dlg, IDC_SSHLTRLISTENADDR);
660 EnableWindow(dlg_item, FALSE);
661 dlg_item = GetDlgItem(dlg, IDC_SSHLTRTOHOST);
662 EnableWindow(dlg_item, FALSE);
663 dlg_item = GetDlgItem(dlg, IDC_SSHLTRTOPORT);
664 EnableWindow(dlg_item, FALSE);
665 }
666 if (type_to == FWD_LOCAL_TO_REMOTE || type_to == FWD_LOCAL_DYNAMIC) {
667 dlg_item = GetDlgItem(dlg, IDC_SSHRTLFROMPORT);
668 EnableWindow(dlg_item, FALSE);
669 dlg_item = GetDlgItem(dlg, IDC_SSHRTLLISTENADDR);
670 EnableWindow(dlg_item, FALSE);
671 dlg_item = GetDlgItem(dlg, IDC_SSHRTLTOHOST);
672 EnableWindow(dlg_item, FALSE);
673 dlg_item = GetDlgItem(dlg, IDC_SSHRTLTOPORT);
674 EnableWindow(dlg_item, FALSE);
675 }
676 if (type_to == FWD_REMOTE_TO_LOCAL || type_to == FWD_LOCAL_TO_REMOTE) {
677 dlg_item = GetDlgItem(dlg, IDC_SSHDYNFROMPORT);
678 EnableWindow(dlg_item, FALSE);
679 dlg_item = GetDlgItem(dlg, IDC_SSHDYNLISTENADDR);
680 EnableWindow(dlg_item, FALSE);
681 }
682 }
683
684 static void shift_over_input(HWND dlg, FWDType type_from, FWDType type_to,
685 WORD rtl_item, WORD ltr_item, WORD dyn_item)
686 {
687 HWND shift_from = NULL;
688 HWND shift_to = NULL;
689
690 if (type_from == FWD_LOCAL_TO_REMOTE ) {
691 shift_from = GetDlgItem(dlg, ltr_item);
692 }
693 else if (type_from == FWD_REMOTE_TO_LOCAL) {
694 shift_from = GetDlgItem(dlg, rtl_item);
695 }
696 else if (type_from == FWD_LOCAL_DYNAMIC && dyn_item != 0) {
697 shift_from = GetDlgItem(dlg, dyn_item);
698 }
699
700 if (type_to == FWD_LOCAL_TO_REMOTE ) {
701 shift_to = GetDlgItem(dlg, ltr_item);
702 }
703 else if (type_to == FWD_REMOTE_TO_LOCAL) {
704 shift_to = GetDlgItem(dlg, rtl_item);
705 }
706 else if (type_to == FWD_LOCAL_DYNAMIC && dyn_item != 0) {
707 shift_to = GetDlgItem(dlg, dyn_item);
708 }
709
710 if (shift_from != 0) {
711 EnableWindow(shift_from, FALSE);
712 }
713 if (shift_to != 0) {
714 EnableWindow(shift_to, TRUE);
715 }
716
717 if (shift_from != 0 && shift_to != 0 && GetWindowTextLength(shift_to) == 0) {
718 char buf[128];
719
720 GetWindowText(shift_from, buf, sizeof(buf));
721 buf[sizeof(buf) - 1] = 0;
722 SetWindowText(shift_to, buf);
723 SetWindowText(shift_from, "");
724 }
725 }
726
727 static void set_dir_options_status(HWND dlg)
728 {
729 FWDType type_to, type_from;
730 BOOL enable_LTR, enable_RTL, enable_DYN;
731
732 type_to = FWD_REMOTE_TO_LOCAL;
733 if (IsDlgButtonChecked(dlg, IDC_SSHFWDLOCALTOREMOTE)) {
734 type_to = FWD_LOCAL_TO_REMOTE;
735 }
736 if (IsDlgButtonChecked(dlg, IDC_SSHFWDLOCALDYNAMIC)) {
737 type_to = FWD_LOCAL_DYNAMIC;
738 }
739
740 enable_LTR = IsWindowEnabled(GetDlgItem(dlg, IDC_SSHLTRFROMPORT));
741 enable_RTL = IsWindowEnabled(GetDlgItem(dlg, IDC_SSHRTLFROMPORT));
742 enable_DYN = IsWindowEnabled(GetDlgItem(dlg, IDC_SSHDYNFROMPORT));
743 type_from = FWD_NONE; // �_�C�A���O�\��������������Enable����
744 if (enable_LTR && !enable_RTL && !enable_DYN) {
745 type_from = FWD_LOCAL_TO_REMOTE;
746 }
747 else if (!enable_LTR && enable_RTL && !enable_DYN) {
748 type_from = FWD_REMOTE_TO_LOCAL;
749 }
750 else if (!enable_LTR && !enable_RTL && enable_DYN) {
751 type_from = FWD_LOCAL_DYNAMIC;
752 }
753
754 if (type_from == FWD_NONE) {
755 init_input(dlg, type_to);
756 }
757 else {
758 shift_over_input(dlg, type_from, type_to, IDC_SSHRTLFROMPORT, IDC_SSHLTRFROMPORT, IDC_SSHDYNFROMPORT);
759 shift_over_input(dlg, type_from, type_to, IDC_SSHRTLLISTENADDR, IDC_SSHLTRLISTENADDR, IDC_SSHDYNLISTENADDR);
760 shift_over_input(dlg, type_from, type_to, IDC_SSHRTLTOHOST, IDC_SSHLTRTOHOST, 0);
761 shift_over_input(dlg, type_from, type_to, IDC_SSHRTLTOPORT, IDC_SSHLTRTOPORT, 0);
762 }
763 }
764
765 static void setup_edit_controls(HWND dlg, FWDRequestSpec *spec,
766 WORD radio_item,
767 WORD from_port_item, WORD listen_address_item,
768 WORD to_host_item, WORD to_port_item)
769 {
770 CheckDlgButton(dlg, radio_item, TRUE);
771 SetFocus(GetDlgItem(dlg, radio_item));
772 SetDlgItemText(dlg, from_port_item, spec->from_port_name);
773 if (to_port_item != 0) {
774 SetDlgItemText(dlg, to_port_item, spec->to_port_name);
775 }
776 if (to_host_item != 0 && strcmp(spec->to_host, "localhost") != 0) {
777 SetDlgItemText(dlg, to_host_item, spec->to_host);
778 }
779 if (strcmp(spec->bind_address, "localhost") != 0) {
780 SetDlgItemText(dlg, listen_address_item, spec->bind_address);
781 }
782
783 set_dir_options_status(dlg);
784 }
785
786 static void init_fwd_edit_dlg(PTInstVar pvar, FWDRequestSpec *spec, HWND dlg)
787 {
788 static const DlgTextInfo text_info[] = {
789 { 0, "DLG_FWD_TITLE" },
790 { IDD_SSHFWDBANNER, "DLG_FWD_BANNER" },
791 { IDC_SSHFWDLOCALTOREMOTE, "DLG_FWD_LOCAL_PORT" },
792 { IDC_SSHFWDLOCALTOREMOTE_LISTEN, "DLG_FWD_LOCAL_LISTEN" },
793 { IDC_SSHFWDLOCALTOREMOTE_HOST, "DLG_FWD_LOCAL_REMOTE" },
794 { IDC_SSHFWDLOCALTOREMOTE_PORT, "DLG_FWD_LOCAL_REMOTE_PORT" },
795 { IDC_SSHFWDREMOTETOLOCAL, "DLG_FWD_REMOTE_PORT" },
796 { IDC_SSHFWDREMOTETOLOCAL_LISTEN, "DLG_FWD_REMOTE_LISTEN" },
797 { IDC_SSHFWDREMOTETOLOCAL_HOST, "DLG_FWD_REMOTE_LOCAL" },
798 { IDC_SSHFWDREMOTETOLOCAL_PORT, "DLG_FWD_REMOTE_LOCAL_PORT" },
799 { IDC_SSHFWDLOCALDYNAMIC, "DLG_FWD_DYNAMIC_PORT" },
800 { IDC_SSHFWDLOCALDYNAMIC_LISTEN, "DLG_FWD_DYNAMIC_LISTEN" },
801 { IDOK, "BTN_OK" },
802 { IDCANCEL, "BTN_CANCEL" },
803 };
804 SetI18nDlgStrsW(dlg, "TTSSH", text_info, _countof(text_info), pvar->ts->UILanguageFileW);
805
806 switch (spec->type) {
807 case FWD_REMOTE_TO_LOCAL:
808 setup_edit_controls(dlg, spec, IDC_SSHFWDREMOTETOLOCAL,
809 IDC_SSHRTLFROMPORT, IDC_SSHRTLLISTENADDR,
810 IDC_SSHRTLTOHOST, IDC_SSHRTLTOPORT);
811 break;
812 case FWD_LOCAL_TO_REMOTE:
813 setup_edit_controls(dlg, spec, IDC_SSHFWDLOCALTOREMOTE,
814 IDC_SSHLTRFROMPORT, IDC_SSHLTRLISTENADDR,
815 IDC_SSHLTRTOHOST, IDC_SSHLTRTOPORT);
816 break;
817 case FWD_LOCAL_DYNAMIC:
818 setup_edit_controls(dlg, spec, IDC_SSHFWDLOCALDYNAMIC,
819 IDC_SSHDYNFROMPORT, IDC_SSHDYNLISTENADDR,
820 0, 0);
821 break;
822 }
823
824 fill_service_names(dlg, IDC_SSHRTLFROMPORT);
825 fill_service_names(dlg, IDC_SSHLTRFROMPORT);
826 fill_service_names(dlg, IDC_SSHRTLTOPORT);
827 fill_service_names(dlg, IDC_SSHLTRTOPORT);
828 }
829
830 static void grab_control_text(HWND dlg, FWDType type,
831 WORD rtl_item, WORD ltr_item, WORD dyn_item,
832 char *buf, int bufsize)
833 {
834 WORD dlg_item = ltr_item;
835 if (type == FWD_REMOTE_TO_LOCAL) {
836 dlg_item = rtl_item;
837 }
838 else if (type == FWD_LOCAL_DYNAMIC) {
839 dlg_item = dyn_item;
840 }
841
842 GetDlgItemText(dlg, dlg_item, buf, bufsize);
843 buf[bufsize - 1] = 0;
844 }
845
846 static BOOL end_fwd_edit_dlg(PTInstVar pvar, FWDRequestSpec *spec, HWND dlg)
847 {
848 FWDRequestSpec new_spec;
849 FWDType type;
850 char buf[1024];
851
852 type = FWD_LOCAL_TO_REMOTE;
853 if (IsDlgButtonChecked(dlg, IDC_SSHFWDREMOTETOLOCAL)) {
854 type = FWD_REMOTE_TO_LOCAL;
855 }
856 else if (IsDlgButtonChecked(dlg, IDC_SSHFWDLOCALDYNAMIC)) {
857 type = FWD_LOCAL_DYNAMIC;
858 }
859 new_spec.type = type;
860
861 grab_control_text(dlg, type,
862 IDC_SSHRTLFROMPORT, IDC_SSHLTRFROMPORT, IDC_SSHDYNFROMPORT,
863 new_spec.from_port_name, sizeof(new_spec.from_port_name));
864
865 grab_control_text(dlg, type,
866 IDC_SSHRTLLISTENADDR, IDC_SSHLTRLISTENADDR, IDC_SSHDYNLISTENADDR,
867 new_spec.bind_address, sizeof(new_spec.bind_address));
868 if (new_spec.bind_address[0] == 0) {
869 strncpy_s(new_spec.bind_address, sizeof(new_spec.bind_address), "localhost", _TRUNCATE);
870 }
871 else if (strcmp(new_spec.bind_address, "*") == 0 ) {
872 strncpy_s(new_spec.bind_address, sizeof(new_spec.bind_address), "0.0.0.0", _TRUNCATE);
873 }
874 else {
875 // IPv6 �A�h���X�� "[", "]" ������������
876 if (new_spec.bind_address[strlen(new_spec.bind_address)-1] == ']') {
877 new_spec.bind_address[strlen(new_spec.bind_address)-1] = '\0';
878 }
879 if (new_spec.bind_address[0] == '[') {
880 memmove(new_spec.bind_address, new_spec.bind_address + 1, strlen(new_spec.bind_address)+1);
881 }
882 }
883
884 if (type == FWD_LOCAL_TO_REMOTE || type == FWD_REMOTE_TO_LOCAL) {
885 grab_control_text(dlg, type,
886 IDC_SSHRTLTOHOST, IDC_SSHLTRTOHOST, 0,
887 new_spec.to_host, sizeof(new_spec.to_host));
888 if (new_spec.to_host[0] == 0) {
889 strncpy_s(new_spec.to_host, sizeof(new_spec.to_host), "localhost", _TRUNCATE);
890 }
891 else {
892 // IPv6 �A�h���X�� "[", "]" ������������
893 if (new_spec.to_host[strlen(new_spec.to_host)-1] == ']') {
894 new_spec.to_host[strlen(new_spec.to_host)-1] = '\0';
895 }
896 if (new_spec.to_host[0] == '[') {
897 memmove(new_spec.to_host, new_spec.to_host + 1, strlen(new_spec.to_host)+1);
898 }
899 }
900
901 grab_control_text(dlg, type,
902 IDC_SSHRTLTOPORT, IDC_SSHLTRTOPORT, 0,
903 new_spec.to_port_name, sizeof(new_spec.to_port_name));
904 }
905
906 new_spec.from_port = parse_port_from_buf(new_spec.from_port_name);
907 if (new_spec.from_port < 0) {
908 UTIL_get_lang_msg("MSG_INVALID_PORT_ERROR", pvar,
909 "Port \"%s\" is not a valid port number.\n"
910 "Either choose a port name from the list, or enter a number between 1 and 65535.");
911 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
912 pvar->UIMsg, new_spec.from_port_name);
913 notify_nonfatal_error(pvar, buf);
914 return FALSE;
915 }
916
917 if (type == FWD_LOCAL_TO_REMOTE || type == FWD_REMOTE_TO_LOCAL) {
918 new_spec.to_port = parse_port_from_buf(new_spec.to_port_name);
919 if (new_spec.to_port < 0) {
920 UTIL_get_lang_msg("MSG_INVALID_PORT_ERROR", pvar,
921 "Port \"%s\" is not a valid port number.\n"
922 "Either choose a port name from the list, or enter a number between 1 and 65535.");
923 _snprintf_s(buf, sizeof(buf), _TRUNCATE,
924 pvar->UIMsg, new_spec.to_port_name);
925 notify_nonfatal_error(pvar, buf);
926 return FALSE;
927 }
928 }
929
930 *spec = new_spec;
931
932 EndDialog(dlg, 1);
933 return TRUE;
934 }
935
936 static INT_PTR CALLBACK fwd_edit_dlg_proc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam)
937 {
938 FWDEditClosure *closure;
939 PTInstVar pvar;
940 BOOL result;
941
942 switch (msg) {
943 case WM_INITDIALOG:
944 closure = (FWDEditClosure *) lParam;
945 SetWindowLongPtr(dlg, DWLP_USER, lParam);
946
947 pvar = closure->pvar;
948 init_fwd_edit_dlg(pvar, closure->spec, dlg);
949 CenterWindow(dlg, GetParent(dlg));
950 return FALSE; /* because we set the focus */
951
952 case WM_COMMAND:
953 closure = (FWDEditClosure *) GetWindowLongPtr(dlg, DWLP_USER);
954
955 switch (LOWORD(wParam)) {
956 case IDOK:
957
958 result = end_fwd_edit_dlg(closure->pvar, closure->spec, dlg);
959
960 if (result) {
961 }
962
963 return result;
964
965 case IDCANCEL:
966 EndDialog(dlg, 0);
967 return TRUE;
968
969 case IDC_SSHFWDLOCALTOREMOTE:
970 case IDC_SSHFWDREMOTETOLOCAL:
971 case IDC_SSHFWDLOCALDYNAMIC:
972 set_dir_options_status(dlg);
973 return TRUE;
974
975 default:
976 return FALSE;
977 }
978
979 default:
980 return FALSE;
981 }
982 }
983
984 static void add_forwarding_entry(PTInstVar pvar, HWND dlg)
985 {
986 FWDRequestSpec new_spec;
987 INT_PTR result;
988 FWDEditClosure closure = { &new_spec, pvar };
989
990 new_spec.type = FWD_LOCAL_TO_REMOTE;
991 new_spec.from_port_name[0] = 0;
992 new_spec.bind_address[0] = 0;
993 new_spec.to_host[0] = 0;
994 new_spec.to_port_name[0] = 0;
995
996 result = DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHFWDEDIT),
997 dlg, fwd_edit_dlg_proc, (LPARAM) & closure);
998
999 if (result == -1) {
1000 UTIL_get_lang_msg("MSG_CREATEWINDOW_FWDEDIT_ERROR", pvar,
1001 "Unable to display forwarding edit dialog box.");
1002 notify_nonfatal_error(pvar, pvar->UIMsg);
1003 } else if (result) {
1004 int index = add_spec_to_listbox(dlg, &new_spec, pvar);
1005
1006 if (index >= 0) {
1007 SendMessage(GetDlgItem(dlg, IDC_SSHFWDLIST), LB_SETCURSEL,
1008 index, 0);
1009 }
1010 update_listbox_selection(dlg);
1011 }
1012 }
1013
1014 static void edit_forwarding_entry(PTInstVar pvar, HWND dlg)
1015 {
1016 HWND listbox = GetDlgItem(dlg, IDC_SSHFWDLIST);
1017 int cursel = SendMessage(listbox, LB_GETCURSEL, 0, 0);
1018
1019 if (cursel >= 0) {
1020 FWDRequestSpec *spec = (FWDRequestSpec *)
1021 SendMessage(listbox, LB_GETITEMDATA, cursel, 0);
1022
1023 if (spec != NULL) {
1024 FWDEditClosure closure = { spec, pvar };
1025
1026 INT_PTR result =
1027 DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHFWDEDIT),
1028 dlg, fwd_edit_dlg_proc, (LPARAM) & closure);
1029
1030 if (result == -1) {
1031 UTIL_get_lang_msg("MSG_CREATEWINDOW_FWDEDIT_ERROR", pvar,
1032 "Unable to display forwarding edit dialog box.");
1033 notify_nonfatal_error(pvar, pvar->UIMsg);
1034 } else if (result) {
1035 SendMessage(listbox, LB_DELETESTRING, cursel, 0);
1036
1037 cursel = add_spec_to_listbox(dlg, spec, pvar);
1038 free(spec);
1039 if (cursel >= 0) {
1040 SendMessage(GetDlgItem(dlg, IDC_SSHFWDLIST),
1041 LB_SETCURSEL, cursel, 0);
1042 }
1043 update_listbox_selection(dlg);
1044 }
1045 }
1046 }
1047 }
1048
1049 static void remove_forwarding_entry(HWND dlg)
1050 {
1051 HWND listbox = GetDlgItem(dlg, IDC_SSHFWDLIST);
1052 int cursel = SendMessage(listbox, LB_GETCURSEL, 0, 0);
1053
1054 if (cursel >= 0) {
1055 free_listbox_spec(listbox, cursel);
1056 SendMessage(listbox, LB_DELETESTRING, cursel, 0);
1057 init_listbox_selection(dlg);
1058 }
1059 }
1060
1061 static INT_PTR CALLBACK fwd_dlg_proc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam)
1062 {
1063 PTInstVar pvar;
1064 BOOL ret;
1065
1066 switch (msg) {
1067 case WM_INITDIALOG:
1068 pvar = (PTInstVar) lParam;
1069 SetWindowLongPtr(dlg, DWLP_USER, lParam);
1070
1071 init_fwd_dlg(pvar, dlg);
1072 CenterWindow(dlg, GetParent(dlg));
1073 return TRUE; /* because we do not set the focus */
1074
1075 case WM_COMMAND:
1076 pvar = (PTInstVar) GetWindowLongPtr(dlg, DWLP_USER);
1077
1078 switch (LOWORD(wParam)) {
1079 case IDOK:
1080
1081 ret = end_fwd_dlg(pvar, dlg);
1082 return ret;
1083
1084 case IDCANCEL:
1085 free_all_listbox_specs(dlg);
1086 EndDialog(dlg, 0);
1087 return TRUE;
1088
1089 case IDC_SSHFWDSETUP_HELP:
1090 PostMessage(GetParent(dlg), WM_USER_DLGHELP2, HlpMenuSetupSshforward, 0);
1091 return TRUE;
1092
1093 case IDC_ADD:
1094 add_forwarding_entry(pvar, dlg);
1095 return TRUE;
1096
1097 case IDC_EDIT:
1098 edit_forwarding_entry(pvar, dlg);
1099 return TRUE;
1100
1101 case IDC_REMOVE:
1102 remove_forwarding_entry(dlg);
1103 return TRUE;
1104
1105 case IDC_SSHFWDLIST:
1106 update_listbox_selection(dlg);
1107 return TRUE;
1108
1109 default:
1110 return FALSE;
1111 }
1112
1113 default:
1114 return FALSE;
1115 }
1116 }
1117
1118 void FWDUI_do_forwarding_dialog(PTInstVar pvar)
1119 {
1120 HWND cur_active = GetActiveWindow();
1121
1122 if (DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SSHFWDSETUP),
1123 cur_active != NULL ? cur_active
1124 : pvar->NotificationWindow,
1125 fwd_dlg_proc, (LPARAM) pvar) == -1) {
1126 UTIL_get_lang_msg("MSG_CREATEWINDOW_FWDSETUP_ERROR", pvar,
1127 "Unable to display forwarding setup dialog box.");
1128 notify_nonfatal_error(pvar, pvar->UIMsg);
1129 }
1130 }
1131
1132 /* vim: set ts=4 sw=4 ff=dos : */

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