From a9422f39e34f55d1925d1ebef35ace1a0f1c2f6a Mon Sep 17 00:00:00 2001 From: simon Date: Fri, 6 Oct 2000 13:21:36 +0000 Subject: [PATCH] Create settings.c and move the load/save session code out of windlg.c into it. Allows plink and pscp to no longer link with windlg.c, meaning they lose some of the sillier stub functions and also can provide a console-based form of verify_ssh_host_key(). git-svn-id: svn://svn.tartarus.org/sgt/putty@683 cda61777-01e9-0310-a592-d414129be87e --- Makefile | 9 +- plink.c | 79 +++++++++++++-- putty.h | 10 +- scp.c | 78 ++++++++++++-- settings.c | 336 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ windlg.c | 335 +----------------------------------------------------------- window.c | 4 +- 7 files changed, 498 insertions(+), 353 deletions(-) create mode 100644 settings.c diff --git a/Makefile b/Makefile index 5f9973f4..731cf5df 100644 --- a/Makefile +++ b/Makefile @@ -60,11 +60,11 @@ POBJS = be_all.$(OBJ) ##-- objects puttytel TOBJS = be_nossh.$(OBJ) ##-- objects plink -PLOBJS = plink.$(OBJ) windlg.$(OBJ) +PLOBJS = plink.$(OBJ) ##-- objects pscp -SOBJS = scp.$(OBJ) windlg.$(OBJ) be_none.$(OBJ) +SOBJS = scp.$(OBJ) be_none.$(OBJ) ##-- objects putty puttytel pscp plink -MOBJS = misc.$(OBJ) version.$(OBJ) winstore.$(OBJ) +MOBJS = misc.$(OBJ) version.$(OBJ) winstore.$(OBJ) settings.$(OBJ) ##-- objects putty pscp plink OBJS1 = sshcrc.$(OBJ) sshdes.$(OBJ) sshmd5.$(OBJ) sshrsa.$(OBJ) sshrand.$(OBJ) OBJS2 = sshsha.$(OBJ) sshblowf.$(OBJ) noise.$(OBJ) sshdh.$(OBJ) sshdss.$(OBJ) @@ -178,7 +178,8 @@ plink.rsp: makefile ##-- dependencies window.$(OBJ): window.c putty.h win_res.h storage.h -windlg.$(OBJ): windlg.c putty.h ssh.h win_res.h storage.h +windlg.$(OBJ): windlg.c putty.h ssh.h win_res.h +settings.$(OBJ): settings.c putty.h storage.h winstore.$(OBJ): winstore.c putty.h storage.h terminal.$(OBJ): terminal.c putty.h sizetip.$(OBJ): sizetip.c putty.h diff --git a/plink.c b/plink.c index 62394c03..1d68e978 100644 --- a/plink.c +++ b/plink.c @@ -11,6 +11,7 @@ #define PUTTY_DO_GLOBALS /* actually _define_ globals */ #include "putty.h" +#include "storage.h" void fatalbox (char *p, ...) { va_list ap; @@ -35,11 +36,75 @@ void connection_fatal (char *p, ...) { static char *password = NULL; -/* - * Stubs for linking with other modules. - */ -void write_clip (void *data, int len, int must_deselect) { } -void term_deselect(void) { } +void logevent(char *string) { } + +void verify_ssh_host_key(char *host, int port, char *keytype, + char *keystr, char *fingerprint) { + int ret; + + static const char absentmsg[] = + "The server's host key is not cached in the registry. You\n" + "have no guarantee that the server is the computer you\n" + "think it is.\n" + "The server's key fingerprint is:\n" + "%s\n" + "If you trust this host, enter \"y\" to add the key to\n" + "PuTTY's cache and carry on connecting.\n" + "If you do not trust this host, enter \"n\" to abandon the\n" + "connection.\n" + "Continue connecting? (y/n) "; + + static const char wrongmsg[] = + "WARNING - POTENTIAL SECURITY BREACH!\n" + "The server's host key does not match the one PuTTY has\n" + "cached in the registry. This means that either the\n" + "server administrator has changed the host key, or you\n" + "have actually connected to another computer pretending\n" + "to be the server.\n" + "The new key fingerprint is:\n" + "%s\n" + "If you were expecting this change and trust the new key,\n" + "enter \"y\" to update PuTTY's cache and continue connecting.\n" + "If you want to carry on connecting but without updating\n" + "the cache, enter \"n\".\n" + "If you want to abandon the connection completely, press\n" + "Return to cancel. Pressing Return is the ONLY guaranteed\n" + "safe choice.\n" + "Update cached key? (y/n, Return cancels connection) "; + + static const char abandoned[] = "Connection abandoned.\n"; + + char line[32]; + + /* + * Verify the key against the registry. + */ + ret = verify_host_key(host, port, keytype, keystr); + + if (ret == 0) /* success - key matched OK */ + return; + if (ret == 2) { /* key was different */ + fprintf(stderr, wrongmsg, fingerprint); + if (fgets(line, sizeof(line), stdin) && + line[0] != '\0' && line[0] != '\n') { + if (line[0] == 'y' || line[0] == 'Y') + store_host_key(host, port, keytype, keystr); + } else { + fprintf(stderr, abandoned); + exit(0); + } + } + if (ret == 1) { /* key was absent */ + fprintf(stderr, absentmsg, fingerprint); + if (fgets(line, sizeof(line), stdin) && + (line[0] == 'y' || line[0] == 'Y')) + store_host_key(host, port, keytype, keystr); + else { + fprintf(stderr, abandoned); + exit(0); + } + } +} HANDLE outhandle; DWORD orig_console_mode; @@ -162,7 +227,7 @@ int main(int argc, char **argv) { /* * Process the command line. */ - do_defaults(NULL); + do_defaults(NULL, &cfg); default_protocol = cfg.protocol; default_port = cfg.port; { @@ -270,7 +335,7 @@ int main(int argc, char **argv) { /* * One string. */ - do_defaults (p); + do_defaults (p, &cfg); if (cfg.host[0] == '\0') { /* No settings for this host; use defaults */ strncpy(cfg.host, p, sizeof(cfg.host)-1); diff --git a/putty.h b/putty.h index 2f510ff4..48e9d2e5 100644 --- a/putty.h +++ b/putty.h @@ -268,19 +268,25 @@ void random_destroy_seed(void); */ int do_config (void); int do_reconfig (HWND); -void do_defaults (char *); +void do_defaults (char *, Config *); void logevent (char *); void showeventlog (HWND); void showabout (HWND); void verify_ssh_host_key(char *host, int port, char *keytype, char *keystr, char *fingerprint); -void get_sesslist(int allocate); void registry_cleanup(void); GLOBAL int nsessions; GLOBAL char **sessions; /* + * Exports from settings.c. + */ +void save_settings (char *section, int do_host, Config *cfg); +void load_settings (char *section, int do_host, Config *cfg); +void get_sesslist(int allocate); + +/* * Exports from terminal.c. */ diff --git a/scp.c b/scp.c index 53db80a5..36863cfa 100644 --- a/scp.c +++ b/scp.c @@ -26,6 +26,7 @@ #define PUTTY_DO_GLOBALS #include "putty.h" +#include "storage.h" #define TIME_POSIX_TO_WIN(t, ft) (*(LONGLONG*)&(ft) = \ ((LONGLONG) (t) + (LONGLONG) 11644473600) * (LONGLONG) 10000000) @@ -72,13 +73,76 @@ static void send_char_msg(unsigned int msg_id, char c); static void send_str_msg(unsigned int msg_id, char *str); static void gui_update_stats(char *name, unsigned long size, int percentage, time_t elapsed); -/* - * These functions are needed to link with other modules, but - * (should) never get called. - */ void begin_session(void) { } -void write_clip (void *data, int len, int must_deselect) { } -void term_deselect(void) { } +void logevent(char *string) { } + +void verify_ssh_host_key(char *host, int port, char *keytype, + char *keystr, char *fingerprint) { + int ret; + + static const char absentmsg[] = + "The server's host key is not cached in the registry. You\n" + "have no guarantee that the server is the computer you\n" + "think it is.\n" + "The server's key fingerprint is:\n" + "%s\n" + "If you trust this host, enter \"y\" to add the key to\n" + "PuTTY's cache and carry on connecting.\n" + "If you do not trust this host, enter \"n\" to abandon the\n" + "connection.\n" + "Continue connecting? (y/n) "; + + static const char wrongmsg[] = + "WARNING - POTENTIAL SECURITY BREACH!\n" + "The server's host key does not match the one PuTTY has\n" + "cached in the registry. This means that either the\n" + "server administrator has changed the host key, or you\n" + "have actually connected to another computer pretending\n" + "to be the server.\n" + "The new key fingerprint is:\n" + "%s\n" + "If you were expecting this change and trust the new key,\n" + "enter Yes to update PuTTY's cache and continue connecting.\n" + "If you want to carry on connecting but without updating\n" + "the cache, enter No.\n" + "If you want to abandon the connection completely, press\n" + "Return to cancel. Pressing Return is the ONLY guaranteed\n" + "safe choice.\n" + "Update cached key? (y/n, Return cancels connection) "; + + static const char abandoned[] = "Connection abandoned.\n"; + + char line[32]; + + /* + * Verify the key against the registry. + */ + ret = verify_host_key(host, port, keytype, keystr); + + if (ret == 0) /* success - key matched OK */ + return; + if (ret == 2) { /* key was different */ + fprintf(stderr, wrongmsg, fingerprint); + if (fgets(line, sizeof(line), stdin) && + line[0] != '\0' && line[0] != '\n') { + if (line[0] == 'y' || line[0] == 'Y') + store_host_key(host, port, keytype, keystr); + } else { + fprintf(stderr, abandoned); + exit(0); + } + } + if (ret == 1) { /* key was absent */ + fprintf(stderr, absentmsg, fingerprint); + if (fgets(line, sizeof(line), stdin) && + (line[0] == 'y' || line[0] == 'Y')) + store_host_key(host, port, keytype, keystr); + else { + fprintf(stderr, abandoned); + exit(0); + } + } +} /* GUI Adaptation - Sept 2000 */ static void send_msg(HWND h, UINT message, WPARAM wParam) @@ -368,7 +432,7 @@ static void do_cmd(char *host, char *user, char *cmd) bump("Empty host name"); /* Try to load settings for this host */ - do_defaults(host); + do_defaults(host, &cfg); if (cfg.host[0] == '\0') { /* No settings for this host; use defaults */ strncpy(cfg.host, host, sizeof(cfg.host)-1); diff --git a/settings.c b/settings.c new file mode 100644 index 00000000..6204227c --- /dev/null +++ b/settings.c @@ -0,0 +1,336 @@ +/* + * settings.c: read and write saved sessions. + */ + +#include +#include +#include "putty.h" +#include "storage.h" + +static void gpps(void *handle, char *name, char *def, char *val, int len) { + if (!read_setting_s(handle, name, val, len)) { + strncpy(val, def, len); + val[len-1] = '\0'; + } +} + +static void gppi(void *handle, char *name, int def, int *i) { + *i = read_setting_i(handle, name, def); +} + +void save_settings (char *section, int do_host, Config *cfg) { + int i; + char *p; + void *sesskey; + + sesskey = open_settings_w(section); + if (!sesskey) + return; + + write_setting_i (sesskey, "Present", 1); + if (do_host) { + write_setting_s (sesskey, "HostName", cfg->host); + write_setting_i (sesskey, "PortNumber", cfg->port); + p = "raw"; + for (i = 0; backends[i].name != NULL; i++) + if (backends[i].protocol == cfg->protocol) { + p = backends[i].name; + break; + } + write_setting_s (sesskey, "Protocol", p); + } + write_setting_i (sesskey, "CloseOnExit", !!cfg->close_on_exit); + write_setting_i (sesskey, "WarnOnClose", !!cfg->warn_on_close); + write_setting_s (sesskey, "TerminalType", cfg->termtype); + write_setting_s (sesskey, "TerminalSpeed", cfg->termspeed); + { + char buf[2*sizeof(cfg->environmt)], *p, *q; + p = buf; + q = cfg->environmt; + while (*q) { + while (*q) { + int c = *q++; + if (c == '=' || c == ',' || c == '\\') + *p++ = '\\'; + if (c == '\t') + c = '='; + *p++ = c; + } + *p++ = ','; + q++; + } + *p = '\0'; + write_setting_s (sesskey, "Environment", buf); + } + write_setting_s (sesskey, "UserName", cfg->username); + write_setting_i (sesskey, "NoPTY", cfg->nopty); + write_setting_i (sesskey, "AgentFwd", cfg->agentfwd); + write_setting_s (sesskey, "RemoteCmd", cfg->remote_cmd); + write_setting_s (sesskey, "Cipher", cfg->cipher == CIPHER_BLOWFISH ? "blowfish" : + cfg->cipher == CIPHER_DES ? "des" : "3des"); + write_setting_i (sesskey, "AuthTIS", cfg->try_tis_auth); + write_setting_i (sesskey, "SshProt", cfg->sshprot); + write_setting_s (sesskey, "PublicKeyFile", cfg->keyfile); + write_setting_s (sesskey, "RemoteCommand", cfg->remote_cmd); + write_setting_i (sesskey, "RFCEnviron", cfg->rfc_environ); + write_setting_i (sesskey, "BackspaceIsDelete", cfg->bksp_is_delete); + write_setting_i (sesskey, "RXVTHomeEnd", cfg->rxvt_homeend); + write_setting_i (sesskey, "LinuxFunctionKeys", cfg->funky_type); + write_setting_i (sesskey, "ApplicationCursorKeys", cfg->app_cursor); + write_setting_i (sesskey, "ApplicationKeypad", cfg->app_keypad); + write_setting_i (sesskey, "NetHackKeypad", cfg->nethack_keypad); + write_setting_i (sesskey, "AltF4", cfg->alt_f4); + write_setting_i (sesskey, "AltSpace", cfg->alt_space); + write_setting_i (sesskey, "LdiscTerm", cfg->ldisc_term); + write_setting_i (sesskey, "BlinkCur", cfg->blink_cur); + write_setting_i (sesskey, "Beep", cfg->beep); + write_setting_i (sesskey, "ScrollbackLines", cfg->savelines); + write_setting_i (sesskey, "DECOriginMode", cfg->dec_om); + write_setting_i (sesskey, "AutoWrapMode", cfg->wrap_mode); + write_setting_i (sesskey, "LFImpliesCR", cfg->lfhascr); + write_setting_i (sesskey, "WinNameAlways", cfg->win_name_always); + write_setting_s (sesskey, "WinTitle", cfg->wintitle); + write_setting_i (sesskey, "TermWidth", cfg->width); + write_setting_i (sesskey, "TermHeight", cfg->height); + write_setting_s (sesskey, "Font", cfg->font); + write_setting_i (sesskey, "FontIsBold", cfg->fontisbold); + write_setting_i (sesskey, "FontCharSet", cfg->fontcharset); + write_setting_i (sesskey, "FontHeight", cfg->fontheight); + write_setting_i (sesskey, "FontVTMode", cfg->vtmode); + write_setting_i (sesskey, "TryPalette", cfg->try_palette); + write_setting_i (sesskey, "BoldAsColour", cfg->bold_colour); + for (i=0; i<22; i++) { + char buf[20], buf2[30]; + sprintf(buf, "Colour%d", i); + sprintf(buf2, "%d,%d,%d", cfg->colours[i][0], + cfg->colours[i][1], cfg->colours[i][2]); + write_setting_s (sesskey, buf, buf2); + } + write_setting_i (sesskey, "MouseIsXterm", cfg->mouse_is_xterm); + for (i=0; i<256; i+=32) { + char buf[20], buf2[256]; + int j; + sprintf(buf, "Wordness%d", i); + *buf2 = '\0'; + for (j=i; jwordness[j]); + } + write_setting_s (sesskey, buf, buf2); + } + write_setting_i (sesskey, "KoiWinXlat", cfg->xlat_enablekoiwin); + write_setting_i (sesskey, "88592Xlat", cfg->xlat_88592w1250); + write_setting_i (sesskey, "CapsLockCyr", cfg->xlat_capslockcyr); + write_setting_i (sesskey, "ScrollBar", cfg->scrollbar); + write_setting_i (sesskey, "ScrollOnKey", cfg->scroll_on_key); + write_setting_i (sesskey, "LockSize", cfg->locksize); + write_setting_i (sesskey, "BCE", cfg->bce); + write_setting_i (sesskey, "BlinkText", cfg->blinktext); + + close_settings_w(sesskey); +} + +void load_settings (char *section, int do_host, Config *cfg) { + int i; + char prot[10]; + void *sesskey; + + sesskey = open_settings_r(section); + + gpps (sesskey, "HostName", "", cfg->host, sizeof(cfg->host)); + gppi (sesskey, "PortNumber", default_port, &cfg->port); + + gpps (sesskey, "Protocol", "default", prot, 10); + cfg->protocol = default_protocol; + for (i = 0; backends[i].name != NULL; i++) + if (!strcmp(prot, backends[i].name)) { + cfg->protocol = backends[i].protocol; + break; + } + + gppi (sesskey, "CloseOnExit", 1, &cfg->close_on_exit); + gppi (sesskey, "WarnOnClose", 1, &cfg->warn_on_close); + gpps (sesskey, "TerminalType", "xterm", cfg->termtype, + sizeof(cfg->termtype)); + gpps (sesskey, "TerminalSpeed", "38400,38400", cfg->termspeed, + sizeof(cfg->termspeed)); + { + char buf[2*sizeof(cfg->environmt)], *p, *q; + gpps (sesskey, "Environment", "", buf, sizeof(buf)); + p = buf; + q = cfg->environmt; + while (*p) { + while (*p && *p != ',') { + int c = *p++; + if (c == '=') + c = '\t'; + if (c == '\\') + c = *p++; + *q++ = c; + } + if (*p == ',') p++; + *q++ = '\0'; + } + *q = '\0'; + } + gpps (sesskey, "UserName", "", cfg->username, sizeof(cfg->username)); + gppi (sesskey, "NoPTY", 0, &cfg->nopty); + gppi (sesskey, "AgentFwd", 0, &cfg->agentfwd); + gpps (sesskey, "RemoteCmd", "", cfg->remote_cmd, sizeof(cfg->remote_cmd)); + { + char cipher[10]; + gpps (sesskey, "Cipher", "3des", cipher, 10); + if (!strcmp(cipher, "blowfish")) + cfg->cipher = CIPHER_BLOWFISH; + else if (!strcmp(cipher, "des")) + cfg->cipher = CIPHER_DES; + else + cfg->cipher = CIPHER_3DES; + } + gppi (sesskey, "SshProt", 1, &cfg->sshprot); + gppi (sesskey, "AuthTIS", 0, &cfg->try_tis_auth); + gpps (sesskey, "PublicKeyFile", "", cfg->keyfile, sizeof(cfg->keyfile)); + gpps (sesskey, "RemoteCommand", "", cfg->remote_cmd, + sizeof(cfg->remote_cmd)); + gppi (sesskey, "RFCEnviron", 0, &cfg->rfc_environ); + gppi (sesskey, "BackspaceIsDelete", 1, &cfg->bksp_is_delete); + gppi (sesskey, "RXVTHomeEnd", 0, &cfg->rxvt_homeend); + gppi (sesskey, "LinuxFunctionKeys", 0, &cfg->funky_type); + gppi (sesskey, "ApplicationCursorKeys", 0, &cfg->app_cursor); + gppi (sesskey, "ApplicationKeypad", 0, &cfg->app_keypad); + gppi (sesskey, "NetHackKeypad", 0, &cfg->nethack_keypad); + gppi (sesskey, "AltF4", 1, &cfg->alt_f4); + gppi (sesskey, "AltSpace", 0, &cfg->alt_space); + gppi (sesskey, "LdiscTerm", 0, &cfg->ldisc_term); + gppi (sesskey, "BlinkCur", 0, &cfg->blink_cur); + gppi (sesskey, "Beep", 1, &cfg->beep); + gppi (sesskey, "ScrollbackLines", 200, &cfg->savelines); + gppi (sesskey, "DECOriginMode", 0, &cfg->dec_om); + gppi (sesskey, "AutoWrapMode", 1, &cfg->wrap_mode); + gppi (sesskey, "LFImpliesCR", 0, &cfg->lfhascr); + gppi (sesskey, "WinNameAlways", 0, &cfg->win_name_always); + gpps (sesskey, "WinTitle", "", cfg->wintitle, sizeof(cfg->wintitle)); + gppi (sesskey, "TermWidth", 80, &cfg->width); + gppi (sesskey, "TermHeight", 24, &cfg->height); + gpps (sesskey, "Font", "Courier", cfg->font, sizeof(cfg->font)); + gppi (sesskey, "FontIsBold", 0, &cfg->fontisbold); + gppi (sesskey, "FontCharSet", ANSI_CHARSET, &cfg->fontcharset); + gppi (sesskey, "FontHeight", 10, &cfg->fontheight); + gppi (sesskey, "FontVTMode", VT_OEMANSI, (int *)&cfg->vtmode); + gppi (sesskey, "TryPalette", 0, &cfg->try_palette); + gppi (sesskey, "BoldAsColour", 1, &cfg->bold_colour); + for (i=0; i<22; i++) { + static char *defaults[] = { + "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0", + "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85", + "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187", + "85,85,255", "187,0,187", "255,85,255", "0,187,187", + "85,255,255", "187,187,187", "255,255,255" + }; + char buf[20], buf2[30]; + int c0, c1, c2; + sprintf(buf, "Colour%d", i); + gpps (sesskey, buf, defaults[i], buf2, sizeof(buf2)); + if(sscanf(buf2, "%d,%d,%d", &c0, &c1, &c2) == 3) { + cfg->colours[i][0] = c0; + cfg->colours[i][1] = c1; + cfg->colours[i][2] = c2; + } + } + gppi (sesskey, "MouseIsXterm", 0, &cfg->mouse_is_xterm); + for (i=0; i<256; i+=32) { + static char *defaults[] = { + "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", + "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", + "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", + "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", + "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", + "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", + "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", + "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" + }; + char buf[20], buf2[256], *p; + int j; + sprintf(buf, "Wordness%d", i); + gpps (sesskey, buf, defaults[i/32], buf2, sizeof(buf2)); + p = buf2; + for (j=i; jwordness[j] = atoi(q); + } + } + gppi (sesskey, "KoiWinXlat", 0, &cfg->xlat_enablekoiwin); + gppi (sesskey, "88592Xlat", 0, &cfg->xlat_88592w1250); + gppi (sesskey, "CapsLockCyr", 0, &cfg->xlat_capslockcyr); + gppi (sesskey, "ScrollBar", 1, &cfg->scrollbar); + gppi (sesskey, "ScrollOnKey", 0, &cfg->scroll_on_key); + gppi (sesskey, "LockSize", 0, &cfg->locksize); + gppi (sesskey, "BCE", 0, &cfg->bce); + gppi (sesskey, "BlinkText", 0, &cfg->blinktext); + + close_settings_r(sesskey); +} + +void do_defaults (char *session, Config *cfg) { + if (session) + load_settings (session, TRUE, cfg); + else + load_settings ("Default Settings", FALSE, cfg); +} + +void get_sesslist(int allocate) { + static char otherbuf[2048]; + static char *buffer; + int buflen, bufsize, i; + char *p, *ret; + void *handle; + + if (allocate) { + + if ((handle = enum_settings_start()) == NULL) + return; + + buflen = bufsize = 0; + buffer = NULL; + do { + ret = enum_settings_next(handle, otherbuf, sizeof(otherbuf)); + if (ret) { + int len = strlen(otherbuf)+1; + if (bufsize < buflen+len) { + bufsize = buflen + len + 2048; + buffer = srealloc(buffer, bufsize); + } + strcpy(buffer+buflen, otherbuf); + buflen += strlen(buffer+buflen)+1; + } + } while (ret); + enum_settings_finish(handle); + buffer = srealloc(buffer, buflen+1); + buffer[buflen] = '\0'; + + p = buffer; + nsessions = 1; /* "Default Settings" counts as one */ + while (*p) { + if (strcmp(p, "Default Settings")) + nsessions++; + while (*p) p++; + p++; + } + + sessions = smalloc(nsessions * sizeof(char *)); + sessions[0] = "Default Settings"; + p = buffer; + i = 1; + while (*p) { + if (strcmp(p, "Default Settings")) + sessions[i++] = p; + while (*p) p++; + p++; + } + } else { + sfree (buffer); + sfree (sessions); + } +} diff --git a/windlg.c b/windlg.c index faa71994..050996b9 100644 --- a/windlg.c +++ b/windlg.c @@ -25,279 +25,13 @@ static int nevents = 0, negsize = 0; static HWND logbox = NULL, abtbox = NULL; -static void gpps(void *handle, char *name, char *def, char *val, int len) { - if (!read_setting_s(handle, name, val, len)) { - strncpy(val, def, len); - val[len-1] = '\0'; - } -} - -static void gppi(void *handle, char *name, int def, int *i) { - *i = read_setting_i(handle, name, def); -} - static HINSTANCE hinst; static int readytogo; -static void save_settings (char *section, int do_host) { - int i; - char *p; - void *sesskey; - - sesskey = open_settings_w(section); - if (!sesskey) - return; - - write_setting_i (sesskey, "Present", 1); - if (do_host) { - write_setting_s (sesskey, "HostName", cfg.host); - write_setting_i (sesskey, "PortNumber", cfg.port); - p = "raw"; - for (i = 0; backends[i].name != NULL; i++) - if (backends[i].protocol == cfg.protocol) { - p = backends[i].name; - break; - } - write_setting_s (sesskey, "Protocol", p); - } - write_setting_i (sesskey, "CloseOnExit", !!cfg.close_on_exit); - write_setting_i (sesskey, "WarnOnClose", !!cfg.warn_on_close); - write_setting_s (sesskey, "TerminalType", cfg.termtype); - write_setting_s (sesskey, "TerminalSpeed", cfg.termspeed); - { - char buf[2*sizeof(cfg.environmt)], *p, *q; - p = buf; - q = cfg.environmt; - while (*q) { - while (*q) { - int c = *q++; - if (c == '=' || c == ',' || c == '\\') - *p++ = '\\'; - if (c == '\t') - c = '='; - *p++ = c; - } - *p++ = ','; - q++; - } - *p = '\0'; - write_setting_s (sesskey, "Environment", buf); - } - write_setting_s (sesskey, "UserName", cfg.username); - write_setting_i (sesskey, "NoPTY", cfg.nopty); - write_setting_i (sesskey, "AgentFwd", cfg.agentfwd); - write_setting_s (sesskey, "RemoteCmd", cfg.remote_cmd); - write_setting_s (sesskey, "Cipher", cfg.cipher == CIPHER_BLOWFISH ? "blowfish" : - cfg.cipher == CIPHER_DES ? "des" : "3des"); - write_setting_i (sesskey, "AuthTIS", cfg.try_tis_auth); - write_setting_i (sesskey, "SshProt", cfg.sshprot); - write_setting_s (sesskey, "PublicKeyFile", cfg.keyfile); - write_setting_s (sesskey, "RemoteCommand", cfg.remote_cmd); - write_setting_i (sesskey, "RFCEnviron", cfg.rfc_environ); - write_setting_i (sesskey, "BackspaceIsDelete", cfg.bksp_is_delete); - write_setting_i (sesskey, "RXVTHomeEnd", cfg.rxvt_homeend); - write_setting_i (sesskey, "LinuxFunctionKeys", cfg.funky_type); - write_setting_i (sesskey, "ApplicationCursorKeys", cfg.app_cursor); - write_setting_i (sesskey, "ApplicationKeypad", cfg.app_keypad); - write_setting_i (sesskey, "NetHackKeypad", cfg.nethack_keypad); - write_setting_i (sesskey, "AltF4", cfg.alt_f4); - write_setting_i (sesskey, "AltSpace", cfg.alt_space); - write_setting_i (sesskey, "LdiscTerm", cfg.ldisc_term); - write_setting_i (sesskey, "BlinkCur", cfg.blink_cur); - write_setting_i (sesskey, "Beep", cfg.beep); - write_setting_i (sesskey, "ScrollbackLines", cfg.savelines); - write_setting_i (sesskey, "DECOriginMode", cfg.dec_om); - write_setting_i (sesskey, "AutoWrapMode", cfg.wrap_mode); - write_setting_i (sesskey, "LFImpliesCR", cfg.lfhascr); - write_setting_i (sesskey, "WinNameAlways", cfg.win_name_always); - write_setting_s (sesskey, "WinTitle", cfg.wintitle); - write_setting_i (sesskey, "TermWidth", cfg.width); - write_setting_i (sesskey, "TermHeight", cfg.height); - write_setting_s (sesskey, "Font", cfg.font); - write_setting_i (sesskey, "FontIsBold", cfg.fontisbold); - write_setting_i (sesskey, "FontCharSet", cfg.fontcharset); - write_setting_i (sesskey, "FontHeight", cfg.fontheight); - write_setting_i (sesskey, "FontVTMode", cfg.vtmode); - write_setting_i (sesskey, "TryPalette", cfg.try_palette); - write_setting_i (sesskey, "BoldAsColour", cfg.bold_colour); - for (i=0; i<22; i++) { - char buf[20], buf2[30]; - sprintf(buf, "Colour%d", i); - sprintf(buf2, "%d,%d,%d", cfg.colours[i][0], - cfg.colours[i][1], cfg.colours[i][2]); - write_setting_s (sesskey, buf, buf2); - } - write_setting_i (sesskey, "MouseIsXterm", cfg.mouse_is_xterm); - for (i=0; i<256; i+=32) { - char buf[20], buf2[256]; - int j; - sprintf(buf, "Wordness%d", i); - *buf2 = '\0'; - for (j=i; j= negsize) { negsize += 64; diff --git a/window.c b/window.c index 0ab58cfd..de431d62 100644 --- a/window.c +++ b/window.c @@ -132,7 +132,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { default_protocol = DEFAULT_PROTOCOL; default_port = DEFAULT_PORT; - do_defaults(NULL); + do_defaults(NULL, &cfg); p = cmdline; while (*p && isspace(*p)) p++; @@ -190,7 +190,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { * An initial @ means to activate a saved session. */ if (*p == '@') { - do_defaults (p+1); + do_defaults (p+1, &cfg); if (!*cfg.host && !do_config()) { WSACleanup(); return 0; -- 2.11.0