{
Conf *conf = (Conf *)data;
if (event == EVENT_REFRESH) {
+ /*
+ * We must fetch the previously configured value from the Conf
+ * before we start modifying the drop-down list, otherwise the
+ * spurious SELCHANGE we trigger in the process will overwrite
+ * the value we wanted to keep.
+ */
+ int oldconf = conf_get_int(conf, ctrl->listbox.context.i);
dlg_update_start(ctrl, dlg);
dlg_listbox_clear(ctrl, dlg);
dlg_listbox_addwithid(ctrl, dlg, "Auto", AUTO);
dlg_listbox_addwithid(ctrl, dlg, "Off", FORCE_OFF);
dlg_listbox_addwithid(ctrl, dlg, "On", FORCE_ON);
- switch (conf_get_int(conf, ctrl->listbox.context.i)) {
+ switch (oldconf) {
case AUTO: dlg_listbox_select(ctrl, dlg, 0); break;
case FORCE_OFF: dlg_listbox_select(ctrl, dlg, 1); break;
case FORCE_ON: dlg_listbox_select(ctrl, dlg, 2); break;
}
}
-#define SAVEDSESSION_LEN 2048
-
struct sessionsaver_data {
union control *editbox, *listbox, *loadbutton, *savebutton, *delbutton;
union control *okbutton, *cancelbutton;
struct sesslist sesslist;
int midsession;
+ char *savedsession; /* the current contents of ssd->editbox */
};
+static void sessionsaver_data_free(void *ssdv)
+{
+ struct sessionsaver_data *ssd = (struct sessionsaver_data *)ssdv;
+ sfree(ssd->savedsession);
+ sfree(ssd);
+}
+
/*
* Helper function to load the session selected in the list box, if
* any, as this is done in more than one place below. Returns 0 for
* failure.
*/
static int load_selected_session(struct sessionsaver_data *ssd,
- char *savedsession,
void *dlg, Conf *conf, int *maybe_launch)
{
int i = dlg_listbox_index(ssd->listbox, dlg);
}
isdef = !strcmp(ssd->sesslist.sessions[i], "Default Settings");
load_settings(ssd->sesslist.sessions[i], conf);
- if (!isdef) {
- strncpy(savedsession, ssd->sesslist.sessions[i],
- SAVEDSESSION_LEN);
- savedsession[SAVEDSESSION_LEN-1] = '\0';
- if (maybe_launch)
- *maybe_launch = TRUE;
- } else {
- savedsession[0] = '\0';
- if (maybe_launch)
- *maybe_launch = FALSE;
- }
+ sfree(ssd->savedsession);
+ ssd->savedsession = dupstr(isdef ? "" : ssd->sesslist.sessions[i]);
+ if (maybe_launch)
+ *maybe_launch = !isdef;
dlg_refresh(NULL, dlg);
/* Restore the selection, which might have been clobbered by
* changing the value of the edit box. */
Conf *conf = (Conf *)data;
struct sessionsaver_data *ssd =
(struct sessionsaver_data *)ctrl->generic.context.p;
- char *savedsession;
-
- /*
- * The first time we're called in a new dialog, we must
- * allocate space to store the current contents of the saved
- * session edit box (since it must persist even when we switch
- * panels, but is not part of the Conf).
- *
- * FIXME: this is disgusting, and we'd do much better to have
- * the persistent storage be dynamically allocated and get rid
- * of the arbitrary limit SAVEDSESSION_LEN. To do that would
- * require a means of making sure the memory gets freed at the
- * appropriate moment.
- */
- if (!ssd->editbox) {
- savedsession = NULL;
- } else if (!dlg_get_privdata(ssd->editbox, dlg)) {
- savedsession = (char *)
- dlg_alloc_privdata(ssd->editbox, dlg, SAVEDSESSION_LEN);
- savedsession[0] = '\0';
- } else {
- savedsession = dlg_get_privdata(ssd->editbox, dlg);
- }
if (event == EVENT_REFRESH) {
if (ctrl == ssd->editbox) {
- dlg_editbox_set(ctrl, dlg, savedsession);
+ dlg_editbox_set(ctrl, dlg, ssd->savedsession);
} else if (ctrl == ssd->listbox) {
int i;
dlg_update_start(ctrl, dlg);
} else if (event == EVENT_VALCHANGE) {
int top, bottom, halfway, i;
if (ctrl == ssd->editbox) {
- char *tmp = dlg_editbox_get(ctrl, dlg);
- strncpy(savedsession, tmp, SAVEDSESSION_LEN);
- sfree(tmp);
+ sfree(ssd->savedsession);
+ ssd->savedsession = dlg_editbox_get(ctrl, dlg);
top = ssd->sesslist.nsessions;
bottom = -1;
while (top-bottom > 1) {
halfway = (top+bottom)/2;
- i = strcmp(savedsession, ssd->sesslist.sessions[halfway]);
+ i = strcmp(ssd->savedsession, ssd->sesslist.sessions[halfway]);
if (i <= 0 ) {
top = halfway;
} else {
* double-click on the list box _and_ that session
* contains a hostname.
*/
- if (load_selected_session(ssd, savedsession, dlg, conf, &mbl) &&
+ if (load_selected_session(ssd, dlg, conf, &mbl) &&
(mbl && ctrl == ssd->listbox && conf_launchable(conf))) {
dlg_end(dlg, 1); /* it's all over, and succeeded */
}
} else if (ctrl == ssd->savebutton) {
- int isdef = !strcmp(savedsession, "Default Settings");
- if (!savedsession[0]) {
+ int isdef = !strcmp(ssd->savedsession, "Default Settings");
+ if (!ssd->savedsession[0]) {
int i = dlg_listbox_index(ssd->listbox, dlg);
if (i < 0) {
dlg_beep(dlg);
return;
}
isdef = !strcmp(ssd->sesslist.sessions[i], "Default Settings");
- if (!isdef) {
- strncpy(savedsession, ssd->sesslist.sessions[i],
- SAVEDSESSION_LEN);
- savedsession[SAVEDSESSION_LEN-1] = '\0';
- } else {
- savedsession[0] = '\0';
- }
+ sfree(ssd->savedsession);
+ ssd->savedsession = dupstr(isdef ? "" :
+ ssd->sesslist.sessions[i]);
}
{
- char *errmsg = save_settings(savedsession, conf);
+ char *errmsg = save_settings(ssd->savedsession, conf);
if (errmsg) {
dlg_error_msg(dlg, errmsg);
sfree(errmsg);
!conf_launchable(conf)) {
Conf *conf2 = conf_new();
int mbl = FALSE;
- if (!load_selected_session(ssd, savedsession, dlg,
- conf2, &mbl)) {
+ if (!load_selected_session(ssd, dlg, conf2, &mbl)) {
dlg_beep(dlg);
conf_free(conf2);
return;
char *str;
ssd = (struct sessionsaver_data *)
- ctrl_alloc(b, sizeof(struct sessionsaver_data));
+ ctrl_alloc_with_free(b, sizeof(struct sessionsaver_data),
+ sessionsaver_data_free);
memset(ssd, 0, sizeof(*ssd));
+ ssd->savedsession = dupstr("");
ssd->midsession = midsession;
/*
ctrl_droplist(s, "Chokes on SSH-2 ignore messages", '2', 20,
HELPCTX(ssh_bugs_ignore2),
sshbug_handler, I(CONF_sshbug_ignore2));
+ ctrl_droplist(s, "Chokes on PuTTY's SSH-2 'winadj' requests", 'j',
+ 20, HELPCTX(ssh_bugs_winadj),
+ sshbug_handler, I(CONF_sshbug_winadj));
ctrl_droplist(s, "Miscomputes SSH-2 HMAC keys", 'm', 20,
HELPCTX(ssh_bugs_hmac2),
sshbug_handler, I(CONF_sshbug_hmac2));