While we're doing a hostkey reorg, store port numbers as well
[u/mdw/putty] / windlg.c
CommitLineData
374330e2 1#include <windows.h>
2#include <commctrl.h>
3#include <commdlg.h>
4d331a77 4#ifndef AUTO_WINSOCK
5#ifdef WINSOCK_TWO
6#include <winsock2.h>
7#else
374330e2 8#include <winsock.h>
4d331a77 9#endif
10#endif
374330e2 11#include <stdio.h>
12#include <stdlib.h>
13
374330e2 14#include "ssh.h"
bea1ef5f 15#include "putty.h"
374330e2 16#include "win_res.h"
d5859615 17#include "storage.h"
374330e2 18
14963b8f 19#define NPANELS 8
20#define MAIN_NPANELS 8
21#define RECONF_NPANELS 5
374330e2 22
c5e9c988 23static char **events = NULL;
24static int nevents = 0, negsize = 0;
25
374330e2 26static HWND logbox = NULL, abtbox = NULL;
27
d1622aed 28static void gpps(void *handle, char *name, char *def, char *val, int len) {
29 if (!read_setting_s(handle, name, val, len)) {
374330e2 30 strncpy(val, def, len);
31 val[len-1] = '\0';
32 }
33}
34
d1622aed 35static void gppi(void *handle, char *name, int def, int *i) {
36 *i = read_setting_i(handle, name, def);
374330e2 37}
38
374330e2 39static HINSTANCE hinst;
40
1cd246bb 41static int readytogo;
42
374330e2 43static void save_settings (char *section, int do_host) {
44 int i;
374330e2 45 char *p;
d1622aed 46 void *sesskey;
374330e2 47
d1622aed 48 sesskey = open_settings_w(section);
49 if (!sesskey)
50 return;
374330e2 51
d1622aed 52 write_setting_i (sesskey, "Present", 1);
374330e2 53 if (do_host) {
d1622aed 54 write_setting_s (sesskey, "HostName", cfg.host);
55 write_setting_i (sesskey, "PortNumber", cfg.port);
89ee5268 56 p = "raw";
a721b9eb 57 for (i = 0; backends[i].name != NULL; i++)
89ee5268 58 if (backends[i].protocol == cfg.protocol) {
59 p = backends[i].name;
60 break;
61 }
d1622aed 62 write_setting_s (sesskey, "Protocol", p);
374330e2 63 }
d1622aed 64 write_setting_i (sesskey, "CloseOnExit", !!cfg.close_on_exit);
65 write_setting_i (sesskey, "WarnOnClose", !!cfg.warn_on_close);
66 write_setting_s (sesskey, "TerminalType", cfg.termtype);
67 write_setting_s (sesskey, "TerminalSpeed", cfg.termspeed);
374330e2 68 {
37508af4 69 char buf[2*sizeof(cfg.environmt)], *p, *q;
374330e2 70 p = buf;
37508af4 71 q = cfg.environmt;
374330e2 72 while (*q) {
73 while (*q) {
74 int c = *q++;
75 if (c == '=' || c == ',' || c == '\\')
76 *p++ = '\\';
77 if (c == '\t')
78 c = '=';
79 *p++ = c;
80 }
81 *p++ = ',';
82 q++;
83 }
84 *p = '\0';
d1622aed 85 write_setting_s (sesskey, "Environment", buf);
374330e2 86 }
d1622aed 87 write_setting_s (sesskey, "UserName", cfg.username);
88 write_setting_i (sesskey, "NoPTY", cfg.nopty);
89 write_setting_i (sesskey, "AgentFwd", cfg.agentfwd);
90 write_setting_s (sesskey, "RemoteCmd", cfg.remote_cmd);
91 write_setting_s (sesskey, "Cipher", cfg.cipher == CIPHER_BLOWFISH ? "blowfish" :
9697bfd2 92 cfg.cipher == CIPHER_DES ? "des" : "3des");
d1622aed 93 write_setting_i (sesskey, "AuthTIS", cfg.try_tis_auth);
94 write_setting_i (sesskey, "SshProt", cfg.sshprot);
95 write_setting_s (sesskey, "PublicKeyFile", cfg.keyfile);
96 write_setting_i (sesskey, "RFCEnviron", cfg.rfc_environ);
97 write_setting_i (sesskey, "BackspaceIsDelete", cfg.bksp_is_delete);
98 write_setting_i (sesskey, "RXVTHomeEnd", cfg.rxvt_homeend);
99 write_setting_i (sesskey, "LinuxFunctionKeys", cfg.funky_type);
100 write_setting_i (sesskey, "ApplicationCursorKeys", cfg.app_cursor);
101 write_setting_i (sesskey, "ApplicationKeypad", cfg.app_keypad);
102 write_setting_i (sesskey, "NetHackKeypad", cfg.nethack_keypad);
103 write_setting_i (sesskey, "AltF4", cfg.alt_f4);
104 write_setting_i (sesskey, "AltSpace", cfg.alt_space);
105 write_setting_i (sesskey, "LdiscTerm", cfg.ldisc_term);
106 write_setting_i (sesskey, "BlinkCur", cfg.blink_cur);
107 write_setting_i (sesskey, "Beep", cfg.beep);
108 write_setting_i (sesskey, "ScrollbackLines", cfg.savelines);
109 write_setting_i (sesskey, "DECOriginMode", cfg.dec_om);
110 write_setting_i (sesskey, "AutoWrapMode", cfg.wrap_mode);
111 write_setting_i (sesskey, "LFImpliesCR", cfg.lfhascr);
112 write_setting_i (sesskey, "WinNameAlways", cfg.win_name_always);
113 write_setting_i (sesskey, "TermWidth", cfg.width);
114 write_setting_i (sesskey, "TermHeight", cfg.height);
115 write_setting_s (sesskey, "Font", cfg.font);
116 write_setting_i (sesskey, "FontIsBold", cfg.fontisbold);
117 write_setting_i (sesskey, "FontCharSet", cfg.fontcharset);
118 write_setting_i (sesskey, "FontHeight", cfg.fontheight);
119 write_setting_i (sesskey, "FontVTMode", cfg.vtmode);
120 write_setting_i (sesskey, "TryPalette", cfg.try_palette);
121 write_setting_i (sesskey, "BoldAsColour", cfg.bold_colour);
374330e2 122 for (i=0; i<22; i++) {
123 char buf[20], buf2[30];
124 sprintf(buf, "Colour%d", i);
125 sprintf(buf2, "%d,%d,%d", cfg.colours[i][0],
126 cfg.colours[i][1], cfg.colours[i][2]);
d1622aed 127 write_setting_s (sesskey, buf, buf2);
374330e2 128 }
d1622aed 129 write_setting_i (sesskey, "MouseIsXterm", cfg.mouse_is_xterm);
374330e2 130 for (i=0; i<256; i+=32) {
131 char buf[20], buf2[256];
132 int j;
133 sprintf(buf, "Wordness%d", i);
134 *buf2 = '\0';
135 for (j=i; j<i+32; j++) {
136 sprintf(buf2+strlen(buf2), "%s%d",
137 (*buf2 ? "," : ""), cfg.wordness[j]);
138 }
d1622aed 139 write_setting_s (sesskey, buf, buf2);
374330e2 140 }
d1622aed 141 write_setting_i (sesskey, "KoiWinXlat", cfg.xlat_enablekoiwin);
142 write_setting_i (sesskey, "88592Xlat", cfg.xlat_88592w1250);
143 write_setting_i (sesskey, "CapsLockCyr", cfg.xlat_capslockcyr);
144 write_setting_i (sesskey, "ScrollBar", cfg.scrollbar);
145 write_setting_i (sesskey, "ScrollOnKey", cfg.scroll_on_key);
146 write_setting_i (sesskey, "LockSize", cfg.locksize);
147 write_setting_i (sesskey, "BCE", cfg.bce);
148 write_setting_i (sesskey, "BlinkText", cfg.blinktext);
149
150 close_settings_w(sesskey);
374330e2 151}
152
153static void load_settings (char *section, int do_host) {
154 int i;
e277c42d 155 char prot[10];
d1622aed 156 void *sesskey;
374330e2 157
d1622aed 158 sesskey = open_settings_r(section);
374330e2 159
e277c42d 160 gpps (sesskey, "HostName", "", cfg.host, sizeof(cfg.host));
161 gppi (sesskey, "PortNumber", default_port, &cfg.port);
89ee5268 162
e277c42d 163 gpps (sesskey, "Protocol", "default", prot, 10);
89ee5268 164 cfg.protocol = default_protocol;
a721b9eb 165 for (i = 0; backends[i].name != NULL; i++)
89ee5268 166 if (!strcmp(prot, backends[i].name)) {
167 cfg.protocol = backends[i].protocol;
168 break;
169 }
e277c42d 170
374330e2 171 gppi (sesskey, "CloseOnExit", 1, &cfg.close_on_exit);
9ef49106 172 gppi (sesskey, "WarnOnClose", 1, &cfg.warn_on_close);
374330e2 173 gpps (sesskey, "TerminalType", "xterm", cfg.termtype,
174 sizeof(cfg.termtype));
175 gpps (sesskey, "TerminalSpeed", "38400,38400", cfg.termspeed,
176 sizeof(cfg.termspeed));
177 {
37508af4 178 char buf[2*sizeof(cfg.environmt)], *p, *q;
374330e2 179 gpps (sesskey, "Environment", "", buf, sizeof(buf));
180 p = buf;
29b611b7 181 q = cfg.environmt;
374330e2 182 while (*p) {
183 while (*p && *p != ',') {
184 int c = *p++;
185 if (c == '=')
186 c = '\t';
187 if (c == '\\')
188 c = *p++;
29b611b7 189 *q++ = c;
374330e2 190 }
191 if (*p == ',') p++;
192 *q++ = '\0';
193 }
194 *q = '\0';
195 }
196 gpps (sesskey, "UserName", "", cfg.username, sizeof(cfg.username));
fef97f43 197 gppi (sesskey, "NoPTY", 0, &cfg.nopty);
979310f1 198 gppi (sesskey, "AgentFwd", 0, &cfg.agentfwd);
6abbf9e3 199 gpps (sesskey, "RemoteCmd", "", cfg.remote_cmd, sizeof(cfg.remote_cmd));
bea1ef5f 200 {
201 char cipher[10];
202 gpps (sesskey, "Cipher", "3des", cipher, 10);
203 if (!strcmp(cipher, "blowfish"))
204 cfg.cipher = CIPHER_BLOWFISH;
9697bfd2 205 else if (!strcmp(cipher, "des"))
206 cfg.cipher = CIPHER_DES;
bea1ef5f 207 else
208 cfg.cipher = CIPHER_3DES;
209 }
adf799dd 210 gppi (sesskey, "SshProt", 1, &cfg.sshprot);
ccbfb941 211 gppi (sesskey, "AuthTIS", 0, &cfg.try_tis_auth);
7cca0d81 212 gpps (sesskey, "PublicKeyFile", "", cfg.keyfile, sizeof(cfg.keyfile));
374330e2 213 gppi (sesskey, "RFCEnviron", 0, &cfg.rfc_environ);
214 gppi (sesskey, "BackspaceIsDelete", 1, &cfg.bksp_is_delete);
215 gppi (sesskey, "RXVTHomeEnd", 0, &cfg.rxvt_homeend);
c9def1b8 216 gppi (sesskey, "LinuxFunctionKeys", 0, &cfg.funky_type);
374330e2 217 gppi (sesskey, "ApplicationCursorKeys", 0, &cfg.app_cursor);
218 gppi (sesskey, "ApplicationKeypad", 0, &cfg.app_keypad);
c5e9c988 219 gppi (sesskey, "NetHackKeypad", 0, &cfg.nethack_keypad);
220 gppi (sesskey, "AltF4", 1, &cfg.alt_f4);
221 gppi (sesskey, "AltSpace", 0, &cfg.alt_space);
5bc238bb 222 gppi (sesskey, "LdiscTerm", 0, &cfg.ldisc_term);
217dceef 223 gppi (sesskey, "BlinkCur", 0, &cfg.blink_cur);
2a25a1b4 224 gppi (sesskey, "Beep", 1, &cfg.beep);
374330e2 225 gppi (sesskey, "ScrollbackLines", 200, &cfg.savelines);
226 gppi (sesskey, "DECOriginMode", 0, &cfg.dec_om);
227 gppi (sesskey, "AutoWrapMode", 1, &cfg.wrap_mode);
fef97f43 228 gppi (sesskey, "LFImpliesCR", 0, &cfg.lfhascr);
374330e2 229 gppi (sesskey, "WinNameAlways", 0, &cfg.win_name_always);
230 gppi (sesskey, "TermWidth", 80, &cfg.width);
231 gppi (sesskey, "TermHeight", 24, &cfg.height);
232 gpps (sesskey, "Font", "Courier", cfg.font, sizeof(cfg.font));
233 gppi (sesskey, "FontIsBold", 0, &cfg.fontisbold);
14963b8f 234 gppi (sesskey, "FontCharSet", ANSI_CHARSET, &cfg.fontcharset);
374330e2 235 gppi (sesskey, "FontHeight", 10, &cfg.fontheight);
2a7bfc6e 236 gppi (sesskey, "FontVTMode", VT_OEMANSI, (int *)&cfg.vtmode);
374330e2 237 gppi (sesskey, "TryPalette", 0, &cfg.try_palette);
238 gppi (sesskey, "BoldAsColour", 1, &cfg.bold_colour);
239 for (i=0; i<22; i++) {
240 static char *defaults[] = {
241 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
242 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
243 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
244 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
245 "85,255,255", "187,187,187", "255,255,255"
246 };
247 char buf[20], buf2[30];
1d470ad2 248 int c0, c1, c2;
374330e2 249 sprintf(buf, "Colour%d", i);
250 gpps (sesskey, buf, defaults[i], buf2, sizeof(buf2));
1d470ad2 251 if(sscanf(buf2, "%d,%d,%d", &c0, &c1, &c2) == 3) {
252 cfg.colours[i][0] = c0;
253 cfg.colours[i][1] = c1;
254 cfg.colours[i][2] = c2;
255 }
374330e2 256 }
257 gppi (sesskey, "MouseIsXterm", 0, &cfg.mouse_is_xterm);
258 for (i=0; i<256; i+=32) {
259 static char *defaults[] = {
260 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
261 "0,1,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1",
262 "1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2",
263 "1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1",
264 "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",
265 "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",
266 "2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2",
267 "2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2"
268 };
269 char buf[20], buf2[256], *p;
270 int j;
271 sprintf(buf, "Wordness%d", i);
272 gpps (sesskey, buf, defaults[i/32], buf2, sizeof(buf2));
273 p = buf2;
274 for (j=i; j<i+32; j++) {
275 char *q = p;
276 while (*p && *p != ',') p++;
277 if (*p == ',') *p++ = '\0';
278 cfg.wordness[j] = atoi(q);
279 }
280 }
14963b8f 281 gppi (sesskey, "KoiWinXlat", 0, &cfg.xlat_enablekoiwin);
d3d16feb 282 gppi (sesskey, "88592Xlat", 0, &cfg.xlat_88592w1250);
14963b8f 283 gppi (sesskey, "CapsLockCyr", 0, &cfg.xlat_capslockcyr);
c9def1b8 284 gppi (sesskey, "ScrollBar", 1, &cfg.scrollbar);
285 gppi (sesskey, "ScrollOnKey", 0, &cfg.scroll_on_key);
286 gppi (sesskey, "LockSize", 0, &cfg.locksize);
287 gppi (sesskey, "BCE", 0, &cfg.bce);
288 gppi (sesskey, "BlinkText", 0, &cfg.blinktext);
14963b8f 289
d1622aed 290 close_settings_r(sesskey);
374330e2 291}
292
c9def1b8 293static void force_normal(HWND hwnd)
294{
295static int recurse = 0;
296
297 WINDOWPLACEMENT wp;
298
299 if(recurse) return;
300 recurse = 1;
301
302 wp.length = sizeof(wp);
303 if (GetWindowPlacement(hwnd, &wp))
304 {
305 wp.showCmd = SW_SHOWNORMAL;
306 SetWindowPlacement(hwnd, &wp);
307 }
308 recurse = 0;
309}
310
374330e2 311static void MyGetDlgItemInt (HWND hwnd, int id, int *result) {
312 BOOL ok;
313 int n;
314 n = GetDlgItemInt (hwnd, id, &ok, FALSE);
315 if (ok)
316 *result = n;
317}
318
319static int CALLBACK LogProc (HWND hwnd, UINT msg,
320 WPARAM wParam, LPARAM lParam) {
321 int i;
322
323 switch (msg) {
324 case WM_INITDIALOG:
c5e9c988 325 for (i=0; i<nevents; i++)
374330e2 326 SendDlgItemMessage (hwnd, IDN_LIST, LB_ADDSTRING,
c5e9c988 327 0, (LPARAM)events[i]);
374330e2 328 return 1;
329/* case WM_CTLCOLORDLG: */
330/* return (int) GetStockObject (LTGRAY_BRUSH); */
331 case WM_COMMAND:
332 switch (LOWORD(wParam)) {
333 case IDOK:
334 logbox = NULL;
335 DestroyWindow (hwnd);
336 return 0;
989b10e9 337 case IDN_COPY:
338 if (HIWORD(wParam) == BN_CLICKED ||
339 HIWORD(wParam) == BN_DOUBLECLICKED) {
340 int selcount;
341 int *selitems;
342 selcount = SendDlgItemMessage(hwnd, IDN_LIST,
343 LB_GETSELCOUNT, 0, 0);
344 selitems = malloc(selcount * sizeof(int));
345 if (selitems) {
346 int count = SendDlgItemMessage(hwnd, IDN_LIST,
347 LB_GETSELITEMS,
348 selcount, (LPARAM)selitems);
349 int i;
350 int size;
351 char *clipdata;
352 static unsigned char sel_nl[] = SEL_NL;
353
354 size = 0;
355 for (i = 0; i < count; i++)
356 size += strlen(events[selitems[i]]) + sizeof(sel_nl);
357
358 clipdata = malloc(size);
359 if (clipdata) {
360 char *p = clipdata;
361 for (i = 0; i < count; i++) {
362 char *q = events[selitems[i]];
363 int qlen = strlen(q);
364 memcpy(p, q, qlen);
365 p += qlen;
366 memcpy(p, sel_nl, sizeof(sel_nl));
367 p += sizeof(sel_nl);
368 }
369 write_clip(clipdata, size);
370 term_deselect();
371 free(clipdata);
372 }
373 free(selitems);
374 }
375 }
376 return 0;
374330e2 377 }
378 return 0;
379 case WM_CLOSE:
380 logbox = NULL;
381 DestroyWindow (hwnd);
382 return 0;
383 }
384 return 0;
385}
386
d57835ab 387static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
388 WPARAM wParam, LPARAM lParam) {
389 switch (msg) {
390 case WM_INITDIALOG:
391 return 1;
392 case WM_COMMAND:
393 switch (LOWORD(wParam)) {
394 case IDOK:
395 abtbox = NULL;
396 DestroyWindow (hwnd);
397 return 0;
398 }
399 return 0;
400 case WM_CLOSE:
401 abtbox = NULL;
402 DestroyWindow (hwnd);
403 return 0;
404 }
405 return 0;
406}
407
374330e2 408static int CALLBACK AboutProc (HWND hwnd, UINT msg,
409 WPARAM wParam, LPARAM lParam) {
410 switch (msg) {
411 case WM_INITDIALOG:
067a15ea 412 SetDlgItemText (hwnd, IDA_VERSION, ver);
374330e2 413 return 1;
414/* case WM_CTLCOLORDLG: */
415/* return (int) GetStockObject (LTGRAY_BRUSH); */
416/* case WM_CTLCOLORSTATIC: */
417/* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
418/* return (int) GetStockObject (LTGRAY_BRUSH); */
419 case WM_COMMAND:
420 switch (LOWORD(wParam)) {
421 case IDOK:
422 abtbox = NULL;
423 DestroyWindow (hwnd);
424 return 0;
425 case IDA_LICENCE:
426 EnableWindow(hwnd, 0);
427 DialogBox (hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
d57835ab 428 NULL, LicenceProc);
374330e2 429 EnableWindow(hwnd, 1);
9a70ac47 430 SetActiveWindow(hwnd);
374330e2 431 return 0;
432 }
433 return 0;
434 case WM_CLOSE:
435 abtbox = NULL;
436 DestroyWindow (hwnd);
437 return 0;
438 }
439 return 0;
440}
441
442static int GeneralPanelProc (HWND hwnd, UINT msg,
443 WPARAM wParam, LPARAM lParam) {
444 switch (msg) {
445 case WM_INITDIALOG:
446 SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
447 return 1;
448/* case WM_CTLCOLORDLG: */
449/* return (int) GetStockObject (LTGRAY_BRUSH); */
450/* case WM_CTLCOLORSTATIC: */
451/* case WM_CTLCOLORBTN: */
452/* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
453/* return (int) GetStockObject (LTGRAY_BRUSH); */
454 case WM_CLOSE:
455 DestroyWindow (hwnd);
456 return 1;
457 }
458 return 0;
459}
460
6584031a 461static char savedsession[2048];
462
374330e2 463static int CALLBACK ConnectionProc (HWND hwnd, UINT msg,
464 WPARAM wParam, LPARAM lParam) {
465 int i;
466
467 switch (msg) {
468 case WM_INITDIALOG:
469 SetDlgItemText (hwnd, IDC0_HOST, cfg.host);
6584031a 470 SetDlgItemText (hwnd, IDC0_SESSEDIT, savedsession);
374330e2 471 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
472 for (i = 0; i < nsessions; i++)
473 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
474 0, (LPARAM) (sessions[i]));
5e1a8e27 475 CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH,
476 cfg.protocol==PROT_SSH ? IDC0_PROTSSH :
477 cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW );
374330e2 478 CheckDlgButton (hwnd, IDC0_CLOSEEXIT, cfg.close_on_exit);
9ef49106 479 CheckDlgButton (hwnd, IDC0_CLOSEWARN, cfg.warn_on_close);
374330e2 480 break;
1cd246bb 481 case WM_LBUTTONUP:
482 /*
483 * Button release should trigger WM_OK if there was a
484 * previous double click on the session list.
485 */
486 ReleaseCapture();
487 if (readytogo)
488 SendMessage (GetParent(hwnd), WM_COMMAND, IDOK, 0);
489 break;
374330e2 490 case WM_COMMAND:
491 switch (LOWORD(wParam)) {
492 case IDC0_PROTTELNET:
493 case IDC0_PROTSSH:
5e1a8e27 494 case IDC0_PROTRAW:
374330e2 495 if (HIWORD(wParam) == BN_CLICKED ||
496 HIWORD(wParam) == BN_DOUBLECLICKED) {
497 int i = IsDlgButtonChecked (hwnd, IDC0_PROTSSH);
5e1a8e27 498 int j = IsDlgButtonChecked (hwnd, IDC0_PROTTELNET);
499 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : PROT_RAW ;
374330e2 500 if ((cfg.protocol == PROT_SSH && cfg.port == 23) ||
501 (cfg.protocol == PROT_TELNET && cfg.port == 22)) {
502 cfg.port = i ? 22 : 23;
503 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
504 }
505 }
506 break;
507 case IDC0_HOST:
508 if (HIWORD(wParam) == EN_CHANGE)
509 GetDlgItemText (hwnd, IDC0_HOST, cfg.host,
510 sizeof(cfg.host)-1);
511 break;
512 case IDC0_PORT:
513 if (HIWORD(wParam) == EN_CHANGE)
514 MyGetDlgItemInt (hwnd, IDC0_PORT, &cfg.port);
515 break;
516 case IDC0_CLOSEEXIT:
517 if (HIWORD(wParam) == BN_CLICKED ||
518 HIWORD(wParam) == BN_DOUBLECLICKED)
519 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC0_CLOSEEXIT);
520 break;
9ef49106 521 case IDC0_CLOSEWARN:
522 if (HIWORD(wParam) == BN_CLICKED ||
523 HIWORD(wParam) == BN_DOUBLECLICKED)
524 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC0_CLOSEWARN);
525 break;
374330e2 526 case IDC0_SESSEDIT:
6584031a 527 if (HIWORD(wParam) == EN_CHANGE) {
374330e2 528 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
529 (WPARAM) -1, 0);
6584031a 530 GetDlgItemText (hwnd, IDC0_SESSEDIT,
531 savedsession, sizeof(savedsession)-1);
532 savedsession[sizeof(savedsession)-1] = '\0';
533 }
374330e2 534 break;
535 case IDC0_SESSSAVE:
536 if (HIWORD(wParam) == BN_CLICKED ||
537 HIWORD(wParam) == BN_DOUBLECLICKED) {
538 /*
539 * Save a session
540 */
541 char str[2048];
542 GetDlgItemText (hwnd, IDC0_SESSEDIT, str, sizeof(str)-1);
543 if (!*str) {
544 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
545 LB_GETCURSEL, 0, 0);
546 if (n == LB_ERR) {
547 MessageBeep(0);
548 break;
549 }
550 strcpy (str, sessions[n]);
551 }
552 save_settings (str, !!strcmp(str, "Default Settings"));
553 get_sesslist (FALSE);
554 get_sesslist (TRUE);
555 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_RESETCONTENT,
556 0, 0);
557 for (i = 0; i < nsessions; i++)
558 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
559 0, (LPARAM) (sessions[i]));
560 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
561 (WPARAM) -1, 0);
562 }
563 break;
564 case IDC0_SESSLIST:
565 case IDC0_SESSLOAD:
566 if (LOWORD(wParam) == IDC0_SESSLOAD &&
567 HIWORD(wParam) != BN_CLICKED &&
568 HIWORD(wParam) != BN_DOUBLECLICKED)
569 break;
570 if (LOWORD(wParam) == IDC0_SESSLIST &&
571 HIWORD(wParam) != LBN_DBLCLK)
572 break;
573 {
574 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
575 LB_GETCURSEL, 0, 0);
576 if (n == LB_ERR) {
577 MessageBeep(0);
578 break;
579 }
580 load_settings (sessions[n],
581 !!strcmp(sessions[n], "Default Settings"));
582 SetDlgItemText (hwnd, IDC0_HOST, cfg.host);
583 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
5e1a8e27 584 CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH,
374330e2 585 (cfg.protocol==PROT_SSH ? IDC0_PROTSSH :
5e1a8e27 586 cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW));
374330e2 587 CheckDlgButton (hwnd, IDC0_CLOSEEXIT, cfg.close_on_exit);
9ef49106 588 CheckDlgButton (hwnd, IDC0_CLOSEWARN, cfg.warn_on_close);
374330e2 589 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
590 (WPARAM) -1, 0);
591 }
592 if (LOWORD(wParam) == IDC0_SESSLIST) {
593 /*
594 * A double-click on a saved session should
595 * actually start the session, not just load it.
596 * Unless it's Default Settings or some other
597 * host-less set of saved settings.
598 */
1cd246bb 599 if (*cfg.host) {
600 readytogo = TRUE;
601 SetCapture(hwnd);
602 }
374330e2 603 }
604 break;
605 case IDC0_SESSDEL:
606 if (HIWORD(wParam) == BN_CLICKED ||
607 HIWORD(wParam) == BN_DOUBLECLICKED) {
608 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
609 LB_GETCURSEL, 0, 0);
610 if (n == LB_ERR || n == 0) {
611 MessageBeep(0);
612 break;
613 }
d1622aed 614 del_settings(sessions[n]);
374330e2 615 get_sesslist (FALSE);
616 get_sesslist (TRUE);
617 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_RESETCONTENT,
618 0, 0);
619 for (i = 0; i < nsessions; i++)
620 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
621 0, (LPARAM) (sessions[i]));
622 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
623 (WPARAM) -1, 0);
624 }
625 }
626 }
627 return GeneralPanelProc (hwnd, msg, wParam, lParam);
628}
629
630static int CALLBACK KeyboardProc (HWND hwnd, UINT msg,
631 WPARAM wParam, LPARAM lParam) {
632 switch (msg) {
633 case WM_INITDIALOG:
634 CheckRadioButton (hwnd, IDC1_DEL008, IDC1_DEL127,
635 cfg.bksp_is_delete ? IDC1_DEL127 : IDC1_DEL008);
636 CheckRadioButton (hwnd, IDC1_HOMETILDE, IDC1_HOMERXVT,
637 cfg.rxvt_homeend ? IDC1_HOMERXVT : IDC1_HOMETILDE);
c9def1b8 638 CheckRadioButton (hwnd, IDC1_FUNCTILDE, IDC1_FUNCXTERM,
639 cfg.funky_type ?
640 (cfg.funky_type==2 ? IDC1_FUNCXTERM
641 : IDC1_FUNCLINUX )
642 : IDC1_FUNCTILDE);
374330e2 643 CheckRadioButton (hwnd, IDC1_CURNORMAL, IDC1_CURAPPLIC,
644 cfg.app_cursor ? IDC1_CURAPPLIC : IDC1_CURNORMAL);
c5e9c988 645 CheckRadioButton (hwnd, IDC1_KPNORMAL, IDC1_KPNH,
646 cfg.nethack_keypad ? IDC1_KPNH :
374330e2 647 cfg.app_keypad ? IDC1_KPAPPLIC : IDC1_KPNORMAL);
c5e9c988 648 CheckDlgButton (hwnd, IDC1_ALTF4, cfg.alt_f4);
649 CheckDlgButton (hwnd, IDC1_ALTSPACE, cfg.alt_space);
5bc238bb 650 CheckDlgButton (hwnd, IDC1_LDISCTERM, cfg.ldisc_term);
c9def1b8 651 CheckDlgButton (hwnd, IDC1_SCROLLKEY, cfg.scroll_on_key);
374330e2 652 break;
653 case WM_COMMAND:
654 if (HIWORD(wParam) == BN_CLICKED ||
655 HIWORD(wParam) == BN_DOUBLECLICKED)
656 switch (LOWORD(wParam)) {
657 case IDC1_DEL008:
658 case IDC1_DEL127:
659 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC1_DEL127);
660 break;
661 case IDC1_HOMETILDE:
662 case IDC1_HOMERXVT:
663 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC1_HOMERXVT);
664 break;
c9def1b8 665 case IDC1_FUNCXTERM:
666 cfg.funky_type = 2;
667 break;
374330e2 668 case IDC1_FUNCTILDE:
669 case IDC1_FUNCLINUX:
c9def1b8 670 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC1_FUNCLINUX);
374330e2 671 break;
672 case IDC1_KPNORMAL:
673 case IDC1_KPAPPLIC:
674 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC1_KPAPPLIC);
c5e9c988 675 cfg.nethack_keypad = FALSE;
676 break;
677 case IDC1_KPNH:
678 cfg.app_keypad = FALSE;
679 cfg.nethack_keypad = TRUE;
374330e2 680 break;
681 case IDC1_CURNORMAL:
682 case IDC1_CURAPPLIC:
683 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC1_CURAPPLIC);
684 break;
c5e9c988 685 case IDC1_ALTF4:
686 if (HIWORD(wParam) == BN_CLICKED ||
687 HIWORD(wParam) == BN_DOUBLECLICKED)
688 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC1_ALTF4);
689 break;
690 case IDC1_ALTSPACE:
691 if (HIWORD(wParam) == BN_CLICKED ||
692 HIWORD(wParam) == BN_DOUBLECLICKED)
693 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC1_ALTSPACE);
694 break;
5bc238bb 695 case IDC1_LDISCTERM:
696 if (HIWORD(wParam) == BN_CLICKED ||
697 HIWORD(wParam) == BN_DOUBLECLICKED)
698 cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC1_LDISCTERM);
699 break;
c9def1b8 700 case IDC1_SCROLLKEY:
217dceef 701 if (HIWORD(wParam) == BN_CLICKED ||
702 HIWORD(wParam) == BN_DOUBLECLICKED)
c9def1b8 703 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC1_SCROLLKEY);
217dceef 704 break;
374330e2 705 }
706 }
707 return GeneralPanelProc (hwnd, msg, wParam, lParam);
708}
709
710static void fmtfont (char *buf) {
711 sprintf (buf, "Font: %s, ", cfg.font);
712 if (cfg.fontisbold)
713 strcat(buf, "bold, ");
714 if (cfg.fontheight == 0)
715 strcat (buf, "default height");
716 else
717 sprintf (buf+strlen(buf), "%d-%s",
718 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
719 (cfg.fontheight < 0 ? "pixel" : "point"));
720}
721
722static int CALLBACK TerminalProc (HWND hwnd, UINT msg,
723 WPARAM wParam, LPARAM lParam) {
724 CHOOSEFONT cf;
725 LOGFONT lf;
726 char fontstatic[256];
727
728 switch (msg) {
729 case WM_INITDIALOG:
730 CheckDlgButton (hwnd, IDC2_WRAPMODE, cfg.wrap_mode);
731 CheckDlgButton (hwnd, IDC2_WINNAME, cfg.win_name_always);
732 CheckDlgButton (hwnd, IDC2_DECOM, cfg.dec_om);
fef97f43 733 CheckDlgButton (hwnd, IDC2_LFHASCR, cfg.lfhascr);
374330e2 734 SetDlgItemInt (hwnd, IDC2_ROWSEDIT, cfg.height, FALSE);
735 SetDlgItemInt (hwnd, IDC2_COLSEDIT, cfg.width, FALSE);
736 SetDlgItemInt (hwnd, IDC2_SAVEEDIT, cfg.savelines, FALSE);
737 fmtfont (fontstatic);
738 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
c9def1b8 739 CheckDlgButton (hwnd, IDC1_BLINKCUR, cfg.blink_cur);
740 CheckDlgButton (hwnd, IDC1_BEEP, cfg.beep);
741 CheckDlgButton (hwnd, IDC2_SCROLLBAR, cfg.scrollbar);
742 CheckDlgButton (hwnd, IDC2_LOCKSIZE, cfg.locksize);
743 CheckDlgButton (hwnd, IDC2_BCE, cfg.bce);
744 CheckDlgButton (hwnd, IDC2_BLINKTEXT, cfg.blinktext);
374330e2 745 break;
746 case WM_COMMAND:
747 switch (LOWORD(wParam)) {
748 case IDC2_WRAPMODE:
749 if (HIWORD(wParam) == BN_CLICKED ||
750 HIWORD(wParam) == BN_DOUBLECLICKED)
751 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC2_WRAPMODE);
752 break;
753 case IDC2_WINNAME:
754 if (HIWORD(wParam) == BN_CLICKED ||
755 HIWORD(wParam) == BN_DOUBLECLICKED)
756 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC2_WINNAME);
757 break;
758 case IDC2_DECOM:
759 if (HIWORD(wParam) == BN_CLICKED ||
760 HIWORD(wParam) == BN_DOUBLECLICKED)
761 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC2_DECOM);
762 break;
fef97f43 763 case IDC2_LFHASCR:
764 if (HIWORD(wParam) == BN_CLICKED ||
765 HIWORD(wParam) == BN_DOUBLECLICKED)
766 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC2_LFHASCR);
767 break;
374330e2 768 case IDC2_ROWSEDIT:
769 if (HIWORD(wParam) == EN_CHANGE)
770 MyGetDlgItemInt (hwnd, IDC2_ROWSEDIT, &cfg.height);
771 break;
772 case IDC2_COLSEDIT:
773 if (HIWORD(wParam) == EN_CHANGE)
774 MyGetDlgItemInt (hwnd, IDC2_COLSEDIT, &cfg.width);
775 break;
776 case IDC2_SAVEEDIT:
777 if (HIWORD(wParam) == EN_CHANGE)
778 MyGetDlgItemInt (hwnd, IDC2_SAVEEDIT, &cfg.savelines);
779 break;
780 case IDC2_CHOOSEFONT:
781 lf.lfHeight = cfg.fontheight;
782 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
783 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
784 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
14963b8f 785 lf.lfCharSet = cfg.fontcharset;
374330e2 786 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
787 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
788 lf.lfQuality = DEFAULT_QUALITY;
789 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
790 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
791 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
792
793 cf.lStructSize = sizeof(cf);
794 cf.hwndOwner = hwnd;
795 cf.lpLogFont = &lf;
796 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
797 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
798
799 if (ChooseFont (&cf)) {
800 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
801 cfg.font[sizeof(cfg.font)-1] = '\0';
802 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
14963b8f 803 cfg.fontcharset = lf.lfCharSet;
374330e2 804 cfg.fontheight = lf.lfHeight;
805 fmtfont (fontstatic);
806 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
807 }
808 break;
c9def1b8 809 case IDC1_BLINKCUR:
810 if (HIWORD(wParam) == BN_CLICKED ||
811 HIWORD(wParam) == BN_DOUBLECLICKED)
812 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC1_BLINKCUR);
813 break;
814 case IDC1_BEEP:
815 if (HIWORD(wParam) == BN_CLICKED ||
816 HIWORD(wParam) == BN_DOUBLECLICKED)
817 cfg.beep = IsDlgButtonChecked (hwnd, IDC1_BEEP);
818 break;
819 case IDC2_SCROLLBAR:
820 if (HIWORD(wParam) == BN_CLICKED ||
821 HIWORD(wParam) == BN_DOUBLECLICKED)
822 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC2_SCROLLBAR);
823 break;
824 case IDC2_LOCKSIZE:
825 if (HIWORD(wParam) == BN_CLICKED ||
826 HIWORD(wParam) == BN_DOUBLECLICKED)
827 cfg.locksize = IsDlgButtonChecked (hwnd, IDC2_LOCKSIZE);
828 break;
829 case IDC2_BLINKTEXT:
830 if (HIWORD(wParam) == BN_CLICKED ||
831 HIWORD(wParam) == BN_DOUBLECLICKED)
832 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC2_BLINKTEXT);
833 break;
834 case IDC2_BCE:
835 if (HIWORD(wParam) == BN_CLICKED ||
836 HIWORD(wParam) == BN_DOUBLECLICKED)
837 cfg.bce = IsDlgButtonChecked (hwnd, IDC2_BCE);
838 break;
374330e2 839 }
840 break;
841 }
842 return GeneralPanelProc (hwnd, msg, wParam, lParam);
843}
844
845static int CALLBACK TelnetProc (HWND hwnd, UINT msg,
846 WPARAM wParam, LPARAM lParam) {
847 int i;
848
849 switch (msg) {
850 case WM_INITDIALOG:
851 SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype);
852 SetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed);
853 SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username);
854 {
37508af4 855 char *p = cfg.environmt;
374330e2 856 while (*p) {
857 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING, 0,
858 (LPARAM) p);
859 p += strlen(p)+1;
860 }
861 }
862 CheckRadioButton (hwnd, IDC3_EMBSD, IDC3_EMRFC,
863 cfg.rfc_environ ? IDC3_EMRFC : IDC3_EMBSD);
864 break;
865 case WM_COMMAND:
866 switch (LOWORD(wParam)) {
867 case IDC3_TTEDIT:
868 if (HIWORD(wParam) == EN_CHANGE)
869 GetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype,
870 sizeof(cfg.termtype)-1);
871 break;
872 case IDC3_TSEDIT:
873 if (HIWORD(wParam) == EN_CHANGE)
874 GetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed,
875 sizeof(cfg.termspeed)-1);
876 break;
877 case IDC3_LOGEDIT:
878 if (HIWORD(wParam) == EN_CHANGE)
879 GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username,
880 sizeof(cfg.username)-1);
881 break;
882 case IDC3_EMBSD:
883 case IDC3_EMRFC:
884 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC3_EMRFC);
885 break;
886 case IDC3_ENVADD:
887 if (HIWORD(wParam) == BN_CLICKED ||
888 HIWORD(wParam) == BN_DOUBLECLICKED) {
37508af4 889 char str[sizeof(cfg.environmt)];
374330e2 890 char *p;
891 GetDlgItemText (hwnd, IDC3_VAREDIT, str, sizeof(str)-1);
892 if (!*str) {
893 MessageBeep(0);
894 break;
895 }
896 p = str + strlen(str);
897 *p++ = '\t';
898 GetDlgItemText (hwnd, IDC3_VALEDIT, p, sizeof(str)-1-(p-str));
899 if (!*p) {
900 MessageBeep(0);
901 break;
902 }
37508af4 903 p = cfg.environmt;
374330e2 904 while (*p) {
905 while (*p) p++;
906 p++;
907 }
37508af4 908 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
374330e2 909 strcpy (p, str);
910 p[strlen(str)+1] = '\0';
911 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING,
912 0, (LPARAM)str);
913 SetDlgItemText (hwnd, IDC3_VAREDIT, "");
914 SetDlgItemText (hwnd, IDC3_VALEDIT, "");
915 } else {
916 MessageBox(hwnd, "Environment too big", "PuTTY Error",
917 MB_OK | MB_ICONERROR);
918 }
919 }
920 break;
921 case IDC3_ENVREMOVE:
922 if (HIWORD(wParam) != BN_CLICKED &&
923 HIWORD(wParam) != BN_DOUBLECLICKED)
924 break;
925 i = SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_GETCURSEL, 0, 0);
926 if (i == LB_ERR)
927 MessageBeep (0);
928 else {
929 char *p, *q;
930
931 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_DELETESTRING,
932 i, 0);
37508af4 933 p = cfg.environmt;
374330e2 934 while (i > 0) {
935 if (!*p)
936 goto disaster;
937 while (*p) p++;
938 p++;
939 i--;
940 }
941 q = p;
942 if (!*p)
943 goto disaster;
944 while (*p) p++;
945 p++;
946 while (*p) {
947 while (*p)
948 *q++ = *p++;
949 *q++ = *p++;
950 }
951 *q = '\0';
952 disaster:;
953 }
954 break;
955 }
956 break;
957 }
958 return GeneralPanelProc (hwnd, msg, wParam, lParam);
959}
960
961static int CALLBACK SshProc (HWND hwnd, UINT msg,
962 WPARAM wParam, LPARAM lParam) {
7cca0d81 963 OPENFILENAME of;
964 char filename[sizeof(cfg.keyfile)];
965
374330e2 966 switch (msg) {
967 case WM_INITDIALOG:
968 SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype);
969 SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username);
fef97f43 970 CheckDlgButton (hwnd, IDC3_NOPTY, cfg.nopty);
979310f1 971 CheckDlgButton (hwnd, IDC3_AGENTFWD, cfg.agentfwd);
9697bfd2 972 CheckRadioButton (hwnd, IDC3_CIPHER3DES, IDC3_CIPHERDES,
bea1ef5f 973 cfg.cipher == CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF :
9697bfd2 974 cfg.cipher == CIPHER_DES ? IDC3_CIPHERDES :
bea1ef5f 975 IDC3_CIPHER3DES);
adf799dd 976 CheckRadioButton (hwnd, IDC3_SSHPROT1, IDC3_SSHPROT2,
977 cfg.sshprot == 1 ? IDC3_SSHPROT1 : IDC3_SSHPROT2);
ccbfb941 978 CheckDlgButton (hwnd, IDC3_AUTHTIS, cfg.try_tis_auth);
7cca0d81 979 SetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile);
374330e2 980 break;
981 case WM_COMMAND:
982 switch (LOWORD(wParam)) {
983 case IDC3_TTEDIT:
984 if (HIWORD(wParam) == EN_CHANGE)
985 GetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype,
986 sizeof(cfg.termtype)-1);
987 break;
988 case IDC3_LOGEDIT:
989 if (HIWORD(wParam) == EN_CHANGE)
990 GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username,
991 sizeof(cfg.username)-1);
992 break;
fef97f43 993 case IDC3_NOPTY:
994 if (HIWORD(wParam) == BN_CLICKED ||
995 HIWORD(wParam) == BN_DOUBLECLICKED)
996 cfg.nopty = IsDlgButtonChecked (hwnd, IDC3_NOPTY);
997 break;
979310f1 998 case IDC3_AGENTFWD:
999 if (HIWORD(wParam) == BN_CLICKED ||
1000 HIWORD(wParam) == BN_DOUBLECLICKED)
1001 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC3_AGENTFWD);
1002 break;
bea1ef5f 1003 case IDC3_CIPHER3DES:
1004 case IDC3_CIPHERBLOWF:
9697bfd2 1005 case IDC3_CIPHERDES:
bea1ef5f 1006 if (HIWORD(wParam) == BN_CLICKED ||
1007 HIWORD(wParam) == BN_DOUBLECLICKED) {
1008 if (IsDlgButtonChecked (hwnd, IDC3_CIPHER3DES))
1009 cfg.cipher = CIPHER_3DES;
1010 else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERBLOWF))
1011 cfg.cipher = CIPHER_BLOWFISH;
9697bfd2 1012 else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERDES))
1013 cfg.cipher = CIPHER_DES;
bea1ef5f 1014 }
1015 break;
adf799dd 1016 case IDC3_SSHPROT1:
1017 case IDC3_SSHPROT2:
1018 if (HIWORD(wParam) == BN_CLICKED ||
1019 HIWORD(wParam) == BN_DOUBLECLICKED) {
1020 if (IsDlgButtonChecked (hwnd, IDC3_SSHPROT1))
1021 cfg.sshprot = 1;
1022 else if (IsDlgButtonChecked (hwnd, IDC3_SSHPROT2))
1023 cfg.sshprot = 2;
1024 }
1025 break;
ccbfb941 1026 case IDC3_AUTHTIS:
1027 if (HIWORD(wParam) == BN_CLICKED ||
1028 HIWORD(wParam) == BN_DOUBLECLICKED)
1029 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC3_AUTHTIS);
1030 break;
7cca0d81 1031 case IDC3_PKEDIT:
1032 if (HIWORD(wParam) == EN_CHANGE)
1033 GetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile,
1034 sizeof(cfg.keyfile)-1);
1035 break;
1036 case IDC3_PKBUTTON:
1037 /*
1038 * FIXME: this crashes. Find out why.
1039 */
1040 memset(&of, 0, sizeof(of));
1041#ifdef OPENFILENAME_SIZE_VERSION_400
1042 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1043#else
1044 of.lStructSize = sizeof(of);
1045#endif
1046 of.hwndOwner = hwnd;
1047 of.lpstrFilter = "All Files\0*\0\0\0";
1048 of.lpstrCustomFilter = NULL;
1049 of.nFilterIndex = 1;
1050 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1051 of.nMaxFile = sizeof(filename);
1052 of.lpstrFileTitle = NULL;
1053 of.lpstrInitialDir = NULL;
1054 of.lpstrTitle = "Select Public Key File";
1055 of.Flags = 0;
1056 if (GetOpenFileName(&of)) {
1057 strcpy(cfg.keyfile, filename);
1058 SetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile);
1059 }
1060 break;
374330e2 1061 }
1062 break;
1063 }
1064 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1065}
1066
1067static int CALLBACK SelectionProc (HWND hwnd, UINT msg,
1068 WPARAM wParam, LPARAM lParam) {
1069 int i;
1070
1071 switch (msg) {
1072 case WM_INITDIALOG:
1073 CheckRadioButton (hwnd, IDC4_MBWINDOWS, IDC4_MBXTERM,
1074 cfg.mouse_is_xterm ? IDC4_MBXTERM : IDC4_MBWINDOWS);
1075 {
1076 static int tabs[4] = {25, 61, 96, 128};
1077 SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_SETTABSTOPS, 4,
1078 (LPARAM) tabs);
1079 }
1080 for (i=0; i<256; i++) {
1081 char str[100];
1082 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1083 (i>=0x21 && i != 0x7F) ? i : ' ',
1084 cfg.wordness[i]);
1085 SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_ADDSTRING, 0,
1086 (LPARAM) str);
1087 }
1088 break;
1089 case WM_COMMAND:
1090 switch (LOWORD(wParam)) {
1091 case IDC4_MBWINDOWS:
1092 case IDC4_MBXTERM:
1093 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC4_MBXTERM);
1094 break;
1095 case IDC4_CCSET:
1096 {
1097 BOOL ok;
1098 int i;
1099 int n = GetDlgItemInt (hwnd, IDC4_CCEDIT, &ok, FALSE);
1100
1101 if (!ok)
1102 MessageBeep (0);
1103 else {
1104 for (i=0; i<256; i++)
1105 if (SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_GETSEL,
1106 i, 0)) {
1107 char str[100];
1108 cfg.wordness[i] = n;
1109 SendDlgItemMessage (hwnd, IDC4_CCLIST,
1110 LB_DELETESTRING, i, 0);
1111 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1112 (i>=0x21 && i != 0x7F) ? i : ' ',
1113 cfg.wordness[i]);
1114 SendDlgItemMessage (hwnd, IDC4_CCLIST,
1115 LB_INSERTSTRING, i,
1116 (LPARAM)str);
1117 }
1118 }
1119 }
1120 break;
1121 }
1122 break;
1123 }
1124 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1125}
1126
1127static int CALLBACK ColourProc (HWND hwnd, UINT msg,
1128 WPARAM wParam, LPARAM lParam) {
1129 static const char *const colours[] = {
1130 "Default Foreground", "Default Bold Foreground",
1131 "Default Background", "Default Bold Background",
1132 "Cursor Text", "Cursor Colour",
1133 "ANSI Black", "ANSI Black Bold",
1134 "ANSI Red", "ANSI Red Bold",
1135 "ANSI Green", "ANSI Green Bold",
1136 "ANSI Yellow", "ANSI Yellow Bold",
1137 "ANSI Blue", "ANSI Blue Bold",
1138 "ANSI Magenta", "ANSI Magenta Bold",
1139 "ANSI Cyan", "ANSI Cyan Bold",
1140 "ANSI White", "ANSI White Bold"
1141 };
1142 static const int permanent[] = {
1143 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
1144 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
1145 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
1146 };
1147 switch (msg) {
1148 case WM_INITDIALOG:
1149 CheckDlgButton (hwnd, IDC5_BOLDCOLOUR, cfg.bold_colour);
1150 CheckDlgButton (hwnd, IDC5_PALETTE, cfg.try_palette);
1151 {
1152 int i;
1153 for (i=0; i<22; i++)
1154 if (cfg.bold_colour || permanent[i])
1155 SendDlgItemMessage (hwnd, IDC5_LIST, LB_ADDSTRING, 0,
1156 (LPARAM) colours[i]);
1157 }
1158 SendDlgItemMessage (hwnd, IDC5_LIST, LB_SETCURSEL, 0, 0);
1159 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[0][0], FALSE);
1160 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[0][1], FALSE);
1161 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[0][2], FALSE);
1162 break;
1163 case WM_COMMAND:
1164 switch (LOWORD(wParam)) {
1165 case IDC5_BOLDCOLOUR:
1166 if (HIWORD(wParam) == BN_CLICKED ||
1167 HIWORD(wParam) == BN_DOUBLECLICKED) {
1168 int n, i;
1169 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC5_BOLDCOLOUR);
1170 n = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCOUNT, 0, 0);
1171 if (cfg.bold_colour && n!=22) {
1172 for (i=0; i<22; i++)
1173 if (!permanent[i])
1174 SendDlgItemMessage (hwnd, IDC5_LIST,
1175 LB_INSERTSTRING, i,
1176 (LPARAM) colours[i]);
1177 } else if (!cfg.bold_colour && n!=12) {
1178 for (i=22; i-- ;)
1179 if (!permanent[i])
1180 SendDlgItemMessage (hwnd, IDC5_LIST,
1181 LB_DELETESTRING, i, 0);
1182 }
1183 }
1184 break;
1185 case IDC5_PALETTE:
1186 if (HIWORD(wParam) == BN_CLICKED ||
1187 HIWORD(wParam) == BN_DOUBLECLICKED)
1188 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC5_PALETTE);
1189 break;
1190 case IDC5_LIST:
1191 if (HIWORD(wParam) == LBN_DBLCLK ||
1192 HIWORD(wParam) == LBN_SELCHANGE) {
1193 int i = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCURSEL,
1194 0, 0);
1195 if (!cfg.bold_colour)
1196 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1197 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[i][0], FALSE);
1198 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[i][1], FALSE);
1199 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[i][2], FALSE);
1200 }
1201 break;
1202 case IDC5_CHANGE:
1203 if (HIWORD(wParam) == BN_CLICKED ||
1204 HIWORD(wParam) == BN_DOUBLECLICKED) {
1205 static CHOOSECOLOR cc;
1206 static DWORD custom[16] = {0}; /* zero initialisers */
1207 int i = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCURSEL,
1208 0, 0);
1209 if (!cfg.bold_colour)
1210 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1211 cc.lStructSize = sizeof(cc);
1212 cc.hwndOwner = hwnd;
1d470ad2 1213 cc.hInstance = (HWND)hinst;
374330e2 1214 cc.lpCustColors = custom;
1215 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1216 cfg.colours[i][2]);
1217 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1218 if (ChooseColor(&cc)) {
1219 cfg.colours[i][0] =
1220 (unsigned char) (cc.rgbResult & 0xFF);
1221 cfg.colours[i][1] =
1222 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1223 cfg.colours[i][2] =
1224 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1225 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[i][0],
1226 FALSE);
1227 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[i][1],
1228 FALSE);
1229 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[i][2],
1230 FALSE);
1231 }
1232 }
1233 break;
1234 }
1235 break;
1236 }
1237 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1238}
1239
c9def1b8 1240static int CALLBACK TranslationProc (HWND hwnd, UINT msg,
14963b8f 1241 WPARAM wParam, LPARAM lParam) {
1242 switch (msg) {
1243 case WM_INITDIALOG:
d3d16feb 1244 CheckRadioButton (hwnd, IDC6_NOXLAT, IDC6_88592WIN1250,
1245 cfg.xlat_88592w1250 ? IDC6_88592WIN1250 :
1246 cfg.xlat_enablekoiwin ? IDC6_KOI8WIN1251 :
1247 IDC6_NOXLAT);
14963b8f 1248 CheckDlgButton (hwnd, IDC6_CAPSLOCKCYR, cfg.xlat_capslockcyr);
c9def1b8 1249 CheckRadioButton (hwnd, IDC2_VTXWINDOWS, IDC2_VTPOORMAN,
1250 cfg.vtmode == VT_XWINDOWS ? IDC2_VTXWINDOWS :
1251 cfg.vtmode == VT_OEMANSI ? IDC2_VTOEMANSI :
1252 cfg.vtmode == VT_OEMONLY ? IDC2_VTOEMONLY :
1253 IDC2_VTPOORMAN);
14963b8f 1254 case WM_COMMAND:
1255 switch (LOWORD(wParam)) {
d3d16feb 1256 case IDC6_NOXLAT:
1257 case IDC6_KOI8WIN1251:
1258 case IDC6_88592WIN1250:
1259 cfg.xlat_enablekoiwin =
1260 IsDlgButtonChecked (hwnd, IDC6_KOI8WIN1251);
1261 cfg.xlat_88592w1250 =
1262 IsDlgButtonChecked (hwnd, IDC6_88592WIN1250);
14963b8f 1263 break;
1264 case IDC6_CAPSLOCKCYR:
1265 if (HIWORD(wParam) == BN_CLICKED ||
1266 HIWORD(wParam) == BN_DOUBLECLICKED) {
1267 cfg.xlat_capslockcyr =
1268 IsDlgButtonChecked (hwnd, IDC6_CAPSLOCKCYR);
1269 }
1270 break;
c9def1b8 1271 case IDC2_VTXWINDOWS:
1272 case IDC2_VTOEMANSI:
1273 case IDC2_VTOEMONLY:
1274 case IDC2_VTPOORMAN:
1275 cfg.vtmode =
1276 (IsDlgButtonChecked (hwnd, IDC2_VTXWINDOWS) ? VT_XWINDOWS :
1277 IsDlgButtonChecked (hwnd, IDC2_VTOEMANSI) ? VT_OEMANSI :
1278 IsDlgButtonChecked (hwnd, IDC2_VTOEMONLY) ? VT_OEMONLY :
1279 VT_POORMAN);
1280 break;
14963b8f 1281 }
1282 }
1283 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1284}
1285
374330e2 1286static DLGPROC panelproc[NPANELS] = {
1287 ConnectionProc, KeyboardProc, TerminalProc,
c9def1b8 1288 TelnetProc, SshProc, SelectionProc, ColourProc, TranslationProc
374330e2 1289};
1290static char *panelids[NPANELS] = {
1291 MAKEINTRESOURCE(IDD_PANEL0),
1292 MAKEINTRESOURCE(IDD_PANEL1),
1293 MAKEINTRESOURCE(IDD_PANEL2),
1294 MAKEINTRESOURCE(IDD_PANEL3),
1295 MAKEINTRESOURCE(IDD_PANEL35),
1296 MAKEINTRESOURCE(IDD_PANEL4),
14963b8f 1297 MAKEINTRESOURCE(IDD_PANEL5),
1298 MAKEINTRESOURCE(IDD_PANEL6)
374330e2 1299};
14963b8f 1300
374330e2 1301static char *names[NPANELS] = {
14963b8f 1302 "Connection", "Keyboard", "Terminal", "Telnet",
c9def1b8 1303 "SSH", "Selection", "Colours", "Translation"
374330e2 1304};
1305
14963b8f 1306static int mainp[MAIN_NPANELS] = { 0, 1, 2, 3, 4, 5, 6, 7};
1307static int reconfp[RECONF_NPANELS] = { 1, 2, 5, 6, 7};
374330e2 1308
1309static int GenericMainDlgProc (HWND hwnd, UINT msg,
1310 WPARAM wParam, LPARAM lParam,
1311 int npanels, int *panelnums, HWND *page) {
1312 HWND hw;
1313
1314 switch (msg) {
1315 case WM_INITDIALOG:
1316 { /* centre the window */
1317 RECT rs, rd;
1318
1319 hw = GetDesktopWindow();
1320 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
1321 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
1322 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
1323 rd.right-rd.left, rd.bottom-rd.top, TRUE);
1324 }
1325 *page = NULL;
1326 { /* initialise the tab control */
1327 TC_ITEMHEADER tab;
1328 int i;
1329
1330 hw = GetDlgItem (hwnd, IDC_TAB);
1331 for (i=0; i<npanels; i++) {
1332 tab.mask = TCIF_TEXT;
1333 tab.pszText = names[panelnums[i]];
1334 TabCtrl_InsertItem (hw, i, &tab);
1335 }
1336/* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1337 hwnd, panelproc[panelnums[0]]);*/
1338 *page = CreateDialog (hinst, panelids[panelnums[0]],
1339 hwnd, panelproc[panelnums[0]]);
1340 SetWindowLong (*page, GWL_EXSTYLE,
1341 GetWindowLong (*page, GWL_EXSTYLE) |
1342 WS_EX_CONTROLPARENT);
1343 }
1344 SetFocus (*page);
1345 return 0;
1346 case WM_NOTIFY:
1347 if (LOWORD(wParam) == IDC_TAB &&
1348 ((LPNMHDR)lParam)->code == TCN_SELCHANGE) {
1349 int i = TabCtrl_GetCurSel(((LPNMHDR)lParam)->hwndFrom);
1350 if (*page)
1351 DestroyWindow (*page);
1352/* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1353 hwnd, panelproc[panelnums[i]]);*/
1354 *page = CreateDialog (hinst, panelids[panelnums[i]],
1355 hwnd, panelproc[panelnums[i]]);
1356 SetWindowLong (*page, GWL_EXSTYLE,
1357 GetWindowLong (*page, GWL_EXSTYLE) |
1358 WS_EX_CONTROLPARENT);
1359 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1360 return 0;
1361 }
1362 break;
1363/* case WM_CTLCOLORDLG: */
1364/* return (int) GetStockObject (LTGRAY_BRUSH); */
1365 case WM_COMMAND:
1366 switch (LOWORD(wParam)) {
1367 case IDOK:
1368 if (*cfg.host)
1369 EndDialog (hwnd, 1);
1370 else
1371 MessageBeep (0);
1372 return 0;
1373 case IDCANCEL:
1374 EndDialog (hwnd, 0);
1375 return 0;
1376 }
1377 return 0;
1378 case WM_CLOSE:
1379 EndDialog (hwnd, 0);
1380 return 0;
c9def1b8 1381
1382 /* Grrr Explorer will maximize Dialogs! */
1383 case WM_SIZE:
1384 if (wParam == SIZE_MAXIMIZED)
1385 force_normal(hwnd);
1386 return 0;
374330e2 1387 }
1388 return 0;
1389}
1390
1391static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1392 WPARAM wParam, LPARAM lParam) {
1393#if 0
1394 HWND hw;
1395 int i;
1396#endif
1397 static HWND page = NULL;
1398
1399 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1400#if 0
1401 /*
1402 * If the Connection panel is active and the Session List
1403 * box is selected, we treat a press of Open to have an
1404 * implicit press of Load preceding it.
1405 */
1406 hw = GetDlgItem (hwnd, IDC_TAB);
1407 i = TabCtrl_GetCurSel(hw);
1408 if (panelproc[mainp[i]] == ConnectionProc &&
1409 page && implicit_load_ok) {
1410 SendMessage (page, WM_COMMAND,
1411 MAKELONG(IDC0_SESSLOAD, BN_CLICKED), 0);
1412 }
1413#endif
1414 }
1415 if (msg == WM_COMMAND && LOWORD(wParam) == IDC_ABOUT) {
1416 EnableWindow(hwnd, 0);
1417 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1418 GetParent(hwnd), AboutProc);
1419 EnableWindow(hwnd, 1);
9a70ac47 1420 SetActiveWindow(hwnd);
374330e2 1421 }
1422 return GenericMainDlgProc (hwnd, msg, wParam, lParam,
1423 MAIN_NPANELS, mainp, &page);
1424}
1425
1426static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1427 WPARAM wParam, LPARAM lParam) {
1428 static HWND page;
1429 return GenericMainDlgProc (hwnd, msg, wParam, lParam,
1430 RECONF_NPANELS, reconfp, &page);
1431}
1432
0a4aa984 1433void get_sesslist(int allocate) {
d1622aed 1434 static char otherbuf[2048];
374330e2 1435 static char *buffer;
d1622aed 1436 int buflen, bufsize, i;
1437 char *p, *ret;
1438 void *handle;
374330e2 1439
1440 if (allocate) {
d1622aed 1441
1442 if ((handle = enum_settings_start()) == NULL)
374330e2 1443 return;
1444
1445 buflen = bufsize = 0;
1446 buffer = NULL;
374330e2 1447 do {
d1622aed 1448 ret = enum_settings_next(handle, otherbuf, sizeof(otherbuf));
1449 if (ret) {
1450 int len = strlen(otherbuf)+1;
1451 if (bufsize < buflen+len) {
1452 bufsize = buflen + len + 2048;
1453 buffer = srealloc(buffer, bufsize);
1454 }
1455 strcpy(buffer+buflen, otherbuf);
374330e2 1456 buflen += strlen(buffer+buflen)+1;
1457 }
d1622aed 1458 } while (ret);
1459 enum_settings_finish(handle);
374330e2 1460 buffer = srealloc(buffer, buflen+1);
1461 buffer[buflen] = '\0';
1462
1463 p = buffer;
1464 nsessions = 1; /* "Default Settings" counts as one */
1465 while (*p) {
1466 if (strcmp(p, "Default Settings"))
1467 nsessions++;
1468 while (*p) p++;
1469 p++;
1470 }
1471
1472 sessions = smalloc(nsessions * sizeof(char *));
1473 sessions[0] = "Default Settings";
1474 p = buffer;
1475 i = 1;
1476 while (*p) {
1477 if (strcmp(p, "Default Settings"))
1478 sessions[i++] = p;
1479 while (*p) p++;
1480 p++;
1481 }
1482 } else {
1483 sfree (buffer);
1484 sfree (sessions);
1485 }
1486}
1487
1488int do_config (void) {
1489 int ret;
1490
1491 get_sesslist(TRUE);
6584031a 1492 savedsession[0] = '\0';
374330e2 1493 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
1494 get_sesslist(FALSE);
1495
1496 return ret;
1497}
1498
1499int do_reconfig (HWND hwnd) {
1500 Config backup_cfg;
1501 int ret;
1502
1503 backup_cfg = cfg; /* structure copy */
1504 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
1505 if (!ret)
1506 cfg = backup_cfg; /* structure copy */
c9def1b8 1507 else
1508 force_normal(hwnd);
1509
374330e2 1510 return ret;
1511}
1512
1513void do_defaults (char *session) {
1514 if (session)
1515 load_settings (session, TRUE);
1516 else
1517 load_settings ("Default Settings", FALSE);
1518}
1519
c5e9c988 1520void logevent (char *string) {
1521 if (nevents >= negsize) {
374330e2 1522 negsize += 64;
c5e9c988 1523 events = srealloc (events, negsize * sizeof(*events));
374330e2 1524 }
c5e9c988 1525 events[nevents] = smalloc(1+strlen(string));
1526 strcpy (events[nevents], string);
1527 nevents++;
9ad90448 1528 if (logbox) {
1529 int count;
374330e2 1530 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
1531 0, (LPARAM)string);
9ad90448 1532 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
989b10e9 1533 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
9ad90448 1534 }
374330e2 1535}
1536
c5e9c988 1537void showeventlog (HWND hwnd) {
374330e2 1538 if (!logbox) {
1539 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
1540 hwnd, LogProc);
1541 ShowWindow (logbox, SW_SHOWNORMAL);
1542 }
1543}
1544
1545void showabout (HWND hwnd) {
1546 if (!abtbox) {
1547 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1548 hwnd, AboutProc);
1549 ShowWindow (abtbox, SW_SHOWNORMAL);
1550 }
1551}
1552
d4857987 1553void verify_ssh_host_key(char *host, int port, char *keytype,
d5859615 1554 char *keystr, char *fingerprint) {
1555 int ret;
374330e2 1556
d5859615 1557 static const char absentmsg[] =
1558 "The server's host key is not cached in the registry. You\n"
1559 "have no guarantee that the server is the computer you\n"
1560 "think it is.\n"
1561 "The server's key fingerprint is:\n"
1562 "%s\n"
1563 "If you trust this host, hit Yes to add the key to\n"
1564 "PuTTY's cache and carry on connecting.\n"
1565 "If you do not trust this host, hit No to abandon the\n"
1566 "connection.\n";
1567
1568 static const char wrongmsg[] =
1569 "WARNING - POTENTIAL SECURITY BREACH!\n"
1570 "\n"
1571 "The server's host key does not match the one PuTTY has\n"
1572 "cached in the registry. This means that either the\n"
1573 "server administrator has changed the host key, or you\n"
1574 "have actually connected to another computer pretending\n"
1575 "to be the server.\n"
1576 "The new key fingerprint is:\n"
1577 "%s\n"
1578 "If you were expecting this change and trust the new key,\n"
1579 "hit Yes to update PuTTY's cache and continue connecting.\n"
1580 "If you want to carry on connecting but without updating\n"
1581 "the cache, hit No.\n"
1582 "If you want to abandon the connection completely, hit\n"
1583 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
1584 "choice.\n";
1585
1586 static const char mbtitle[] = "PuTTY Security Alert";
de3df031 1587
d5859615 1588
1589 char message[160+ /* sensible fingerprint max size */
1590 (sizeof(absentmsg) > sizeof(wrongmsg) ?
1591 sizeof(absentmsg) : sizeof(wrongmsg))];
de3df031 1592
1593 /*
d5859615 1594 * Verify the key against the registry.
de3df031 1595 */
d4857987 1596 ret = verify_host_key(host, port, keytype, keystr);
d5859615 1597
1598 if (ret == 0) /* success - key matched OK */
1599 return;
1600 if (ret == 2) { /* key was different */
1601 int mbret;
1602 sprintf(message, wrongmsg, fingerprint);
1603 mbret = MessageBox(NULL, message, mbtitle,
1604 MB_ICONWARNING | MB_YESNOCANCEL);
1605 if (mbret == IDYES)
d4857987 1606 store_host_key(host, port, keytype, keystr);
d5859615 1607 if (mbret == IDCANCEL)
1608 exit(0);
de3df031 1609 }
d5859615 1610 if (ret == 1) { /* key was absent */
1611 int mbret;
1612 sprintf(message, absentmsg, fingerprint);
1613 mbret = MessageBox(NULL, message, mbtitle,
1614 MB_ICONWARNING | MB_YESNO);
1615 if (mbret == IDNO)
1616 exit(0);
d4857987 1617 store_host_key(host, port, keytype, keystr);
de3df031 1618 }
de3df031 1619}