1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Use the new ctrl_alloc_with_free to clean up a long-standing FIXME in

the session saving code, in which the contents of the edit box giving
the current saved session name was stored in a horrid place with a
fixed length. Now it's dangling off sessionsaver_data as it always
ought to have been, and it's dynamically reallocated to the
appropriate length, and there's a free function that cleans it up at
the end of the dialog's lifetime.

[originally from svn r9923]
This commit is contained in:
Simon Tatham 2013-07-14 10:46:34 +00:00
parent ff09d5379b
commit 7554dd5a9c

View File

@ -557,22 +557,27 @@ static void sshbug_handler(union control *ctrl, void *dlg,
}
}
#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);
@ -583,17 +588,10 @@ static int load_selected_session(struct sessionsaver_data *ssd,
}
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. */
@ -607,33 +605,10 @@ static void sessionsaver_handler(union control *ctrl, void *dlg,
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);
@ -645,14 +620,13 @@ static void sessionsaver_handler(union control *ctrl, void *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 {
@ -676,29 +650,25 @@ static void sessionsaver_handler(union control *ctrl, void *dlg,
* 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);
@ -736,8 +706,7 @@ static void sessionsaver_handler(union control *ctrl, void *dlg,
!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;
@ -1256,8 +1225,10 @@ void setup_config_box(struct controlbox *b, int midsession,
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;
/*