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 * `def' is in the storage format.
\r
143 static int gppmap(void *handle, char *name, Conf *conf, int primary)
\r
145 char *buf, *p, *q, *key, *val;
\r
148 * Start by clearing any existing subkeys of this key from conf.
\r
150 while ((key = conf_get_str_nthstrkey(conf, primary, 0)) != NULL)
\r
151 conf_del_str_str(conf, primary, key);
\r
154 * Now read a serialised list from the settings and unmarshal it
\r
155 * into its components.
\r
157 buf = gpps_raw(handle, name, NULL);
\r
165 while (*p && *p != ',') {
\r
181 if (primary == CONF_portfwd && buf[0] == 'D') {
\r
183 * Backwards-compatibility hack: dynamic forwardings are
\r
184 * indexed in the data store as a third type letter in the
\r
185 * key, 'D' alongside 'L' and 'R' - but really, they
\r
186 * should be filed under 'L' with a special _value_,
\r
187 * because local and dynamic forwardings both involve
\r
188 * _listening_ on a local port, and are hence mutually
\r
189 * exclusive on the same port number. So here we translate
\r
190 * the legacy storage format into the sensible internal
\r
193 char *newkey = dupcat("L", buf+1, NULL);
\r
194 conf_set_str_str(conf, primary, newkey, "D");
\r
197 conf_set_str_str(conf, primary, buf, val);
\r
206 * Write a set of name/value pairs in the above format.
\r
208 static void wmap(void *handle, char const *outkey, Conf *conf, int primary)
\r
210 char *buf, *p, *q, *key, *realkey, *val;
\r
213 len = 1; /* allow for NUL */
\r
215 for (val = conf_get_str_strs(conf, primary, NULL, &key);
\r
217 val = conf_get_str_strs(conf, primary, key, &key))
\r
218 len += 2 + 2 * (strlen(key) + strlen(val)); /* allow for escaping */
\r
220 buf = snewn(len, char);
\r
223 for (val = conf_get_str_strs(conf, primary, NULL, &key);
\r
225 val = conf_get_str_strs(conf, primary, key, &key)) {
\r
227 if (primary == CONF_portfwd && !strcmp(val, "D")) {
\r
229 * Backwards-compatibility hack, as above: translate from
\r
230 * the sensible internal representation of dynamic
\r
231 * forwardings (key "L<port>", value "D") to the
\r
232 * conceptually incoherent legacy storage format (key
\r
233 * "D<port>", value empty).
\r
235 realkey = key; /* restore it at end of loop */
\r
237 key = dupcat("D", key+1, NULL);
\r
244 for (q = key; *q; q++) {
\r
245 if (*q == '=' || *q == ',' || *q == '\\')
\r
250 for (q = val; *q; q++) {
\r
251 if (*q == '=' || *q == ',' || *q == '\\')
\r
262 write_setting_s(handle, outkey, buf);
\r
266 static int key2val(const struct keyvalwhere *mapping,
\r
267 int nmaps, char *key)
\r
270 for (i = 0; i < nmaps; i++)
\r
271 if (!strcmp(mapping[i].s, key)) return mapping[i].v;
\r
275 static const char *val2key(const struct keyvalwhere *mapping,
\r
276 int nmaps, int val)
\r
279 for (i = 0; i < nmaps; i++)
\r
280 if (mapping[i].v == val) return mapping[i].s;
\r
285 * Helper function to parse a comma-separated list of strings into
\r
286 * a preference list array of values. Any missing values are added
\r
287 * to the end and duplicates are weeded.
\r
288 * XXX: assumes vals in 'mapping' are small +ve integers
\r
290 static void gprefs(void *sesskey, char *name, char *def,
\r
291 const struct keyvalwhere *mapping, int nvals,
\r
292 Conf *conf, int primary)
\r
296 int i, j, n, v, pos;
\r
297 unsigned long seen = 0; /* bitmap for weeding dups etc */
\r
300 * Fetch the string which we'll parse as a comma-separated list.
\r
302 commalist = gpps_raw(sesskey, name, def);
\r
305 * Go through that list and convert it into values.
\r
310 while (*p && *p == ',') p++;
\r
312 break; /* no more words */
\r
315 while (*p && *p != ',') p++;
\r
316 if (*p) *p++ = '\0';
\r
318 v = key2val(mapping, nvals, q);
\r
319 if (v != -1 && !(seen & (1 << v))) {
\r
321 conf_set_int_int(conf, primary, n, v);
\r
329 * Now go through 'mapping' and add values that weren't mentioned
\r
330 * in the list we fetched. We may have to loop over it multiple
\r
331 * times so that we add values before other values whose default
\r
332 * positions depend on them.
\r
334 while (n < nvals) {
\r
335 for (i = 0; i < nvals; i++) {
\r
336 assert(mapping[i].v < 32);
\r
338 if (!(seen & (1 << mapping[i].v))) {
\r
340 * This element needs adding. But can we add it yet?
\r
342 if (mapping[i].vrel != -1 && !(seen & (1 << mapping[i].vrel)))
\r
343 continue; /* nope */
\r
346 * OK, we can work out where to add this element, so
\r
349 if (mapping[i].vrel == -1) {
\r
350 pos = (mapping[i].where < 0 ? n : 0);
\r
352 for (j = 0; j < n; j++)
\r
353 if (conf_get_int_int(conf, primary, j) ==
\r
356 assert(j < n); /* implied by (seen & (1<<vrel)) */
\r
357 pos = (mapping[i].where < 0 ? j : j+1);
\r
363 for (j = n-1; j >= pos; j--)
\r
364 conf_set_int_int(conf, primary, j+1,
\r
365 conf_get_int_int(conf, primary, j));
\r
366 conf_set_int_int(conf, primary, pos, mapping[i].v);
\r
374 * Write out a preference list.
\r
376 static void wprefs(void *sesskey, char *name,
\r
377 const struct keyvalwhere *mapping, int nvals,
\r
378 Conf *conf, int primary)
\r
383 for (maxlen = i = 0; i < nvals; i++) {
\r
384 const char *s = val2key(mapping, nvals,
\r
385 conf_get_int_int(conf, primary, i));
\r
387 maxlen += (maxlen > 0 ? 1 : 0) + strlen(s);
\r
391 buf = snewn(maxlen + 1, char);
\r
394 for (i = 0; i < nvals; i++) {
\r
395 const char *s = val2key(mapping, nvals,
\r
396 conf_get_int_int(conf, primary, i));
\r
398 p += sprintf(p, "%s%s", (p > buf ? "," : ""), s);
\r
402 assert(p - buf == maxlen);
\r
405 write_setting_s(sesskey, name, buf);
\r
410 char *save_settings(char *section, Conf *conf)
\r
415 sesskey = open_settings_w(section, &errmsg);
\r
418 save_open_settings(sesskey, conf);
\r
419 close_settings_w(sesskey);
\r
423 void save_open_settings(void *sesskey, Conf *conf)
\r
428 write_setting_i(sesskey, "Present", 1);
\r
429 write_setting_s(sesskey, "HostName", conf_get_str(conf, CONF_host));
\r
430 write_setting_filename(sesskey, "LogFileName", conf_get_filename(conf, CONF_logfilename));
\r
431 write_setting_i(sesskey, "LogType", conf_get_int(conf, CONF_logtype));
\r
432 write_setting_i(sesskey, "LogFileClash", conf_get_int(conf, CONF_logxfovr));
\r
433 write_setting_i(sesskey, "LogFlush", conf_get_int(conf, CONF_logflush));
\r
434 write_setting_i(sesskey, "SSHLogOmitPasswords", conf_get_int(conf, CONF_logomitpass));
\r
435 write_setting_i(sesskey, "SSHLogOmitData", conf_get_int(conf, CONF_logomitdata));
\r
438 const Backend *b = backend_from_proto(conf_get_int(conf, CONF_protocol));
\r
442 write_setting_s(sesskey, "Protocol", p);
\r
443 write_setting_i(sesskey, "PortNumber", conf_get_int(conf, CONF_port));
\r
444 /* The CloseOnExit numbers are arranged in a different order from
\r
445 * the standard FORCE_ON / FORCE_OFF / AUTO. */
\r
446 write_setting_i(sesskey, "CloseOnExit", (conf_get_int(conf, CONF_close_on_exit)+2)%3);
\r
447 write_setting_i(sesskey, "WarnOnClose", !!conf_get_int(conf, CONF_warn_on_close));
\r
448 write_setting_i(sesskey, "PingInterval", conf_get_int(conf, CONF_ping_interval) / 60); /* minutes */
\r
449 write_setting_i(sesskey, "PingIntervalSecs", conf_get_int(conf, CONF_ping_interval) % 60); /* seconds */
\r
450 write_setting_i(sesskey, "TCPNoDelay", conf_get_int(conf, CONF_tcp_nodelay));
\r
451 write_setting_i(sesskey, "TCPKeepalives", conf_get_int(conf, CONF_tcp_keepalives));
\r
452 write_setting_s(sesskey, "TerminalType", conf_get_str(conf, CONF_termtype));
\r
453 write_setting_s(sesskey, "TerminalSpeed", conf_get_str(conf, CONF_termspeed));
\r
454 wmap(sesskey, "TerminalModes", conf, CONF_ttymodes);
\r
456 /* Address family selection */
\r
457 write_setting_i(sesskey, "AddressFamily", conf_get_int(conf, CONF_addressfamily));
\r
459 /* proxy settings */
\r
460 write_setting_s(sesskey, "ProxyExcludeList", conf_get_str(conf, CONF_proxy_exclude_list));
\r
461 write_setting_i(sesskey, "ProxyDNS", (conf_get_int(conf, CONF_proxy_dns)+2)%3);
\r
462 write_setting_i(sesskey, "ProxyLocalhost", conf_get_int(conf, CONF_even_proxy_localhost));
\r
463 write_setting_i(sesskey, "ProxyMethod", conf_get_int(conf, CONF_proxy_type));
\r
464 write_setting_s(sesskey, "ProxyHost", conf_get_str(conf, CONF_proxy_host));
\r
465 write_setting_i(sesskey, "ProxyPort", conf_get_int(conf, CONF_proxy_port));
\r
466 write_setting_s(sesskey, "ProxyUsername", conf_get_str(conf, CONF_proxy_username));
\r
467 write_setting_s(sesskey, "ProxyPassword", conf_get_str(conf, CONF_proxy_password));
\r
468 write_setting_s(sesskey, "ProxyTelnetCommand", conf_get_str(conf, CONF_proxy_telnet_command));
\r
469 wmap(sesskey, "Environment", conf, CONF_environmt);
\r
470 write_setting_s(sesskey, "UserName", conf_get_str(conf, CONF_username));
\r
471 write_setting_i(sesskey, "UserNameFromEnvironment", conf_get_int(conf, CONF_username_from_env));
\r
472 write_setting_s(sesskey, "LocalUserName", conf_get_str(conf, CONF_localusername));
\r
473 write_setting_i(sesskey, "NoPTY", conf_get_int(conf, CONF_nopty));
\r
474 write_setting_i(sesskey, "Compression", conf_get_int(conf, CONF_compression));
\r
475 write_setting_i(sesskey, "TryAgent", conf_get_int(conf, CONF_tryagent));
\r
476 write_setting_i(sesskey, "AgentFwd", conf_get_int(conf, CONF_agentfwd));
\r
477 write_setting_i(sesskey, "GssapiFwd", conf_get_int(conf, CONF_gssapifwd));
\r
478 write_setting_i(sesskey, "ChangeUsername", conf_get_int(conf, CONF_change_username));
\r
479 wprefs(sesskey, "Cipher", ciphernames, CIPHER_MAX, conf, CONF_ssh_cipherlist);
\r
480 wprefs(sesskey, "KEX", kexnames, KEX_MAX, conf, CONF_ssh_kexlist);
\r
481 write_setting_i(sesskey, "RekeyTime", conf_get_int(conf, CONF_ssh_rekey_time));
\r
482 write_setting_s(sesskey, "RekeyBytes", conf_get_str(conf, CONF_ssh_rekey_data));
\r
483 write_setting_i(sesskey, "SshNoAuth", conf_get_int(conf, CONF_ssh_no_userauth));
\r
484 write_setting_i(sesskey, "SshBanner", conf_get_int(conf, CONF_ssh_show_banner));
\r
485 write_setting_i(sesskey, "AuthTIS", conf_get_int(conf, CONF_try_tis_auth));
\r
486 write_setting_i(sesskey, "AuthKI", conf_get_int(conf, CONF_try_ki_auth));
\r
487 write_setting_i(sesskey, "AuthGSSAPI", conf_get_int(conf, CONF_try_gssapi_auth));
\r
489 wprefs(sesskey, "GSSLibs", gsslibkeywords, ngsslibs, conf, CONF_ssh_gsslist);
\r
490 write_setting_filename(sesskey, "GSSCustom", conf_get_filename(conf, CONF_ssh_gss_custom));
\r
492 write_setting_i(sesskey, "SshNoShell", conf_get_int(conf, CONF_ssh_no_shell));
\r
493 write_setting_i(sesskey, "SshProt", conf_get_int(conf, CONF_sshprot));
\r
494 write_setting_s(sesskey, "LogHost", conf_get_str(conf, CONF_loghost));
\r
495 write_setting_i(sesskey, "SSH2DES", conf_get_int(conf, CONF_ssh2_des_cbc));
\r
496 write_setting_filename(sesskey, "PublicKeyFile", conf_get_filename(conf, CONF_keyfile));
\r
497 write_setting_s(sesskey, "RemoteCommand", conf_get_str(conf, CONF_remote_cmd));
\r
498 write_setting_i(sesskey, "RFCEnviron", conf_get_int(conf, CONF_rfc_environ));
\r
499 write_setting_i(sesskey, "PassiveTelnet", conf_get_int(conf, CONF_passive_telnet));
\r
500 write_setting_i(sesskey, "BackspaceIsDelete", conf_get_int(conf, CONF_bksp_is_delete));
\r
501 write_setting_i(sesskey, "RXVTHomeEnd", conf_get_int(conf, CONF_rxvt_homeend));
\r
502 write_setting_i(sesskey, "LinuxFunctionKeys", conf_get_int(conf, CONF_funky_type));
\r
503 write_setting_i(sesskey, "NoApplicationKeys", conf_get_int(conf, CONF_no_applic_k));
\r
504 write_setting_i(sesskey, "NoApplicationCursors", conf_get_int(conf, CONF_no_applic_c));
\r
505 write_setting_i(sesskey, "NoMouseReporting", conf_get_int(conf, CONF_no_mouse_rep));
\r
506 write_setting_i(sesskey, "NoRemoteResize", conf_get_int(conf, CONF_no_remote_resize));
\r
507 write_setting_i(sesskey, "NoAltScreen", conf_get_int(conf, CONF_no_alt_screen));
\r
508 write_setting_i(sesskey, "NoRemoteWinTitle", conf_get_int(conf, CONF_no_remote_wintitle));
\r
509 write_setting_i(sesskey, "RemoteQTitleAction", conf_get_int(conf, CONF_remote_qtitle_action));
\r
510 write_setting_i(sesskey, "NoDBackspace", conf_get_int(conf, CONF_no_dbackspace));
\r
511 write_setting_i(sesskey, "NoRemoteCharset", conf_get_int(conf, CONF_no_remote_charset));
\r
512 write_setting_i(sesskey, "ApplicationCursorKeys", conf_get_int(conf, CONF_app_cursor));
\r
513 write_setting_i(sesskey, "ApplicationKeypad", conf_get_int(conf, CONF_app_keypad));
\r
514 write_setting_i(sesskey, "NetHackKeypad", conf_get_int(conf, CONF_nethack_keypad));
\r
515 write_setting_i(sesskey, "AltF4", conf_get_int(conf, CONF_alt_f4));
\r
516 write_setting_i(sesskey, "AltSpace", conf_get_int(conf, CONF_alt_space));
\r
517 write_setting_i(sesskey, "AltOnly", conf_get_int(conf, CONF_alt_only));
\r
518 write_setting_i(sesskey, "ComposeKey", conf_get_int(conf, CONF_compose_key));
\r
519 write_setting_i(sesskey, "CtrlAltKeys", conf_get_int(conf, CONF_ctrlaltkeys));
\r
520 write_setting_i(sesskey, "TelnetKey", conf_get_int(conf, CONF_telnet_keyboard));
\r
521 write_setting_i(sesskey, "TelnetRet", conf_get_int(conf, CONF_telnet_newline));
\r
522 write_setting_i(sesskey, "LocalEcho", conf_get_int(conf, CONF_localecho));
\r
523 write_setting_i(sesskey, "LocalEdit", conf_get_int(conf, CONF_localedit));
\r
524 write_setting_s(sesskey, "Answerback", conf_get_str(conf, CONF_answerback));
\r
525 write_setting_i(sesskey, "AlwaysOnTop", conf_get_int(conf, CONF_alwaysontop));
\r
526 write_setting_i(sesskey, "FullScreenOnAltEnter", conf_get_int(conf, CONF_fullscreenonaltenter));
\r
527 write_setting_i(sesskey, "HideMousePtr", conf_get_int(conf, CONF_hide_mouseptr));
\r
528 write_setting_i(sesskey, "SunkenEdge", conf_get_int(conf, CONF_sunken_edge));
\r
529 write_setting_i(sesskey, "WindowBorder", conf_get_int(conf, CONF_window_border));
\r
530 write_setting_i(sesskey, "CurType", conf_get_int(conf, CONF_cursor_type));
\r
531 write_setting_i(sesskey, "BlinkCur", conf_get_int(conf, CONF_blink_cur));
\r
532 write_setting_i(sesskey, "Beep", conf_get_int(conf, CONF_beep));
\r
533 write_setting_i(sesskey, "BeepInd", conf_get_int(conf, CONF_beep_ind));
\r
534 write_setting_filename(sesskey, "BellWaveFile", conf_get_filename(conf, CONF_bell_wavefile));
\r
535 write_setting_i(sesskey, "BellOverload", conf_get_int(conf, CONF_bellovl));
\r
536 write_setting_i(sesskey, "BellOverloadN", conf_get_int(conf, CONF_bellovl_n));
\r
537 write_setting_i(sesskey, "BellOverloadT", conf_get_int(conf, CONF_bellovl_t)
\r
538 #ifdef PUTTY_UNIX_H
\r
542 write_setting_i(sesskey, "BellOverloadS", conf_get_int(conf, CONF_bellovl_s)
\r
543 #ifdef PUTTY_UNIX_H
\r
547 write_setting_i(sesskey, "ScrollbackLines", conf_get_int(conf, CONF_savelines));
\r
548 write_setting_i(sesskey, "DECOriginMode", conf_get_int(conf, CONF_dec_om));
\r
549 write_setting_i(sesskey, "AutoWrapMode", conf_get_int(conf, CONF_wrap_mode));
\r
550 write_setting_i(sesskey, "LFImpliesCR", conf_get_int(conf, CONF_lfhascr));
\r
551 write_setting_i(sesskey, "CRImpliesLF", conf_get_int(conf, CONF_crhaslf));
\r
552 write_setting_i(sesskey, "DisableArabicShaping", conf_get_int(conf, CONF_arabicshaping));
\r
553 write_setting_i(sesskey, "DisableBidi", conf_get_int(conf, CONF_bidi));
\r
554 write_setting_i(sesskey, "WinNameAlways", conf_get_int(conf, CONF_win_name_always));
\r
555 write_setting_s(sesskey, "WinTitle", conf_get_str(conf, CONF_wintitle));
\r
556 write_setting_i(sesskey, "TermWidth", conf_get_int(conf, CONF_width));
\r
557 write_setting_i(sesskey, "TermHeight", conf_get_int(conf, CONF_height));
\r
558 write_setting_fontspec(sesskey, "Font", conf_get_fontspec(conf, CONF_font));
\r
559 write_setting_i(sesskey, "FontQuality", conf_get_int(conf, CONF_font_quality));
\r
560 write_setting_i(sesskey, "FontVTMode", conf_get_int(conf, CONF_vtmode));
\r
561 write_setting_i(sesskey, "UseSystemColours", conf_get_int(conf, CONF_system_colour));
\r
562 write_setting_i(sesskey, "TryPalette", conf_get_int(conf, CONF_try_palette));
\r
563 write_setting_i(sesskey, "ANSIColour", conf_get_int(conf, CONF_ansi_colour));
\r
564 write_setting_i(sesskey, "Xterm256Colour", conf_get_int(conf, CONF_xterm_256_colour));
\r
565 write_setting_i(sesskey, "BoldAsColour", conf_get_int(conf, CONF_bold_style)-1);
\r
567 for (i = 0; i < 22; i++) {
\r
568 char buf[20], buf2[30];
\r
569 sprintf(buf, "Colour%d", i);
\r
570 sprintf(buf2, "%d,%d,%d",
\r
571 conf_get_int_int(conf, CONF_colours, i*3+0),
\r
572 conf_get_int_int(conf, CONF_colours, i*3+1),
\r
573 conf_get_int_int(conf, CONF_colours, i*3+2));
\r
574 write_setting_s(sesskey, buf, buf2);
\r
576 write_setting_i(sesskey, "RawCNP", conf_get_int(conf, CONF_rawcnp));
\r
577 write_setting_i(sesskey, "PasteRTF", conf_get_int(conf, CONF_rtf_paste));
\r
578 write_setting_i(sesskey, "MouseIsXterm", conf_get_int(conf, CONF_mouse_is_xterm));
\r
579 write_setting_i(sesskey, "RectSelect", conf_get_int(conf, CONF_rect_select));
\r
580 write_setting_i(sesskey, "MouseOverride", conf_get_int(conf, CONF_mouse_override));
\r
581 for (i = 0; i < 256; i += 32) {
\r
582 char buf[20], buf2[256];
\r
584 sprintf(buf, "Wordness%d", i);
\r
586 for (j = i; j < i + 32; j++) {
\r
587 sprintf(buf2 + strlen(buf2), "%s%d",
\r
588 (*buf2 ? "," : ""),
\r
589 conf_get_int_int(conf, CONF_wordness, j));
\r
591 write_setting_s(sesskey, buf, buf2);
\r
593 write_setting_s(sesskey, "LineCodePage", conf_get_str(conf, CONF_line_codepage));
\r
594 write_setting_i(sesskey, "CJKAmbigWide", conf_get_int(conf, CONF_cjk_ambig_wide));
\r
595 write_setting_i(sesskey, "UTF8Override", conf_get_int(conf, CONF_utf8_override));
\r
596 write_setting_s(sesskey, "Printer", conf_get_str(conf, CONF_printer));
\r
597 write_setting_i(sesskey, "CapsLockCyr", conf_get_int(conf, CONF_xlat_capslockcyr));
\r
598 write_setting_i(sesskey, "ScrollBar", conf_get_int(conf, CONF_scrollbar));
\r
599 write_setting_i(sesskey, "ScrollBarFullScreen", conf_get_int(conf, CONF_scrollbar_in_fullscreen));
\r
600 write_setting_i(sesskey, "ScrollOnKey", conf_get_int(conf, CONF_scroll_on_key));
\r
601 write_setting_i(sesskey, "ScrollOnDisp", conf_get_int(conf, CONF_scroll_on_disp));
\r
602 write_setting_i(sesskey, "EraseToScrollback", conf_get_int(conf, CONF_erase_to_scrollback));
\r
603 write_setting_i(sesskey, "LockSize", conf_get_int(conf, CONF_resize_action));
\r
604 write_setting_i(sesskey, "BCE", conf_get_int(conf, CONF_bce));
\r
605 write_setting_i(sesskey, "BlinkText", conf_get_int(conf, CONF_blinktext));
\r
606 write_setting_i(sesskey, "X11Forward", conf_get_int(conf, CONF_x11_forward));
\r
607 write_setting_s(sesskey, "X11Display", conf_get_str(conf, CONF_x11_display));
\r
608 write_setting_i(sesskey, "X11AuthType", conf_get_int(conf, CONF_x11_auth));
\r
609 write_setting_filename(sesskey, "X11AuthFile", conf_get_filename(conf, CONF_xauthfile));
\r
610 write_setting_i(sesskey, "LocalPortAcceptAll", conf_get_int(conf, CONF_lport_acceptall));
\r
611 write_setting_i(sesskey, "RemotePortAcceptAll", conf_get_int(conf, CONF_rport_acceptall));
\r
612 wmap(sesskey, "PortForwardings", conf, CONF_portfwd);
\r
613 write_setting_i(sesskey, "BugIgnore1", 2-conf_get_int(conf, CONF_sshbug_ignore1));
\r
614 write_setting_i(sesskey, "BugPlainPW1", 2-conf_get_int(conf, CONF_sshbug_plainpw1));
\r
615 write_setting_i(sesskey, "BugRSA1", 2-conf_get_int(conf, CONF_sshbug_rsa1));
\r
616 write_setting_i(sesskey, "BugIgnore2", 2-conf_get_int(conf, CONF_sshbug_ignore2));
\r
617 write_setting_i(sesskey, "BugHMAC2", 2-conf_get_int(conf, CONF_sshbug_hmac2));
\r
618 write_setting_i(sesskey, "BugDeriveKey2", 2-conf_get_int(conf, CONF_sshbug_derivekey2));
\r
619 write_setting_i(sesskey, "BugRSAPad2", 2-conf_get_int(conf, CONF_sshbug_rsapad2));
\r
620 write_setting_i(sesskey, "BugPKSessID2", 2-conf_get_int(conf, CONF_sshbug_pksessid2));
\r
621 write_setting_i(sesskey, "BugRekey2", 2-conf_get_int(conf, CONF_sshbug_rekey2));
\r
622 write_setting_i(sesskey, "BugMaxPkt2", 2-conf_get_int(conf, CONF_sshbug_maxpkt2));
\r
623 write_setting_i(sesskey, "BugWinadj", 2-conf_get_int(conf, CONF_sshbug_winadj));
\r
624 write_setting_i(sesskey, "StampUtmp", conf_get_int(conf, CONF_stamp_utmp));
\r
625 write_setting_i(sesskey, "LoginShell", conf_get_int(conf, CONF_login_shell));
\r
626 write_setting_i(sesskey, "ScrollbarOnLeft", conf_get_int(conf, CONF_scrollbar_on_left));
\r
627 write_setting_fontspec(sesskey, "BoldFont", conf_get_fontspec(conf, CONF_boldfont));
\r
628 write_setting_fontspec(sesskey, "WideFont", conf_get_fontspec(conf, CONF_widefont));
\r
629 write_setting_fontspec(sesskey, "WideBoldFont", conf_get_fontspec(conf, CONF_wideboldfont));
\r
630 write_setting_i(sesskey, "ShadowBold", conf_get_int(conf, CONF_shadowbold));
\r
631 write_setting_i(sesskey, "ShadowBoldOffset", conf_get_int(conf, CONF_shadowboldoffset));
\r
632 write_setting_s(sesskey, "SerialLine", conf_get_str(conf, CONF_serline));
\r
633 write_setting_i(sesskey, "SerialSpeed", conf_get_int(conf, CONF_serspeed));
\r
634 write_setting_i(sesskey, "SerialDataBits", conf_get_int(conf, CONF_serdatabits));
\r
635 write_setting_i(sesskey, "SerialStopHalfbits", conf_get_int(conf, CONF_serstopbits));
\r
636 write_setting_i(sesskey, "SerialParity", conf_get_int(conf, CONF_serparity));
\r
637 write_setting_i(sesskey, "SerialFlowControl", conf_get_int(conf, CONF_serflow));
\r
638 write_setting_s(sesskey, "WindowClass", conf_get_str(conf, CONF_winclass));
\r
641 void load_settings(char *section, Conf *conf)
\r
645 sesskey = open_settings_r(section);
\r
646 load_open_settings(sesskey, conf);
\r
647 close_settings_r(sesskey);
\r
649 if (conf_launchable(conf))
\r
650 add_session_to_jumplist(section);
\r
653 void load_open_settings(void *sesskey, Conf *conf)
\r
658 conf_set_int(conf, CONF_ssh_subsys, 0); /* FIXME: load this properly */
\r
659 conf_set_str(conf, CONF_remote_cmd, "");
\r
660 conf_set_str(conf, CONF_remote_cmd2, "");
\r
661 conf_set_str(conf, CONF_ssh_nc_host, "");
\r
663 gpps(sesskey, "HostName", "", conf, CONF_host);
\r
664 gppfile(sesskey, "LogFileName", conf, CONF_logfilename);
\r
665 gppi(sesskey, "LogType", 0, conf, CONF_logtype);
\r
666 gppi(sesskey, "LogFileClash", LGXF_ASK, conf, CONF_logxfovr);
\r
667 gppi(sesskey, "LogFlush", 1, conf, CONF_logflush);
\r
668 gppi(sesskey, "SSHLogOmitPasswords", 1, conf, CONF_logomitpass);
\r
669 gppi(sesskey, "SSHLogOmitData", 0, conf, CONF_logomitdata);
\r
671 prot = gpps_raw(sesskey, "Protocol", "default");
\r
672 conf_set_int(conf, CONF_protocol, default_protocol);
\r
673 conf_set_int(conf, CONF_port, default_port);
\r
675 const Backend *b = backend_from_name(prot);
\r
677 conf_set_int(conf, CONF_protocol, b->protocol);
\r
678 gppi(sesskey, "PortNumber", default_port, conf, CONF_port);
\r
683 /* Address family selection */
\r
684 gppi(sesskey, "AddressFamily", ADDRTYPE_UNSPEC, conf, CONF_addressfamily);
\r
686 /* The CloseOnExit numbers are arranged in a different order from
\r
687 * the standard FORCE_ON / FORCE_OFF / AUTO. */
\r
688 i = gppi_raw(sesskey, "CloseOnExit", 1); conf_set_int(conf, CONF_close_on_exit, (i+1)%3);
\r
689 gppi(sesskey, "WarnOnClose", 1, conf, CONF_warn_on_close);
\r
691 /* This is two values for backward compatibility with 0.50/0.51 */
\r
692 int pingmin, pingsec;
\r
693 pingmin = gppi_raw(sesskey, "PingInterval", 0);
\r
694 pingsec = gppi_raw(sesskey, "PingIntervalSecs", 0);
\r
695 conf_set_int(conf, CONF_ping_interval, pingmin * 60 + pingsec);
\r
697 gppi(sesskey, "TCPNoDelay", 1, conf, CONF_tcp_nodelay);
\r
698 gppi(sesskey, "TCPKeepalives", 0, conf, CONF_tcp_keepalives);
\r
699 gpps(sesskey, "TerminalType", "xterm", conf, CONF_termtype);
\r
700 gpps(sesskey, "TerminalSpeed", "38400,38400", conf, CONF_termspeed);
\r
701 if (!gppmap(sesskey, "TerminalModes", conf, CONF_ttymodes)) {
\r
702 /* This hardcodes a big set of defaults in any new saved
\r
703 * sessions. Let's hope we don't change our mind. */
\r
704 for (i = 0; ttymodes[i]; i++)
\r
705 conf_set_str_str(conf, CONF_ttymodes, ttymodes[i], "A");
\r
708 /* proxy settings */
\r
709 gpps(sesskey, "ProxyExcludeList", "", conf, CONF_proxy_exclude_list);
\r
710 i = gppi_raw(sesskey, "ProxyDNS", 1); conf_set_int(conf, CONF_proxy_dns, (i+1)%3);
\r
711 gppi(sesskey, "ProxyLocalhost", 0, conf, CONF_even_proxy_localhost);
\r
712 gppi(sesskey, "ProxyMethod", -1, conf, CONF_proxy_type);
\r
713 if (conf_get_int(conf, CONF_proxy_type) == -1) {
\r
715 i = gppi_raw(sesskey, "ProxyType", 0);
\r
717 conf_set_int(conf, CONF_proxy_type, PROXY_NONE);
\r
719 conf_set_int(conf, CONF_proxy_type, PROXY_HTTP);
\r
721 conf_set_int(conf, CONF_proxy_type, PROXY_TELNET);
\r
723 conf_set_int(conf, CONF_proxy_type, PROXY_CMD);
\r
725 i = gppi_raw(sesskey, "ProxySOCKSVersion", 5);
\r
727 conf_set_int(conf, CONF_proxy_type, PROXY_SOCKS5);
\r
729 conf_set_int(conf, CONF_proxy_type, PROXY_SOCKS4);
\r
732 gpps(sesskey, "ProxyHost", "proxy", conf, CONF_proxy_host);
\r
733 gppi(sesskey, "ProxyPort", 80, conf, CONF_proxy_port);
\r
734 gpps(sesskey, "ProxyUsername", "", conf, CONF_proxy_username);
\r
735 gpps(sesskey, "ProxyPassword", "", conf, CONF_proxy_password);
\r
736 gpps(sesskey, "ProxyTelnetCommand", "connect %host %port\\n",
\r
737 conf, CONF_proxy_telnet_command);
\r
738 gppmap(sesskey, "Environment", conf, CONF_environmt);
\r
739 gpps(sesskey, "UserName", "", conf, CONF_username);
\r
740 gppi(sesskey, "UserNameFromEnvironment", 0, conf, CONF_username_from_env);
\r
741 gpps(sesskey, "LocalUserName", "", conf, CONF_localusername);
\r
742 gppi(sesskey, "NoPTY", 0, conf, CONF_nopty);
\r
743 gppi(sesskey, "Compression", 0, conf, CONF_compression);
\r
744 gppi(sesskey, "TryAgent", 1, conf, CONF_tryagent);
\r
745 gppi(sesskey, "AgentFwd", 0, conf, CONF_agentfwd);
\r
746 gppi(sesskey, "ChangeUsername", 0, conf, CONF_change_username);
\r
747 gppi(sesskey, "GssapiFwd", 0, conf, CONF_gssapifwd);
\r
748 gprefs(sesskey, "Cipher", "\0",
\r
749 ciphernames, CIPHER_MAX, conf, CONF_ssh_cipherlist);
\r
751 /* Backward-compatibility: we used to have an option to
\r
752 * disable gex under the "bugs" panel after one report of
\r
753 * a server which offered it then choked, but we never got
\r
754 * a server version string or any other reports. */
\r
755 char *default_kexes;
\r
756 i = 2 - gppi_raw(sesskey, "BugDHGEx2", 0);
\r
758 default_kexes = "dh-group14-sha1,dh-group1-sha1,rsa,WARN,dh-gex-sha1";
\r
760 default_kexes = "dh-gex-sha1,dh-group14-sha1,dh-group1-sha1,rsa,WARN";
\r
761 gprefs(sesskey, "KEX", default_kexes,
\r
762 kexnames, KEX_MAX, conf, CONF_ssh_kexlist);
\r
764 gppi(sesskey, "RekeyTime", 60, conf, CONF_ssh_rekey_time);
\r
765 gpps(sesskey, "RekeyBytes", "1G", conf, CONF_ssh_rekey_data);
\r
766 gppi(sesskey, "SshProt", 2, conf, CONF_sshprot);
\r
767 gpps(sesskey, "LogHost", "", conf, CONF_loghost);
\r
768 gppi(sesskey, "SSH2DES", 0, conf, CONF_ssh2_des_cbc);
\r
769 gppi(sesskey, "SshNoAuth", 0, conf, CONF_ssh_no_userauth);
\r
770 gppi(sesskey, "SshBanner", 1, conf, CONF_ssh_show_banner);
\r
771 gppi(sesskey, "AuthTIS", 0, conf, CONF_try_tis_auth);
\r
772 gppi(sesskey, "AuthKI", 1, conf, CONF_try_ki_auth);
\r
773 gppi(sesskey, "AuthGSSAPI", 1, conf, CONF_try_gssapi_auth);
\r
775 gprefs(sesskey, "GSSLibs", "\0",
\r
776 gsslibkeywords, ngsslibs, conf, CONF_ssh_gsslist);
\r
777 gppfile(sesskey, "GSSCustom", conf, CONF_ssh_gss_custom);
\r
779 gppi(sesskey, "SshNoShell", 0, conf, CONF_ssh_no_shell);
\r
780 gppfile(sesskey, "PublicKeyFile", conf, CONF_keyfile);
\r
781 gpps(sesskey, "RemoteCommand", "", conf, CONF_remote_cmd);
\r
782 gppi(sesskey, "RFCEnviron", 0, conf, CONF_rfc_environ);
\r
783 gppi(sesskey, "PassiveTelnet", 0, conf, CONF_passive_telnet);
\r
784 gppi(sesskey, "BackspaceIsDelete", 1, conf, CONF_bksp_is_delete);
\r
785 gppi(sesskey, "RXVTHomeEnd", 0, conf, CONF_rxvt_homeend);
\r
786 gppi(sesskey, "LinuxFunctionKeys", 0, conf, CONF_funky_type);
\r
787 gppi(sesskey, "NoApplicationKeys", 0, conf, CONF_no_applic_k);
\r
788 gppi(sesskey, "NoApplicationCursors", 0, conf, CONF_no_applic_c);
\r
789 gppi(sesskey, "NoMouseReporting", 0, conf, CONF_no_mouse_rep);
\r
790 gppi(sesskey, "NoRemoteResize", 0, conf, CONF_no_remote_resize);
\r
791 gppi(sesskey, "NoAltScreen", 0, conf, CONF_no_alt_screen);
\r
792 gppi(sesskey, "NoRemoteWinTitle", 0, conf, CONF_no_remote_wintitle);
\r
794 /* Backward compatibility */
\r
795 int no_remote_qtitle = gppi_raw(sesskey, "NoRemoteQTitle", 1);
\r
796 /* We deliberately interpret the old setting of "no response" as
\r
797 * "empty string". This changes the behaviour, but hopefully for
\r
798 * the better; the user can always recover the old behaviour. */
\r
799 gppi(sesskey, "RemoteQTitleAction",
\r
800 no_remote_qtitle ? TITLE_EMPTY : TITLE_REAL,
\r
801 conf, CONF_remote_qtitle_action);
\r
803 gppi(sesskey, "NoDBackspace", 0, conf, CONF_no_dbackspace);
\r
804 gppi(sesskey, "NoRemoteCharset", 0, conf, CONF_no_remote_charset);
\r
805 gppi(sesskey, "ApplicationCursorKeys", 0, conf, CONF_app_cursor);
\r
806 gppi(sesskey, "ApplicationKeypad", 0, conf, CONF_app_keypad);
\r
807 gppi(sesskey, "NetHackKeypad", 0, conf, CONF_nethack_keypad);
\r
808 gppi(sesskey, "AltF4", 1, conf, CONF_alt_f4);
\r
809 gppi(sesskey, "AltSpace", 0, conf, CONF_alt_space);
\r
810 gppi(sesskey, "AltOnly", 0, conf, CONF_alt_only);
\r
811 gppi(sesskey, "ComposeKey", 0, conf, CONF_compose_key);
\r
812 gppi(sesskey, "CtrlAltKeys", 1, conf, CONF_ctrlaltkeys);
\r
813 gppi(sesskey, "TelnetKey", 0, conf, CONF_telnet_keyboard);
\r
814 gppi(sesskey, "TelnetRet", 1, conf, CONF_telnet_newline);
\r
815 gppi(sesskey, "LocalEcho", AUTO, conf, CONF_localecho);
\r
816 gppi(sesskey, "LocalEdit", AUTO, conf, CONF_localedit);
\r
817 gpps(sesskey, "Answerback", "PuTTY", conf, CONF_answerback);
\r
818 gppi(sesskey, "AlwaysOnTop", 0, conf, CONF_alwaysontop);
\r
819 gppi(sesskey, "FullScreenOnAltEnter", 0, conf, CONF_fullscreenonaltenter);
\r
820 gppi(sesskey, "HideMousePtr", 0, conf, CONF_hide_mouseptr);
\r
821 gppi(sesskey, "SunkenEdge", 0, conf, CONF_sunken_edge);
\r
822 gppi(sesskey, "WindowBorder", 1, conf, CONF_window_border);
\r
823 gppi(sesskey, "CurType", 0, conf, CONF_cursor_type);
\r
824 gppi(sesskey, "BlinkCur", 0, conf, CONF_blink_cur);
\r
825 /* pedantic compiler tells me I can't use conf, CONF_beep as an int * :-) */
\r
826 gppi(sesskey, "Beep", 1, conf, CONF_beep);
\r
827 gppi(sesskey, "BeepInd", 0, conf, CONF_beep_ind);
\r
828 gppfile(sesskey, "BellWaveFile", conf, CONF_bell_wavefile);
\r
829 gppi(sesskey, "BellOverload", 1, conf, CONF_bellovl);
\r
830 gppi(sesskey, "BellOverloadN", 5, conf, CONF_bellovl_n);
\r
831 i = gppi_raw(sesskey, "BellOverloadT", 2*TICKSPERSEC
\r
832 #ifdef PUTTY_UNIX_H
\r
836 conf_set_int(conf, CONF_bellovl_t, i
\r
837 #ifdef PUTTY_UNIX_H
\r
841 i = gppi_raw(sesskey, "BellOverloadS", 5*TICKSPERSEC
\r
842 #ifdef PUTTY_UNIX_H
\r
846 conf_set_int(conf, CONF_bellovl_s, i
\r
847 #ifdef PUTTY_UNIX_H
\r
851 gppi(sesskey, "ScrollbackLines", 2000, conf, CONF_savelines);
\r
852 gppi(sesskey, "DECOriginMode", 0, conf, CONF_dec_om);
\r
853 gppi(sesskey, "AutoWrapMode", 1, conf, CONF_wrap_mode);
\r
854 gppi(sesskey, "LFImpliesCR", 0, conf, CONF_lfhascr);
\r
855 gppi(sesskey, "CRImpliesLF", 0, conf, CONF_crhaslf);
\r
856 gppi(sesskey, "DisableArabicShaping", 0, conf, CONF_arabicshaping);
\r
857 gppi(sesskey, "DisableBidi", 0, conf, CONF_bidi);
\r
858 gppi(sesskey, "WinNameAlways", 1, conf, CONF_win_name_always);
\r
859 gpps(sesskey, "WinTitle", "", conf, CONF_wintitle);
\r
860 gppi(sesskey, "TermWidth", 80, conf, CONF_width);
\r
861 gppi(sesskey, "TermHeight", 24, conf, CONF_height);
\r
862 gppfont(sesskey, "Font", conf, CONF_font);
\r
863 gppi(sesskey, "FontQuality", FQ_DEFAULT, conf, CONF_font_quality);
\r
864 gppi(sesskey, "FontVTMode", VT_UNICODE, conf, CONF_vtmode);
\r
865 gppi(sesskey, "UseSystemColours", 0, conf, CONF_system_colour);
\r
866 gppi(sesskey, "TryPalette", 0, conf, CONF_try_palette);
\r
867 gppi(sesskey, "ANSIColour", 1, conf, CONF_ansi_colour);
\r
868 gppi(sesskey, "Xterm256Colour", 1, conf, CONF_xterm_256_colour);
\r
869 i = gppi_raw(sesskey, "BoldAsColour", 0); conf_set_int(conf, CONF_bold_style, i+1);
\r
871 for (i = 0; i < 22; i++) {
\r
872 static const char *const defaults[] = {
\r
873 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
\r
874 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
\r
875 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
\r
876 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
\r
877 "85,255,255", "187,187,187", "255,255,255"
\r
879 char buf[20], *buf2;
\r
881 sprintf(buf, "Colour%d", i);
\r
882 buf2 = gpps_raw(sesskey, buf, defaults[i]);
\r
883 if (sscanf(buf2, "%d,%d,%d", &c0, &c1, &c2) == 3) {
\r
884 conf_set_int_int(conf, CONF_colours, i*3+0, c0);
\r
885 conf_set_int_int(conf, CONF_colours, i*3+1, c1);
\r
886 conf_set_int_int(conf, CONF_colours, i*3+2, c2);
\r
890 gppi(sesskey, "RawCNP", 0, conf, CONF_rawcnp);
\r
891 gppi(sesskey, "PasteRTF", 0, conf, CONF_rtf_paste);
\r
892 gppi(sesskey, "MouseIsXterm", 0, conf, CONF_mouse_is_xterm);
\r
893 gppi(sesskey, "RectSelect", 0, conf, CONF_rect_select);
\r
894 gppi(sesskey, "MouseOverride", 1, conf, CONF_mouse_override);
\r
895 for (i = 0; i < 256; i += 32) {
\r
896 static const char *const defaults[] = {
\r
897 "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
898 "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
899 "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
900 "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
901 "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
902 "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
903 "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
904 "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
906 char buf[20], *buf2, *p;
\r
908 sprintf(buf, "Wordness%d", i);
\r
909 buf2 = gpps_raw(sesskey, buf, defaults[i / 32]);
\r
911 for (j = i; j < i + 32; j++) {
\r
913 while (*p && *p != ',')
\r
917 conf_set_int_int(conf, CONF_wordness, j, atoi(q));
\r
922 * The empty default for LineCodePage will be converted later
\r
923 * into a plausible default for the locale.
\r
925 gpps(sesskey, "LineCodePage", "", conf, CONF_line_codepage);
\r
926 gppi(sesskey, "CJKAmbigWide", 0, conf, CONF_cjk_ambig_wide);
\r
927 gppi(sesskey, "UTF8Override", 1, conf, CONF_utf8_override);
\r
928 gpps(sesskey, "Printer", "", conf, CONF_printer);
\r
929 gppi(sesskey, "CapsLockCyr", 0, conf, CONF_xlat_capslockcyr);
\r
930 gppi(sesskey, "ScrollBar", 1, conf, CONF_scrollbar);
\r
931 gppi(sesskey, "ScrollBarFullScreen", 0, conf, CONF_scrollbar_in_fullscreen);
\r
932 gppi(sesskey, "ScrollOnKey", 0, conf, CONF_scroll_on_key);
\r
933 gppi(sesskey, "ScrollOnDisp", 1, conf, CONF_scroll_on_disp);
\r
934 gppi(sesskey, "EraseToScrollback", 1, conf, CONF_erase_to_scrollback);
\r
935 gppi(sesskey, "LockSize", 0, conf, CONF_resize_action);
\r
936 gppi(sesskey, "BCE", 1, conf, CONF_bce);
\r
937 gppi(sesskey, "BlinkText", 0, conf, CONF_blinktext);
\r
938 gppi(sesskey, "X11Forward", 0, conf, CONF_x11_forward);
\r
939 gpps(sesskey, "X11Display", "", conf, CONF_x11_display);
\r
940 gppi(sesskey, "X11AuthType", X11_MIT, conf, CONF_x11_auth);
\r
941 gppfile(sesskey, "X11AuthFile", conf, CONF_xauthfile);
\r
943 gppi(sesskey, "LocalPortAcceptAll", 0, conf, CONF_lport_acceptall);
\r
944 gppi(sesskey, "RemotePortAcceptAll", 0, conf, CONF_rport_acceptall);
\r
945 gppmap(sesskey, "PortForwardings", conf, CONF_portfwd);
\r
946 i = gppi_raw(sesskey, "BugIgnore1", 0); conf_set_int(conf, CONF_sshbug_ignore1, 2-i);
\r
947 i = gppi_raw(sesskey, "BugPlainPW1", 0); conf_set_int(conf, CONF_sshbug_plainpw1, 2-i);
\r
948 i = gppi_raw(sesskey, "BugRSA1", 0); conf_set_int(conf, CONF_sshbug_rsa1, 2-i);
\r
949 i = gppi_raw(sesskey, "BugIgnore2", 0); conf_set_int(conf, CONF_sshbug_ignore2, 2-i);
\r
952 i = gppi_raw(sesskey, "BugHMAC2", 0); conf_set_int(conf, CONF_sshbug_hmac2, 2-i);
\r
954 i = gppi_raw(sesskey, "BuggyMAC", 0);
\r
956 conf_set_int(conf, CONF_sshbug_hmac2, FORCE_ON);
\r
959 i = gppi_raw(sesskey, "BugDeriveKey2", 0); conf_set_int(conf, CONF_sshbug_derivekey2, 2-i);
\r
960 i = gppi_raw(sesskey, "BugRSAPad2", 0); conf_set_int(conf, CONF_sshbug_rsapad2, 2-i);
\r
961 i = gppi_raw(sesskey, "BugPKSessID2", 0); conf_set_int(conf, CONF_sshbug_pksessid2, 2-i);
\r
962 i = gppi_raw(sesskey, "BugRekey2", 0); conf_set_int(conf, CONF_sshbug_rekey2, 2-i);
\r
963 i = gppi_raw(sesskey, "BugMaxPkt2", 0); conf_set_int(conf, CONF_sshbug_maxpkt2, 2-i);
\r
964 i = gppi_raw(sesskey, "BugWinadj", 0); conf_set_int(conf, CONF_sshbug_winadj, 2-i);
\r
965 conf_set_int(conf, CONF_ssh_simple, FALSE);
\r
966 gppi(sesskey, "StampUtmp", 1, conf, CONF_stamp_utmp);
\r
967 gppi(sesskey, "LoginShell", 1, conf, CONF_login_shell);
\r
968 gppi(sesskey, "ScrollbarOnLeft", 0, conf, CONF_scrollbar_on_left);
\r
969 gppi(sesskey, "ShadowBold", 0, conf, CONF_shadowbold);
\r
970 gppfont(sesskey, "BoldFont", conf, CONF_boldfont);
\r
971 gppfont(sesskey, "WideFont", conf, CONF_widefont);
\r
972 gppfont(sesskey, "WideBoldFont", conf, CONF_wideboldfont);
\r
973 gppi(sesskey, "ShadowBoldOffset", 1, conf, CONF_shadowboldoffset);
\r
974 gpps(sesskey, "SerialLine", "", conf, CONF_serline);
\r
975 gppi(sesskey, "SerialSpeed", 9600, conf, CONF_serspeed);
\r
976 gppi(sesskey, "SerialDataBits", 8, conf, CONF_serdatabits);
\r
977 gppi(sesskey, "SerialStopHalfbits", 2, conf, CONF_serstopbits);
\r
978 gppi(sesskey, "SerialParity", SER_PAR_NONE, conf, CONF_serparity);
\r
979 gppi(sesskey, "SerialFlowControl", SER_FLOW_XONXOFF, conf, CONF_serflow);
\r
980 gpps(sesskey, "WindowClass", "", conf, CONF_winclass);
\r
983 void do_defaults(char *session, Conf *conf)
\r
985 load_settings(session, conf);
\r
988 static int sessioncmp(const void *av, const void *bv)
\r
990 const char *a = *(const char *const *) av;
\r
991 const char *b = *(const char *const *) bv;
\r
994 * Alphabetical order, except that "Default Settings" is a
\r
995 * special case and comes first.
\r
997 if (!strcmp(a, "Default Settings"))
\r
998 return -1; /* a comes first */
\r
999 if (!strcmp(b, "Default Settings"))
\r
1000 return +1; /* b comes first */
\r
1002 * FIXME: perhaps we should ignore the first & in determining
\r
1005 return strcmp(a, b); /* otherwise, compare normally */
\r
1008 void get_sesslist(struct sesslist *list, int allocate)
\r
1010 char otherbuf[2048];
\r
1011 int buflen, bufsize, i;
\r
1017 buflen = bufsize = 0;
\r
1018 list->buffer = NULL;
\r
1019 if ((handle = enum_settings_start()) != NULL) {
\r
1021 ret = enum_settings_next(handle, otherbuf, sizeof(otherbuf));
\r
1023 int len = strlen(otherbuf) + 1;
\r
1024 if (bufsize < buflen + len) {
\r
1025 bufsize = buflen + len + 2048;
\r
1026 list->buffer = sresize(list->buffer, bufsize, char);
\r
1028 strcpy(list->buffer + buflen, otherbuf);
\r
1029 buflen += strlen(list->buffer + buflen) + 1;
\r
1032 enum_settings_finish(handle);
\r
1034 list->buffer = sresize(list->buffer, buflen + 1, char);
\r
1035 list->buffer[buflen] = '\0';
\r
1038 * Now set up the list of sessions. Note that "Default
\r
1039 * Settings" must always be claimed to exist, even if it
\r
1044 list->nsessions = 1; /* "Default Settings" counts as one */
\r
1046 if (strcmp(p, "Default Settings"))
\r
1047 list->nsessions++;
\r
1053 list->sessions = snewn(list->nsessions + 1, char *);
\r
1054 list->sessions[0] = "Default Settings";
\r
1058 if (strcmp(p, "Default Settings"))
\r
1059 list->sessions[i++] = p;
\r
1065 qsort(list->sessions, i, sizeof(char *), sessioncmp);
\r
1067 sfree(list->buffer);
\r
1068 sfree(list->sessions);
\r
1069 list->buffer = NULL;
\r
1070 list->sessions = NULL;
\r