Implement Zlib compression, in both SSH1 and SSH2.
[u/mdw/putty] / settings.c
CommitLineData
a9422f39 1/*
2 * settings.c: read and write saved sessions.
3 */
4
5#include <windows.h>
6#include <stdio.h>
49bad831 7#include <stdlib.h>
a9422f39 8#include "putty.h"
9#include "storage.h"
10
11static void gpps(void *handle, char *name, char *def, char *val, int len) {
12 if (!read_setting_s(handle, name, val, len)) {
13 strncpy(val, def, len);
14 val[len-1] = '\0';
15 }
16}
17
18static void gppi(void *handle, char *name, int def, int *i) {
19 *i = read_setting_i(handle, name, def);
20}
21
22void save_settings (char *section, int do_host, Config *cfg) {
23 int i;
24 char *p;
25 void *sesskey;
26
27 sesskey = open_settings_w(section);
28 if (!sesskey)
29 return;
30
31 write_setting_i (sesskey, "Present", 1);
32 if (do_host) {
33 write_setting_s (sesskey, "HostName", cfg->host);
34 write_setting_i (sesskey, "PortNumber", cfg->port);
35 p = "raw";
36 for (i = 0; backends[i].name != NULL; i++)
37 if (backends[i].protocol == cfg->protocol) {
38 p = backends[i].name;
39 break;
40 }
41 write_setting_s (sesskey, "Protocol", p);
42 }
43 write_setting_i (sesskey, "CloseOnExit", !!cfg->close_on_exit);
44 write_setting_i (sesskey, "WarnOnClose", !!cfg->warn_on_close);
ec55b220 45 write_setting_i (sesskey, "PingInterval", cfg->ping_interval);
a9422f39 46 write_setting_s (sesskey, "TerminalType", cfg->termtype);
47 write_setting_s (sesskey, "TerminalSpeed", cfg->termspeed);
48 {
49 char buf[2*sizeof(cfg->environmt)], *p, *q;
50 p = buf;
51 q = cfg->environmt;
52 while (*q) {
53 while (*q) {
54 int c = *q++;
55 if (c == '=' || c == ',' || c == '\\')
56 *p++ = '\\';
57 if (c == '\t')
58 c = '=';
59 *p++ = c;
60 }
61 *p++ = ',';
62 q++;
63 }
64 *p = '\0';
65 write_setting_s (sesskey, "Environment", buf);
66 }
67 write_setting_s (sesskey, "UserName", cfg->username);
68 write_setting_i (sesskey, "NoPTY", cfg->nopty);
4ba9b64b 69 write_setting_i (sesskey, "Compression", cfg->compression);
a9422f39 70 write_setting_i (sesskey, "AgentFwd", cfg->agentfwd);
71 write_setting_s (sesskey, "RemoteCmd", cfg->remote_cmd);
72 write_setting_s (sesskey, "Cipher", cfg->cipher == CIPHER_BLOWFISH ? "blowfish" :
73 cfg->cipher == CIPHER_DES ? "des" : "3des");
74 write_setting_i (sesskey, "AuthTIS", cfg->try_tis_auth);
75 write_setting_i (sesskey, "SshProt", cfg->sshprot);
7591b9ff 76 write_setting_i (sesskey, "BuggyMAC", cfg->buggymac);
a9422f39 77 write_setting_s (sesskey, "PublicKeyFile", cfg->keyfile);
78 write_setting_s (sesskey, "RemoteCommand", cfg->remote_cmd);
79 write_setting_i (sesskey, "RFCEnviron", cfg->rfc_environ);
80 write_setting_i (sesskey, "BackspaceIsDelete", cfg->bksp_is_delete);
81 write_setting_i (sesskey, "RXVTHomeEnd", cfg->rxvt_homeend);
82 write_setting_i (sesskey, "LinuxFunctionKeys", cfg->funky_type);
b00f8b34 83 write_setting_i (sesskey, "NoApplicationKeys", cfg->no_applic_k);
84 write_setting_i (sesskey, "NoApplicationCursors", cfg->no_applic_c);
a9422f39 85 write_setting_i (sesskey, "ApplicationCursorKeys", cfg->app_cursor);
86 write_setting_i (sesskey, "ApplicationKeypad", cfg->app_keypad);
87 write_setting_i (sesskey, "NetHackKeypad", cfg->nethack_keypad);
88 write_setting_i (sesskey, "AltF4", cfg->alt_f4);
89 write_setting_i (sesskey, "AltSpace", cfg->alt_space);
a094ae43 90 write_setting_i (sesskey, "AltOnly", cfg->alt_only);
91 write_setting_i (sesskey, "ComposeKey", cfg->compose_key);
a9422f39 92 write_setting_i (sesskey, "LdiscTerm", cfg->ldisc_term);
e95edc00 93 write_setting_i (sesskey, "AlwaysOnTop", cfg->alwaysontop);
a9422f39 94 write_setting_i (sesskey, "BlinkCur", cfg->blink_cur);
95 write_setting_i (sesskey, "Beep", cfg->beep);
96 write_setting_i (sesskey, "ScrollbackLines", cfg->savelines);
97 write_setting_i (sesskey, "DECOriginMode", cfg->dec_om);
98 write_setting_i (sesskey, "AutoWrapMode", cfg->wrap_mode);
99 write_setting_i (sesskey, "LFImpliesCR", cfg->lfhascr);
100 write_setting_i (sesskey, "WinNameAlways", cfg->win_name_always);
101 write_setting_s (sesskey, "WinTitle", cfg->wintitle);
102 write_setting_i (sesskey, "TermWidth", cfg->width);
103 write_setting_i (sesskey, "TermHeight", cfg->height);
104 write_setting_s (sesskey, "Font", cfg->font);
105 write_setting_i (sesskey, "FontIsBold", cfg->fontisbold);
106 write_setting_i (sesskey, "FontCharSet", cfg->fontcharset);
107 write_setting_i (sesskey, "FontHeight", cfg->fontheight);
108 write_setting_i (sesskey, "FontVTMode", cfg->vtmode);
109 write_setting_i (sesskey, "TryPalette", cfg->try_palette);
110 write_setting_i (sesskey, "BoldAsColour", cfg->bold_colour);
111 for (i=0; i<22; i++) {
112 char buf[20], buf2[30];
113 sprintf(buf, "Colour%d", i);
114 sprintf(buf2, "%d,%d,%d", cfg->colours[i][0],
115 cfg->colours[i][1], cfg->colours[i][2]);
116 write_setting_s (sesskey, buf, buf2);
117 }
118 write_setting_i (sesskey, "MouseIsXterm", cfg->mouse_is_xterm);
119 for (i=0; i<256; i+=32) {
120 char buf[20], buf2[256];
121 int j;
122 sprintf(buf, "Wordness%d", i);
123 *buf2 = '\0';
124 for (j=i; j<i+32; j++) {
125 sprintf(buf2+strlen(buf2), "%s%d",
126 (*buf2 ? "," : ""), cfg->wordness[j]);
127 }
128 write_setting_s (sesskey, buf, buf2);
129 }
130 write_setting_i (sesskey, "KoiWinXlat", cfg->xlat_enablekoiwin);
131 write_setting_i (sesskey, "88592Xlat", cfg->xlat_88592w1250);
b0faa571 132 write_setting_i (sesskey, "88592-CP852", cfg->xlat_88592cp852);
a9422f39 133 write_setting_i (sesskey, "CapsLockCyr", cfg->xlat_capslockcyr);
134 write_setting_i (sesskey, "ScrollBar", cfg->scrollbar);
135 write_setting_i (sesskey, "ScrollOnKey", cfg->scroll_on_key);
a094ae43 136 write_setting_i (sesskey, "ScrollOnDisp", cfg->scroll_on_disp);
a9422f39 137 write_setting_i (sesskey, "LockSize", cfg->locksize);
138 write_setting_i (sesskey, "BCE", cfg->bce);
139 write_setting_i (sesskey, "BlinkText", cfg->blinktext);
140
141 close_settings_w(sesskey);
142}
143
144void load_settings (char *section, int do_host, Config *cfg) {
145 int i;
146 char prot[10];
147 void *sesskey;
148
149 sesskey = open_settings_r(section);
150
151 gpps (sesskey, "HostName", "", cfg->host, sizeof(cfg->host));
152 gppi (sesskey, "PortNumber", default_port, &cfg->port);
153
154 gpps (sesskey, "Protocol", "default", prot, 10);
155 cfg->protocol = default_protocol;
156 for (i = 0; backends[i].name != NULL; i++)
157 if (!strcmp(prot, backends[i].name)) {
158 cfg->protocol = backends[i].protocol;
159 break;
160 }
161
162 gppi (sesskey, "CloseOnExit", 1, &cfg->close_on_exit);
163 gppi (sesskey, "WarnOnClose", 1, &cfg->warn_on_close);
ec55b220 164 gppi (sesskey, "PingInterval", 0, &cfg->ping_interval);
a9422f39 165 gpps (sesskey, "TerminalType", "xterm", cfg->termtype,
166 sizeof(cfg->termtype));
167 gpps (sesskey, "TerminalSpeed", "38400,38400", cfg->termspeed,
168 sizeof(cfg->termspeed));
169 {
170 char buf[2*sizeof(cfg->environmt)], *p, *q;
171 gpps (sesskey, "Environment", "", buf, sizeof(buf));
172 p = buf;
173 q = cfg->environmt;
174 while (*p) {
175 while (*p && *p != ',') {
176 int c = *p++;
177 if (c == '=')
178 c = '\t';
179 if (c == '\\')
180 c = *p++;
181 *q++ = c;
182 }
183 if (*p == ',') p++;
184 *q++ = '\0';
185 }
186 *q = '\0';
187 }
188 gpps (sesskey, "UserName", "", cfg->username, sizeof(cfg->username));
189 gppi (sesskey, "NoPTY", 0, &cfg->nopty);
4ba9b64b 190 gppi (sesskey, "Compression", 0, &cfg->compression);
a9422f39 191 gppi (sesskey, "AgentFwd", 0, &cfg->agentfwd);
192 gpps (sesskey, "RemoteCmd", "", cfg->remote_cmd, sizeof(cfg->remote_cmd));
193 {
194 char cipher[10];
195 gpps (sesskey, "Cipher", "3des", cipher, 10);
196 if (!strcmp(cipher, "blowfish"))
197 cfg->cipher = CIPHER_BLOWFISH;
198 else if (!strcmp(cipher, "des"))
199 cfg->cipher = CIPHER_DES;
200 else
201 cfg->cipher = CIPHER_3DES;
202 }
203 gppi (sesskey, "SshProt", 1, &cfg->sshprot);
7591b9ff 204 gppi (sesskey, "BuggyMAC", 0, &cfg->buggymac);
a9422f39 205 gppi (sesskey, "AuthTIS", 0, &cfg->try_tis_auth);
206 gpps (sesskey, "PublicKeyFile", "", cfg->keyfile, sizeof(cfg->keyfile));
207 gpps (sesskey, "RemoteCommand", "", cfg->remote_cmd,
208 sizeof(cfg->remote_cmd));
209 gppi (sesskey, "RFCEnviron", 0, &cfg->rfc_environ);
210 gppi (sesskey, "BackspaceIsDelete", 1, &cfg->bksp_is_delete);
211 gppi (sesskey, "RXVTHomeEnd", 0, &cfg->rxvt_homeend);
212 gppi (sesskey, "LinuxFunctionKeys", 0, &cfg->funky_type);
b00f8b34 213 gppi (sesskey, "NoApplicationKeys", 0, &cfg->no_applic_k);
214 gppi (sesskey, "NoApplicationCursors", 0, &cfg->no_applic_c);
a9422f39 215 gppi (sesskey, "ApplicationCursorKeys", 0, &cfg->app_cursor);
216 gppi (sesskey, "ApplicationKeypad", 0, &cfg->app_keypad);
217 gppi (sesskey, "NetHackKeypad", 0, &cfg->nethack_keypad);
218 gppi (sesskey, "AltF4", 1, &cfg->alt_f4);
219 gppi (sesskey, "AltSpace", 0, &cfg->alt_space);
a094ae43 220 gppi (sesskey, "AltOnly", 0, &cfg->alt_only);
221 gppi (sesskey, "ComposeKey", 0, &cfg->compose_key);
a9422f39 222 gppi (sesskey, "LdiscTerm", 0, &cfg->ldisc_term);
e95edc00 223 gppi (sesskey, "AlwaysOnTop", 0, &cfg->alwaysontop);
a9422f39 224 gppi (sesskey, "BlinkCur", 0, &cfg->blink_cur);
225 gppi (sesskey, "Beep", 1, &cfg->beep);
226 gppi (sesskey, "ScrollbackLines", 200, &cfg->savelines);
227 gppi (sesskey, "DECOriginMode", 0, &cfg->dec_om);
228 gppi (sesskey, "AutoWrapMode", 1, &cfg->wrap_mode);
229 gppi (sesskey, "LFImpliesCR", 0, &cfg->lfhascr);
230 gppi (sesskey, "WinNameAlways", 0, &cfg->win_name_always);
231 gpps (sesskey, "WinTitle", "", cfg->wintitle, sizeof(cfg->wintitle));
232 gppi (sesskey, "TermWidth", 80, &cfg->width);
233 gppi (sesskey, "TermHeight", 24, &cfg->height);
234 gpps (sesskey, "Font", "Courier", cfg->font, sizeof(cfg->font));
235 gppi (sesskey, "FontIsBold", 0, &cfg->fontisbold);
236 gppi (sesskey, "FontCharSet", ANSI_CHARSET, &cfg->fontcharset);
237 gppi (sesskey, "FontHeight", 10, &cfg->fontheight);
238 gppi (sesskey, "FontVTMode", VT_OEMANSI, (int *)&cfg->vtmode);
239 gppi (sesskey, "TryPalette", 0, &cfg->try_palette);
240 gppi (sesskey, "BoldAsColour", 1, &cfg->bold_colour);
241 for (i=0; i<22; i++) {
242 static char *defaults[] = {
243 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
244 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
245 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
246 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
247 "85,255,255", "187,187,187", "255,255,255"
248 };
249 char buf[20], buf2[30];
250 int c0, c1, c2;
251 sprintf(buf, "Colour%d", i);
252 gpps (sesskey, buf, defaults[i], buf2, sizeof(buf2));
253 if(sscanf(buf2, "%d,%d,%d", &c0, &c1, &c2) == 3) {
254 cfg->colours[i][0] = c0;
255 cfg->colours[i][1] = c1;
256 cfg->colours[i][2] = c2;
257 }
258 }
259 gppi (sesskey, "MouseIsXterm", 0, &cfg->mouse_is_xterm);
260 for (i=0; i<256; i+=32) {
261 static char *defaults[] = {
262 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
263 "0,1,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1",
264 "1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2",
265 "1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1",
266 "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",
267 "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",
268 "2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2",
269 "2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2"
270 };
271 char buf[20], buf2[256], *p;
272 int j;
273 sprintf(buf, "Wordness%d", i);
274 gpps (sesskey, buf, defaults[i/32], buf2, sizeof(buf2));
275 p = buf2;
276 for (j=i; j<i+32; j++) {
277 char *q = p;
278 while (*p && *p != ',') p++;
279 if (*p == ',') *p++ = '\0';
280 cfg->wordness[j] = atoi(q);
281 }
282 }
283 gppi (sesskey, "KoiWinXlat", 0, &cfg->xlat_enablekoiwin);
284 gppi (sesskey, "88592Xlat", 0, &cfg->xlat_88592w1250);
b0faa571 285 gppi (sesskey, "88592-CP852", 0, &cfg->xlat_88592cp852);
a9422f39 286 gppi (sesskey, "CapsLockCyr", 0, &cfg->xlat_capslockcyr);
287 gppi (sesskey, "ScrollBar", 1, &cfg->scrollbar);
288 gppi (sesskey, "ScrollOnKey", 0, &cfg->scroll_on_key);
a094ae43 289 gppi (sesskey, "ScrollOnDisp", 1, &cfg->scroll_on_disp);
a9422f39 290 gppi (sesskey, "LockSize", 0, &cfg->locksize);
291 gppi (sesskey, "BCE", 0, &cfg->bce);
292 gppi (sesskey, "BlinkText", 0, &cfg->blinktext);
293
294 close_settings_r(sesskey);
295}
296
297void do_defaults (char *session, Config *cfg) {
298 if (session)
299 load_settings (session, TRUE, cfg);
300 else
301 load_settings ("Default Settings", FALSE, cfg);
302}
303
a84ca2f5 304static int sessioncmp(const void *av, const void *bv) {
305 const char *a = *(const char *const *)av;
306 const char *b = *(const char *const *)bv;
307
308 /*
309 * Alphabetical order, except that "Default Settings" is a
310 * special case and comes first.
311 */
312 if (!strcmp(a, "Default Settings"))
313 return -1; /* a comes first */
314 if (!strcmp(b, "Default Settings"))
315 return +1; /* b comes first */
316 return strcmp(a, b); /* otherwise, compare normally */
317}
318
a9422f39 319void get_sesslist(int allocate) {
320 static char otherbuf[2048];
321 static char *buffer;
322 int buflen, bufsize, i;
323 char *p, *ret;
324 void *handle;
325
326 if (allocate) {
327
328 if ((handle = enum_settings_start()) == NULL)
329 return;
330
331 buflen = bufsize = 0;
332 buffer = NULL;
333 do {
334 ret = enum_settings_next(handle, otherbuf, sizeof(otherbuf));
335 if (ret) {
336 int len = strlen(otherbuf)+1;
337 if (bufsize < buflen+len) {
338 bufsize = buflen + len + 2048;
339 buffer = srealloc(buffer, bufsize);
340 }
341 strcpy(buffer+buflen, otherbuf);
342 buflen += strlen(buffer+buflen)+1;
343 }
344 } while (ret);
345 enum_settings_finish(handle);
346 buffer = srealloc(buffer, buflen+1);
347 buffer[buflen] = '\0';
348
2221af18 349 /*
350 * Now set up the list of sessions. Note that "Default
351 * Settings" must always be claimed to exist, even if it
352 * doesn't really.
353 */
354
a9422f39 355 p = buffer;
2221af18 356 nsessions = 1; /* "Default Settings" counts as one */
a9422f39 357 while (*p) {
2221af18 358 if (strcmp(p, "Default Settings"))
359 nsessions++;
a9422f39 360 while (*p) p++;
361 p++;
362 }
363
2221af18 364 sessions = smalloc((nsessions+1) * sizeof(char *));
365 sessions[0] = "Default Settings";
a9422f39 366 p = buffer;
2221af18 367 i = 1;
a9422f39 368 while (*p) {
2221af18 369 if (strcmp(p, "Default Settings"))
370 sessions[i++] = p;
a9422f39 371 while (*p) p++;
372 p++;
373 }
a84ca2f5 374
375 qsort(sessions, i, sizeof(char *), sessioncmp);
a9422f39 376 } else {
377 sfree (buffer);
378 sfree (sessions);
379 }
380}