Make the new test suite's comment more accurate :-)
[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
9ca5da42 19#define NPANELS 9
20#define MAIN_NPANELS 9
21#define RECONF_NPANELS 6
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);
9ca5da42 113 write_setting_s (sesskey, "WinTitle", cfg.wintitle);
d1622aed 114 write_setting_i (sesskey, "TermWidth", cfg.width);
115 write_setting_i (sesskey, "TermHeight", cfg.height);
116 write_setting_s (sesskey, "Font", cfg.font);
117 write_setting_i (sesskey, "FontIsBold", cfg.fontisbold);
118 write_setting_i (sesskey, "FontCharSet", cfg.fontcharset);
119 write_setting_i (sesskey, "FontHeight", cfg.fontheight);
120 write_setting_i (sesskey, "FontVTMode", cfg.vtmode);
121 write_setting_i (sesskey, "TryPalette", cfg.try_palette);
122 write_setting_i (sesskey, "BoldAsColour", cfg.bold_colour);
374330e2 123 for (i=0; i<22; i++) {
124 char buf[20], buf2[30];
125 sprintf(buf, "Colour%d", i);
126 sprintf(buf2, "%d,%d,%d", cfg.colours[i][0],
127 cfg.colours[i][1], cfg.colours[i][2]);
d1622aed 128 write_setting_s (sesskey, buf, buf2);
374330e2 129 }
d1622aed 130 write_setting_i (sesskey, "MouseIsXterm", cfg.mouse_is_xterm);
374330e2 131 for (i=0; i<256; i+=32) {
132 char buf[20], buf2[256];
133 int j;
134 sprintf(buf, "Wordness%d", i);
135 *buf2 = '\0';
136 for (j=i; j<i+32; j++) {
137 sprintf(buf2+strlen(buf2), "%s%d",
138 (*buf2 ? "," : ""), cfg.wordness[j]);
139 }
d1622aed 140 write_setting_s (sesskey, buf, buf2);
374330e2 141 }
d1622aed 142 write_setting_i (sesskey, "KoiWinXlat", cfg.xlat_enablekoiwin);
143 write_setting_i (sesskey, "88592Xlat", cfg.xlat_88592w1250);
144 write_setting_i (sesskey, "CapsLockCyr", cfg.xlat_capslockcyr);
145 write_setting_i (sesskey, "ScrollBar", cfg.scrollbar);
146 write_setting_i (sesskey, "ScrollOnKey", cfg.scroll_on_key);
147 write_setting_i (sesskey, "LockSize", cfg.locksize);
148 write_setting_i (sesskey, "BCE", cfg.bce);
149 write_setting_i (sesskey, "BlinkText", cfg.blinktext);
150
151 close_settings_w(sesskey);
374330e2 152}
153
154static void load_settings (char *section, int do_host) {
155 int i;
e277c42d 156 char prot[10];
d1622aed 157 void *sesskey;
374330e2 158
d1622aed 159 sesskey = open_settings_r(section);
374330e2 160
e277c42d 161 gpps (sesskey, "HostName", "", cfg.host, sizeof(cfg.host));
162 gppi (sesskey, "PortNumber", default_port, &cfg.port);
89ee5268 163
e277c42d 164 gpps (sesskey, "Protocol", "default", prot, 10);
89ee5268 165 cfg.protocol = default_protocol;
a721b9eb 166 for (i = 0; backends[i].name != NULL; i++)
89ee5268 167 if (!strcmp(prot, backends[i].name)) {
168 cfg.protocol = backends[i].protocol;
169 break;
170 }
e277c42d 171
374330e2 172 gppi (sesskey, "CloseOnExit", 1, &cfg.close_on_exit);
9ef49106 173 gppi (sesskey, "WarnOnClose", 1, &cfg.warn_on_close);
374330e2 174 gpps (sesskey, "TerminalType", "xterm", cfg.termtype,
175 sizeof(cfg.termtype));
176 gpps (sesskey, "TerminalSpeed", "38400,38400", cfg.termspeed,
177 sizeof(cfg.termspeed));
178 {
37508af4 179 char buf[2*sizeof(cfg.environmt)], *p, *q;
374330e2 180 gpps (sesskey, "Environment", "", buf, sizeof(buf));
181 p = buf;
29b611b7 182 q = cfg.environmt;
374330e2 183 while (*p) {
184 while (*p && *p != ',') {
185 int c = *p++;
186 if (c == '=')
187 c = '\t';
188 if (c == '\\')
189 c = *p++;
29b611b7 190 *q++ = c;
374330e2 191 }
192 if (*p == ',') p++;
193 *q++ = '\0';
194 }
195 *q = '\0';
196 }
197 gpps (sesskey, "UserName", "", cfg.username, sizeof(cfg.username));
fef97f43 198 gppi (sesskey, "NoPTY", 0, &cfg.nopty);
979310f1 199 gppi (sesskey, "AgentFwd", 0, &cfg.agentfwd);
6abbf9e3 200 gpps (sesskey, "RemoteCmd", "", cfg.remote_cmd, sizeof(cfg.remote_cmd));
bea1ef5f 201 {
202 char cipher[10];
203 gpps (sesskey, "Cipher", "3des", cipher, 10);
204 if (!strcmp(cipher, "blowfish"))
205 cfg.cipher = CIPHER_BLOWFISH;
9697bfd2 206 else if (!strcmp(cipher, "des"))
207 cfg.cipher = CIPHER_DES;
bea1ef5f 208 else
209 cfg.cipher = CIPHER_3DES;
210 }
adf799dd 211 gppi (sesskey, "SshProt", 1, &cfg.sshprot);
ccbfb941 212 gppi (sesskey, "AuthTIS", 0, &cfg.try_tis_auth);
7cca0d81 213 gpps (sesskey, "PublicKeyFile", "", cfg.keyfile, sizeof(cfg.keyfile));
374330e2 214 gppi (sesskey, "RFCEnviron", 0, &cfg.rfc_environ);
215 gppi (sesskey, "BackspaceIsDelete", 1, &cfg.bksp_is_delete);
216 gppi (sesskey, "RXVTHomeEnd", 0, &cfg.rxvt_homeend);
c9def1b8 217 gppi (sesskey, "LinuxFunctionKeys", 0, &cfg.funky_type);
374330e2 218 gppi (sesskey, "ApplicationCursorKeys", 0, &cfg.app_cursor);
219 gppi (sesskey, "ApplicationKeypad", 0, &cfg.app_keypad);
c5e9c988 220 gppi (sesskey, "NetHackKeypad", 0, &cfg.nethack_keypad);
221 gppi (sesskey, "AltF4", 1, &cfg.alt_f4);
222 gppi (sesskey, "AltSpace", 0, &cfg.alt_space);
5bc238bb 223 gppi (sesskey, "LdiscTerm", 0, &cfg.ldisc_term);
217dceef 224 gppi (sesskey, "BlinkCur", 0, &cfg.blink_cur);
2a25a1b4 225 gppi (sesskey, "Beep", 1, &cfg.beep);
374330e2 226 gppi (sesskey, "ScrollbackLines", 200, &cfg.savelines);
227 gppi (sesskey, "DECOriginMode", 0, &cfg.dec_om);
228 gppi (sesskey, "AutoWrapMode", 1, &cfg.wrap_mode);
fef97f43 229 gppi (sesskey, "LFImpliesCR", 0, &cfg.lfhascr);
374330e2 230 gppi (sesskey, "WinNameAlways", 0, &cfg.win_name_always);
9ca5da42 231 gpps (sesskey, "WinTitle", "", cfg.wintitle, sizeof(cfg.wintitle));
374330e2 232 gppi (sesskey, "TermWidth", 80, &cfg.width);
233 gppi (sesskey, "TermHeight", 24, &cfg.height);
234 gpps (sesskey, "Font", "Courier", cfg.font, sizeof(cfg.font));
235 gppi (sesskey, "FontIsBold", 0, &cfg.fontisbold);
14963b8f 236 gppi (sesskey, "FontCharSet", ANSI_CHARSET, &cfg.fontcharset);
374330e2 237 gppi (sesskey, "FontHeight", 10, &cfg.fontheight);
2a7bfc6e 238 gppi (sesskey, "FontVTMode", VT_OEMANSI, (int *)&cfg.vtmode);
374330e2 239 gppi (sesskey, "TryPalette", 0, &cfg.try_palette);
240 gppi (sesskey, "BoldAsColour", 1, &cfg.bold_colour);
241 for (i=0; i<22; i++) {
242 static char *defaults[] = {
243 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
244 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
245 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
246 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
247 "85,255,255", "187,187,187", "255,255,255"
248 };
249 char buf[20], buf2[30];
1d470ad2 250 int c0, c1, c2;
374330e2 251 sprintf(buf, "Colour%d", i);
252 gpps (sesskey, buf, defaults[i], buf2, sizeof(buf2));
1d470ad2 253 if(sscanf(buf2, "%d,%d,%d", &c0, &c1, &c2) == 3) {
254 cfg.colours[i][0] = c0;
255 cfg.colours[i][1] = c1;
256 cfg.colours[i][2] = c2;
257 }
374330e2 258 }
259 gppi (sesskey, "MouseIsXterm", 0, &cfg.mouse_is_xterm);
260 for (i=0; i<256; i+=32) {
261 static char *defaults[] = {
262 "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",
263 "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",
264 "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",
265 "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",
266 "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",
267 "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",
268 "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",
269 "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"
270 };
271 char buf[20], buf2[256], *p;
272 int j;
273 sprintf(buf, "Wordness%d", i);
274 gpps (sesskey, buf, defaults[i/32], buf2, sizeof(buf2));
275 p = buf2;
276 for (j=i; j<i+32; j++) {
277 char *q = p;
278 while (*p && *p != ',') p++;
279 if (*p == ',') *p++ = '\0';
280 cfg.wordness[j] = atoi(q);
281 }
282 }
14963b8f 283 gppi (sesskey, "KoiWinXlat", 0, &cfg.xlat_enablekoiwin);
d3d16feb 284 gppi (sesskey, "88592Xlat", 0, &cfg.xlat_88592w1250);
14963b8f 285 gppi (sesskey, "CapsLockCyr", 0, &cfg.xlat_capslockcyr);
c9def1b8 286 gppi (sesskey, "ScrollBar", 1, &cfg.scrollbar);
287 gppi (sesskey, "ScrollOnKey", 0, &cfg.scroll_on_key);
288 gppi (sesskey, "LockSize", 0, &cfg.locksize);
289 gppi (sesskey, "BCE", 0, &cfg.bce);
290 gppi (sesskey, "BlinkText", 0, &cfg.blinktext);
14963b8f 291
d1622aed 292 close_settings_r(sesskey);
374330e2 293}
294
c9def1b8 295static void force_normal(HWND hwnd)
296{
297static int recurse = 0;
298
299 WINDOWPLACEMENT wp;
300
301 if(recurse) return;
302 recurse = 1;
303
304 wp.length = sizeof(wp);
305 if (GetWindowPlacement(hwnd, &wp))
306 {
307 wp.showCmd = SW_SHOWNORMAL;
308 SetWindowPlacement(hwnd, &wp);
309 }
310 recurse = 0;
311}
312
374330e2 313static void MyGetDlgItemInt (HWND hwnd, int id, int *result) {
314 BOOL ok;
315 int n;
316 n = GetDlgItemInt (hwnd, id, &ok, FALSE);
317 if (ok)
318 *result = n;
319}
320
321static int CALLBACK LogProc (HWND hwnd, UINT msg,
322 WPARAM wParam, LPARAM lParam) {
323 int i;
324
325 switch (msg) {
326 case WM_INITDIALOG:
c5e9c988 327 for (i=0; i<nevents; i++)
374330e2 328 SendDlgItemMessage (hwnd, IDN_LIST, LB_ADDSTRING,
c5e9c988 329 0, (LPARAM)events[i]);
374330e2 330 return 1;
331/* case WM_CTLCOLORDLG: */
332/* return (int) GetStockObject (LTGRAY_BRUSH); */
333 case WM_COMMAND:
334 switch (LOWORD(wParam)) {
335 case IDOK:
336 logbox = NULL;
337 DestroyWindow (hwnd);
338 return 0;
989b10e9 339 case IDN_COPY:
340 if (HIWORD(wParam) == BN_CLICKED ||
341 HIWORD(wParam) == BN_DOUBLECLICKED) {
342 int selcount;
343 int *selitems;
344 selcount = SendDlgItemMessage(hwnd, IDN_LIST,
345 LB_GETSELCOUNT, 0, 0);
346 selitems = malloc(selcount * sizeof(int));
347 if (selitems) {
348 int count = SendDlgItemMessage(hwnd, IDN_LIST,
349 LB_GETSELITEMS,
350 selcount, (LPARAM)selitems);
351 int i;
352 int size;
353 char *clipdata;
354 static unsigned char sel_nl[] = SEL_NL;
355
356 size = 0;
357 for (i = 0; i < count; i++)
358 size += strlen(events[selitems[i]]) + sizeof(sel_nl);
359
360 clipdata = malloc(size);
361 if (clipdata) {
362 char *p = clipdata;
363 for (i = 0; i < count; i++) {
364 char *q = events[selitems[i]];
365 int qlen = strlen(q);
366 memcpy(p, q, qlen);
367 p += qlen;
368 memcpy(p, sel_nl, sizeof(sel_nl));
369 p += sizeof(sel_nl);
370 }
371 write_clip(clipdata, size);
372 term_deselect();
373 free(clipdata);
374 }
375 free(selitems);
376 }
377 }
378 return 0;
374330e2 379 }
380 return 0;
381 case WM_CLOSE:
382 logbox = NULL;
383 DestroyWindow (hwnd);
384 return 0;
385 }
386 return 0;
387}
388
d57835ab 389static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
390 WPARAM wParam, LPARAM lParam) {
391 switch (msg) {
392 case WM_INITDIALOG:
393 return 1;
394 case WM_COMMAND:
395 switch (LOWORD(wParam)) {
396 case IDOK:
97749503 397 EndDialog(hwnd, 1);
d57835ab 398 return 0;
399 }
400 return 0;
401 case WM_CLOSE:
97749503 402 EndDialog(hwnd, 1);
d57835ab 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);
374330e2 731 CheckDlgButton (hwnd, IDC2_DECOM, cfg.dec_om);
fef97f43 732 CheckDlgButton (hwnd, IDC2_LFHASCR, cfg.lfhascr);
374330e2 733 SetDlgItemInt (hwnd, IDC2_ROWSEDIT, cfg.height, FALSE);
734 SetDlgItemInt (hwnd, IDC2_COLSEDIT, cfg.width, FALSE);
735 SetDlgItemInt (hwnd, IDC2_SAVEEDIT, cfg.savelines, FALSE);
736 fmtfont (fontstatic);
737 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
c9def1b8 738 CheckDlgButton (hwnd, IDC1_BEEP, cfg.beep);
c9def1b8 739 CheckDlgButton (hwnd, IDC2_BCE, cfg.bce);
740 CheckDlgButton (hwnd, IDC2_BLINKTEXT, cfg.blinktext);
374330e2 741 break;
742 case WM_COMMAND:
743 switch (LOWORD(wParam)) {
744 case IDC2_WRAPMODE:
745 if (HIWORD(wParam) == BN_CLICKED ||
746 HIWORD(wParam) == BN_DOUBLECLICKED)
747 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC2_WRAPMODE);
748 break;
374330e2 749 case IDC2_DECOM:
750 if (HIWORD(wParam) == BN_CLICKED ||
751 HIWORD(wParam) == BN_DOUBLECLICKED)
752 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC2_DECOM);
753 break;
fef97f43 754 case IDC2_LFHASCR:
755 if (HIWORD(wParam) == BN_CLICKED ||
756 HIWORD(wParam) == BN_DOUBLECLICKED)
757 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC2_LFHASCR);
758 break;
374330e2 759 case IDC2_ROWSEDIT:
760 if (HIWORD(wParam) == EN_CHANGE)
761 MyGetDlgItemInt (hwnd, IDC2_ROWSEDIT, &cfg.height);
762 break;
763 case IDC2_COLSEDIT:
764 if (HIWORD(wParam) == EN_CHANGE)
765 MyGetDlgItemInt (hwnd, IDC2_COLSEDIT, &cfg.width);
766 break;
767 case IDC2_SAVEEDIT:
768 if (HIWORD(wParam) == EN_CHANGE)
769 MyGetDlgItemInt (hwnd, IDC2_SAVEEDIT, &cfg.savelines);
770 break;
771 case IDC2_CHOOSEFONT:
772 lf.lfHeight = cfg.fontheight;
773 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
774 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
775 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
14963b8f 776 lf.lfCharSet = cfg.fontcharset;
374330e2 777 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
778 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
779 lf.lfQuality = DEFAULT_QUALITY;
780 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
781 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
782 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
783
784 cf.lStructSize = sizeof(cf);
785 cf.hwndOwner = hwnd;
786 cf.lpLogFont = &lf;
787 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
788 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
789
790 if (ChooseFont (&cf)) {
791 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
792 cfg.font[sizeof(cfg.font)-1] = '\0';
793 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
14963b8f 794 cfg.fontcharset = lf.lfCharSet;
374330e2 795 cfg.fontheight = lf.lfHeight;
796 fmtfont (fontstatic);
797 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
798 }
799 break;
c9def1b8 800 case IDC1_BEEP:
801 if (HIWORD(wParam) == BN_CLICKED ||
802 HIWORD(wParam) == BN_DOUBLECLICKED)
803 cfg.beep = IsDlgButtonChecked (hwnd, IDC1_BEEP);
804 break;
c9def1b8 805 case IDC2_BLINKTEXT:
806 if (HIWORD(wParam) == BN_CLICKED ||
807 HIWORD(wParam) == BN_DOUBLECLICKED)
808 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC2_BLINKTEXT);
809 break;
810 case IDC2_BCE:
811 if (HIWORD(wParam) == BN_CLICKED ||
812 HIWORD(wParam) == BN_DOUBLECLICKED)
813 cfg.bce = IsDlgButtonChecked (hwnd, IDC2_BCE);
814 break;
374330e2 815 }
816 break;
817 }
818 return GeneralPanelProc (hwnd, msg, wParam, lParam);
819}
820
9ca5da42 821static int CALLBACK WindowProc (HWND hwnd, UINT msg,
822 WPARAM wParam, LPARAM lParam) {
823 switch (msg) {
824 case WM_INITDIALOG:
825 SetDlgItemText (hwnd, IDCW_WINEDIT, cfg.wintitle);
826 CheckDlgButton (hwnd, IDCW_WINNAME, cfg.win_name_always);
827 CheckDlgButton (hwnd, IDCW_BLINKCUR, cfg.blink_cur);
828 CheckDlgButton (hwnd, IDCW_SCROLLBAR, cfg.scrollbar);
829 CheckDlgButton (hwnd, IDCW_LOCKSIZE, cfg.locksize);
830 break;
831 case WM_COMMAND:
832 switch (LOWORD(wParam)) {
833 case IDCW_WINNAME:
834 if (HIWORD(wParam) == BN_CLICKED ||
835 HIWORD(wParam) == BN_DOUBLECLICKED)
836 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDCW_WINNAME);
837 break;
838 case IDCW_BLINKCUR:
839 if (HIWORD(wParam) == BN_CLICKED ||
840 HIWORD(wParam) == BN_DOUBLECLICKED)
841 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDCW_BLINKCUR);
842 break;
843 case IDCW_SCROLLBAR:
844 if (HIWORD(wParam) == BN_CLICKED ||
845 HIWORD(wParam) == BN_DOUBLECLICKED)
846 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDCW_SCROLLBAR);
847 break;
848 case IDCW_LOCKSIZE:
849 if (HIWORD(wParam) == BN_CLICKED ||
850 HIWORD(wParam) == BN_DOUBLECLICKED)
851 cfg.locksize = IsDlgButtonChecked (hwnd, IDCW_LOCKSIZE);
852 break;
853 case IDCW_WINEDIT:
854 if (HIWORD(wParam) == EN_CHANGE)
855 GetDlgItemText (hwnd, IDCW_WINEDIT, cfg.wintitle,
856 sizeof(cfg.wintitle)-1);
857 break;
858 }
859 break;
860 }
861 return GeneralPanelProc (hwnd, msg, wParam, lParam);
862}
863
374330e2 864static int CALLBACK TelnetProc (HWND hwnd, UINT msg,
865 WPARAM wParam, LPARAM lParam) {
866 int i;
867
868 switch (msg) {
869 case WM_INITDIALOG:
870 SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype);
871 SetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed);
872 SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username);
873 {
37508af4 874 char *p = cfg.environmt;
374330e2 875 while (*p) {
876 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING, 0,
877 (LPARAM) p);
878 p += strlen(p)+1;
879 }
880 }
881 CheckRadioButton (hwnd, IDC3_EMBSD, IDC3_EMRFC,
882 cfg.rfc_environ ? IDC3_EMRFC : IDC3_EMBSD);
883 break;
884 case WM_COMMAND:
885 switch (LOWORD(wParam)) {
886 case IDC3_TTEDIT:
887 if (HIWORD(wParam) == EN_CHANGE)
888 GetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype,
889 sizeof(cfg.termtype)-1);
890 break;
891 case IDC3_TSEDIT:
892 if (HIWORD(wParam) == EN_CHANGE)
893 GetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed,
894 sizeof(cfg.termspeed)-1);
895 break;
896 case IDC3_LOGEDIT:
897 if (HIWORD(wParam) == EN_CHANGE)
898 GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username,
899 sizeof(cfg.username)-1);
900 break;
901 case IDC3_EMBSD:
902 case IDC3_EMRFC:
903 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC3_EMRFC);
904 break;
905 case IDC3_ENVADD:
906 if (HIWORD(wParam) == BN_CLICKED ||
907 HIWORD(wParam) == BN_DOUBLECLICKED) {
37508af4 908 char str[sizeof(cfg.environmt)];
374330e2 909 char *p;
910 GetDlgItemText (hwnd, IDC3_VAREDIT, str, sizeof(str)-1);
911 if (!*str) {
912 MessageBeep(0);
913 break;
914 }
915 p = str + strlen(str);
916 *p++ = '\t';
917 GetDlgItemText (hwnd, IDC3_VALEDIT, p, sizeof(str)-1-(p-str));
918 if (!*p) {
919 MessageBeep(0);
920 break;
921 }
37508af4 922 p = cfg.environmt;
374330e2 923 while (*p) {
924 while (*p) p++;
925 p++;
926 }
37508af4 927 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
374330e2 928 strcpy (p, str);
929 p[strlen(str)+1] = '\0';
930 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING,
931 0, (LPARAM)str);
932 SetDlgItemText (hwnd, IDC3_VAREDIT, "");
933 SetDlgItemText (hwnd, IDC3_VALEDIT, "");
934 } else {
935 MessageBox(hwnd, "Environment too big", "PuTTY Error",
936 MB_OK | MB_ICONERROR);
937 }
938 }
939 break;
940 case IDC3_ENVREMOVE:
941 if (HIWORD(wParam) != BN_CLICKED &&
942 HIWORD(wParam) != BN_DOUBLECLICKED)
943 break;
944 i = SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_GETCURSEL, 0, 0);
945 if (i == LB_ERR)
946 MessageBeep (0);
947 else {
948 char *p, *q;
949
950 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_DELETESTRING,
951 i, 0);
37508af4 952 p = cfg.environmt;
374330e2 953 while (i > 0) {
954 if (!*p)
955 goto disaster;
956 while (*p) p++;
957 p++;
958 i--;
959 }
960 q = p;
961 if (!*p)
962 goto disaster;
963 while (*p) p++;
964 p++;
965 while (*p) {
966 while (*p)
967 *q++ = *p++;
968 *q++ = *p++;
969 }
970 *q = '\0';
971 disaster:;
972 }
973 break;
974 }
975 break;
976 }
977 return GeneralPanelProc (hwnd, msg, wParam, lParam);
978}
979
980static int CALLBACK SshProc (HWND hwnd, UINT msg,
981 WPARAM wParam, LPARAM lParam) {
7cca0d81 982 OPENFILENAME of;
983 char filename[sizeof(cfg.keyfile)];
984
374330e2 985 switch (msg) {
986 case WM_INITDIALOG:
987 SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype);
988 SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username);
fef97f43 989 CheckDlgButton (hwnd, IDC3_NOPTY, cfg.nopty);
979310f1 990 CheckDlgButton (hwnd, IDC3_AGENTFWD, cfg.agentfwd);
9697bfd2 991 CheckRadioButton (hwnd, IDC3_CIPHER3DES, IDC3_CIPHERDES,
bea1ef5f 992 cfg.cipher == CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF :
9697bfd2 993 cfg.cipher == CIPHER_DES ? IDC3_CIPHERDES :
bea1ef5f 994 IDC3_CIPHER3DES);
adf799dd 995 CheckRadioButton (hwnd, IDC3_SSHPROT1, IDC3_SSHPROT2,
996 cfg.sshprot == 1 ? IDC3_SSHPROT1 : IDC3_SSHPROT2);
ccbfb941 997 CheckDlgButton (hwnd, IDC3_AUTHTIS, cfg.try_tis_auth);
7cca0d81 998 SetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile);
374330e2 999 break;
1000 case WM_COMMAND:
1001 switch (LOWORD(wParam)) {
1002 case IDC3_TTEDIT:
1003 if (HIWORD(wParam) == EN_CHANGE)
1004 GetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype,
1005 sizeof(cfg.termtype)-1);
1006 break;
1007 case IDC3_LOGEDIT:
1008 if (HIWORD(wParam) == EN_CHANGE)
1009 GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username,
1010 sizeof(cfg.username)-1);
1011 break;
fef97f43 1012 case IDC3_NOPTY:
1013 if (HIWORD(wParam) == BN_CLICKED ||
1014 HIWORD(wParam) == BN_DOUBLECLICKED)
1015 cfg.nopty = IsDlgButtonChecked (hwnd, IDC3_NOPTY);
1016 break;
979310f1 1017 case IDC3_AGENTFWD:
1018 if (HIWORD(wParam) == BN_CLICKED ||
1019 HIWORD(wParam) == BN_DOUBLECLICKED)
1020 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC3_AGENTFWD);
1021 break;
bea1ef5f 1022 case IDC3_CIPHER3DES:
1023 case IDC3_CIPHERBLOWF:
9697bfd2 1024 case IDC3_CIPHERDES:
bea1ef5f 1025 if (HIWORD(wParam) == BN_CLICKED ||
1026 HIWORD(wParam) == BN_DOUBLECLICKED) {
1027 if (IsDlgButtonChecked (hwnd, IDC3_CIPHER3DES))
1028 cfg.cipher = CIPHER_3DES;
1029 else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERBLOWF))
1030 cfg.cipher = CIPHER_BLOWFISH;
9697bfd2 1031 else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERDES))
1032 cfg.cipher = CIPHER_DES;
bea1ef5f 1033 }
1034 break;
adf799dd 1035 case IDC3_SSHPROT1:
1036 case IDC3_SSHPROT2:
1037 if (HIWORD(wParam) == BN_CLICKED ||
1038 HIWORD(wParam) == BN_DOUBLECLICKED) {
1039 if (IsDlgButtonChecked (hwnd, IDC3_SSHPROT1))
1040 cfg.sshprot = 1;
1041 else if (IsDlgButtonChecked (hwnd, IDC3_SSHPROT2))
1042 cfg.sshprot = 2;
1043 }
1044 break;
ccbfb941 1045 case IDC3_AUTHTIS:
1046 if (HIWORD(wParam) == BN_CLICKED ||
1047 HIWORD(wParam) == BN_DOUBLECLICKED)
1048 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC3_AUTHTIS);
1049 break;
7cca0d81 1050 case IDC3_PKEDIT:
1051 if (HIWORD(wParam) == EN_CHANGE)
1052 GetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile,
1053 sizeof(cfg.keyfile)-1);
1054 break;
1055 case IDC3_PKBUTTON:
1056 /*
1057 * FIXME: this crashes. Find out why.
1058 */
1059 memset(&of, 0, sizeof(of));
1060#ifdef OPENFILENAME_SIZE_VERSION_400
1061 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1062#else
1063 of.lStructSize = sizeof(of);
1064#endif
1065 of.hwndOwner = hwnd;
1066 of.lpstrFilter = "All Files\0*\0\0\0";
1067 of.lpstrCustomFilter = NULL;
1068 of.nFilterIndex = 1;
1069 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1070 of.nMaxFile = sizeof(filename);
1071 of.lpstrFileTitle = NULL;
1072 of.lpstrInitialDir = NULL;
1073 of.lpstrTitle = "Select Public Key File";
1074 of.Flags = 0;
1075 if (GetOpenFileName(&of)) {
1076 strcpy(cfg.keyfile, filename);
1077 SetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile);
1078 }
1079 break;
374330e2 1080 }
1081 break;
1082 }
1083 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1084}
1085
1086static int CALLBACK SelectionProc (HWND hwnd, UINT msg,
1087 WPARAM wParam, LPARAM lParam) {
1088 int i;
1089
1090 switch (msg) {
1091 case WM_INITDIALOG:
1092 CheckRadioButton (hwnd, IDC4_MBWINDOWS, IDC4_MBXTERM,
1093 cfg.mouse_is_xterm ? IDC4_MBXTERM : IDC4_MBWINDOWS);
1094 {
1095 static int tabs[4] = {25, 61, 96, 128};
1096 SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_SETTABSTOPS, 4,
1097 (LPARAM) tabs);
1098 }
1099 for (i=0; i<256; i++) {
1100 char str[100];
1101 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1102 (i>=0x21 && i != 0x7F) ? i : ' ',
1103 cfg.wordness[i]);
1104 SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_ADDSTRING, 0,
1105 (LPARAM) str);
1106 }
1107 break;
1108 case WM_COMMAND:
1109 switch (LOWORD(wParam)) {
1110 case IDC4_MBWINDOWS:
1111 case IDC4_MBXTERM:
1112 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC4_MBXTERM);
1113 break;
1114 case IDC4_CCSET:
1115 {
1116 BOOL ok;
1117 int i;
1118 int n = GetDlgItemInt (hwnd, IDC4_CCEDIT, &ok, FALSE);
1119
1120 if (!ok)
1121 MessageBeep (0);
1122 else {
1123 for (i=0; i<256; i++)
1124 if (SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_GETSEL,
1125 i, 0)) {
1126 char str[100];
1127 cfg.wordness[i] = n;
1128 SendDlgItemMessage (hwnd, IDC4_CCLIST,
1129 LB_DELETESTRING, i, 0);
1130 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1131 (i>=0x21 && i != 0x7F) ? i : ' ',
1132 cfg.wordness[i]);
1133 SendDlgItemMessage (hwnd, IDC4_CCLIST,
1134 LB_INSERTSTRING, i,
1135 (LPARAM)str);
1136 }
1137 }
1138 }
1139 break;
1140 }
1141 break;
1142 }
1143 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1144}
1145
1146static int CALLBACK ColourProc (HWND hwnd, UINT msg,
1147 WPARAM wParam, LPARAM lParam) {
1148 static const char *const colours[] = {
1149 "Default Foreground", "Default Bold Foreground",
1150 "Default Background", "Default Bold Background",
1151 "Cursor Text", "Cursor Colour",
1152 "ANSI Black", "ANSI Black Bold",
1153 "ANSI Red", "ANSI Red Bold",
1154 "ANSI Green", "ANSI Green Bold",
1155 "ANSI Yellow", "ANSI Yellow Bold",
1156 "ANSI Blue", "ANSI Blue Bold",
1157 "ANSI Magenta", "ANSI Magenta Bold",
1158 "ANSI Cyan", "ANSI Cyan Bold",
1159 "ANSI White", "ANSI White Bold"
1160 };
1161 static const int permanent[] = {
1162 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
1163 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
1164 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
1165 };
1166 switch (msg) {
1167 case WM_INITDIALOG:
1168 CheckDlgButton (hwnd, IDC5_BOLDCOLOUR, cfg.bold_colour);
1169 CheckDlgButton (hwnd, IDC5_PALETTE, cfg.try_palette);
1170 {
1171 int i;
1172 for (i=0; i<22; i++)
1173 if (cfg.bold_colour || permanent[i])
1174 SendDlgItemMessage (hwnd, IDC5_LIST, LB_ADDSTRING, 0,
1175 (LPARAM) colours[i]);
1176 }
1177 SendDlgItemMessage (hwnd, IDC5_LIST, LB_SETCURSEL, 0, 0);
1178 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[0][0], FALSE);
1179 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[0][1], FALSE);
1180 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[0][2], FALSE);
1181 break;
1182 case WM_COMMAND:
1183 switch (LOWORD(wParam)) {
1184 case IDC5_BOLDCOLOUR:
1185 if (HIWORD(wParam) == BN_CLICKED ||
1186 HIWORD(wParam) == BN_DOUBLECLICKED) {
1187 int n, i;
1188 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC5_BOLDCOLOUR);
1189 n = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCOUNT, 0, 0);
1190 if (cfg.bold_colour && n!=22) {
1191 for (i=0; i<22; i++)
1192 if (!permanent[i])
1193 SendDlgItemMessage (hwnd, IDC5_LIST,
1194 LB_INSERTSTRING, i,
1195 (LPARAM) colours[i]);
1196 } else if (!cfg.bold_colour && n!=12) {
1197 for (i=22; i-- ;)
1198 if (!permanent[i])
1199 SendDlgItemMessage (hwnd, IDC5_LIST,
1200 LB_DELETESTRING, i, 0);
1201 }
1202 }
1203 break;
1204 case IDC5_PALETTE:
1205 if (HIWORD(wParam) == BN_CLICKED ||
1206 HIWORD(wParam) == BN_DOUBLECLICKED)
1207 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC5_PALETTE);
1208 break;
1209 case IDC5_LIST:
1210 if (HIWORD(wParam) == LBN_DBLCLK ||
1211 HIWORD(wParam) == LBN_SELCHANGE) {
1212 int i = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCURSEL,
1213 0, 0);
1214 if (!cfg.bold_colour)
1215 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1216 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[i][0], FALSE);
1217 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[i][1], FALSE);
1218 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[i][2], FALSE);
1219 }
1220 break;
1221 case IDC5_CHANGE:
1222 if (HIWORD(wParam) == BN_CLICKED ||
1223 HIWORD(wParam) == BN_DOUBLECLICKED) {
1224 static CHOOSECOLOR cc;
1225 static DWORD custom[16] = {0}; /* zero initialisers */
1226 int i = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCURSEL,
1227 0, 0);
1228 if (!cfg.bold_colour)
1229 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1230 cc.lStructSize = sizeof(cc);
1231 cc.hwndOwner = hwnd;
1d470ad2 1232 cc.hInstance = (HWND)hinst;
374330e2 1233 cc.lpCustColors = custom;
1234 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1235 cfg.colours[i][2]);
1236 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1237 if (ChooseColor(&cc)) {
1238 cfg.colours[i][0] =
1239 (unsigned char) (cc.rgbResult & 0xFF);
1240 cfg.colours[i][1] =
1241 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1242 cfg.colours[i][2] =
1243 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1244 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[i][0],
1245 FALSE);
1246 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[i][1],
1247 FALSE);
1248 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[i][2],
1249 FALSE);
1250 }
1251 }
1252 break;
1253 }
1254 break;
1255 }
1256 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1257}
1258
c9def1b8 1259static int CALLBACK TranslationProc (HWND hwnd, UINT msg,
14963b8f 1260 WPARAM wParam, LPARAM lParam) {
1261 switch (msg) {
1262 case WM_INITDIALOG:
d3d16feb 1263 CheckRadioButton (hwnd, IDC6_NOXLAT, IDC6_88592WIN1250,
1264 cfg.xlat_88592w1250 ? IDC6_88592WIN1250 :
1265 cfg.xlat_enablekoiwin ? IDC6_KOI8WIN1251 :
1266 IDC6_NOXLAT);
14963b8f 1267 CheckDlgButton (hwnd, IDC6_CAPSLOCKCYR, cfg.xlat_capslockcyr);
c9def1b8 1268 CheckRadioButton (hwnd, IDC2_VTXWINDOWS, IDC2_VTPOORMAN,
1269 cfg.vtmode == VT_XWINDOWS ? IDC2_VTXWINDOWS :
1270 cfg.vtmode == VT_OEMANSI ? IDC2_VTOEMANSI :
1271 cfg.vtmode == VT_OEMONLY ? IDC2_VTOEMONLY :
1272 IDC2_VTPOORMAN);
14963b8f 1273 case WM_COMMAND:
1274 switch (LOWORD(wParam)) {
d3d16feb 1275 case IDC6_NOXLAT:
1276 case IDC6_KOI8WIN1251:
1277 case IDC6_88592WIN1250:
1278 cfg.xlat_enablekoiwin =
1279 IsDlgButtonChecked (hwnd, IDC6_KOI8WIN1251);
1280 cfg.xlat_88592w1250 =
1281 IsDlgButtonChecked (hwnd, IDC6_88592WIN1250);
14963b8f 1282 break;
1283 case IDC6_CAPSLOCKCYR:
1284 if (HIWORD(wParam) == BN_CLICKED ||
1285 HIWORD(wParam) == BN_DOUBLECLICKED) {
1286 cfg.xlat_capslockcyr =
1287 IsDlgButtonChecked (hwnd, IDC6_CAPSLOCKCYR);
1288 }
1289 break;
c9def1b8 1290 case IDC2_VTXWINDOWS:
1291 case IDC2_VTOEMANSI:
1292 case IDC2_VTOEMONLY:
1293 case IDC2_VTPOORMAN:
1294 cfg.vtmode =
1295 (IsDlgButtonChecked (hwnd, IDC2_VTXWINDOWS) ? VT_XWINDOWS :
1296 IsDlgButtonChecked (hwnd, IDC2_VTOEMANSI) ? VT_OEMANSI :
1297 IsDlgButtonChecked (hwnd, IDC2_VTOEMONLY) ? VT_OEMONLY :
1298 VT_POORMAN);
1299 break;
14963b8f 1300 }
1301 }
1302 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1303}
1304
374330e2 1305static DLGPROC panelproc[NPANELS] = {
9ca5da42 1306 ConnectionProc, KeyboardProc, TerminalProc, WindowProc,
c9def1b8 1307 TelnetProc, SshProc, SelectionProc, ColourProc, TranslationProc
374330e2 1308};
1309static char *panelids[NPANELS] = {
1310 MAKEINTRESOURCE(IDD_PANEL0),
1311 MAKEINTRESOURCE(IDD_PANEL1),
1312 MAKEINTRESOURCE(IDD_PANEL2),
9ca5da42 1313 MAKEINTRESOURCE(IDD_PANELW),
374330e2 1314 MAKEINTRESOURCE(IDD_PANEL3),
1315 MAKEINTRESOURCE(IDD_PANEL35),
1316 MAKEINTRESOURCE(IDD_PANEL4),
14963b8f 1317 MAKEINTRESOURCE(IDD_PANEL5),
1318 MAKEINTRESOURCE(IDD_PANEL6)
374330e2 1319};
14963b8f 1320
374330e2 1321static char *names[NPANELS] = {
9ca5da42 1322 "Connection", "Keyboard", "Terminal", "Window", "Telnet",
c9def1b8 1323 "SSH", "Selection", "Colours", "Translation"
374330e2 1324};
1325
9ca5da42 1326static int mainp[MAIN_NPANELS] = { 0, 1, 2, 3, 4, 5, 6, 7, 8};
1327static int reconfp[RECONF_NPANELS] = { 1, 2, 3, 6, 7, 8};
374330e2 1328
1329static int GenericMainDlgProc (HWND hwnd, UINT msg,
1330 WPARAM wParam, LPARAM lParam,
1331 int npanels, int *panelnums, HWND *page) {
1332 HWND hw;
1333
1334 switch (msg) {
1335 case WM_INITDIALOG:
1336 { /* centre the window */
1337 RECT rs, rd;
1338
1339 hw = GetDesktopWindow();
1340 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
1341 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
1342 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
1343 rd.right-rd.left, rd.bottom-rd.top, TRUE);
1344 }
1345 *page = NULL;
1346 { /* initialise the tab control */
1347 TC_ITEMHEADER tab;
1348 int i;
1349
1350 hw = GetDlgItem (hwnd, IDC_TAB);
1351 for (i=0; i<npanels; i++) {
1352 tab.mask = TCIF_TEXT;
1353 tab.pszText = names[panelnums[i]];
1354 TabCtrl_InsertItem (hw, i, &tab);
1355 }
1356/* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1357 hwnd, panelproc[panelnums[0]]);*/
1358 *page = CreateDialog (hinst, panelids[panelnums[0]],
1359 hwnd, panelproc[panelnums[0]]);
1360 SetWindowLong (*page, GWL_EXSTYLE,
1361 GetWindowLong (*page, GWL_EXSTYLE) |
1362 WS_EX_CONTROLPARENT);
1363 }
1364 SetFocus (*page);
1365 return 0;
1366 case WM_NOTIFY:
1367 if (LOWORD(wParam) == IDC_TAB &&
1368 ((LPNMHDR)lParam)->code == TCN_SELCHANGE) {
1369 int i = TabCtrl_GetCurSel(((LPNMHDR)lParam)->hwndFrom);
1370 if (*page)
1371 DestroyWindow (*page);
1372/* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1373 hwnd, panelproc[panelnums[i]]);*/
1374 *page = CreateDialog (hinst, panelids[panelnums[i]],
1375 hwnd, panelproc[panelnums[i]]);
1376 SetWindowLong (*page, GWL_EXSTYLE,
1377 GetWindowLong (*page, GWL_EXSTYLE) |
1378 WS_EX_CONTROLPARENT);
1379 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1380 return 0;
1381 }
1382 break;
1383/* case WM_CTLCOLORDLG: */
1384/* return (int) GetStockObject (LTGRAY_BRUSH); */
1385 case WM_COMMAND:
1386 switch (LOWORD(wParam)) {
1387 case IDOK:
1388 if (*cfg.host)
1389 EndDialog (hwnd, 1);
1390 else
1391 MessageBeep (0);
1392 return 0;
1393 case IDCANCEL:
1394 EndDialog (hwnd, 0);
1395 return 0;
1396 }
1397 return 0;
1398 case WM_CLOSE:
1399 EndDialog (hwnd, 0);
1400 return 0;
c9def1b8 1401
1402 /* Grrr Explorer will maximize Dialogs! */
1403 case WM_SIZE:
1404 if (wParam == SIZE_MAXIMIZED)
1405 force_normal(hwnd);
1406 return 0;
374330e2 1407 }
1408 return 0;
1409}
1410
1411static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1412 WPARAM wParam, LPARAM lParam) {
1413#if 0
1414 HWND hw;
1415 int i;
1416#endif
1417 static HWND page = NULL;
1418
1419 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1420#if 0
1421 /*
1422 * If the Connection panel is active and the Session List
1423 * box is selected, we treat a press of Open to have an
1424 * implicit press of Load preceding it.
1425 */
1426 hw = GetDlgItem (hwnd, IDC_TAB);
1427 i = TabCtrl_GetCurSel(hw);
1428 if (panelproc[mainp[i]] == ConnectionProc &&
1429 page && implicit_load_ok) {
1430 SendMessage (page, WM_COMMAND,
1431 MAKELONG(IDC0_SESSLOAD, BN_CLICKED), 0);
1432 }
1433#endif
1434 }
1435 if (msg == WM_COMMAND && LOWORD(wParam) == IDC_ABOUT) {
1436 EnableWindow(hwnd, 0);
1437 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1438 GetParent(hwnd), AboutProc);
1439 EnableWindow(hwnd, 1);
9a70ac47 1440 SetActiveWindow(hwnd);
374330e2 1441 }
1442 return GenericMainDlgProc (hwnd, msg, wParam, lParam,
1443 MAIN_NPANELS, mainp, &page);
1444}
1445
1446static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1447 WPARAM wParam, LPARAM lParam) {
1448 static HWND page;
1449 return GenericMainDlgProc (hwnd, msg, wParam, lParam,
1450 RECONF_NPANELS, reconfp, &page);
1451}
1452
0a4aa984 1453void get_sesslist(int allocate) {
d1622aed 1454 static char otherbuf[2048];
374330e2 1455 static char *buffer;
d1622aed 1456 int buflen, bufsize, i;
1457 char *p, *ret;
1458 void *handle;
374330e2 1459
1460 if (allocate) {
d1622aed 1461
1462 if ((handle = enum_settings_start()) == NULL)
374330e2 1463 return;
1464
1465 buflen = bufsize = 0;
1466 buffer = NULL;
374330e2 1467 do {
d1622aed 1468 ret = enum_settings_next(handle, otherbuf, sizeof(otherbuf));
1469 if (ret) {
1470 int len = strlen(otherbuf)+1;
1471 if (bufsize < buflen+len) {
1472 bufsize = buflen + len + 2048;
1473 buffer = srealloc(buffer, bufsize);
1474 }
1475 strcpy(buffer+buflen, otherbuf);
374330e2 1476 buflen += strlen(buffer+buflen)+1;
1477 }
d1622aed 1478 } while (ret);
1479 enum_settings_finish(handle);
374330e2 1480 buffer = srealloc(buffer, buflen+1);
1481 buffer[buflen] = '\0';
1482
1483 p = buffer;
1484 nsessions = 1; /* "Default Settings" counts as one */
1485 while (*p) {
1486 if (strcmp(p, "Default Settings"))
1487 nsessions++;
1488 while (*p) p++;
1489 p++;
1490 }
1491
1492 sessions = smalloc(nsessions * sizeof(char *));
1493 sessions[0] = "Default Settings";
1494 p = buffer;
1495 i = 1;
1496 while (*p) {
1497 if (strcmp(p, "Default Settings"))
1498 sessions[i++] = p;
1499 while (*p) p++;
1500 p++;
1501 }
1502 } else {
1503 sfree (buffer);
1504 sfree (sessions);
1505 }
1506}
1507
1508int do_config (void) {
1509 int ret;
1510
1511 get_sesslist(TRUE);
6584031a 1512 savedsession[0] = '\0';
374330e2 1513 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
1514 get_sesslist(FALSE);
1515
1516 return ret;
1517}
1518
1519int do_reconfig (HWND hwnd) {
1520 Config backup_cfg;
1521 int ret;
1522
1523 backup_cfg = cfg; /* structure copy */
1524 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
1525 if (!ret)
1526 cfg = backup_cfg; /* structure copy */
c9def1b8 1527 else
1528 force_normal(hwnd);
1529
374330e2 1530 return ret;
1531}
1532
1533void do_defaults (char *session) {
1534 if (session)
1535 load_settings (session, TRUE);
1536 else
1537 load_settings ("Default Settings", FALSE);
1538}
1539
c5e9c988 1540void logevent (char *string) {
1541 if (nevents >= negsize) {
374330e2 1542 negsize += 64;
c5e9c988 1543 events = srealloc (events, negsize * sizeof(*events));
374330e2 1544 }
c5e9c988 1545 events[nevents] = smalloc(1+strlen(string));
1546 strcpy (events[nevents], string);
1547 nevents++;
9ad90448 1548 if (logbox) {
1549 int count;
374330e2 1550 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
1551 0, (LPARAM)string);
9ad90448 1552 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
989b10e9 1553 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
9ad90448 1554 }
374330e2 1555}
1556
c5e9c988 1557void showeventlog (HWND hwnd) {
374330e2 1558 if (!logbox) {
1559 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
1560 hwnd, LogProc);
1561 ShowWindow (logbox, SW_SHOWNORMAL);
1562 }
1563}
1564
1565void showabout (HWND hwnd) {
1566 if (!abtbox) {
1567 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1568 hwnd, AboutProc);
1569 ShowWindow (abtbox, SW_SHOWNORMAL);
1570 }
1571}
1572
d4857987 1573void verify_ssh_host_key(char *host, int port, char *keytype,
d5859615 1574 char *keystr, char *fingerprint) {
1575 int ret;
374330e2 1576
d5859615 1577 static const char absentmsg[] =
1578 "The server's host key is not cached in the registry. You\n"
1579 "have no guarantee that the server is the computer you\n"
1580 "think it is.\n"
1581 "The server's key fingerprint is:\n"
1582 "%s\n"
1583 "If you trust this host, hit Yes to add the key to\n"
1584 "PuTTY's cache and carry on connecting.\n"
1585 "If you do not trust this host, hit No to abandon the\n"
1586 "connection.\n";
1587
1588 static const char wrongmsg[] =
1589 "WARNING - POTENTIAL SECURITY BREACH!\n"
1590 "\n"
1591 "The server's host key does not match the one PuTTY has\n"
1592 "cached in the registry. This means that either the\n"
1593 "server administrator has changed the host key, or you\n"
1594 "have actually connected to another computer pretending\n"
1595 "to be the server.\n"
1596 "The new key fingerprint is:\n"
1597 "%s\n"
1598 "If you were expecting this change and trust the new key,\n"
1599 "hit Yes to update PuTTY's cache and continue connecting.\n"
1600 "If you want to carry on connecting but without updating\n"
1601 "the cache, hit No.\n"
1602 "If you want to abandon the connection completely, hit\n"
1603 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
1604 "choice.\n";
1605
1606 static const char mbtitle[] = "PuTTY Security Alert";
de3df031 1607
d5859615 1608
1609 char message[160+ /* sensible fingerprint max size */
1610 (sizeof(absentmsg) > sizeof(wrongmsg) ?
1611 sizeof(absentmsg) : sizeof(wrongmsg))];
de3df031 1612
1613 /*
d5859615 1614 * Verify the key against the registry.
de3df031 1615 */
d4857987 1616 ret = verify_host_key(host, port, keytype, keystr);
d5859615 1617
1618 if (ret == 0) /* success - key matched OK */
1619 return;
1620 if (ret == 2) { /* key was different */
1621 int mbret;
1622 sprintf(message, wrongmsg, fingerprint);
1623 mbret = MessageBox(NULL, message, mbtitle,
1624 MB_ICONWARNING | MB_YESNOCANCEL);
1625 if (mbret == IDYES)
d4857987 1626 store_host_key(host, port, keytype, keystr);
d5859615 1627 if (mbret == IDCANCEL)
1628 exit(0);
de3df031 1629 }
d5859615 1630 if (ret == 1) { /* key was absent */
1631 int mbret;
1632 sprintf(message, absentmsg, fingerprint);
1633 mbret = MessageBox(NULL, message, mbtitle,
1634 MB_ICONWARNING | MB_YESNO);
1635 if (mbret == IDNO)
1636 exit(0);
d4857987 1637 store_host_key(host, port, keytype, keystr);
de3df031 1638 }
de3df031 1639}