Deletion case 2c can shift the root; case 3b is not the only case that
[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:
97749503 395 EndDialog(hwnd, 1);
d57835ab 396 return 0;
397 }
398 return 0;
399 case WM_CLOSE:
97749503 400 EndDialog(hwnd, 1);
d57835ab 401 return 0;
402 }
403 return 0;
404}
405
374330e2 406static int CALLBACK AboutProc (HWND hwnd, UINT msg,
407 WPARAM wParam, LPARAM lParam) {
408 switch (msg) {
409 case WM_INITDIALOG:
067a15ea 410 SetDlgItemText (hwnd, IDA_VERSION, ver);
374330e2 411 return 1;
412/* case WM_CTLCOLORDLG: */
413/* return (int) GetStockObject (LTGRAY_BRUSH); */
414/* case WM_CTLCOLORSTATIC: */
415/* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
416/* return (int) GetStockObject (LTGRAY_BRUSH); */
417 case WM_COMMAND:
418 switch (LOWORD(wParam)) {
419 case IDOK:
420 abtbox = NULL;
421 DestroyWindow (hwnd);
422 return 0;
423 case IDA_LICENCE:
424 EnableWindow(hwnd, 0);
425 DialogBox (hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
d57835ab 426 NULL, LicenceProc);
374330e2 427 EnableWindow(hwnd, 1);
9a70ac47 428 SetActiveWindow(hwnd);
374330e2 429 return 0;
430 }
431 return 0;
432 case WM_CLOSE:
433 abtbox = NULL;
434 DestroyWindow (hwnd);
435 return 0;
436 }
437 return 0;
438}
439
440static int GeneralPanelProc (HWND hwnd, UINT msg,
441 WPARAM wParam, LPARAM lParam) {
442 switch (msg) {
443 case WM_INITDIALOG:
444 SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
445 return 1;
446/* case WM_CTLCOLORDLG: */
447/* return (int) GetStockObject (LTGRAY_BRUSH); */
448/* case WM_CTLCOLORSTATIC: */
449/* case WM_CTLCOLORBTN: */
450/* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
451/* return (int) GetStockObject (LTGRAY_BRUSH); */
452 case WM_CLOSE:
453 DestroyWindow (hwnd);
454 return 1;
455 }
456 return 0;
457}
458
6584031a 459static char savedsession[2048];
460
374330e2 461static int CALLBACK ConnectionProc (HWND hwnd, UINT msg,
462 WPARAM wParam, LPARAM lParam) {
463 int i;
464
465 switch (msg) {
466 case WM_INITDIALOG:
467 SetDlgItemText (hwnd, IDC0_HOST, cfg.host);
6584031a 468 SetDlgItemText (hwnd, IDC0_SESSEDIT, savedsession);
374330e2 469 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
470 for (i = 0; i < nsessions; i++)
471 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
472 0, (LPARAM) (sessions[i]));
5e1a8e27 473 CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH,
474 cfg.protocol==PROT_SSH ? IDC0_PROTSSH :
475 cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW );
374330e2 476 CheckDlgButton (hwnd, IDC0_CLOSEEXIT, cfg.close_on_exit);
9ef49106 477 CheckDlgButton (hwnd, IDC0_CLOSEWARN, cfg.warn_on_close);
374330e2 478 break;
1cd246bb 479 case WM_LBUTTONUP:
480 /*
481 * Button release should trigger WM_OK if there was a
482 * previous double click on the session list.
483 */
484 ReleaseCapture();
485 if (readytogo)
486 SendMessage (GetParent(hwnd), WM_COMMAND, IDOK, 0);
487 break;
374330e2 488 case WM_COMMAND:
489 switch (LOWORD(wParam)) {
490 case IDC0_PROTTELNET:
491 case IDC0_PROTSSH:
5e1a8e27 492 case IDC0_PROTRAW:
374330e2 493 if (HIWORD(wParam) == BN_CLICKED ||
494 HIWORD(wParam) == BN_DOUBLECLICKED) {
495 int i = IsDlgButtonChecked (hwnd, IDC0_PROTSSH);
5e1a8e27 496 int j = IsDlgButtonChecked (hwnd, IDC0_PROTTELNET);
497 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : PROT_RAW ;
374330e2 498 if ((cfg.protocol == PROT_SSH && cfg.port == 23) ||
499 (cfg.protocol == PROT_TELNET && cfg.port == 22)) {
500 cfg.port = i ? 22 : 23;
501 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
502 }
503 }
504 break;
505 case IDC0_HOST:
506 if (HIWORD(wParam) == EN_CHANGE)
507 GetDlgItemText (hwnd, IDC0_HOST, cfg.host,
508 sizeof(cfg.host)-1);
509 break;
510 case IDC0_PORT:
511 if (HIWORD(wParam) == EN_CHANGE)
512 MyGetDlgItemInt (hwnd, IDC0_PORT, &cfg.port);
513 break;
514 case IDC0_CLOSEEXIT:
515 if (HIWORD(wParam) == BN_CLICKED ||
516 HIWORD(wParam) == BN_DOUBLECLICKED)
517 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC0_CLOSEEXIT);
518 break;
9ef49106 519 case IDC0_CLOSEWARN:
520 if (HIWORD(wParam) == BN_CLICKED ||
521 HIWORD(wParam) == BN_DOUBLECLICKED)
522 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC0_CLOSEWARN);
523 break;
374330e2 524 case IDC0_SESSEDIT:
6584031a 525 if (HIWORD(wParam) == EN_CHANGE) {
374330e2 526 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
527 (WPARAM) -1, 0);
6584031a 528 GetDlgItemText (hwnd, IDC0_SESSEDIT,
529 savedsession, sizeof(savedsession)-1);
530 savedsession[sizeof(savedsession)-1] = '\0';
531 }
374330e2 532 break;
533 case IDC0_SESSSAVE:
534 if (HIWORD(wParam) == BN_CLICKED ||
535 HIWORD(wParam) == BN_DOUBLECLICKED) {
536 /*
537 * Save a session
538 */
539 char str[2048];
540 GetDlgItemText (hwnd, IDC0_SESSEDIT, str, sizeof(str)-1);
541 if (!*str) {
542 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
543 LB_GETCURSEL, 0, 0);
544 if (n == LB_ERR) {
545 MessageBeep(0);
546 break;
547 }
548 strcpy (str, sessions[n]);
549 }
550 save_settings (str, !!strcmp(str, "Default Settings"));
551 get_sesslist (FALSE);
552 get_sesslist (TRUE);
553 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_RESETCONTENT,
554 0, 0);
555 for (i = 0; i < nsessions; i++)
556 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
557 0, (LPARAM) (sessions[i]));
558 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
559 (WPARAM) -1, 0);
560 }
561 break;
562 case IDC0_SESSLIST:
563 case IDC0_SESSLOAD:
564 if (LOWORD(wParam) == IDC0_SESSLOAD &&
565 HIWORD(wParam) != BN_CLICKED &&
566 HIWORD(wParam) != BN_DOUBLECLICKED)
567 break;
568 if (LOWORD(wParam) == IDC0_SESSLIST &&
569 HIWORD(wParam) != LBN_DBLCLK)
570 break;
571 {
572 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
573 LB_GETCURSEL, 0, 0);
574 if (n == LB_ERR) {
575 MessageBeep(0);
576 break;
577 }
578 load_settings (sessions[n],
579 !!strcmp(sessions[n], "Default Settings"));
580 SetDlgItemText (hwnd, IDC0_HOST, cfg.host);
581 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
5e1a8e27 582 CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH,
374330e2 583 (cfg.protocol==PROT_SSH ? IDC0_PROTSSH :
5e1a8e27 584 cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW));
374330e2 585 CheckDlgButton (hwnd, IDC0_CLOSEEXIT, cfg.close_on_exit);
9ef49106 586 CheckDlgButton (hwnd, IDC0_CLOSEWARN, cfg.warn_on_close);
374330e2 587 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
588 (WPARAM) -1, 0);
589 }
590 if (LOWORD(wParam) == IDC0_SESSLIST) {
591 /*
592 * A double-click on a saved session should
593 * actually start the session, not just load it.
594 * Unless it's Default Settings or some other
595 * host-less set of saved settings.
596 */
1cd246bb 597 if (*cfg.host) {
598 readytogo = TRUE;
599 SetCapture(hwnd);
600 }
374330e2 601 }
602 break;
603 case IDC0_SESSDEL:
604 if (HIWORD(wParam) == BN_CLICKED ||
605 HIWORD(wParam) == BN_DOUBLECLICKED) {
606 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
607 LB_GETCURSEL, 0, 0);
608 if (n == LB_ERR || n == 0) {
609 MessageBeep(0);
610 break;
611 }
d1622aed 612 del_settings(sessions[n]);
374330e2 613 get_sesslist (FALSE);
614 get_sesslist (TRUE);
615 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_RESETCONTENT,
616 0, 0);
617 for (i = 0; i < nsessions; i++)
618 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
619 0, (LPARAM) (sessions[i]));
620 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
621 (WPARAM) -1, 0);
622 }
623 }
624 }
625 return GeneralPanelProc (hwnd, msg, wParam, lParam);
626}
627
628static int CALLBACK KeyboardProc (HWND hwnd, UINT msg,
629 WPARAM wParam, LPARAM lParam) {
630 switch (msg) {
631 case WM_INITDIALOG:
632 CheckRadioButton (hwnd, IDC1_DEL008, IDC1_DEL127,
633 cfg.bksp_is_delete ? IDC1_DEL127 : IDC1_DEL008);
634 CheckRadioButton (hwnd, IDC1_HOMETILDE, IDC1_HOMERXVT,
635 cfg.rxvt_homeend ? IDC1_HOMERXVT : IDC1_HOMETILDE);
c9def1b8 636 CheckRadioButton (hwnd, IDC1_FUNCTILDE, IDC1_FUNCXTERM,
637 cfg.funky_type ?
638 (cfg.funky_type==2 ? IDC1_FUNCXTERM
639 : IDC1_FUNCLINUX )
640 : IDC1_FUNCTILDE);
374330e2 641 CheckRadioButton (hwnd, IDC1_CURNORMAL, IDC1_CURAPPLIC,
642 cfg.app_cursor ? IDC1_CURAPPLIC : IDC1_CURNORMAL);
c5e9c988 643 CheckRadioButton (hwnd, IDC1_KPNORMAL, IDC1_KPNH,
644 cfg.nethack_keypad ? IDC1_KPNH :
374330e2 645 cfg.app_keypad ? IDC1_KPAPPLIC : IDC1_KPNORMAL);
c5e9c988 646 CheckDlgButton (hwnd, IDC1_ALTF4, cfg.alt_f4);
647 CheckDlgButton (hwnd, IDC1_ALTSPACE, cfg.alt_space);
5bc238bb 648 CheckDlgButton (hwnd, IDC1_LDISCTERM, cfg.ldisc_term);
c9def1b8 649 CheckDlgButton (hwnd, IDC1_SCROLLKEY, cfg.scroll_on_key);
374330e2 650 break;
651 case WM_COMMAND:
652 if (HIWORD(wParam) == BN_CLICKED ||
653 HIWORD(wParam) == BN_DOUBLECLICKED)
654 switch (LOWORD(wParam)) {
655 case IDC1_DEL008:
656 case IDC1_DEL127:
657 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC1_DEL127);
658 break;
659 case IDC1_HOMETILDE:
660 case IDC1_HOMERXVT:
661 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC1_HOMERXVT);
662 break;
c9def1b8 663 case IDC1_FUNCXTERM:
664 cfg.funky_type = 2;
665 break;
374330e2 666 case IDC1_FUNCTILDE:
667 case IDC1_FUNCLINUX:
c9def1b8 668 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC1_FUNCLINUX);
374330e2 669 break;
670 case IDC1_KPNORMAL:
671 case IDC1_KPAPPLIC:
672 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC1_KPAPPLIC);
c5e9c988 673 cfg.nethack_keypad = FALSE;
674 break;
675 case IDC1_KPNH:
676 cfg.app_keypad = FALSE;
677 cfg.nethack_keypad = TRUE;
374330e2 678 break;
679 case IDC1_CURNORMAL:
680 case IDC1_CURAPPLIC:
681 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC1_CURAPPLIC);
682 break;
c5e9c988 683 case IDC1_ALTF4:
684 if (HIWORD(wParam) == BN_CLICKED ||
685 HIWORD(wParam) == BN_DOUBLECLICKED)
686 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC1_ALTF4);
687 break;
688 case IDC1_ALTSPACE:
689 if (HIWORD(wParam) == BN_CLICKED ||
690 HIWORD(wParam) == BN_DOUBLECLICKED)
691 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC1_ALTSPACE);
692 break;
5bc238bb 693 case IDC1_LDISCTERM:
694 if (HIWORD(wParam) == BN_CLICKED ||
695 HIWORD(wParam) == BN_DOUBLECLICKED)
696 cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC1_LDISCTERM);
697 break;
c9def1b8 698 case IDC1_SCROLLKEY:
217dceef 699 if (HIWORD(wParam) == BN_CLICKED ||
700 HIWORD(wParam) == BN_DOUBLECLICKED)
c9def1b8 701 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC1_SCROLLKEY);
217dceef 702 break;
374330e2 703 }
704 }
705 return GeneralPanelProc (hwnd, msg, wParam, lParam);
706}
707
708static void fmtfont (char *buf) {
709 sprintf (buf, "Font: %s, ", cfg.font);
710 if (cfg.fontisbold)
711 strcat(buf, "bold, ");
712 if (cfg.fontheight == 0)
713 strcat (buf, "default height");
714 else
715 sprintf (buf+strlen(buf), "%d-%s",
716 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
717 (cfg.fontheight < 0 ? "pixel" : "point"));
718}
719
720static int CALLBACK TerminalProc (HWND hwnd, UINT msg,
721 WPARAM wParam, LPARAM lParam) {
722 CHOOSEFONT cf;
723 LOGFONT lf;
724 char fontstatic[256];
725
726 switch (msg) {
727 case WM_INITDIALOG:
728 CheckDlgButton (hwnd, IDC2_WRAPMODE, cfg.wrap_mode);
729 CheckDlgButton (hwnd, IDC2_WINNAME, cfg.win_name_always);
730 CheckDlgButton (hwnd, IDC2_DECOM, cfg.dec_om);
fef97f43 731 CheckDlgButton (hwnd, IDC2_LFHASCR, cfg.lfhascr);
374330e2 732 SetDlgItemInt (hwnd, IDC2_ROWSEDIT, cfg.height, FALSE);
733 SetDlgItemInt (hwnd, IDC2_COLSEDIT, cfg.width, FALSE);
734 SetDlgItemInt (hwnd, IDC2_SAVEEDIT, cfg.savelines, FALSE);
735 fmtfont (fontstatic);
736 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
c9def1b8 737 CheckDlgButton (hwnd, IDC1_BLINKCUR, cfg.blink_cur);
738 CheckDlgButton (hwnd, IDC1_BEEP, cfg.beep);
739 CheckDlgButton (hwnd, IDC2_SCROLLBAR, cfg.scrollbar);
740 CheckDlgButton (hwnd, IDC2_LOCKSIZE, cfg.locksize);
741 CheckDlgButton (hwnd, IDC2_BCE, cfg.bce);
742 CheckDlgButton (hwnd, IDC2_BLINKTEXT, cfg.blinktext);
374330e2 743 break;
744 case WM_COMMAND:
745 switch (LOWORD(wParam)) {
746 case IDC2_WRAPMODE:
747 if (HIWORD(wParam) == BN_CLICKED ||
748 HIWORD(wParam) == BN_DOUBLECLICKED)
749 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC2_WRAPMODE);
750 break;
751 case IDC2_WINNAME:
752 if (HIWORD(wParam) == BN_CLICKED ||
753 HIWORD(wParam) == BN_DOUBLECLICKED)
754 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC2_WINNAME);
755 break;
756 case IDC2_DECOM:
757 if (HIWORD(wParam) == BN_CLICKED ||
758 HIWORD(wParam) == BN_DOUBLECLICKED)
759 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC2_DECOM);
760 break;
fef97f43 761 case IDC2_LFHASCR:
762 if (HIWORD(wParam) == BN_CLICKED ||
763 HIWORD(wParam) == BN_DOUBLECLICKED)
764 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC2_LFHASCR);
765 break;
374330e2 766 case IDC2_ROWSEDIT:
767 if (HIWORD(wParam) == EN_CHANGE)
768 MyGetDlgItemInt (hwnd, IDC2_ROWSEDIT, &cfg.height);
769 break;
770 case IDC2_COLSEDIT:
771 if (HIWORD(wParam) == EN_CHANGE)
772 MyGetDlgItemInt (hwnd, IDC2_COLSEDIT, &cfg.width);
773 break;
774 case IDC2_SAVEEDIT:
775 if (HIWORD(wParam) == EN_CHANGE)
776 MyGetDlgItemInt (hwnd, IDC2_SAVEEDIT, &cfg.savelines);
777 break;
778 case IDC2_CHOOSEFONT:
779 lf.lfHeight = cfg.fontheight;
780 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
781 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
782 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
14963b8f 783 lf.lfCharSet = cfg.fontcharset;
374330e2 784 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
785 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
786 lf.lfQuality = DEFAULT_QUALITY;
787 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
788 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
789 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
790
791 cf.lStructSize = sizeof(cf);
792 cf.hwndOwner = hwnd;
793 cf.lpLogFont = &lf;
794 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
795 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
796
797 if (ChooseFont (&cf)) {
798 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
799 cfg.font[sizeof(cfg.font)-1] = '\0';
800 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
14963b8f 801 cfg.fontcharset = lf.lfCharSet;
374330e2 802 cfg.fontheight = lf.lfHeight;
803 fmtfont (fontstatic);
804 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
805 }
806 break;
c9def1b8 807 case IDC1_BLINKCUR:
808 if (HIWORD(wParam) == BN_CLICKED ||
809 HIWORD(wParam) == BN_DOUBLECLICKED)
810 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC1_BLINKCUR);
811 break;
812 case IDC1_BEEP:
813 if (HIWORD(wParam) == BN_CLICKED ||
814 HIWORD(wParam) == BN_DOUBLECLICKED)
815 cfg.beep = IsDlgButtonChecked (hwnd, IDC1_BEEP);
816 break;
817 case IDC2_SCROLLBAR:
818 if (HIWORD(wParam) == BN_CLICKED ||
819 HIWORD(wParam) == BN_DOUBLECLICKED)
820 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC2_SCROLLBAR);
821 break;
822 case IDC2_LOCKSIZE:
823 if (HIWORD(wParam) == BN_CLICKED ||
824 HIWORD(wParam) == BN_DOUBLECLICKED)
825 cfg.locksize = IsDlgButtonChecked (hwnd, IDC2_LOCKSIZE);
826 break;
827 case IDC2_BLINKTEXT:
828 if (HIWORD(wParam) == BN_CLICKED ||
829 HIWORD(wParam) == BN_DOUBLECLICKED)
830 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC2_BLINKTEXT);
831 break;
832 case IDC2_BCE:
833 if (HIWORD(wParam) == BN_CLICKED ||
834 HIWORD(wParam) == BN_DOUBLECLICKED)
835 cfg.bce = IsDlgButtonChecked (hwnd, IDC2_BCE);
836 break;
374330e2 837 }
838 break;
839 }
840 return GeneralPanelProc (hwnd, msg, wParam, lParam);
841}
842
843static int CALLBACK TelnetProc (HWND hwnd, UINT msg,
844 WPARAM wParam, LPARAM lParam) {
845 int i;
846
847 switch (msg) {
848 case WM_INITDIALOG:
849 SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype);
850 SetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed);
851 SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username);
852 {
37508af4 853 char *p = cfg.environmt;
374330e2 854 while (*p) {
855 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING, 0,
856 (LPARAM) p);
857 p += strlen(p)+1;
858 }
859 }
860 CheckRadioButton (hwnd, IDC3_EMBSD, IDC3_EMRFC,
861 cfg.rfc_environ ? IDC3_EMRFC : IDC3_EMBSD);
862 break;
863 case WM_COMMAND:
864 switch (LOWORD(wParam)) {
865 case IDC3_TTEDIT:
866 if (HIWORD(wParam) == EN_CHANGE)
867 GetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype,
868 sizeof(cfg.termtype)-1);
869 break;
870 case IDC3_TSEDIT:
871 if (HIWORD(wParam) == EN_CHANGE)
872 GetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed,
873 sizeof(cfg.termspeed)-1);
874 break;
875 case IDC3_LOGEDIT:
876 if (HIWORD(wParam) == EN_CHANGE)
877 GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username,
878 sizeof(cfg.username)-1);
879 break;
880 case IDC3_EMBSD:
881 case IDC3_EMRFC:
882 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC3_EMRFC);
883 break;
884 case IDC3_ENVADD:
885 if (HIWORD(wParam) == BN_CLICKED ||
886 HIWORD(wParam) == BN_DOUBLECLICKED) {
37508af4 887 char str[sizeof(cfg.environmt)];
374330e2 888 char *p;
889 GetDlgItemText (hwnd, IDC3_VAREDIT, str, sizeof(str)-1);
890 if (!*str) {
891 MessageBeep(0);
892 break;
893 }
894 p = str + strlen(str);
895 *p++ = '\t';
896 GetDlgItemText (hwnd, IDC3_VALEDIT, p, sizeof(str)-1-(p-str));
897 if (!*p) {
898 MessageBeep(0);
899 break;
900 }
37508af4 901 p = cfg.environmt;
374330e2 902 while (*p) {
903 while (*p) p++;
904 p++;
905 }
37508af4 906 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
374330e2 907 strcpy (p, str);
908 p[strlen(str)+1] = '\0';
909 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING,
910 0, (LPARAM)str);
911 SetDlgItemText (hwnd, IDC3_VAREDIT, "");
912 SetDlgItemText (hwnd, IDC3_VALEDIT, "");
913 } else {
914 MessageBox(hwnd, "Environment too big", "PuTTY Error",
915 MB_OK | MB_ICONERROR);
916 }
917 }
918 break;
919 case IDC3_ENVREMOVE:
920 if (HIWORD(wParam) != BN_CLICKED &&
921 HIWORD(wParam) != BN_DOUBLECLICKED)
922 break;
923 i = SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_GETCURSEL, 0, 0);
924 if (i == LB_ERR)
925 MessageBeep (0);
926 else {
927 char *p, *q;
928
929 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_DELETESTRING,
930 i, 0);
37508af4 931 p = cfg.environmt;
374330e2 932 while (i > 0) {
933 if (!*p)
934 goto disaster;
935 while (*p) p++;
936 p++;
937 i--;
938 }
939 q = p;
940 if (!*p)
941 goto disaster;
942 while (*p) p++;
943 p++;
944 while (*p) {
945 while (*p)
946 *q++ = *p++;
947 *q++ = *p++;
948 }
949 *q = '\0';
950 disaster:;
951 }
952 break;
953 }
954 break;
955 }
956 return GeneralPanelProc (hwnd, msg, wParam, lParam);
957}
958
959static int CALLBACK SshProc (HWND hwnd, UINT msg,
960 WPARAM wParam, LPARAM lParam) {
7cca0d81 961 OPENFILENAME of;
962 char filename[sizeof(cfg.keyfile)];
963
374330e2 964 switch (msg) {
965 case WM_INITDIALOG:
966 SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype);
967 SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username);
fef97f43 968 CheckDlgButton (hwnd, IDC3_NOPTY, cfg.nopty);
979310f1 969 CheckDlgButton (hwnd, IDC3_AGENTFWD, cfg.agentfwd);
9697bfd2 970 CheckRadioButton (hwnd, IDC3_CIPHER3DES, IDC3_CIPHERDES,
bea1ef5f 971 cfg.cipher == CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF :
9697bfd2 972 cfg.cipher == CIPHER_DES ? IDC3_CIPHERDES :
bea1ef5f 973 IDC3_CIPHER3DES);
adf799dd 974 CheckRadioButton (hwnd, IDC3_SSHPROT1, IDC3_SSHPROT2,
975 cfg.sshprot == 1 ? IDC3_SSHPROT1 : IDC3_SSHPROT2);
ccbfb941 976 CheckDlgButton (hwnd, IDC3_AUTHTIS, cfg.try_tis_auth);
7cca0d81 977 SetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile);
374330e2 978 break;
979 case WM_COMMAND:
980 switch (LOWORD(wParam)) {
981 case IDC3_TTEDIT:
982 if (HIWORD(wParam) == EN_CHANGE)
983 GetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype,
984 sizeof(cfg.termtype)-1);
985 break;
986 case IDC3_LOGEDIT:
987 if (HIWORD(wParam) == EN_CHANGE)
988 GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username,
989 sizeof(cfg.username)-1);
990 break;
fef97f43 991 case IDC3_NOPTY:
992 if (HIWORD(wParam) == BN_CLICKED ||
993 HIWORD(wParam) == BN_DOUBLECLICKED)
994 cfg.nopty = IsDlgButtonChecked (hwnd, IDC3_NOPTY);
995 break;
979310f1 996 case IDC3_AGENTFWD:
997 if (HIWORD(wParam) == BN_CLICKED ||
998 HIWORD(wParam) == BN_DOUBLECLICKED)
999 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC3_AGENTFWD);
1000 break;
bea1ef5f 1001 case IDC3_CIPHER3DES:
1002 case IDC3_CIPHERBLOWF:
9697bfd2 1003 case IDC3_CIPHERDES:
bea1ef5f 1004 if (HIWORD(wParam) == BN_CLICKED ||
1005 HIWORD(wParam) == BN_DOUBLECLICKED) {
1006 if (IsDlgButtonChecked (hwnd, IDC3_CIPHER3DES))
1007 cfg.cipher = CIPHER_3DES;
1008 else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERBLOWF))
1009 cfg.cipher = CIPHER_BLOWFISH;
9697bfd2 1010 else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERDES))
1011 cfg.cipher = CIPHER_DES;
bea1ef5f 1012 }
1013 break;
adf799dd 1014 case IDC3_SSHPROT1:
1015 case IDC3_SSHPROT2:
1016 if (HIWORD(wParam) == BN_CLICKED ||
1017 HIWORD(wParam) == BN_DOUBLECLICKED) {
1018 if (IsDlgButtonChecked (hwnd, IDC3_SSHPROT1))
1019 cfg.sshprot = 1;
1020 else if (IsDlgButtonChecked (hwnd, IDC3_SSHPROT2))
1021 cfg.sshprot = 2;
1022 }
1023 break;
ccbfb941 1024 case IDC3_AUTHTIS:
1025 if (HIWORD(wParam) == BN_CLICKED ||
1026 HIWORD(wParam) == BN_DOUBLECLICKED)
1027 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC3_AUTHTIS);
1028 break;
7cca0d81 1029 case IDC3_PKEDIT:
1030 if (HIWORD(wParam) == EN_CHANGE)
1031 GetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile,
1032 sizeof(cfg.keyfile)-1);
1033 break;
1034 case IDC3_PKBUTTON:
1035 /*
1036 * FIXME: this crashes. Find out why.
1037 */
1038 memset(&of, 0, sizeof(of));
1039#ifdef OPENFILENAME_SIZE_VERSION_400
1040 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1041#else
1042 of.lStructSize = sizeof(of);
1043#endif
1044 of.hwndOwner = hwnd;
1045 of.lpstrFilter = "All Files\0*\0\0\0";
1046 of.lpstrCustomFilter = NULL;
1047 of.nFilterIndex = 1;
1048 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1049 of.nMaxFile = sizeof(filename);
1050 of.lpstrFileTitle = NULL;
1051 of.lpstrInitialDir = NULL;
1052 of.lpstrTitle = "Select Public Key File";
1053 of.Flags = 0;
1054 if (GetOpenFileName(&of)) {
1055 strcpy(cfg.keyfile, filename);
1056 SetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile);
1057 }
1058 break;
374330e2 1059 }
1060 break;
1061 }
1062 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1063}
1064
1065static int CALLBACK SelectionProc (HWND hwnd, UINT msg,
1066 WPARAM wParam, LPARAM lParam) {
1067 int i;
1068
1069 switch (msg) {
1070 case WM_INITDIALOG:
1071 CheckRadioButton (hwnd, IDC4_MBWINDOWS, IDC4_MBXTERM,
1072 cfg.mouse_is_xterm ? IDC4_MBXTERM : IDC4_MBWINDOWS);
1073 {
1074 static int tabs[4] = {25, 61, 96, 128};
1075 SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_SETTABSTOPS, 4,
1076 (LPARAM) tabs);
1077 }
1078 for (i=0; i<256; i++) {
1079 char str[100];
1080 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1081 (i>=0x21 && i != 0x7F) ? i : ' ',
1082 cfg.wordness[i]);
1083 SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_ADDSTRING, 0,
1084 (LPARAM) str);
1085 }
1086 break;
1087 case WM_COMMAND:
1088 switch (LOWORD(wParam)) {
1089 case IDC4_MBWINDOWS:
1090 case IDC4_MBXTERM:
1091 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC4_MBXTERM);
1092 break;
1093 case IDC4_CCSET:
1094 {
1095 BOOL ok;
1096 int i;
1097 int n = GetDlgItemInt (hwnd, IDC4_CCEDIT, &ok, FALSE);
1098
1099 if (!ok)
1100 MessageBeep (0);
1101 else {
1102 for (i=0; i<256; i++)
1103 if (SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_GETSEL,
1104 i, 0)) {
1105 char str[100];
1106 cfg.wordness[i] = n;
1107 SendDlgItemMessage (hwnd, IDC4_CCLIST,
1108 LB_DELETESTRING, i, 0);
1109 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1110 (i>=0x21 && i != 0x7F) ? i : ' ',
1111 cfg.wordness[i]);
1112 SendDlgItemMessage (hwnd, IDC4_CCLIST,
1113 LB_INSERTSTRING, i,
1114 (LPARAM)str);
1115 }
1116 }
1117 }
1118 break;
1119 }
1120 break;
1121 }
1122 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1123}
1124
1125static int CALLBACK ColourProc (HWND hwnd, UINT msg,
1126 WPARAM wParam, LPARAM lParam) {
1127 static const char *const colours[] = {
1128 "Default Foreground", "Default Bold Foreground",
1129 "Default Background", "Default Bold Background",
1130 "Cursor Text", "Cursor Colour",
1131 "ANSI Black", "ANSI Black Bold",
1132 "ANSI Red", "ANSI Red Bold",
1133 "ANSI Green", "ANSI Green Bold",
1134 "ANSI Yellow", "ANSI Yellow Bold",
1135 "ANSI Blue", "ANSI Blue Bold",
1136 "ANSI Magenta", "ANSI Magenta Bold",
1137 "ANSI Cyan", "ANSI Cyan Bold",
1138 "ANSI White", "ANSI White Bold"
1139 };
1140 static const int permanent[] = {
1141 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
1142 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
1143 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
1144 };
1145 switch (msg) {
1146 case WM_INITDIALOG:
1147 CheckDlgButton (hwnd, IDC5_BOLDCOLOUR, cfg.bold_colour);
1148 CheckDlgButton (hwnd, IDC5_PALETTE, cfg.try_palette);
1149 {
1150 int i;
1151 for (i=0; i<22; i++)
1152 if (cfg.bold_colour || permanent[i])
1153 SendDlgItemMessage (hwnd, IDC5_LIST, LB_ADDSTRING, 0,
1154 (LPARAM) colours[i]);
1155 }
1156 SendDlgItemMessage (hwnd, IDC5_LIST, LB_SETCURSEL, 0, 0);
1157 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[0][0], FALSE);
1158 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[0][1], FALSE);
1159 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[0][2], FALSE);
1160 break;
1161 case WM_COMMAND:
1162 switch (LOWORD(wParam)) {
1163 case IDC5_BOLDCOLOUR:
1164 if (HIWORD(wParam) == BN_CLICKED ||
1165 HIWORD(wParam) == BN_DOUBLECLICKED) {
1166 int n, i;
1167 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC5_BOLDCOLOUR);
1168 n = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCOUNT, 0, 0);
1169 if (cfg.bold_colour && n!=22) {
1170 for (i=0; i<22; i++)
1171 if (!permanent[i])
1172 SendDlgItemMessage (hwnd, IDC5_LIST,
1173 LB_INSERTSTRING, i,
1174 (LPARAM) colours[i]);
1175 } else if (!cfg.bold_colour && n!=12) {
1176 for (i=22; i-- ;)
1177 if (!permanent[i])
1178 SendDlgItemMessage (hwnd, IDC5_LIST,
1179 LB_DELETESTRING, i, 0);
1180 }
1181 }
1182 break;
1183 case IDC5_PALETTE:
1184 if (HIWORD(wParam) == BN_CLICKED ||
1185 HIWORD(wParam) == BN_DOUBLECLICKED)
1186 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC5_PALETTE);
1187 break;
1188 case IDC5_LIST:
1189 if (HIWORD(wParam) == LBN_DBLCLK ||
1190 HIWORD(wParam) == LBN_SELCHANGE) {
1191 int i = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCURSEL,
1192 0, 0);
1193 if (!cfg.bold_colour)
1194 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1195 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[i][0], FALSE);
1196 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[i][1], FALSE);
1197 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[i][2], FALSE);
1198 }
1199 break;
1200 case IDC5_CHANGE:
1201 if (HIWORD(wParam) == BN_CLICKED ||
1202 HIWORD(wParam) == BN_DOUBLECLICKED) {
1203 static CHOOSECOLOR cc;
1204 static DWORD custom[16] = {0}; /* zero initialisers */
1205 int i = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCURSEL,
1206 0, 0);
1207 if (!cfg.bold_colour)
1208 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1209 cc.lStructSize = sizeof(cc);
1210 cc.hwndOwner = hwnd;
1d470ad2 1211 cc.hInstance = (HWND)hinst;
374330e2 1212 cc.lpCustColors = custom;
1213 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1214 cfg.colours[i][2]);
1215 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1216 if (ChooseColor(&cc)) {
1217 cfg.colours[i][0] =
1218 (unsigned char) (cc.rgbResult & 0xFF);
1219 cfg.colours[i][1] =
1220 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1221 cfg.colours[i][2] =
1222 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1223 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[i][0],
1224 FALSE);
1225 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[i][1],
1226 FALSE);
1227 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[i][2],
1228 FALSE);
1229 }
1230 }
1231 break;
1232 }
1233 break;
1234 }
1235 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1236}
1237
c9def1b8 1238static int CALLBACK TranslationProc (HWND hwnd, UINT msg,
14963b8f 1239 WPARAM wParam, LPARAM lParam) {
1240 switch (msg) {
1241 case WM_INITDIALOG:
d3d16feb 1242 CheckRadioButton (hwnd, IDC6_NOXLAT, IDC6_88592WIN1250,
1243 cfg.xlat_88592w1250 ? IDC6_88592WIN1250 :
1244 cfg.xlat_enablekoiwin ? IDC6_KOI8WIN1251 :
1245 IDC6_NOXLAT);
14963b8f 1246 CheckDlgButton (hwnd, IDC6_CAPSLOCKCYR, cfg.xlat_capslockcyr);
c9def1b8 1247 CheckRadioButton (hwnd, IDC2_VTXWINDOWS, IDC2_VTPOORMAN,
1248 cfg.vtmode == VT_XWINDOWS ? IDC2_VTXWINDOWS :
1249 cfg.vtmode == VT_OEMANSI ? IDC2_VTOEMANSI :
1250 cfg.vtmode == VT_OEMONLY ? IDC2_VTOEMONLY :
1251 IDC2_VTPOORMAN);
14963b8f 1252 case WM_COMMAND:
1253 switch (LOWORD(wParam)) {
d3d16feb 1254 case IDC6_NOXLAT:
1255 case IDC6_KOI8WIN1251:
1256 case IDC6_88592WIN1250:
1257 cfg.xlat_enablekoiwin =
1258 IsDlgButtonChecked (hwnd, IDC6_KOI8WIN1251);
1259 cfg.xlat_88592w1250 =
1260 IsDlgButtonChecked (hwnd, IDC6_88592WIN1250);
14963b8f 1261 break;
1262 case IDC6_CAPSLOCKCYR:
1263 if (HIWORD(wParam) == BN_CLICKED ||
1264 HIWORD(wParam) == BN_DOUBLECLICKED) {
1265 cfg.xlat_capslockcyr =
1266 IsDlgButtonChecked (hwnd, IDC6_CAPSLOCKCYR);
1267 }
1268 break;
c9def1b8 1269 case IDC2_VTXWINDOWS:
1270 case IDC2_VTOEMANSI:
1271 case IDC2_VTOEMONLY:
1272 case IDC2_VTPOORMAN:
1273 cfg.vtmode =
1274 (IsDlgButtonChecked (hwnd, IDC2_VTXWINDOWS) ? VT_XWINDOWS :
1275 IsDlgButtonChecked (hwnd, IDC2_VTOEMANSI) ? VT_OEMANSI :
1276 IsDlgButtonChecked (hwnd, IDC2_VTOEMONLY) ? VT_OEMONLY :
1277 VT_POORMAN);
1278 break;
14963b8f 1279 }
1280 }
1281 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1282}
1283
374330e2 1284static DLGPROC panelproc[NPANELS] = {
1285 ConnectionProc, KeyboardProc, TerminalProc,
c9def1b8 1286 TelnetProc, SshProc, SelectionProc, ColourProc, TranslationProc
374330e2 1287};
1288static char *panelids[NPANELS] = {
1289 MAKEINTRESOURCE(IDD_PANEL0),
1290 MAKEINTRESOURCE(IDD_PANEL1),
1291 MAKEINTRESOURCE(IDD_PANEL2),
1292 MAKEINTRESOURCE(IDD_PANEL3),
1293 MAKEINTRESOURCE(IDD_PANEL35),
1294 MAKEINTRESOURCE(IDD_PANEL4),
14963b8f 1295 MAKEINTRESOURCE(IDD_PANEL5),
1296 MAKEINTRESOURCE(IDD_PANEL6)
374330e2 1297};
14963b8f 1298
374330e2 1299static char *names[NPANELS] = {
14963b8f 1300 "Connection", "Keyboard", "Terminal", "Telnet",
c9def1b8 1301 "SSH", "Selection", "Colours", "Translation"
374330e2 1302};
1303
14963b8f 1304static int mainp[MAIN_NPANELS] = { 0, 1, 2, 3, 4, 5, 6, 7};
1305static int reconfp[RECONF_NPANELS] = { 1, 2, 5, 6, 7};
374330e2 1306
1307static int GenericMainDlgProc (HWND hwnd, UINT msg,
1308 WPARAM wParam, LPARAM lParam,
1309 int npanels, int *panelnums, HWND *page) {
1310 HWND hw;
1311
1312 switch (msg) {
1313 case WM_INITDIALOG:
1314 { /* centre the window */
1315 RECT rs, rd;
1316
1317 hw = GetDesktopWindow();
1318 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
1319 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
1320 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
1321 rd.right-rd.left, rd.bottom-rd.top, TRUE);
1322 }
1323 *page = NULL;
1324 { /* initialise the tab control */
1325 TC_ITEMHEADER tab;
1326 int i;
1327
1328 hw = GetDlgItem (hwnd, IDC_TAB);
1329 for (i=0; i<npanels; i++) {
1330 tab.mask = TCIF_TEXT;
1331 tab.pszText = names[panelnums[i]];
1332 TabCtrl_InsertItem (hw, i, &tab);
1333 }
1334/* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1335 hwnd, panelproc[panelnums[0]]);*/
1336 *page = CreateDialog (hinst, panelids[panelnums[0]],
1337 hwnd, panelproc[panelnums[0]]);
1338 SetWindowLong (*page, GWL_EXSTYLE,
1339 GetWindowLong (*page, GWL_EXSTYLE) |
1340 WS_EX_CONTROLPARENT);
1341 }
1342 SetFocus (*page);
1343 return 0;
1344 case WM_NOTIFY:
1345 if (LOWORD(wParam) == IDC_TAB &&
1346 ((LPNMHDR)lParam)->code == TCN_SELCHANGE) {
1347 int i = TabCtrl_GetCurSel(((LPNMHDR)lParam)->hwndFrom);
1348 if (*page)
1349 DestroyWindow (*page);
1350/* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1351 hwnd, panelproc[panelnums[i]]);*/
1352 *page = CreateDialog (hinst, panelids[panelnums[i]],
1353 hwnd, panelproc[panelnums[i]]);
1354 SetWindowLong (*page, GWL_EXSTYLE,
1355 GetWindowLong (*page, GWL_EXSTYLE) |
1356 WS_EX_CONTROLPARENT);
1357 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1358 return 0;
1359 }
1360 break;
1361/* case WM_CTLCOLORDLG: */
1362/* return (int) GetStockObject (LTGRAY_BRUSH); */
1363 case WM_COMMAND:
1364 switch (LOWORD(wParam)) {
1365 case IDOK:
1366 if (*cfg.host)
1367 EndDialog (hwnd, 1);
1368 else
1369 MessageBeep (0);
1370 return 0;
1371 case IDCANCEL:
1372 EndDialog (hwnd, 0);
1373 return 0;
1374 }
1375 return 0;
1376 case WM_CLOSE:
1377 EndDialog (hwnd, 0);
1378 return 0;
c9def1b8 1379
1380 /* Grrr Explorer will maximize Dialogs! */
1381 case WM_SIZE:
1382 if (wParam == SIZE_MAXIMIZED)
1383 force_normal(hwnd);
1384 return 0;
374330e2 1385 }
1386 return 0;
1387}
1388
1389static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1390 WPARAM wParam, LPARAM lParam) {
1391#if 0
1392 HWND hw;
1393 int i;
1394#endif
1395 static HWND page = NULL;
1396
1397 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1398#if 0
1399 /*
1400 * If the Connection panel is active and the Session List
1401 * box is selected, we treat a press of Open to have an
1402 * implicit press of Load preceding it.
1403 */
1404 hw = GetDlgItem (hwnd, IDC_TAB);
1405 i = TabCtrl_GetCurSel(hw);
1406 if (panelproc[mainp[i]] == ConnectionProc &&
1407 page && implicit_load_ok) {
1408 SendMessage (page, WM_COMMAND,
1409 MAKELONG(IDC0_SESSLOAD, BN_CLICKED), 0);
1410 }
1411#endif
1412 }
1413 if (msg == WM_COMMAND && LOWORD(wParam) == IDC_ABOUT) {
1414 EnableWindow(hwnd, 0);
1415 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1416 GetParent(hwnd), AboutProc);
1417 EnableWindow(hwnd, 1);
9a70ac47 1418 SetActiveWindow(hwnd);
374330e2 1419 }
1420 return GenericMainDlgProc (hwnd, msg, wParam, lParam,
1421 MAIN_NPANELS, mainp, &page);
1422}
1423
1424static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1425 WPARAM wParam, LPARAM lParam) {
1426 static HWND page;
1427 return GenericMainDlgProc (hwnd, msg, wParam, lParam,
1428 RECONF_NPANELS, reconfp, &page);
1429}
1430
0a4aa984 1431void get_sesslist(int allocate) {
d1622aed 1432 static char otherbuf[2048];
374330e2 1433 static char *buffer;
d1622aed 1434 int buflen, bufsize, i;
1435 char *p, *ret;
1436 void *handle;
374330e2 1437
1438 if (allocate) {
d1622aed 1439
1440 if ((handle = enum_settings_start()) == NULL)
374330e2 1441 return;
1442
1443 buflen = bufsize = 0;
1444 buffer = NULL;
374330e2 1445 do {
d1622aed 1446 ret = enum_settings_next(handle, otherbuf, sizeof(otherbuf));
1447 if (ret) {
1448 int len = strlen(otherbuf)+1;
1449 if (bufsize < buflen+len) {
1450 bufsize = buflen + len + 2048;
1451 buffer = srealloc(buffer, bufsize);
1452 }
1453 strcpy(buffer+buflen, otherbuf);
374330e2 1454 buflen += strlen(buffer+buflen)+1;
1455 }
d1622aed 1456 } while (ret);
1457 enum_settings_finish(handle);
374330e2 1458 buffer = srealloc(buffer, buflen+1);
1459 buffer[buflen] = '\0';
1460
1461 p = buffer;
1462 nsessions = 1; /* "Default Settings" counts as one */
1463 while (*p) {
1464 if (strcmp(p, "Default Settings"))
1465 nsessions++;
1466 while (*p) p++;
1467 p++;
1468 }
1469
1470 sessions = smalloc(nsessions * sizeof(char *));
1471 sessions[0] = "Default Settings";
1472 p = buffer;
1473 i = 1;
1474 while (*p) {
1475 if (strcmp(p, "Default Settings"))
1476 sessions[i++] = p;
1477 while (*p) p++;
1478 p++;
1479 }
1480 } else {
1481 sfree (buffer);
1482 sfree (sessions);
1483 }
1484}
1485
1486int do_config (void) {
1487 int ret;
1488
1489 get_sesslist(TRUE);
6584031a 1490 savedsession[0] = '\0';
374330e2 1491 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
1492 get_sesslist(FALSE);
1493
1494 return ret;
1495}
1496
1497int do_reconfig (HWND hwnd) {
1498 Config backup_cfg;
1499 int ret;
1500
1501 backup_cfg = cfg; /* structure copy */
1502 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
1503 if (!ret)
1504 cfg = backup_cfg; /* structure copy */
c9def1b8 1505 else
1506 force_normal(hwnd);
1507
374330e2 1508 return ret;
1509}
1510
1511void do_defaults (char *session) {
1512 if (session)
1513 load_settings (session, TRUE);
1514 else
1515 load_settings ("Default Settings", FALSE);
1516}
1517
c5e9c988 1518void logevent (char *string) {
1519 if (nevents >= negsize) {
374330e2 1520 negsize += 64;
c5e9c988 1521 events = srealloc (events, negsize * sizeof(*events));
374330e2 1522 }
c5e9c988 1523 events[nevents] = smalloc(1+strlen(string));
1524 strcpy (events[nevents], string);
1525 nevents++;
9ad90448 1526 if (logbox) {
1527 int count;
374330e2 1528 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
1529 0, (LPARAM)string);
9ad90448 1530 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
989b10e9 1531 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
9ad90448 1532 }
374330e2 1533}
1534
c5e9c988 1535void showeventlog (HWND hwnd) {
374330e2 1536 if (!logbox) {
1537 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
1538 hwnd, LogProc);
1539 ShowWindow (logbox, SW_SHOWNORMAL);
1540 }
1541}
1542
1543void showabout (HWND hwnd) {
1544 if (!abtbox) {
1545 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1546 hwnd, AboutProc);
1547 ShowWindow (abtbox, SW_SHOWNORMAL);
1548 }
1549}
1550
d4857987 1551void verify_ssh_host_key(char *host, int port, char *keytype,
d5859615 1552 char *keystr, char *fingerprint) {
1553 int ret;
374330e2 1554
d5859615 1555 static const char absentmsg[] =
1556 "The server's host key is not cached in the registry. You\n"
1557 "have no guarantee that the server is the computer you\n"
1558 "think it is.\n"
1559 "The server's key fingerprint is:\n"
1560 "%s\n"
1561 "If you trust this host, hit Yes to add the key to\n"
1562 "PuTTY's cache and carry on connecting.\n"
1563 "If you do not trust this host, hit No to abandon the\n"
1564 "connection.\n";
1565
1566 static const char wrongmsg[] =
1567 "WARNING - POTENTIAL SECURITY BREACH!\n"
1568 "\n"
1569 "The server's host key does not match the one PuTTY has\n"
1570 "cached in the registry. This means that either the\n"
1571 "server administrator has changed the host key, or you\n"
1572 "have actually connected to another computer pretending\n"
1573 "to be the server.\n"
1574 "The new key fingerprint is:\n"
1575 "%s\n"
1576 "If you were expecting this change and trust the new key,\n"
1577 "hit Yes to update PuTTY's cache and continue connecting.\n"
1578 "If you want to carry on connecting but without updating\n"
1579 "the cache, hit No.\n"
1580 "If you want to abandon the connection completely, hit\n"
1581 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
1582 "choice.\n";
1583
1584 static const char mbtitle[] = "PuTTY Security Alert";
de3df031 1585
d5859615 1586
1587 char message[160+ /* sensible fingerprint max size */
1588 (sizeof(absentmsg) > sizeof(wrongmsg) ?
1589 sizeof(absentmsg) : sizeof(wrongmsg))];
de3df031 1590
1591 /*
d5859615 1592 * Verify the key against the registry.
de3df031 1593 */
d4857987 1594 ret = verify_host_key(host, port, keytype, keystr);
d5859615 1595
1596 if (ret == 0) /* success - key matched OK */
1597 return;
1598 if (ret == 2) { /* key was different */
1599 int mbret;
1600 sprintf(message, wrongmsg, fingerprint);
1601 mbret = MessageBox(NULL, message, mbtitle,
1602 MB_ICONWARNING | MB_YESNOCANCEL);
1603 if (mbret == IDYES)
d4857987 1604 store_host_key(host, port, keytype, keystr);
d5859615 1605 if (mbret == IDCANCEL)
1606 exit(0);
de3df031 1607 }
d5859615 1608 if (ret == 1) { /* key was absent */
1609 int mbret;
1610 sprintf(message, absentmsg, fingerprint);
1611 mbret = MessageBox(NULL, message, mbtitle,
1612 MB_ICONWARNING | MB_YESNO);
1613 if (mbret == IDNO)
1614 exit(0);
d4857987 1615 store_host_key(host, port, keytype, keystr);
de3df031 1616 }
de3df031 1617}