2 * settings.c: read and write saved sessions. (platform-independent)
\r
11 /* The cipher order given here is the default order. */
\r
12 static const struct keyvalwhere ciphernames[] = {
\r
13 { "aes", CIPHER_AES, -1, -1 },
\r
14 { "blowfish", CIPHER_BLOWFISH, -1, -1 },
\r
15 { "3des", CIPHER_3DES, -1, -1 },
\r
16 { "WARN", CIPHER_WARN, -1, -1 },
\r
17 { "arcfour", CIPHER_ARCFOUR, -1, -1 },
\r
18 { "des", CIPHER_DES, -1, -1 }
\r
21 static const struct keyvalwhere kexnames[] = {
\r
22 { "dh-gex-sha1", KEX_DHGEX, -1, -1 },
\r
23 { "dh-group14-sha1", KEX_DHGROUP14, -1, -1 },
\r
24 { "dh-group1-sha1", KEX_DHGROUP1, -1, -1 },
\r
25 { "rsa", KEX_RSA, KEX_WARN, -1 },
\r
26 { "WARN", KEX_WARN, -1, -1 }
\r
30 * All the terminal modes that we know about for the "TerminalModes"
\r
31 * setting. (Also used by config.c for the drop-down list.)
\r
32 * This is currently precisely the same as the set in ssh.c, but could
\r
33 * in principle differ if other backends started to support tty modes
\r
34 * (e.g., the pty backend).
\r
36 const char *const ttymodes[] = {
\r
37 "INTR", "QUIT", "ERASE", "KILL", "EOF",
\r
38 "EOL", "EOL2", "START", "STOP", "SUSP",
\r
39 "DSUSP", "REPRINT", "WERASE", "LNEXT", "FLUSH",
\r
40 "SWTCH", "STATUS", "DISCARD", "IGNPAR", "PARMRK",
\r
41 "INPCK", "ISTRIP", "INLCR", "IGNCR", "ICRNL",
\r
42 "IUCLC", "IXON", "IXANY", "IXOFF", "IMAXBEL",
\r
43 "ISIG", "ICANON", "XCASE", "ECHO", "ECHOE",
\r
44 "ECHOK", "ECHONL", "NOFLSH", "TOSTOP", "IEXTEN",
\r
45 "ECHOCTL", "ECHOKE", "PENDIN", "OPOST", "OLCUC",
\r
46 "ONLCR", "OCRNL", "ONOCR", "ONLRET", "CS7",
\r
47 "CS8", "PARENB", "PARODD", NULL
\r
51 * Convenience functions to access the backends[] array
\r
52 * (which is only present in tools that manage settings).
\r
55 Backend *backend_from_name(const char *name)
\r
58 for (p = backends; *p != NULL; p++)
\r
59 if (!strcmp((*p)->name, name))
\r
64 Backend *backend_from_proto(int proto)
\r
67 for (p = backends; *p != NULL; p++)
\r
68 if ((*p)->protocol == proto)
\r
73 char *get_remote_username(Conf *conf)
\r
75 char *username = conf_get_str(conf, CONF_username);
\r
77 return dupstr(username);
\r
78 } else if (conf_get_int(conf, CONF_username_from_env)) {
\r
79 /* Use local username. */
\r
80 return get_username(); /* might still be NULL */
\r
86 static char *gpps_raw(void *handle, const char *name, const char *def)
\r
88 char *ret = read_setting_s(handle, name);
\r
90 ret = platform_default_s(name);
\r
92 ret = def ? dupstr(def) : NULL; /* permit NULL as final fallback */
\r
96 static void gpps(void *handle, const char *name, const char *def,
\r
97 Conf *conf, int primary)
\r
99 char *val = gpps_raw(handle, name, def);
\r
100 conf_set_str(conf, primary, val);
\r
105 * gppfont and gppfile cannot have local defaults, since the very
\r
106 * format of a Filename or FontSpec is platform-dependent. So the
\r
107 * platform-dependent functions MUST return some sort of value.
\r
109 static void gppfont(void *handle, const char *name, Conf *conf, int primary)
\r
111 FontSpec *result = read_setting_fontspec(handle, name);
\r
113 result = platform_default_fontspec(name);
\r
114 conf_set_fontspec(conf, primary, result);
\r
115 fontspec_free(result);
\r
117 static void gppfile(void *handle, const char *name, Conf *conf, int primary)
\r
119 Filename *result = read_setting_filename(handle, name);
\r
121 result = platform_default_filename(name);
\r
122 conf_set_filename(conf, primary, result);
\r
123 filename_free(result);
\r
126 static int gppi_raw(void *handle, char *name, int def)
\r
128 def = platform_default_i(name, def);
\r
129 return read_setting_i(handle, name, def);
\r
132 static void gppi(void *handle, char *name, int def, Conf *conf, int primary)
\r
134 conf_set_int(conf, primary, gppi_raw(handle, name, def));
\r
138 * Read a set of name-value pairs in the format we occasionally use:
\r
139 * NAME\tVALUE\0NAME\tVALUE\0\0 in memory
\r
140 * NAME=VALUE,NAME=VALUE, in storage
\r
141 * If there's no "=VALUE" (e.g. just NAME,NAME,NAME) then those keys
\r
142 * are mapped to the empty string.
\r
144 static int gppmap(void *handle, char *name, Conf *conf, int primary)
\r
146 char *buf, *p, *q, *key, *val;
\r
149 * Start by clearing any existing subkeys of this key from conf.
\r
151 while ((key = conf_get_str_nthstrkey(conf, primary, 0)) != NULL)
\r
152 conf_del_str_str(conf, primary, key);
\r
155 * Now read a serialised list from the settings and unmarshal it
\r
156 * into its components.
\r
158 buf = gpps_raw(handle, name, NULL);
\r
166 while (*p && *p != ',') {
\r
182 if (primary == CONF_portfwd && strchr(buf, 'D') != NULL) {
\r
184 * Backwards-compatibility hack: dynamic forwardings are
\r
185 * indexed in the data store as a third type letter in the
\r
186 * key, 'D' alongside 'L' and 'R' - but really, they
\r
187 * should be filed under 'L' with a special _value_,
\r
188 * because local and dynamic forwardings both involve
\r
189 * _listening_ on a local port, and are hence mutually
\r
190 * exclusive on the same port number. So here we translate
\r
191 * the legacy storage format into the sensible internal
\r
192 * form, by finding the D and turning it into a L.
\r
194 char *newkey = dupstr(buf);
\r
195 *strchr(newkey, 'D') = 'L';
\r
196 conf_set_str_str(conf, primary, newkey, "D");
\r
199 conf_set_str_str(conf, primary, buf, val);
\r
208 * Write a set of name/value pairs in the above format, or just the
\r
209 * names if include_values is FALSE.
\r
211 static void wmap(void *handle, char const *outkey, Conf *conf, int primary,
\r
212 int include_values)
\r
214 char *buf, *p, *q, *key, *realkey, *val;
\r
217 len = 1; /* allow for NUL */
\r
219 for (val = conf_get_str_strs(conf, primary, NULL, &key);
\r
221 val = conf_get_str_strs(conf, primary, key, &key))
\r
222 len += 2 + 2 * (strlen(key) + strlen(val)); /* allow for escaping */
\r
224 buf = snewn(len, char);
\r
227 for (val = conf_get_str_strs(conf, primary, NULL, &key);
\r
229 val = conf_get_str_strs(conf, primary, key, &key)) {
\r
231 if (primary == CONF_portfwd && !strcmp(val, "D")) {
\r
233 * Backwards-compatibility hack, as above: translate from
\r
234 * the sensible internal representation of dynamic
\r
235 * forwardings (key "L<port>", value "D") to the
\r
236 * conceptually incoherent legacy storage format (key
\r
237 * "D<port>", value empty).
\r
241 realkey = key; /* restore it at end of loop */
\r
244 L = strchr(key, 'L');
\r
252 for (q = key; *q; q++) {
\r
253 if (*q == '=' || *q == ',' || *q == '\\')
\r
257 if (include_values) {
\r
259 for (q = val; *q; q++) {
\r
260 if (*q == '=' || *q == ',' || *q == '\\')
\r
272 write_setting_s(handle, outkey, buf);
\r
276 static int key2val(const struct keyvalwhere *mapping,
\r
277 int nmaps, char *key)
\r
280 for (i = 0; i < nmaps; i++)
\r
281 if (!strcmp(mapping[i].s, key)) return mapping[i].v;
\r
285 static const char *val2key(const struct keyvalwhere *mapping,
\r
286 int nmaps, int val)
\r
289 for (i = 0; i < nmaps; i++)
\r
290 if (mapping[i].v == val) return mapping[i].s;
\r
295 * Helper function to parse a comma-separated list of strings into
\r
296 * a preference list array of values. Any missing values are added
\r
297 * to the end and duplicates are weeded.
\r
298 * XXX: assumes vals in 'mapping' are small +ve integers
\r
300 static void gprefs(void *sesskey, char *name, char *def,
\r
301 const struct keyvalwhere *mapping, int nvals,
\r
302 Conf *conf, int primary)
\r
306 int i, j, n, v, pos;
\r
307 unsigned long seen = 0; /* bitmap for weeding dups etc */
\r
310 * Fetch the string which we'll parse as a comma-separated list.
\r
312 commalist = gpps_raw(sesskey, name, def);
\r
315 * Go through that list and convert it into values.
\r
320 while (*p && *p == ',') p++;
\r
322 break; /* no more words */
\r
325 while (*p && *p != ',') p++;
\r
326 if (*p) *p++ = '\0';
\r
328 v = key2val(mapping, nvals, q);
\r
329 if (v != -1 && !(seen & (1 << v))) {
\r
331 conf_set_int_int(conf, primary, n, v);
\r
339 * Now go through 'mapping' and add values that weren't mentioned
\r
340 * in the list we fetched. We may have to loop over it multiple
\r
341 * times so that we add values before other values whose default
\r
342 * positions depend on them.
\r
344 while (n < nvals) {
\r
345 for (i = 0; i < nvals; i++) {
\r
346 assert(mapping[i].v < 32);
\r
348 if (!(seen & (1 << mapping[i].v))) {
\r
350 * This element needs adding. But can we add it yet?
\r
352 if (mapping[i].vrel != -1 && !(seen & (1 << mapping[i].vrel)))
\r
353 continue; /* nope */
\r
356 * OK, we can work out where to add this element, so
\r
359 if (mapping[i].vrel == -1) {
\r
360 pos = (mapping[i].where < 0 ? n : 0);
\r
362 for (j = 0; j < n; j++)
\r
363 if (conf_get_int_int(conf, primary, j) ==
\r
366 assert(j < n); /* implied by (seen & (1<<vrel)) */
\r
367 pos = (mapping[i].where < 0 ? j : j+1);
\r
373 for (j = n-1; j >= pos; j--)
\r
374 conf_set_int_int(conf, primary, j+1,
\r
375 conf_get_int_int(conf, primary, j));
\r
376 conf_set_int_int(conf, primary, pos, mapping[i].v);
\r
384 * Write out a preference list.
\r
386 static void wprefs(void *sesskey, char *name,
\r
387 const struct keyvalwhere *mapping, int nvals,
\r
388 Conf *conf, int primary)
\r
393 for (maxlen = i = 0; i < nvals; i++) {
\r
394 const char *s = val2key(mapping, nvals,
\r
395 conf_get_int_int(conf, primary, i));
\r
397 maxlen += (maxlen > 0 ? 1 : 0) + strlen(s);
\r
401 buf = snewn(maxlen + 1, char);
\r
404 for (i = 0; i < nvals; i++) {
\r
405 const char *s = val2key(mapping, nvals,
\r
406 conf_get_int_int(conf, primary, i));
\r
408 p += sprintf(p, "%s%s", (p > buf ? "," : ""), s);
\r
412 assert(p - buf == maxlen);
\r
415 write_setting_s(sesskey, name, buf);
\r
420 char *save_settings(char *section, Conf *conf)
\r
425 sesskey = open_settings_w(section, &errmsg);
\r
428 save_open_settings(sesskey, conf);
\r
429 close_settings_w(sesskey);
\r
433 void save_open_settings(void *sesskey, Conf *conf)
\r
438 write_setting_i(sesskey, "Present", 1);
\r
439 write_setting_s(sesskey, "HostName", conf_get_str(conf, CONF_host));
\r
440 write_setting_filename(sesskey, "LogFileName", conf_get_filename(conf, CONF_logfilename));
\r
441 write_setting_i(sesskey, "LogType", conf_get_int(conf, CONF_logtype));
\r
442 write_setting_i(sesskey, "LogFileClash", conf_get_int(conf, CONF_logxfovr));
\r
443 write_setting_i(sesskey, "LogFlush", conf_get_int(conf, CONF_logflush));
\r
444 write_setting_i(sesskey, "SSHLogOmitPasswords", conf_get_int(conf, CONF_logomitpass));
\r
445 write_setting_i(sesskey, "SSHLogOmitData", conf_get_int(conf, CONF_logomitdata));
\r
448 const Backend *b = backend_from_proto(conf_get_int(conf, CONF_protocol));
\r
452 write_setting_s(sesskey, "Protocol", p);
\r
453 write_setting_i(sesskey, "PortNumber", conf_get_int(conf, CONF_port));
\r
454 /* The CloseOnExit numbers are arranged in a different order from
\r
455 * the standard FORCE_ON / FORCE_OFF / AUTO. */
\r
456 write_setting_i(sesskey, "CloseOnExit", (conf_get_int(conf, CONF_close_on_exit)+2)%3);
\r
457 write_setting_i(sesskey, "WarnOnClose", !!conf_get_int(conf, CONF_warn_on_close));
\r
458 write_setting_i(sesskey, "PingInterval", conf_get_int(conf, CONF_ping_interval) / 60); /* minutes */
\r
459 write_setting_i(sesskey, "PingIntervalSecs", conf_get_int(conf, CONF_ping_interval) % 60); /* seconds */
\r
460 write_setting_i(sesskey, "TCPNoDelay", conf_get_int(conf, CONF_tcp_nodelay));
\r
461 write_setting_i(sesskey, "TCPKeepalives", conf_get_int(conf, CONF_tcp_keepalives));
\r
462 write_setting_s(sesskey, "TerminalType", conf_get_str(conf, CONF_termtype));
\r
463 write_setting_s(sesskey, "TerminalSpeed", conf_get_str(conf, CONF_termspeed));
\r
464 wmap(sesskey, "TerminalModes", conf, CONF_ttymodes, TRUE);
\r
466 /* Address family selection */
\r
467 write_setting_i(sesskey, "AddressFamily", conf_get_int(conf, CONF_addressfamily));
\r
469 /* proxy settings */
\r
470 write_setting_s(sesskey, "ProxyExcludeList", conf_get_str(conf, CONF_proxy_exclude_list));
\r
471 write_setting_i(sesskey, "ProxyDNS", (conf_get_int(conf, CONF_proxy_dns)+2)%3);
\r
472 write_setting_i(sesskey, "ProxyLocalhost", conf_get_int(conf, CONF_even_proxy_localhost));
\r
473 write_setting_i(sesskey, "ProxyMethod", conf_get_int(conf, CONF_proxy_type));
\r
474 write_setting_s(sesskey, "ProxyHost", conf_get_str(conf, CONF_proxy_host));
\r
475 write_setting_i(sesskey, "ProxyPort", conf_get_int(conf, CONF_proxy_port));
\r
476 write_setting_s(sesskey, "ProxyUsername", conf_get_str(conf, CONF_proxy_username));
\r
477 write_setting_s(sesskey, "ProxyPassword", conf_get_str(conf, CONF_proxy_password));
\r
478 write_setting_s(sesskey, "ProxyTelnetCommand", conf_get_str(conf, CONF_proxy_telnet_command));
\r
479 wmap(sesskey, "Environment", conf, CONF_environmt, TRUE);
\r
480 write_setting_s(sesskey, "UserName", conf_get_str(conf, CONF_username));
\r
481 write_setting_i(sesskey, "UserNameFromEnvironment", conf_get_int(conf, CONF_username_from_env));
\r
482 write_setting_s(sesskey, "LocalUserName", conf_get_str(conf, CONF_localusername));
\r
483 write_setting_i(sesskey, "NoPTY", conf_get_int(conf, CONF_nopty));
\r
484 write_setting_i(sesskey, "Compression", conf_get_int(conf, CONF_compression));
\r
485 write_setting_i(sesskey, "TryAgent", conf_get_int(conf, CONF_tryagent));
\r
486 write_setting_i(sesskey, "AgentFwd", conf_get_int(conf, CONF_agentfwd));
\r
487 write_setting_i(sesskey, "GssapiFwd", conf_get_int(conf, CONF_gssapifwd));
\r
488 write_setting_i(sesskey, "ChangeUsername", conf_get_int(conf, CONF_change_username));
\r
489 wprefs(sesskey, "Cipher", ciphernames, CIPHER_MAX, conf, CONF_ssh_cipherlist);
\r
490 wprefs(sesskey, "KEX", kexnames, KEX_MAX, conf, CONF_ssh_kexlist);
\r
491 write_setting_i(sesskey, "RekeyTime", conf_get_int(conf, CONF_ssh_rekey_time));
\r
492 write_setting_s(sesskey, "RekeyBytes", conf_get_str(conf, CONF_ssh_rekey_data));
\r
493 write_setting_i(sesskey, "SshNoAuth", conf_get_int(conf, CONF_ssh_no_userauth));
\r
494 write_setting_i(sesskey, "SshBanner", conf_get_int(conf, CONF_ssh_show_banner));
\r
495 write_setting_i(sesskey, "AuthTIS", conf_get_int(conf, CONF_try_tis_auth));
\r
496 write_setting_i(sesskey, "AuthKI", conf_get_int(conf, CONF_try_ki_auth));
\r
497 write_setting_i(sesskey, "AuthGSSAPI", conf_get_int(conf, CONF_try_gssapi_auth));
\r
499 wprefs(sesskey, "GSSLibs", gsslibkeywords, ngsslibs, conf, CONF_ssh_gsslist);
\r
500 write_setting_filename(sesskey, "GSSCustom", conf_get_filename(conf, CONF_ssh_gss_custom));
\r
502 write_setting_i(sesskey, "SshNoShell", conf_get_int(conf, CONF_ssh_no_shell));
\r
503 write_setting_i(sesskey, "SshProt", conf_get_int(conf, CONF_sshprot));
\r
504 write_setting_s(sesskey, "LogHost", conf_get_str(conf, CONF_loghost));
\r
505 write_setting_i(sesskey, "SSH2DES", conf_get_int(conf, CONF_ssh2_des_cbc));
\r
506 write_setting_filename(sesskey, "PublicKeyFile", conf_get_filename(conf, CONF_keyfile));
\r
507 write_setting_s(sesskey, "RemoteCommand", conf_get_str(conf, CONF_remote_cmd));
\r
508 write_setting_i(sesskey, "RFCEnviron", conf_get_int(conf, CONF_rfc_environ));
\r
509 write_setting_i(sesskey, "PassiveTelnet", conf_get_int(conf, CONF_passive_telnet));
\r
510 write_setting_i(sesskey, "BackspaceIsDelete", conf_get_int(conf, CONF_bksp_is_delete));
\r
511 write_setting_i(sesskey, "RXVTHomeEnd", conf_get_int(conf, CONF_rxvt_homeend));
\r
512 write_setting_i(sesskey, "LinuxFunctionKeys", conf_get_int(conf, CONF_funky_type));
\r
513 write_setting_i(sesskey, "NoApplicationKeys", conf_get_int(conf, CONF_no_applic_k));
\r
514 write_setting_i(sesskey, "NoApplicationCursors", conf_get_int(conf, CONF_no_applic_c));
\r
515 write_setting_i(sesskey, "NoMouseReporting", conf_get_int(conf, CONF_no_mouse_rep));
\r
516 write_setting_i(sesskey, "NoRemoteResize", conf_get_int(conf, CONF_no_remote_resize));
\r
517 write_setting_i(sesskey, "NoAltScreen", conf_get_int(conf, CONF_no_alt_screen));
\r
518 write_setting_i(sesskey, "NoRemoteWinTitle", conf_get_int(conf, CONF_no_remote_wintitle));
\r
519 write_setting_i(sesskey, "RemoteQTitleAction", conf_get_int(conf, CONF_remote_qtitle_action));
\r
520 write_setting_i(sesskey, "NoDBackspace", conf_get_int(conf, CONF_no_dbackspace));
\r
521 write_setting_i(sesskey, "NoRemoteCharset", conf_get_int(conf, CONF_no_remote_charset));
\r
522 write_setting_i(sesskey, "ApplicationCursorKeys", conf_get_int(conf, CONF_app_cursor));
\r
523 write_setting_i(sesskey, "ApplicationKeypad", conf_get_int(conf, CONF_app_keypad));
\r
524 write_setting_i(sesskey, "NetHackKeypad", conf_get_int(conf, CONF_nethack_keypad));
\r
525 write_setting_i(sesskey, "AltF4", conf_get_int(conf, CONF_alt_f4));
\r
526 write_setting_i(sesskey, "AltSpace", conf_get_int(conf, CONF_alt_space));
\r
527 write_setting_i(sesskey, "AltOnly", conf_get_int(conf, CONF_alt_only));
\r
528 write_setting_i(sesskey, "ComposeKey", conf_get_int(conf, CONF_compose_key));
\r
529 write_setting_i(sesskey, "CtrlAltKeys", conf_get_int(conf, CONF_ctrlaltkeys));
\r
530 write_setting_i(sesskey, "TelnetKey", conf_get_int(conf, CONF_telnet_keyboard));
\r
531 write_setting_i(sesskey, "TelnetRet", conf_get_int(conf, CONF_telnet_newline));
\r
532 write_setting_i(sesskey, "LocalEcho", conf_get_int(conf, CONF_localecho));
\r
533 write_setting_i(sesskey, "LocalEdit", conf_get_int(conf, CONF_localedit));
\r
534 write_setting_s(sesskey, "Answerback", conf_get_str(conf, CONF_answerback));
\r
535 write_setting_i(sesskey, "AlwaysOnTop", conf_get_int(conf, CONF_alwaysontop));
\r
536 write_setting_i(sesskey, "FullScreenOnAltEnter", conf_get_int(conf, CONF_fullscreenonaltenter));
\r
537 write_setting_i(sesskey, "HideMousePtr", conf_get_int(conf, CONF_hide_mouseptr));
\r
538 write_setting_i(sesskey, "SunkenEdge", conf_get_int(conf, CONF_sunken_edge));
\r
539 write_setting_i(sesskey, "WindowBorder", conf_get_int(conf, CONF_window_border));
\r
540 write_setting_i(sesskey, "CurType", conf_get_int(conf, CONF_cursor_type));
\r
541 write_setting_i(sesskey, "BlinkCur", conf_get_int(conf, CONF_blink_cur));
\r
542 write_setting_i(sesskey, "Beep", conf_get_int(conf, CONF_beep));
\r
543 write_setting_i(sesskey, "BeepInd", conf_get_int(conf, CONF_beep_ind));
\r
544 write_setting_filename(sesskey, "BellWaveFile", conf_get_filename(conf, CONF_bell_wavefile));
\r
545 write_setting_i(sesskey, "BellOverload", conf_get_int(conf, CONF_bellovl));
\r
546 write_setting_i(sesskey, "BellOverloadN", conf_get_int(conf, CONF_bellovl_n));
\r
547 write_setting_i(sesskey, "BellOverloadT", conf_get_int(conf, CONF_bellovl_t)
\r
548 #ifdef PUTTY_UNIX_H
\r
552 write_setting_i(sesskey, "BellOverloadS", conf_get_int(conf, CONF_bellovl_s)
\r
553 #ifdef PUTTY_UNIX_H
\r
557 write_setting_i(sesskey, "ScrollbackLines", conf_get_int(conf, CONF_savelines));
\r
558 write_setting_i(sesskey, "DECOriginMode", conf_get_int(conf, CONF_dec_om));
\r
559 write_setting_i(sesskey, "AutoWrapMode", conf_get_int(conf, CONF_wrap_mode));
\r
560 write_setting_i(sesskey, "LFImpliesCR", conf_get_int(conf, CONF_lfhascr));
\r
561 write_setting_i(sesskey, "CRImpliesLF", conf_get_int(conf, CONF_crhaslf));
\r
562 write_setting_i(sesskey, "DisableArabicShaping", conf_get_int(conf, CONF_arabicshaping));
\r
563 write_setting_i(sesskey, "DisableBidi", conf_get_int(conf, CONF_bidi));
\r
564 write_setting_i(sesskey, "WinNameAlways", conf_get_int(conf, CONF_win_name_always));
\r
565 write_setting_s(sesskey, "WinTitle", conf_get_str(conf, CONF_wintitle));
\r
566 write_setting_i(sesskey, "TermWidth", conf_get_int(conf, CONF_width));
\r
567 write_setting_i(sesskey, "TermHeight", conf_get_int(conf, CONF_height));
\r
568 write_setting_fontspec(sesskey, "Font", conf_get_fontspec(conf, CONF_font));
\r
569 write_setting_i(sesskey, "FontQuality", conf_get_int(conf, CONF_font_quality));
\r
570 write_setting_i(sesskey, "FontVTMode", conf_get_int(conf, CONF_vtmode));
\r
571 write_setting_i(sesskey, "UseSystemColours", conf_get_int(conf, CONF_system_colour));
\r
572 write_setting_i(sesskey, "TryPalette", conf_get_int(conf, CONF_try_palette));
\r
573 write_setting_i(sesskey, "ANSIColour", conf_get_int(conf, CONF_ansi_colour));
\r
574 write_setting_i(sesskey, "Xterm256Colour", conf_get_int(conf, CONF_xterm_256_colour));
\r
575 write_setting_i(sesskey, "BoldAsColour", conf_get_int(conf, CONF_bold_style)-1);
\r
577 for (i = 0; i < 22; i++) {
\r
578 char buf[20], buf2[30];
\r
579 sprintf(buf, "Colour%d", i);
\r
580 sprintf(buf2, "%d,%d,%d",
\r
581 conf_get_int_int(conf, CONF_colours, i*3+0),
\r
582 conf_get_int_int(conf, CONF_colours, i*3+1),
\r
583 conf_get_int_int(conf, CONF_colours, i*3+2));
\r
584 write_setting_s(sesskey, buf, buf2);
\r
586 write_setting_i(sesskey, "RawCNP", conf_get_int(conf, CONF_rawcnp));
\r
587 write_setting_i(sesskey, "PasteRTF", conf_get_int(conf, CONF_rtf_paste));
\r
588 write_setting_i(sesskey, "MouseIsXterm", conf_get_int(conf, CONF_mouse_is_xterm));
\r
589 write_setting_i(sesskey, "RectSelect", conf_get_int(conf, CONF_rect_select));
\r
590 write_setting_i(sesskey, "MouseOverride", conf_get_int(conf, CONF_mouse_override));
\r
591 for (i = 0; i < 256; i += 32) {
\r
592 char buf[20], buf2[256];
\r
594 sprintf(buf, "Wordness%d", i);
\r
596 for (j = i; j < i + 32; j++) {
\r
597 sprintf(buf2 + strlen(buf2), "%s%d",
\r
598 (*buf2 ? "," : ""),
\r
599 conf_get_int_int(conf, CONF_wordness, j));
\r
601 write_setting_s(sesskey, buf, buf2);
\r
603 write_setting_s(sesskey, "LineCodePage", conf_get_str(conf, CONF_line_codepage));
\r
604 write_setting_i(sesskey, "CJKAmbigWide", conf_get_int(conf, CONF_cjk_ambig_wide));
\r
605 write_setting_i(sesskey, "UTF8Override", conf_get_int(conf, CONF_utf8_override));
\r
606 write_setting_s(sesskey, "Printer", conf_get_str(conf, CONF_printer));
\r
607 write_setting_i(sesskey, "CapsLockCyr", conf_get_int(conf, CONF_xlat_capslockcyr));
\r
608 write_setting_i(sesskey, "ScrollBar", conf_get_int(conf, CONF_scrollbar));
\r
609 write_setting_i(sesskey, "ScrollBarFullScreen", conf_get_int(conf, CONF_scrollbar_in_fullscreen));
\r
610 write_setting_i(sesskey, "ScrollOnKey", conf_get_int(conf, CONF_scroll_on_key));
\r
611 write_setting_i(sesskey, "ScrollOnDisp", conf_get_int(conf, CONF_scroll_on_disp));
\r
612 write_setting_i(sesskey, "EraseToScrollback", conf_get_int(conf, CONF_erase_to_scrollback));
\r
613 write_setting_i(sesskey, "LockSize", conf_get_int(conf, CONF_resize_action));
\r
614 write_setting_i(sesskey, "BCE", conf_get_int(conf, CONF_bce));
\r
615 write_setting_i(sesskey, "BlinkText", conf_get_int(conf, CONF_blinktext));
\r
616 write_setting_i(sesskey, "X11Forward", conf_get_int(conf, CONF_x11_forward));
\r
617 write_setting_s(sesskey, "X11Display", conf_get_str(conf, CONF_x11_display));
\r
618 write_setting_i(sesskey, "X11AuthType", conf_get_int(conf, CONF_x11_auth));
\r
619 write_setting_filename(sesskey, "X11AuthFile", conf_get_filename(conf, CONF_xauthfile));
\r
620 write_setting_i(sesskey, "LocalPortAcceptAll", conf_get_int(conf, CONF_lport_acceptall));
\r
621 write_setting_i(sesskey, "RemotePortAcceptAll", conf_get_int(conf, CONF_rport_acceptall));
\r
622 wmap(sesskey, "PortForwardings", conf, CONF_portfwd, TRUE);
\r
623 write_setting_i(sesskey, "BugIgnore1", 2-conf_get_int(conf, CONF_sshbug_ignore1));
\r
624 write_setting_i(sesskey, "BugPlainPW1", 2-conf_get_int(conf, CONF_sshbug_plainpw1));
\r
625 write_setting_i(sesskey, "BugRSA1", 2-conf_get_int(conf, CONF_sshbug_rsa1));
\r
626 write_setting_i(sesskey, "BugIgnore2", 2-conf_get_int(conf, CONF_sshbug_ignore2));
\r
627 write_setting_i(sesskey, "BugHMAC2", 2-conf_get_int(conf, CONF_sshbug_hmac2));
\r
628 write_setting_i(sesskey, "BugDeriveKey2", 2-conf_get_int(conf, CONF_sshbug_derivekey2));
\r
629 write_setting_i(sesskey, "BugRSAPad2", 2-conf_get_int(conf, CONF_sshbug_rsapad2));
\r
630 write_setting_i(sesskey, "BugPKSessID2", 2-conf_get_int(conf, CONF_sshbug_pksessid2));
\r
631 write_setting_i(sesskey, "BugRekey2", 2-conf_get_int(conf, CONF_sshbug_rekey2));
\r
632 write_setting_i(sesskey, "BugMaxPkt2", 2-conf_get_int(conf, CONF_sshbug_maxpkt2));
\r
633 write_setting_i(sesskey, "BugWinadj", 2-conf_get_int(conf, CONF_sshbug_winadj));
\r
634 write_setting_i(sesskey, "BugChanReq", 2-conf_get_int(conf, CONF_sshbug_chanreq));
\r
635 write_setting_i(sesskey, "StampUtmp", conf_get_int(conf, CONF_stamp_utmp));
\r
636 write_setting_i(sesskey, "LoginShell", conf_get_int(conf, CONF_login_shell));
\r
637 write_setting_i(sesskey, "ScrollbarOnLeft", conf_get_int(conf, CONF_scrollbar_on_left));
\r
638 write_setting_fontspec(sesskey, "BoldFont", conf_get_fontspec(conf, CONF_boldfont));
\r
639 write_setting_fontspec(sesskey, "WideFont", conf_get_fontspec(conf, CONF_widefont));
\r
640 write_setting_fontspec(sesskey, "WideBoldFont", conf_get_fontspec(conf, CONF_wideboldfont));
\r
641 write_setting_i(sesskey, "ShadowBold", conf_get_int(conf, CONF_shadowbold));
\r
642 write_setting_i(sesskey, "ShadowBoldOffset", conf_get_int(conf, CONF_shadowboldoffset));
\r
643 write_setting_s(sesskey, "SerialLine", conf_get_str(conf, CONF_serline));
\r
644 write_setting_i(sesskey, "SerialSpeed", conf_get_int(conf, CONF_serspeed));
\r
645 write_setting_i(sesskey, "SerialDataBits", conf_get_int(conf, CONF_serdatabits));
\r
646 write_setting_i(sesskey, "SerialStopHalfbits", conf_get_int(conf, CONF_serstopbits));
\r
647 write_setting_i(sesskey, "SerialParity", conf_get_int(conf, CONF_serparity));
\r
648 write_setting_i(sesskey, "SerialFlowControl", conf_get_int(conf, CONF_serflow));
\r
649 write_setting_s(sesskey, "WindowClass", conf_get_str(conf, CONF_winclass));
\r
650 write_setting_i(sesskey, "ConnectionSharing", conf_get_int(conf, CONF_ssh_connection_sharing));
\r
651 write_setting_i(sesskey, "ConnectionSharingUpstream", conf_get_int(conf, CONF_ssh_connection_sharing_upstream));
\r
652 write_setting_i(sesskey, "ConnectionSharingDownstream", conf_get_int(conf, CONF_ssh_connection_sharing_downstream));
\r
653 wmap(sesskey, "SSHManualHostKeys", conf, CONF_ssh_manual_hostkeys, FALSE);
\r
656 void load_settings(char *section, Conf *conf)
\r
660 sesskey = open_settings_r(section);
\r
661 load_open_settings(sesskey, conf);
\r
662 close_settings_r(sesskey);
\r
664 if (conf_launchable(conf))
\r
665 add_session_to_jumplist(section);
\r
668 void load_open_settings(void *sesskey, Conf *conf)
\r
673 conf_set_int(conf, CONF_ssh_subsys, 0); /* FIXME: load this properly */
\r
674 conf_set_str(conf, CONF_remote_cmd, "");
\r
675 conf_set_str(conf, CONF_remote_cmd2, "");
\r
676 conf_set_str(conf, CONF_ssh_nc_host, "");
\r
678 gpps(sesskey, "HostName", "", conf, CONF_host);
\r
679 gppfile(sesskey, "LogFileName", conf, CONF_logfilename);
\r
680 gppi(sesskey, "LogType", 0, conf, CONF_logtype);
\r
681 gppi(sesskey, "LogFileClash", LGXF_ASK, conf, CONF_logxfovr);
\r
682 gppi(sesskey, "LogFlush", 1, conf, CONF_logflush);
\r
683 gppi(sesskey, "SSHLogOmitPasswords", 1, conf, CONF_logomitpass);
\r
684 gppi(sesskey, "SSHLogOmitData", 0, conf, CONF_logomitdata);
\r
686 prot = gpps_raw(sesskey, "Protocol", "default");
\r
687 conf_set_int(conf, CONF_protocol, default_protocol);
\r
688 conf_set_int(conf, CONF_port, default_port);
\r
690 const Backend *b = backend_from_name(prot);
\r
692 conf_set_int(conf, CONF_protocol, b->protocol);
\r
693 gppi(sesskey, "PortNumber", default_port, conf, CONF_port);
\r
698 /* Address family selection */
\r
699 gppi(sesskey, "AddressFamily", ADDRTYPE_UNSPEC, conf, CONF_addressfamily);
\r
701 /* The CloseOnExit numbers are arranged in a different order from
\r
702 * the standard FORCE_ON / FORCE_OFF / AUTO. */
\r
703 i = gppi_raw(sesskey, "CloseOnExit", 1); conf_set_int(conf, CONF_close_on_exit, (i+1)%3);
\r
704 gppi(sesskey, "WarnOnClose", 1, conf, CONF_warn_on_close);
\r
706 /* This is two values for backward compatibility with 0.50/0.51 */
\r
707 int pingmin, pingsec;
\r
708 pingmin = gppi_raw(sesskey, "PingInterval", 0);
\r
709 pingsec = gppi_raw(sesskey, "PingIntervalSecs", 0);
\r
710 conf_set_int(conf, CONF_ping_interval, pingmin * 60 + pingsec);
\r
712 gppi(sesskey, "TCPNoDelay", 1, conf, CONF_tcp_nodelay);
\r
713 gppi(sesskey, "TCPKeepalives", 0, conf, CONF_tcp_keepalives);
\r
714 gpps(sesskey, "TerminalType", "xterm", conf, CONF_termtype);
\r
715 gpps(sesskey, "TerminalSpeed", "38400,38400", conf, CONF_termspeed);
\r
716 if (!gppmap(sesskey, "TerminalModes", conf, CONF_ttymodes)) {
\r
717 /* This hardcodes a big set of defaults in any new saved
\r
718 * sessions. Let's hope we don't change our mind. */
\r
719 for (i = 0; ttymodes[i]; i++)
\r
720 conf_set_str_str(conf, CONF_ttymodes, ttymodes[i], "A");
\r
723 /* proxy settings */
\r
724 gpps(sesskey, "ProxyExcludeList", "", conf, CONF_proxy_exclude_list);
\r
725 i = gppi_raw(sesskey, "ProxyDNS", 1); conf_set_int(conf, CONF_proxy_dns, (i+1)%3);
\r
726 gppi(sesskey, "ProxyLocalhost", 0, conf, CONF_even_proxy_localhost);
\r
727 gppi(sesskey, "ProxyMethod", -1, conf, CONF_proxy_type);
\r
728 if (conf_get_int(conf, CONF_proxy_type) == -1) {
\r
730 i = gppi_raw(sesskey, "ProxyType", 0);
\r
732 conf_set_int(conf, CONF_proxy_type, PROXY_NONE);
\r
734 conf_set_int(conf, CONF_proxy_type, PROXY_HTTP);
\r
736 conf_set_int(conf, CONF_proxy_type, PROXY_TELNET);
\r
738 conf_set_int(conf, CONF_proxy_type, PROXY_CMD);
\r
740 i = gppi_raw(sesskey, "ProxySOCKSVersion", 5);
\r
742 conf_set_int(conf, CONF_proxy_type, PROXY_SOCKS5);
\r
744 conf_set_int(conf, CONF_proxy_type, PROXY_SOCKS4);
\r
747 gpps(sesskey, "ProxyHost", "proxy", conf, CONF_proxy_host);
\r
748 gppi(sesskey, "ProxyPort", 80, conf, CONF_proxy_port);
\r
749 gpps(sesskey, "ProxyUsername", "", conf, CONF_proxy_username);
\r
750 gpps(sesskey, "ProxyPassword", "", conf, CONF_proxy_password);
\r
751 gpps(sesskey, "ProxyTelnetCommand", "connect %host %port\\n",
\r
752 conf, CONF_proxy_telnet_command);
\r
753 gppmap(sesskey, "Environment", conf, CONF_environmt);
\r
754 gpps(sesskey, "UserName", "", conf, CONF_username);
\r
755 gppi(sesskey, "UserNameFromEnvironment", 0, conf, CONF_username_from_env);
\r
756 gpps(sesskey, "LocalUserName", "", conf, CONF_localusername);
\r
757 gppi(sesskey, "NoPTY", 0, conf, CONF_nopty);
\r
758 gppi(sesskey, "Compression", 0, conf, CONF_compression);
\r
759 gppi(sesskey, "TryAgent", 1, conf, CONF_tryagent);
\r
760 gppi(sesskey, "AgentFwd", 0, conf, CONF_agentfwd);
\r
761 gppi(sesskey, "ChangeUsername", 0, conf, CONF_change_username);
\r
762 gppi(sesskey, "GssapiFwd", 0, conf, CONF_gssapifwd);
\r
763 gprefs(sesskey, "Cipher", "\0",
\r
764 ciphernames, CIPHER_MAX, conf, CONF_ssh_cipherlist);
\r
766 /* Backward-compatibility: we used to have an option to
\r
767 * disable gex under the "bugs" panel after one report of
\r
768 * a server which offered it then choked, but we never got
\r
769 * a server version string or any other reports. */
\r
770 char *default_kexes;
\r
771 i = 2 - gppi_raw(sesskey, "BugDHGEx2", 0);
\r
773 default_kexes = "dh-group14-sha1,dh-group1-sha1,rsa,WARN,dh-gex-sha1";
\r
775 default_kexes = "dh-gex-sha1,dh-group14-sha1,dh-group1-sha1,rsa,WARN";
\r
776 gprefs(sesskey, "KEX", default_kexes,
\r
777 kexnames, KEX_MAX, conf, CONF_ssh_kexlist);
\r
779 gppi(sesskey, "RekeyTime", 60, conf, CONF_ssh_rekey_time);
\r
780 gpps(sesskey, "RekeyBytes", "1G", conf, CONF_ssh_rekey_data);
\r
781 /* SSH-2 only by default */
\r
782 gppi(sesskey, "SshProt", 3, conf, CONF_sshprot);
\r
783 gpps(sesskey, "LogHost", "", conf, CONF_loghost);
\r
784 gppi(sesskey, "SSH2DES", 0, conf, CONF_ssh2_des_cbc);
\r
785 gppi(sesskey, "SshNoAuth", 0, conf, CONF_ssh_no_userauth);
\r
786 gppi(sesskey, "SshBanner", 1, conf, CONF_ssh_show_banner);
\r
787 gppi(sesskey, "AuthTIS", 0, conf, CONF_try_tis_auth);
\r
788 gppi(sesskey, "AuthKI", 1, conf, CONF_try_ki_auth);
\r
789 gppi(sesskey, "AuthGSSAPI", 1, conf, CONF_try_gssapi_auth);
\r
791 gprefs(sesskey, "GSSLibs", "\0",
\r
792 gsslibkeywords, ngsslibs, conf, CONF_ssh_gsslist);
\r
793 gppfile(sesskey, "GSSCustom", conf, CONF_ssh_gss_custom);
\r
795 gppi(sesskey, "SshNoShell", 0, conf, CONF_ssh_no_shell);
\r
796 gppfile(sesskey, "PublicKeyFile", conf, CONF_keyfile);
\r
797 gpps(sesskey, "RemoteCommand", "", conf, CONF_remote_cmd);
\r
798 gppi(sesskey, "RFCEnviron", 0, conf, CONF_rfc_environ);
\r
799 gppi(sesskey, "PassiveTelnet", 0, conf, CONF_passive_telnet);
\r
800 gppi(sesskey, "BackspaceIsDelete", 1, conf, CONF_bksp_is_delete);
\r
801 gppi(sesskey, "RXVTHomeEnd", 0, conf, CONF_rxvt_homeend);
\r
802 gppi(sesskey, "LinuxFunctionKeys", 0, conf, CONF_funky_type);
\r
803 gppi(sesskey, "NoApplicationKeys", 0, conf, CONF_no_applic_k);
\r
804 gppi(sesskey, "NoApplicationCursors", 0, conf, CONF_no_applic_c);
\r
805 gppi(sesskey, "NoMouseReporting", 0, conf, CONF_no_mouse_rep);
\r
806 gppi(sesskey, "NoRemoteResize", 0, conf, CONF_no_remote_resize);
\r
807 gppi(sesskey, "NoAltScreen", 0, conf, CONF_no_alt_screen);
\r
808 gppi(sesskey, "NoRemoteWinTitle", 0, conf, CONF_no_remote_wintitle);
\r
810 /* Backward compatibility */
\r
811 int no_remote_qtitle = gppi_raw(sesskey, "NoRemoteQTitle", 1);
\r
812 /* We deliberately interpret the old setting of "no response" as
\r
813 * "empty string". This changes the behaviour, but hopefully for
\r
814 * the better; the user can always recover the old behaviour. */
\r
815 gppi(sesskey, "RemoteQTitleAction",
\r
816 no_remote_qtitle ? TITLE_EMPTY : TITLE_REAL,
\r
817 conf, CONF_remote_qtitle_action);
\r
819 gppi(sesskey, "NoDBackspace", 0, conf, CONF_no_dbackspace);
\r
820 gppi(sesskey, "NoRemoteCharset", 0, conf, CONF_no_remote_charset);
\r
821 gppi(sesskey, "ApplicationCursorKeys", 0, conf, CONF_app_cursor);
\r
822 gppi(sesskey, "ApplicationKeypad", 0, conf, CONF_app_keypad);
\r
823 gppi(sesskey, "NetHackKeypad", 0, conf, CONF_nethack_keypad);
\r
824 gppi(sesskey, "AltF4", 1, conf, CONF_alt_f4);
\r
825 gppi(sesskey, "AltSpace", 0, conf, CONF_alt_space);
\r
826 gppi(sesskey, "AltOnly", 0, conf, CONF_alt_only);
\r
827 gppi(sesskey, "ComposeKey", 0, conf, CONF_compose_key);
\r
828 gppi(sesskey, "CtrlAltKeys", 1, conf, CONF_ctrlaltkeys);
\r
829 gppi(sesskey, "TelnetKey", 0, conf, CONF_telnet_keyboard);
\r
830 gppi(sesskey, "TelnetRet", 1, conf, CONF_telnet_newline);
\r
831 gppi(sesskey, "LocalEcho", AUTO, conf, CONF_localecho);
\r
832 gppi(sesskey, "LocalEdit", AUTO, conf, CONF_localedit);
\r
833 gpps(sesskey, "Answerback", "PuTTY", conf, CONF_answerback);
\r
834 gppi(sesskey, "AlwaysOnTop", 0, conf, CONF_alwaysontop);
\r
835 gppi(sesskey, "FullScreenOnAltEnter", 0, conf, CONF_fullscreenonaltenter);
\r
836 gppi(sesskey, "HideMousePtr", 0, conf, CONF_hide_mouseptr);
\r
837 gppi(sesskey, "SunkenEdge", 0, conf, CONF_sunken_edge);
\r
838 gppi(sesskey, "WindowBorder", 1, conf, CONF_window_border);
\r
839 gppi(sesskey, "CurType", 0, conf, CONF_cursor_type);
\r
840 gppi(sesskey, "BlinkCur", 0, conf, CONF_blink_cur);
\r
841 /* pedantic compiler tells me I can't use conf, CONF_beep as an int * :-) */
\r
842 gppi(sesskey, "Beep", 1, conf, CONF_beep);
\r
843 gppi(sesskey, "BeepInd", 0, conf, CONF_beep_ind);
\r
844 gppfile(sesskey, "BellWaveFile", conf, CONF_bell_wavefile);
\r
845 gppi(sesskey, "BellOverload", 1, conf, CONF_bellovl);
\r
846 gppi(sesskey, "BellOverloadN", 5, conf, CONF_bellovl_n);
\r
847 i = gppi_raw(sesskey, "BellOverloadT", 2*TICKSPERSEC
\r
848 #ifdef PUTTY_UNIX_H
\r
852 conf_set_int(conf, CONF_bellovl_t, i
\r
853 #ifdef PUTTY_UNIX_H
\r
857 i = gppi_raw(sesskey, "BellOverloadS", 5*TICKSPERSEC
\r
858 #ifdef PUTTY_UNIX_H
\r
862 conf_set_int(conf, CONF_bellovl_s, i
\r
863 #ifdef PUTTY_UNIX_H
\r
867 gppi(sesskey, "ScrollbackLines", 2000, conf, CONF_savelines);
\r
868 gppi(sesskey, "DECOriginMode", 0, conf, CONF_dec_om);
\r
869 gppi(sesskey, "AutoWrapMode", 1, conf, CONF_wrap_mode);
\r
870 gppi(sesskey, "LFImpliesCR", 0, conf, CONF_lfhascr);
\r
871 gppi(sesskey, "CRImpliesLF", 0, conf, CONF_crhaslf);
\r
872 gppi(sesskey, "DisableArabicShaping", 0, conf, CONF_arabicshaping);
\r
873 gppi(sesskey, "DisableBidi", 0, conf, CONF_bidi);
\r
874 gppi(sesskey, "WinNameAlways", 1, conf, CONF_win_name_always);
\r
875 gpps(sesskey, "WinTitle", "", conf, CONF_wintitle);
\r
876 gppi(sesskey, "TermWidth", 80, conf, CONF_width);
\r
877 gppi(sesskey, "TermHeight", 24, conf, CONF_height);
\r
878 gppfont(sesskey, "Font", conf, CONF_font);
\r
879 gppi(sesskey, "FontQuality", FQ_DEFAULT, conf, CONF_font_quality);
\r
880 gppi(sesskey, "FontVTMode", VT_UNICODE, conf, CONF_vtmode);
\r
881 gppi(sesskey, "UseSystemColours", 0, conf, CONF_system_colour);
\r
882 gppi(sesskey, "TryPalette", 0, conf, CONF_try_palette);
\r
883 gppi(sesskey, "ANSIColour", 1, conf, CONF_ansi_colour);
\r
884 gppi(sesskey, "Xterm256Colour", 1, conf, CONF_xterm_256_colour);
\r
885 i = gppi_raw(sesskey, "BoldAsColour", 1); conf_set_int(conf, CONF_bold_style, i+1);
\r
887 for (i = 0; i < 22; i++) {
\r
888 static const char *const defaults[] = {
\r
889 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
\r
890 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
\r
891 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
\r
892 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
\r
893 "85,255,255", "187,187,187", "255,255,255"
\r
895 char buf[20], *buf2;
\r
897 sprintf(buf, "Colour%d", i);
\r
898 buf2 = gpps_raw(sesskey, buf, defaults[i]);
\r
899 if (sscanf(buf2, "%d,%d,%d", &c0, &c1, &c2) == 3) {
\r
900 conf_set_int_int(conf, CONF_colours, i*3+0, c0);
\r
901 conf_set_int_int(conf, CONF_colours, i*3+1, c1);
\r
902 conf_set_int_int(conf, CONF_colours, i*3+2, c2);
\r
906 gppi(sesskey, "RawCNP", 0, conf, CONF_rawcnp);
\r
907 gppi(sesskey, "PasteRTF", 0, conf, CONF_rtf_paste);
\r
908 gppi(sesskey, "MouseIsXterm", 0, conf, CONF_mouse_is_xterm);
\r
909 gppi(sesskey, "RectSelect", 0, conf, CONF_rect_select);
\r
910 gppi(sesskey, "MouseOverride", 1, conf, CONF_mouse_override);
\r
911 for (i = 0; i < 256; i += 32) {
\r
912 static const char *const defaults[] = {
\r
913 "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",
\r
914 "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",
\r
915 "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",
\r
916 "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",
\r
917 "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",
\r
918 "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",
\r
919 "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",
\r
920 "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"
\r
922 char buf[20], *buf2, *p;
\r
924 sprintf(buf, "Wordness%d", i);
\r
925 buf2 = gpps_raw(sesskey, buf, defaults[i / 32]);
\r
927 for (j = i; j < i + 32; j++) {
\r
929 while (*p && *p != ',')
\r
933 conf_set_int_int(conf, CONF_wordness, j, atoi(q));
\r
938 * The empty default for LineCodePage will be converted later
\r
939 * into a plausible default for the locale.
\r
941 gpps(sesskey, "LineCodePage", "", conf, CONF_line_codepage);
\r
942 gppi(sesskey, "CJKAmbigWide", 0, conf, CONF_cjk_ambig_wide);
\r
943 gppi(sesskey, "UTF8Override", 1, conf, CONF_utf8_override);
\r
944 gpps(sesskey, "Printer", "", conf, CONF_printer);
\r
945 gppi(sesskey, "CapsLockCyr", 0, conf, CONF_xlat_capslockcyr);
\r
946 gppi(sesskey, "ScrollBar", 1, conf, CONF_scrollbar);
\r
947 gppi(sesskey, "ScrollBarFullScreen", 0, conf, CONF_scrollbar_in_fullscreen);
\r
948 gppi(sesskey, "ScrollOnKey", 0, conf, CONF_scroll_on_key);
\r
949 gppi(sesskey, "ScrollOnDisp", 1, conf, CONF_scroll_on_disp);
\r
950 gppi(sesskey, "EraseToScrollback", 1, conf, CONF_erase_to_scrollback);
\r
951 gppi(sesskey, "LockSize", 0, conf, CONF_resize_action);
\r
952 gppi(sesskey, "BCE", 1, conf, CONF_bce);
\r
953 gppi(sesskey, "BlinkText", 0, conf, CONF_blinktext);
\r
954 gppi(sesskey, "X11Forward", 0, conf, CONF_x11_forward);
\r
955 gpps(sesskey, "X11Display", "", conf, CONF_x11_display);
\r
956 gppi(sesskey, "X11AuthType", X11_MIT, conf, CONF_x11_auth);
\r
957 gppfile(sesskey, "X11AuthFile", conf, CONF_xauthfile);
\r
959 gppi(sesskey, "LocalPortAcceptAll", 0, conf, CONF_lport_acceptall);
\r
960 gppi(sesskey, "RemotePortAcceptAll", 0, conf, CONF_rport_acceptall);
\r
961 gppmap(sesskey, "PortForwardings", conf, CONF_portfwd);
\r
962 i = gppi_raw(sesskey, "BugIgnore1", 0); conf_set_int(conf, CONF_sshbug_ignore1, 2-i);
\r
963 i = gppi_raw(sesskey, "BugPlainPW1", 0); conf_set_int(conf, CONF_sshbug_plainpw1, 2-i);
\r
964 i = gppi_raw(sesskey, "BugRSA1", 0); conf_set_int(conf, CONF_sshbug_rsa1, 2-i);
\r
965 i = gppi_raw(sesskey, "BugIgnore2", 0); conf_set_int(conf, CONF_sshbug_ignore2, 2-i);
\r
968 i = gppi_raw(sesskey, "BugHMAC2", 0); conf_set_int(conf, CONF_sshbug_hmac2, 2-i);
\r
970 i = gppi_raw(sesskey, "BuggyMAC", 0);
\r
972 conf_set_int(conf, CONF_sshbug_hmac2, FORCE_ON);
\r
975 i = gppi_raw(sesskey, "BugDeriveKey2", 0); conf_set_int(conf, CONF_sshbug_derivekey2, 2-i);
\r
976 i = gppi_raw(sesskey, "BugRSAPad2", 0); conf_set_int(conf, CONF_sshbug_rsapad2, 2-i);
\r
977 i = gppi_raw(sesskey, "BugPKSessID2", 0); conf_set_int(conf, CONF_sshbug_pksessid2, 2-i);
\r
978 i = gppi_raw(sesskey, "BugRekey2", 0); conf_set_int(conf, CONF_sshbug_rekey2, 2-i);
\r
979 i = gppi_raw(sesskey, "BugMaxPkt2", 0); conf_set_int(conf, CONF_sshbug_maxpkt2, 2-i);
\r
980 i = gppi_raw(sesskey, "BugWinadj", 0); conf_set_int(conf, CONF_sshbug_winadj, 2-i);
\r
981 i = gppi_raw(sesskey, "BugChanReq", 0); conf_set_int(conf, CONF_sshbug_chanreq, 2-i);
\r
982 conf_set_int(conf, CONF_ssh_simple, FALSE);
\r
983 gppi(sesskey, "StampUtmp", 1, conf, CONF_stamp_utmp);
\r
984 gppi(sesskey, "LoginShell", 1, conf, CONF_login_shell);
\r
985 gppi(sesskey, "ScrollbarOnLeft", 0, conf, CONF_scrollbar_on_left);
\r
986 gppi(sesskey, "ShadowBold", 0, conf, CONF_shadowbold);
\r
987 gppfont(sesskey, "BoldFont", conf, CONF_boldfont);
\r
988 gppfont(sesskey, "WideFont", conf, CONF_widefont);
\r
989 gppfont(sesskey, "WideBoldFont", conf, CONF_wideboldfont);
\r
990 gppi(sesskey, "ShadowBoldOffset", 1, conf, CONF_shadowboldoffset);
\r
991 gpps(sesskey, "SerialLine", "", conf, CONF_serline);
\r
992 gppi(sesskey, "SerialSpeed", 9600, conf, CONF_serspeed);
\r
993 gppi(sesskey, "SerialDataBits", 8, conf, CONF_serdatabits);
\r
994 gppi(sesskey, "SerialStopHalfbits", 2, conf, CONF_serstopbits);
\r
995 gppi(sesskey, "SerialParity", SER_PAR_NONE, conf, CONF_serparity);
\r
996 gppi(sesskey, "SerialFlowControl", SER_FLOW_XONXOFF, conf, CONF_serflow);
\r
997 gpps(sesskey, "WindowClass", "", conf, CONF_winclass);
\r
998 gppi(sesskey, "ConnectionSharing", 0, conf, CONF_ssh_connection_sharing);
\r
999 gppi(sesskey, "ConnectionSharingUpstream", 1, conf, CONF_ssh_connection_sharing_upstream);
\r
1000 gppi(sesskey, "ConnectionSharingDownstream", 1, conf, CONF_ssh_connection_sharing_downstream);
\r
1001 gppmap(sesskey, "SSHManualHostKeys", conf, CONF_ssh_manual_hostkeys);
\r
1004 void do_defaults(char *session, Conf *conf)
\r
1006 load_settings(session, conf);
\r
1009 static int sessioncmp(const void *av, const void *bv)
\r
1011 const char *a = *(const char *const *) av;
\r
1012 const char *b = *(const char *const *) bv;
\r
1015 * Alphabetical order, except that "Default Settings" is a
\r
1016 * special case and comes first.
\r
1018 if (!strcmp(a, "Default Settings"))
\r
1019 return -1; /* a comes first */
\r
1020 if (!strcmp(b, "Default Settings"))
\r
1021 return +1; /* b comes first */
\r
1023 * FIXME: perhaps we should ignore the first & in determining
\r
1026 return strcmp(a, b); /* otherwise, compare normally */
\r
1029 void get_sesslist(struct sesslist *list, int allocate)
\r
1031 char otherbuf[2048];
\r
1032 int buflen, bufsize, i;
\r
1038 buflen = bufsize = 0;
\r
1039 list->buffer = NULL;
\r
1040 if ((handle = enum_settings_start()) != NULL) {
\r
1042 ret = enum_settings_next(handle, otherbuf, sizeof(otherbuf));
\r
1044 int len = strlen(otherbuf) + 1;
\r
1045 if (bufsize < buflen + len) {
\r
1046 bufsize = buflen + len + 2048;
\r
1047 list->buffer = sresize(list->buffer, bufsize, char);
\r
1049 strcpy(list->buffer + buflen, otherbuf);
\r
1050 buflen += strlen(list->buffer + buflen) + 1;
\r
1053 enum_settings_finish(handle);
\r
1055 list->buffer = sresize(list->buffer, buflen + 1, char);
\r
1056 list->buffer[buflen] = '\0';
\r
1059 * Now set up the list of sessions. Note that "Default
\r
1060 * Settings" must always be claimed to exist, even if it
\r
1065 list->nsessions = 1; /* "Default Settings" counts as one */
\r
1067 if (strcmp(p, "Default Settings"))
\r
1068 list->nsessions++;
\r
1074 list->sessions = snewn(list->nsessions + 1, char *);
\r
1075 list->sessions[0] = "Default Settings";
\r
1079 if (strcmp(p, "Default Settings"))
\r
1080 list->sessions[i++] = p;
\r
1086 qsort(list->sessions, i, sizeof(char *), sessioncmp);
\r
1088 sfree(list->buffer);
\r
1089 sfree(list->sessions);
\r
1090 list->buffer = NULL;
\r
1091 list->sessions = NULL;
\r