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, "BugOldGex2", 2-conf_get_int(conf, CONF_sshbug_oldgex2));
\r
634 write_setting_i(sesskey, "BugWinadj", 2-conf_get_int(conf, CONF_sshbug_winadj));
\r
635 write_setting_i(sesskey, "BugChanReq", 2-conf_get_int(conf, CONF_sshbug_chanreq));
\r
636 write_setting_i(sesskey, "StampUtmp", conf_get_int(conf, CONF_stamp_utmp));
\r
637 write_setting_i(sesskey, "LoginShell", conf_get_int(conf, CONF_login_shell));
\r
638 write_setting_i(sesskey, "ScrollbarOnLeft", conf_get_int(conf, CONF_scrollbar_on_left));
\r
639 write_setting_fontspec(sesskey, "BoldFont", conf_get_fontspec(conf, CONF_boldfont));
\r
640 write_setting_fontspec(sesskey, "WideFont", conf_get_fontspec(conf, CONF_widefont));
\r
641 write_setting_fontspec(sesskey, "WideBoldFont", conf_get_fontspec(conf, CONF_wideboldfont));
\r
642 write_setting_i(sesskey, "ShadowBold", conf_get_int(conf, CONF_shadowbold));
\r
643 write_setting_i(sesskey, "ShadowBoldOffset", conf_get_int(conf, CONF_shadowboldoffset));
\r
644 write_setting_s(sesskey, "SerialLine", conf_get_str(conf, CONF_serline));
\r
645 write_setting_i(sesskey, "SerialSpeed", conf_get_int(conf, CONF_serspeed));
\r
646 write_setting_i(sesskey, "SerialDataBits", conf_get_int(conf, CONF_serdatabits));
\r
647 write_setting_i(sesskey, "SerialStopHalfbits", conf_get_int(conf, CONF_serstopbits));
\r
648 write_setting_i(sesskey, "SerialParity", conf_get_int(conf, CONF_serparity));
\r
649 write_setting_i(sesskey, "SerialFlowControl", conf_get_int(conf, CONF_serflow));
\r
650 write_setting_s(sesskey, "WindowClass", conf_get_str(conf, CONF_winclass));
\r
651 write_setting_i(sesskey, "ConnectionSharing", conf_get_int(conf, CONF_ssh_connection_sharing));
\r
652 write_setting_i(sesskey, "ConnectionSharingUpstream", conf_get_int(conf, CONF_ssh_connection_sharing_upstream));
\r
653 write_setting_i(sesskey, "ConnectionSharingDownstream", conf_get_int(conf, CONF_ssh_connection_sharing_downstream));
\r
654 wmap(sesskey, "SSHManualHostKeys", conf, CONF_ssh_manual_hostkeys, FALSE);
\r
657 void load_settings(char *section, Conf *conf)
\r
661 sesskey = open_settings_r(section);
\r
662 load_open_settings(sesskey, conf);
\r
663 close_settings_r(sesskey);
\r
665 if (conf_launchable(conf))
\r
666 add_session_to_jumplist(section);
\r
669 void load_open_settings(void *sesskey, Conf *conf)
\r
674 conf_set_int(conf, CONF_ssh_subsys, 0); /* FIXME: load this properly */
\r
675 conf_set_str(conf, CONF_remote_cmd, "");
\r
676 conf_set_str(conf, CONF_remote_cmd2, "");
\r
677 conf_set_str(conf, CONF_ssh_nc_host, "");
\r
679 gpps(sesskey, "HostName", "", conf, CONF_host);
\r
680 gppfile(sesskey, "LogFileName", conf, CONF_logfilename);
\r
681 gppi(sesskey, "LogType", 0, conf, CONF_logtype);
\r
682 gppi(sesskey, "LogFileClash", LGXF_ASK, conf, CONF_logxfovr);
\r
683 gppi(sesskey, "LogFlush", 1, conf, CONF_logflush);
\r
684 gppi(sesskey, "SSHLogOmitPasswords", 1, conf, CONF_logomitpass);
\r
685 gppi(sesskey, "SSHLogOmitData", 0, conf, CONF_logomitdata);
\r
687 prot = gpps_raw(sesskey, "Protocol", "default");
\r
688 conf_set_int(conf, CONF_protocol, default_protocol);
\r
689 conf_set_int(conf, CONF_port, default_port);
\r
691 const Backend *b = backend_from_name(prot);
\r
693 conf_set_int(conf, CONF_protocol, b->protocol);
\r
694 gppi(sesskey, "PortNumber", default_port, conf, CONF_port);
\r
699 /* Address family selection */
\r
700 gppi(sesskey, "AddressFamily", ADDRTYPE_UNSPEC, conf, CONF_addressfamily);
\r
702 /* The CloseOnExit numbers are arranged in a different order from
\r
703 * the standard FORCE_ON / FORCE_OFF / AUTO. */
\r
704 i = gppi_raw(sesskey, "CloseOnExit", 1); conf_set_int(conf, CONF_close_on_exit, (i+1)%3);
\r
705 gppi(sesskey, "WarnOnClose", 1, conf, CONF_warn_on_close);
\r
707 /* This is two values for backward compatibility with 0.50/0.51 */
\r
708 int pingmin, pingsec;
\r
709 pingmin = gppi_raw(sesskey, "PingInterval", 0);
\r
710 pingsec = gppi_raw(sesskey, "PingIntervalSecs", 0);
\r
711 conf_set_int(conf, CONF_ping_interval, pingmin * 60 + pingsec);
\r
713 gppi(sesskey, "TCPNoDelay", 1, conf, CONF_tcp_nodelay);
\r
714 gppi(sesskey, "TCPKeepalives", 0, conf, CONF_tcp_keepalives);
\r
715 gpps(sesskey, "TerminalType", "xterm", conf, CONF_termtype);
\r
716 gpps(sesskey, "TerminalSpeed", "38400,38400", conf, CONF_termspeed);
\r
717 if (!gppmap(sesskey, "TerminalModes", conf, CONF_ttymodes)) {
\r
718 /* This hardcodes a big set of defaults in any new saved
\r
719 * sessions. Let's hope we don't change our mind. */
\r
720 for (i = 0; ttymodes[i]; i++)
\r
721 conf_set_str_str(conf, CONF_ttymodes, ttymodes[i], "A");
\r
724 /* proxy settings */
\r
725 gpps(sesskey, "ProxyExcludeList", "", conf, CONF_proxy_exclude_list);
\r
726 i = gppi_raw(sesskey, "ProxyDNS", 1); conf_set_int(conf, CONF_proxy_dns, (i+1)%3);
\r
727 gppi(sesskey, "ProxyLocalhost", 0, conf, CONF_even_proxy_localhost);
\r
728 gppi(sesskey, "ProxyMethod", -1, conf, CONF_proxy_type);
\r
729 if (conf_get_int(conf, CONF_proxy_type) == -1) {
\r
731 i = gppi_raw(sesskey, "ProxyType", 0);
\r
733 conf_set_int(conf, CONF_proxy_type, PROXY_NONE);
\r
735 conf_set_int(conf, CONF_proxy_type, PROXY_HTTP);
\r
737 conf_set_int(conf, CONF_proxy_type, PROXY_TELNET);
\r
739 conf_set_int(conf, CONF_proxy_type, PROXY_CMD);
\r
741 i = gppi_raw(sesskey, "ProxySOCKSVersion", 5);
\r
743 conf_set_int(conf, CONF_proxy_type, PROXY_SOCKS5);
\r
745 conf_set_int(conf, CONF_proxy_type, PROXY_SOCKS4);
\r
748 gpps(sesskey, "ProxyHost", "proxy", conf, CONF_proxy_host);
\r
749 gppi(sesskey, "ProxyPort", 80, conf, CONF_proxy_port);
\r
750 gpps(sesskey, "ProxyUsername", "", conf, CONF_proxy_username);
\r
751 gpps(sesskey, "ProxyPassword", "", conf, CONF_proxy_password);
\r
752 gpps(sesskey, "ProxyTelnetCommand", "connect %host %port\\n",
\r
753 conf, CONF_proxy_telnet_command);
\r
754 gppmap(sesskey, "Environment", conf, CONF_environmt);
\r
755 gpps(sesskey, "UserName", "", conf, CONF_username);
\r
756 gppi(sesskey, "UserNameFromEnvironment", 0, conf, CONF_username_from_env);
\r
757 gpps(sesskey, "LocalUserName", "", conf, CONF_localusername);
\r
758 gppi(sesskey, "NoPTY", 0, conf, CONF_nopty);
\r
759 gppi(sesskey, "Compression", 0, conf, CONF_compression);
\r
760 gppi(sesskey, "TryAgent", 1, conf, CONF_tryagent);
\r
761 gppi(sesskey, "AgentFwd", 0, conf, CONF_agentfwd);
\r
762 gppi(sesskey, "ChangeUsername", 0, conf, CONF_change_username);
\r
763 gppi(sesskey, "GssapiFwd", 0, conf, CONF_gssapifwd);
\r
764 gprefs(sesskey, "Cipher", "\0",
\r
765 ciphernames, CIPHER_MAX, conf, CONF_ssh_cipherlist);
\r
767 /* Backward-compatibility: we used to have an option to
\r
768 * disable gex under the "bugs" panel after one report of
\r
769 * a server which offered it then choked, but we never got
\r
770 * a server version string or any other reports. */
\r
771 char *default_kexes;
\r
772 i = 2 - gppi_raw(sesskey, "BugDHGEx2", 0);
\r
774 default_kexes = "dh-group14-sha1,dh-group1-sha1,rsa,WARN,dh-gex-sha1";
\r
776 default_kexes = "dh-gex-sha1,dh-group14-sha1,dh-group1-sha1,rsa,WARN";
\r
777 gprefs(sesskey, "KEX", default_kexes,
\r
778 kexnames, KEX_MAX, conf, CONF_ssh_kexlist);
\r
780 gppi(sesskey, "RekeyTime", 60, conf, CONF_ssh_rekey_time);
\r
781 gpps(sesskey, "RekeyBytes", "1G", conf, CONF_ssh_rekey_data);
\r
782 /* SSH-2 only by default */
\r
783 gppi(sesskey, "SshProt", 3, conf, CONF_sshprot);
\r
784 gpps(sesskey, "LogHost", "", conf, CONF_loghost);
\r
785 gppi(sesskey, "SSH2DES", 0, conf, CONF_ssh2_des_cbc);
\r
786 gppi(sesskey, "SshNoAuth", 0, conf, CONF_ssh_no_userauth);
\r
787 gppi(sesskey, "SshBanner", 1, conf, CONF_ssh_show_banner);
\r
788 gppi(sesskey, "AuthTIS", 0, conf, CONF_try_tis_auth);
\r
789 gppi(sesskey, "AuthKI", 1, conf, CONF_try_ki_auth);
\r
790 gppi(sesskey, "AuthGSSAPI", 1, conf, CONF_try_gssapi_auth);
\r
792 gprefs(sesskey, "GSSLibs", "\0",
\r
793 gsslibkeywords, ngsslibs, conf, CONF_ssh_gsslist);
\r
794 gppfile(sesskey, "GSSCustom", conf, CONF_ssh_gss_custom);
\r
796 gppi(sesskey, "SshNoShell", 0, conf, CONF_ssh_no_shell);
\r
797 gppfile(sesskey, "PublicKeyFile", conf, CONF_keyfile);
\r
798 gpps(sesskey, "RemoteCommand", "", conf, CONF_remote_cmd);
\r
799 gppi(sesskey, "RFCEnviron", 0, conf, CONF_rfc_environ);
\r
800 gppi(sesskey, "PassiveTelnet", 0, conf, CONF_passive_telnet);
\r
801 gppi(sesskey, "BackspaceIsDelete", 1, conf, CONF_bksp_is_delete);
\r
802 gppi(sesskey, "RXVTHomeEnd", 0, conf, CONF_rxvt_homeend);
\r
803 gppi(sesskey, "LinuxFunctionKeys", 0, conf, CONF_funky_type);
\r
804 gppi(sesskey, "NoApplicationKeys", 0, conf, CONF_no_applic_k);
\r
805 gppi(sesskey, "NoApplicationCursors", 0, conf, CONF_no_applic_c);
\r
806 gppi(sesskey, "NoMouseReporting", 0, conf, CONF_no_mouse_rep);
\r
807 gppi(sesskey, "NoRemoteResize", 0, conf, CONF_no_remote_resize);
\r
808 gppi(sesskey, "NoAltScreen", 0, conf, CONF_no_alt_screen);
\r
809 gppi(sesskey, "NoRemoteWinTitle", 0, conf, CONF_no_remote_wintitle);
\r
811 /* Backward compatibility */
\r
812 int no_remote_qtitle = gppi_raw(sesskey, "NoRemoteQTitle", 1);
\r
813 /* We deliberately interpret the old setting of "no response" as
\r
814 * "empty string". This changes the behaviour, but hopefully for
\r
815 * the better; the user can always recover the old behaviour. */
\r
816 gppi(sesskey, "RemoteQTitleAction",
\r
817 no_remote_qtitle ? TITLE_EMPTY : TITLE_REAL,
\r
818 conf, CONF_remote_qtitle_action);
\r
820 gppi(sesskey, "NoDBackspace", 0, conf, CONF_no_dbackspace);
\r
821 gppi(sesskey, "NoRemoteCharset", 0, conf, CONF_no_remote_charset);
\r
822 gppi(sesskey, "ApplicationCursorKeys", 0, conf, CONF_app_cursor);
\r
823 gppi(sesskey, "ApplicationKeypad", 0, conf, CONF_app_keypad);
\r
824 gppi(sesskey, "NetHackKeypad", 0, conf, CONF_nethack_keypad);
\r
825 gppi(sesskey, "AltF4", 1, conf, CONF_alt_f4);
\r
826 gppi(sesskey, "AltSpace", 0, conf, CONF_alt_space);
\r
827 gppi(sesskey, "AltOnly", 0, conf, CONF_alt_only);
\r
828 gppi(sesskey, "ComposeKey", 0, conf, CONF_compose_key);
\r
829 gppi(sesskey, "CtrlAltKeys", 1, conf, CONF_ctrlaltkeys);
\r
830 gppi(sesskey, "TelnetKey", 0, conf, CONF_telnet_keyboard);
\r
831 gppi(sesskey, "TelnetRet", 1, conf, CONF_telnet_newline);
\r
832 gppi(sesskey, "LocalEcho", AUTO, conf, CONF_localecho);
\r
833 gppi(sesskey, "LocalEdit", AUTO, conf, CONF_localedit);
\r
834 gpps(sesskey, "Answerback", "PuTTY", conf, CONF_answerback);
\r
835 gppi(sesskey, "AlwaysOnTop", 0, conf, CONF_alwaysontop);
\r
836 gppi(sesskey, "FullScreenOnAltEnter", 0, conf, CONF_fullscreenonaltenter);
\r
837 gppi(sesskey, "HideMousePtr", 0, conf, CONF_hide_mouseptr);
\r
838 gppi(sesskey, "SunkenEdge", 0, conf, CONF_sunken_edge);
\r
839 gppi(sesskey, "WindowBorder", 1, conf, CONF_window_border);
\r
840 gppi(sesskey, "CurType", 0, conf, CONF_cursor_type);
\r
841 gppi(sesskey, "BlinkCur", 0, conf, CONF_blink_cur);
\r
842 /* pedantic compiler tells me I can't use conf, CONF_beep as an int * :-) */
\r
843 gppi(sesskey, "Beep", 1, conf, CONF_beep);
\r
844 gppi(sesskey, "BeepInd", 0, conf, CONF_beep_ind);
\r
845 gppfile(sesskey, "BellWaveFile", conf, CONF_bell_wavefile);
\r
846 gppi(sesskey, "BellOverload", 1, conf, CONF_bellovl);
\r
847 gppi(sesskey, "BellOverloadN", 5, conf, CONF_bellovl_n);
\r
848 i = gppi_raw(sesskey, "BellOverloadT", 2*TICKSPERSEC
\r
849 #ifdef PUTTY_UNIX_H
\r
853 conf_set_int(conf, CONF_bellovl_t, i
\r
854 #ifdef PUTTY_UNIX_H
\r
858 i = gppi_raw(sesskey, "BellOverloadS", 5*TICKSPERSEC
\r
859 #ifdef PUTTY_UNIX_H
\r
863 conf_set_int(conf, CONF_bellovl_s, i
\r
864 #ifdef PUTTY_UNIX_H
\r
868 gppi(sesskey, "ScrollbackLines", 2000, conf, CONF_savelines);
\r
869 gppi(sesskey, "DECOriginMode", 0, conf, CONF_dec_om);
\r
870 gppi(sesskey, "AutoWrapMode", 1, conf, CONF_wrap_mode);
\r
871 gppi(sesskey, "LFImpliesCR", 0, conf, CONF_lfhascr);
\r
872 gppi(sesskey, "CRImpliesLF", 0, conf, CONF_crhaslf);
\r
873 gppi(sesskey, "DisableArabicShaping", 0, conf, CONF_arabicshaping);
\r
874 gppi(sesskey, "DisableBidi", 0, conf, CONF_bidi);
\r
875 gppi(sesskey, "WinNameAlways", 1, conf, CONF_win_name_always);
\r
876 gpps(sesskey, "WinTitle", "", conf, CONF_wintitle);
\r
877 gppi(sesskey, "TermWidth", 80, conf, CONF_width);
\r
878 gppi(sesskey, "TermHeight", 24, conf, CONF_height);
\r
879 gppfont(sesskey, "Font", conf, CONF_font);
\r
880 gppi(sesskey, "FontQuality", FQ_DEFAULT, conf, CONF_font_quality);
\r
881 gppi(sesskey, "FontVTMode", VT_UNICODE, conf, CONF_vtmode);
\r
882 gppi(sesskey, "UseSystemColours", 0, conf, CONF_system_colour);
\r
883 gppi(sesskey, "TryPalette", 0, conf, CONF_try_palette);
\r
884 gppi(sesskey, "ANSIColour", 1, conf, CONF_ansi_colour);
\r
885 gppi(sesskey, "Xterm256Colour", 1, conf, CONF_xterm_256_colour);
\r
886 i = gppi_raw(sesskey, "BoldAsColour", 1); conf_set_int(conf, CONF_bold_style, i+1);
\r
888 for (i = 0; i < 22; i++) {
\r
889 static const char *const defaults[] = {
\r
890 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
\r
891 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
\r
892 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
\r
893 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
\r
894 "85,255,255", "187,187,187", "255,255,255"
\r
896 char buf[20], *buf2;
\r
898 sprintf(buf, "Colour%d", i);
\r
899 buf2 = gpps_raw(sesskey, buf, defaults[i]);
\r
900 if (sscanf(buf2, "%d,%d,%d", &c0, &c1, &c2) == 3) {
\r
901 conf_set_int_int(conf, CONF_colours, i*3+0, c0);
\r
902 conf_set_int_int(conf, CONF_colours, i*3+1, c1);
\r
903 conf_set_int_int(conf, CONF_colours, i*3+2, c2);
\r
907 gppi(sesskey, "RawCNP", 0, conf, CONF_rawcnp);
\r
908 gppi(sesskey, "PasteRTF", 0, conf, CONF_rtf_paste);
\r
909 gppi(sesskey, "MouseIsXterm", 0, conf, CONF_mouse_is_xterm);
\r
910 gppi(sesskey, "RectSelect", 0, conf, CONF_rect_select);
\r
911 gppi(sesskey, "MouseOverride", 1, conf, CONF_mouse_override);
\r
912 for (i = 0; i < 256; i += 32) {
\r
913 static const char *const defaults[] = {
\r
914 "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
915 "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
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,2",
\r
917 "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
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 "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
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
921 "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
923 char buf[20], *buf2, *p;
\r
925 sprintf(buf, "Wordness%d", i);
\r
926 buf2 = gpps_raw(sesskey, buf, defaults[i / 32]);
\r
928 for (j = i; j < i + 32; j++) {
\r
930 while (*p && *p != ',')
\r
934 conf_set_int_int(conf, CONF_wordness, j, atoi(q));
\r
939 * The empty default for LineCodePage will be converted later
\r
940 * into a plausible default for the locale.
\r
942 gpps(sesskey, "LineCodePage", "", conf, CONF_line_codepage);
\r
943 gppi(sesskey, "CJKAmbigWide", 0, conf, CONF_cjk_ambig_wide);
\r
944 gppi(sesskey, "UTF8Override", 1, conf, CONF_utf8_override);
\r
945 gpps(sesskey, "Printer", "", conf, CONF_printer);
\r
946 gppi(sesskey, "CapsLockCyr", 0, conf, CONF_xlat_capslockcyr);
\r
947 gppi(sesskey, "ScrollBar", 1, conf, CONF_scrollbar);
\r
948 gppi(sesskey, "ScrollBarFullScreen", 0, conf, CONF_scrollbar_in_fullscreen);
\r
949 gppi(sesskey, "ScrollOnKey", 0, conf, CONF_scroll_on_key);
\r
950 gppi(sesskey, "ScrollOnDisp", 1, conf, CONF_scroll_on_disp);
\r
951 gppi(sesskey, "EraseToScrollback", 1, conf, CONF_erase_to_scrollback);
\r
952 gppi(sesskey, "LockSize", 0, conf, CONF_resize_action);
\r
953 gppi(sesskey, "BCE", 1, conf, CONF_bce);
\r
954 gppi(sesskey, "BlinkText", 0, conf, CONF_blinktext);
\r
955 gppi(sesskey, "X11Forward", 0, conf, CONF_x11_forward);
\r
956 gpps(sesskey, "X11Display", "", conf, CONF_x11_display);
\r
957 gppi(sesskey, "X11AuthType", X11_MIT, conf, CONF_x11_auth);
\r
958 gppfile(sesskey, "X11AuthFile", conf, CONF_xauthfile);
\r
960 gppi(sesskey, "LocalPortAcceptAll", 0, conf, CONF_lport_acceptall);
\r
961 gppi(sesskey, "RemotePortAcceptAll", 0, conf, CONF_rport_acceptall);
\r
962 gppmap(sesskey, "PortForwardings", conf, CONF_portfwd);
\r
963 i = gppi_raw(sesskey, "BugIgnore1", 0); conf_set_int(conf, CONF_sshbug_ignore1, 2-i);
\r
964 i = gppi_raw(sesskey, "BugPlainPW1", 0); conf_set_int(conf, CONF_sshbug_plainpw1, 2-i);
\r
965 i = gppi_raw(sesskey, "BugRSA1", 0); conf_set_int(conf, CONF_sshbug_rsa1, 2-i);
\r
966 i = gppi_raw(sesskey, "BugIgnore2", 0); conf_set_int(conf, CONF_sshbug_ignore2, 2-i);
\r
969 i = gppi_raw(sesskey, "BugHMAC2", 0); conf_set_int(conf, CONF_sshbug_hmac2, 2-i);
\r
971 i = gppi_raw(sesskey, "BuggyMAC", 0);
\r
973 conf_set_int(conf, CONF_sshbug_hmac2, FORCE_ON);
\r
976 i = gppi_raw(sesskey, "BugDeriveKey2", 0); conf_set_int(conf, CONF_sshbug_derivekey2, 2-i);
\r
977 i = gppi_raw(sesskey, "BugRSAPad2", 0); conf_set_int(conf, CONF_sshbug_rsapad2, 2-i);
\r
978 i = gppi_raw(sesskey, "BugPKSessID2", 0); conf_set_int(conf, CONF_sshbug_pksessid2, 2-i);
\r
979 i = gppi_raw(sesskey, "BugRekey2", 0); conf_set_int(conf, CONF_sshbug_rekey2, 2-i);
\r
980 i = gppi_raw(sesskey, "BugMaxPkt2", 0); conf_set_int(conf, CONF_sshbug_maxpkt2, 2-i);
\r
981 i = gppi_raw(sesskey, "BugOldGex2", 0); conf_set_int(conf, CONF_sshbug_oldgex2, 2-i);
\r
982 i = gppi_raw(sesskey, "BugWinadj", 0); conf_set_int(conf, CONF_sshbug_winadj, 2-i);
\r
983 i = gppi_raw(sesskey, "BugChanReq", 0); conf_set_int(conf, CONF_sshbug_chanreq, 2-i);
\r
984 conf_set_int(conf, CONF_ssh_simple, FALSE);
\r
985 gppi(sesskey, "StampUtmp", 1, conf, CONF_stamp_utmp);
\r
986 gppi(sesskey, "LoginShell", 1, conf, CONF_login_shell);
\r
987 gppi(sesskey, "ScrollbarOnLeft", 0, conf, CONF_scrollbar_on_left);
\r
988 gppi(sesskey, "ShadowBold", 0, conf, CONF_shadowbold);
\r
989 gppfont(sesskey, "BoldFont", conf, CONF_boldfont);
\r
990 gppfont(sesskey, "WideFont", conf, CONF_widefont);
\r
991 gppfont(sesskey, "WideBoldFont", conf, CONF_wideboldfont);
\r
992 gppi(sesskey, "ShadowBoldOffset", 1, conf, CONF_shadowboldoffset);
\r
993 gpps(sesskey, "SerialLine", "", conf, CONF_serline);
\r
994 gppi(sesskey, "SerialSpeed", 9600, conf, CONF_serspeed);
\r
995 gppi(sesskey, "SerialDataBits", 8, conf, CONF_serdatabits);
\r
996 gppi(sesskey, "SerialStopHalfbits", 2, conf, CONF_serstopbits);
\r
997 gppi(sesskey, "SerialParity", SER_PAR_NONE, conf, CONF_serparity);
\r
998 gppi(sesskey, "SerialFlowControl", SER_FLOW_XONXOFF, conf, CONF_serflow);
\r
999 gpps(sesskey, "WindowClass", "", conf, CONF_winclass);
\r
1000 gppi(sesskey, "ConnectionSharing", 0, conf, CONF_ssh_connection_sharing);
\r
1001 gppi(sesskey, "ConnectionSharingUpstream", 1, conf, CONF_ssh_connection_sharing_upstream);
\r
1002 gppi(sesskey, "ConnectionSharingDownstream", 1, conf, CONF_ssh_connection_sharing_downstream);
\r
1003 gppmap(sesskey, "SSHManualHostKeys", conf, CONF_ssh_manual_hostkeys);
\r
1006 void do_defaults(char *session, Conf *conf)
\r
1008 load_settings(session, conf);
\r
1011 static int sessioncmp(const void *av, const void *bv)
\r
1013 const char *a = *(const char *const *) av;
\r
1014 const char *b = *(const char *const *) bv;
\r
1017 * Alphabetical order, except that "Default Settings" is a
\r
1018 * special case and comes first.
\r
1020 if (!strcmp(a, "Default Settings"))
\r
1021 return -1; /* a comes first */
\r
1022 if (!strcmp(b, "Default Settings"))
\r
1023 return +1; /* b comes first */
\r
1025 * FIXME: perhaps we should ignore the first & in determining
\r
1028 return strcmp(a, b); /* otherwise, compare normally */
\r
1031 void get_sesslist(struct sesslist *list, int allocate)
\r
1033 char otherbuf[2048];
\r
1034 int buflen, bufsize, i;
\r
1040 buflen = bufsize = 0;
\r
1041 list->buffer = NULL;
\r
1042 if ((handle = enum_settings_start()) != NULL) {
\r
1044 ret = enum_settings_next(handle, otherbuf, sizeof(otherbuf));
\r
1046 int len = strlen(otherbuf) + 1;
\r
1047 if (bufsize < buflen + len) {
\r
1048 bufsize = buflen + len + 2048;
\r
1049 list->buffer = sresize(list->buffer, bufsize, char);
\r
1051 strcpy(list->buffer + buflen, otherbuf);
\r
1052 buflen += strlen(list->buffer + buflen) + 1;
\r
1055 enum_settings_finish(handle);
\r
1057 list->buffer = sresize(list->buffer, buflen + 1, char);
\r
1058 list->buffer[buflen] = '\0';
\r
1061 * Now set up the list of sessions. Note that "Default
\r
1062 * Settings" must always be claimed to exist, even if it
\r
1067 list->nsessions = 1; /* "Default Settings" counts as one */
\r
1069 if (strcmp(p, "Default Settings"))
\r
1070 list->nsessions++;
\r
1076 list->sessions = snewn(list->nsessions + 1, char *);
\r
1077 list->sessions[0] = "Default Settings";
\r
1081 if (strcmp(p, "Default Settings"))
\r
1082 list->sessions[i++] = p;
\r
1088 qsort(list->sessions, i, sizeof(char *), sessioncmp);
\r
1090 sfree(list->buffer);
\r
1091 sfree(list->sessions);
\r
1092 list->buffer = NULL;
\r
1093 list->sessions = NULL;
\r