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

3075 lines
124 KiB
C
Raw Normal View History

/*
* config.c - the platform-independent parts of the PuTTY
* configuration box.
*/
#include <assert.h>
#include <stdlib.h>
#include "putty.h"
#include "dialog.h"
#include "storage.h"
#define PRINTER_DISABLED_STRING "None (printing disabled)"
#define HOST_BOX_TITLE "Host Name (or IP address)"
#define PORT_BOX_TITLE "Port"
void conf_radiobutton_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
{
int button;
Conf *conf = (Conf *)data;
/*
* For a standard radio button set, the context parameter gives
* the primary key (CONF_foo), and the extra data per button
* gives the value the target field should take if that button
* is the one selected.
*/
if (event == EVENT_REFRESH) {
int val = conf_get_int(conf, ctrl->radio.context.i);
for (button = 0; button < ctrl->radio.nbuttons; button++)
if (val == ctrl->radio.buttondata[button].i)
break;
/* We expected that `break' to happen, in all circumstances. */
assert(button < ctrl->radio.nbuttons);
dlg_radiobutton_set(ctrl, dlg, button);
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
} else if (event == EVENT_VALCHANGE) {
button = dlg_radiobutton_get(ctrl, dlg);
assert(button >= 0 && button < ctrl->radio.nbuttons);
conf_set_int(conf, ctrl->radio.context.i,
ctrl->radio.buttondata[button].i);
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
}
}
void conf_radiobutton_bool_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
int button;
Conf *conf = (Conf *)data;
/*
* Same as conf_radiobutton_handler, but using conf_set_bool in
* place of conf_set_int, because it's dealing with a bool-typed
* config option.
*/
if (event == EVENT_REFRESH) {
int val = conf_get_bool(conf, ctrl->radio.context.i);
for (button = 0; button < ctrl->radio.nbuttons; button++)
if (val == ctrl->radio.buttondata[button].i)
break;
/* We expected that `break' to happen, in all circumstances. */
assert(button < ctrl->radio.nbuttons);
dlg_radiobutton_set(ctrl, dlg, button);
} else if (event == EVENT_VALCHANGE) {
button = dlg_radiobutton_get(ctrl, dlg);
assert(button >= 0 && button < ctrl->radio.nbuttons);
conf_set_bool(conf, ctrl->radio.context.i,
ctrl->radio.buttondata[button].i);
}
}
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
#define CHECKBOX_INVERT (1<<30)
void conf_checkbox_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
{
int key;
bool invert;
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
Conf *conf = (Conf *)data;
/*
* For a standard checkbox, the context parameter gives the
* primary key (CONF_foo), optionally ORed with CHECKBOX_INVERT.
*/
key = ctrl->checkbox.context.i;
if (key & CHECKBOX_INVERT) {
key &= ~CHECKBOX_INVERT;
invert = true;
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
} else
invert = false;
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
/*
* C lacks a logical XOR, so the following code uses the idiom
* (!a ^ !b) to obtain the logical XOR of a and b. (That is, 1
* iff exactly one of a and b is nonzero, otherwise 0.)
*/
if (event == EVENT_REFRESH) {
bool val = conf_get_bool(conf, key);
dlg_checkbox_set(ctrl, dlg, (!val ^ !invert));
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
} else if (event == EVENT_VALCHANGE) {
conf_set_bool(conf, key, !dlg_checkbox_get(ctrl,dlg) ^ !invert);
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
}
}
void conf_editbox_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
{
/*
* The standard edit-box handler expects the main `context'
* field to contain the primary key. The secondary `context2'
* field indicates the type of this field:
*
* - if context2 > 0, the field is a string.
* - if context2 == -1, the field is an int and the edit box
* is numeric.
* - if context2 < -1, the field is an int and the edit box is
* _floating_, and (-context2) gives the scale. (E.g. if
* context2 == -1000, then typing 1.2 into the box will set
* the field to 1200.)
*/
int key = ctrl->editbox.context.i;
int length = ctrl->editbox.context2.i;
Conf *conf = (Conf *)data;
if (length > 0) {
if (event == EVENT_REFRESH) {
char *field = conf_get_str(conf, key);
dlg_editbox_set(ctrl, dlg, field);
} else if (event == EVENT_VALCHANGE) {
char *field = dlg_editbox_get(ctrl, dlg);
conf_set_str(conf, key, field);
sfree(field);
}
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
} else if (length < 0) {
if (event == EVENT_REFRESH) {
char str[80];
int value = conf_get_int(conf, key);
if (length == -1)
sprintf(str, "%d", value);
else
sprintf(str, "%g", (double)value / (double)(-length));
dlg_editbox_set(ctrl, dlg, str);
} else if (event == EVENT_VALCHANGE) {
char *str = dlg_editbox_get(ctrl, dlg);
if (length == -1)
conf_set_int(conf, key, atoi(str));
else
conf_set_int(conf, key, (int)((-length) * atof(str)));
sfree(str);
}
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
}
}
void conf_filesel_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
{
int key = ctrl->fileselect.context.i;
Conf *conf = (Conf *)data;
if (event == EVENT_REFRESH) {
dlg_filesel_set(
Convert a lot of 'int' variables to 'bool'. My normal habit these days, in new code, is to treat int and bool as _almost_ completely separate types. I'm still willing to use C's implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine, no need to spell it out as blob.len != 0), but generally, if a variable is going to be conceptually a boolean, I like to declare it bool and assign to it using 'true' or 'false' rather than 0 or 1. PuTTY is an exception, because it predates the C99 bool, and I've stuck to its existing coding style even when adding new code to it. But it's been annoying me more and more, so now that I've decided C99 bool is an acceptable thing to require from our toolchain in the first place, here's a quite thorough trawl through the source doing 'boolification'. Many variables and function parameters are now typed as bool rather than int; many assignments of 0 or 1 to those variables are now spelled 'true' or 'false'. I managed this thorough conversion with the help of a custom clang plugin that I wrote to trawl the AST and apply heuristics to point out where things might want changing. So I've even managed to do a decent job on parts of the code I haven't looked at in years! To make the plugin's work easier, I pushed platform front ends generally in the direction of using standard 'bool' in preference to platform-specific boolean types like Windows BOOL or GTK's gboolean; I've left the platform booleans in places they _have_ to be for the platform APIs to work right, but variables only used by my own code have been converted wherever I found them. In a few places there are int values that look very like booleans in _most_ of the places they're used, but have a rarely-used third value, or a distinction between different nonzero values that most users don't care about. In these cases, I've _removed_ uses of 'true' and 'false' for the return values, to emphasise that there's something more subtle going on than a simple boolean answer: - the 'multisel' field in dialog.h's list box structure, for which the GTK front end in particular recognises a difference between 1 and 2 but nearly everything else treats as boolean - the 'urgent' parameter to plug_receive, where 1 vs 2 tells you something about the specific location of the urgent pointer, but most clients only care about 0 vs 'something nonzero' - the return value of wc_match, where -1 indicates a syntax error in the wildcard. - the return values from SSH-1 RSA-key loading functions, which use -1 for 'wrong passphrase' and 0 for all other failures (so any caller which already knows it's not loading an _encrypted private_ key can treat them as boolean) - term->esc_query, and the 'query' parameter in toggle_mode in terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h, but can also hold -1 for some other intervening character that we don't support. In a few places there's an integer that I haven't turned into a bool even though it really _can_ only take values 0 or 1 (and, as above, tried to make the call sites consistent in not calling those values true and false), on the grounds that I thought it would make it more confusing to imply that the 0 value was in some sense 'negative' or bad and the 1 positive or good: - the return value of plug_accepting uses the POSIXish convention of 0=success and nonzero=error; I think if I made it bool then I'd also want to reverse its sense, and that's a job for a separate piece of work. - the 'screen' parameter to lineptr() in terminal.c, where 0 and 1 represent the default and alternate screens. There's no obvious reason why one of those should be considered 'true' or 'positive' or 'success' - they're just indices - so I've left it as int. ssh_scp_recv had particularly confusing semantics for its previous int return value: its call sites used '<= 0' to check for error, but it never actually returned a negative number, just 0 or 1. Now the function and its call sites agree that it's a bool. In a couple of places I've renamed variables called 'ret', because I don't like that name any more - it's unclear whether it means the return value (in preparation) for the _containing_ function or the return value received from a subroutine call, and occasionally I've accidentally used the same variable for both and introduced a bug. So where one of those got in my way, I've renamed it to 'toret' or 'retd' (the latter short for 'returned') in line with my usual modern practice, but I haven't done a thorough job of finding all of them. Finally, one amusing side effect of doing this is that I've had to separate quite a few chained assignments. It used to be perfectly fine to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a the 'true' defined by stdbool.h, that idiom provokes a warning from gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
ctrl, dlg, conf_get_filename(conf, key));
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
} else if (event == EVENT_VALCHANGE) {
Filename *filename = dlg_filesel_get(ctrl, dlg);
conf_set_filename(conf, key, filename);
filename_free(filename);
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
}
}
void conf_fontsel_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
{
int key = ctrl->fontselect.context.i;
Conf *conf = (Conf *)data;
if (event == EVENT_REFRESH) {
dlg_fontsel_set(
Convert a lot of 'int' variables to 'bool'. My normal habit these days, in new code, is to treat int and bool as _almost_ completely separate types. I'm still willing to use C's implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine, no need to spell it out as blob.len != 0), but generally, if a variable is going to be conceptually a boolean, I like to declare it bool and assign to it using 'true' or 'false' rather than 0 or 1. PuTTY is an exception, because it predates the C99 bool, and I've stuck to its existing coding style even when adding new code to it. But it's been annoying me more and more, so now that I've decided C99 bool is an acceptable thing to require from our toolchain in the first place, here's a quite thorough trawl through the source doing 'boolification'. Many variables and function parameters are now typed as bool rather than int; many assignments of 0 or 1 to those variables are now spelled 'true' or 'false'. I managed this thorough conversion with the help of a custom clang plugin that I wrote to trawl the AST and apply heuristics to point out where things might want changing. So I've even managed to do a decent job on parts of the code I haven't looked at in years! To make the plugin's work easier, I pushed platform front ends generally in the direction of using standard 'bool' in preference to platform-specific boolean types like Windows BOOL or GTK's gboolean; I've left the platform booleans in places they _have_ to be for the platform APIs to work right, but variables only used by my own code have been converted wherever I found them. In a few places there are int values that look very like booleans in _most_ of the places they're used, but have a rarely-used third value, or a distinction between different nonzero values that most users don't care about. In these cases, I've _removed_ uses of 'true' and 'false' for the return values, to emphasise that there's something more subtle going on than a simple boolean answer: - the 'multisel' field in dialog.h's list box structure, for which the GTK front end in particular recognises a difference between 1 and 2 but nearly everything else treats as boolean - the 'urgent' parameter to plug_receive, where 1 vs 2 tells you something about the specific location of the urgent pointer, but most clients only care about 0 vs 'something nonzero' - the return value of wc_match, where -1 indicates a syntax error in the wildcard. - the return values from SSH-1 RSA-key loading functions, which use -1 for 'wrong passphrase' and 0 for all other failures (so any caller which already knows it's not loading an _encrypted private_ key can treat them as boolean) - term->esc_query, and the 'query' parameter in toggle_mode in terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h, but can also hold -1 for some other intervening character that we don't support. In a few places there's an integer that I haven't turned into a bool even though it really _can_ only take values 0 or 1 (and, as above, tried to make the call sites consistent in not calling those values true and false), on the grounds that I thought it would make it more confusing to imply that the 0 value was in some sense 'negative' or bad and the 1 positive or good: - the return value of plug_accepting uses the POSIXish convention of 0=success and nonzero=error; I think if I made it bool then I'd also want to reverse its sense, and that's a job for a separate piece of work. - the 'screen' parameter to lineptr() in terminal.c, where 0 and 1 represent the default and alternate screens. There's no obvious reason why one of those should be considered 'true' or 'positive' or 'success' - they're just indices - so I've left it as int. ssh_scp_recv had particularly confusing semantics for its previous int return value: its call sites used '<= 0' to check for error, but it never actually returned a negative number, just 0 or 1. Now the function and its call sites agree that it's a bool. In a couple of places I've renamed variables called 'ret', because I don't like that name any more - it's unclear whether it means the return value (in preparation) for the _containing_ function or the return value received from a subroutine call, and occasionally I've accidentally used the same variable for both and introduced a bug. So where one of those got in my way, I've renamed it to 'toret' or 'retd' (the latter short for 'returned') in line with my usual modern practice, but I haven't done a thorough job of finding all of them. Finally, one amusing side effect of doing this is that I've had to separate quite a few chained assignments. It used to be perfectly fine to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a the 'true' defined by stdbool.h, that idiom provokes a warning from gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
ctrl, dlg, conf_get_fontspec(conf, key));
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
} else if (event == EVENT_VALCHANGE) {
FontSpec *fontspec = dlg_fontsel_get(ctrl, dlg);
conf_set_fontspec(conf, key, fontspec);
fontspec_free(fontspec);
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
}
}
static void config_host_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
Conf *conf = (Conf *)data;
/*
* This function works just like the standard edit box handler,
* only it has to choose the control's label and text from two
* different places depending on the protocol.
*/
if (event == EVENT_REFRESH) {
if (conf_get_int(conf, CONF_protocol) == PROT_SERIAL) {
/*
* This label text is carefully chosen to contain an n,
* since that's the shortcut for the host name control.
*/
dlg_label_change(ctrl, dlg, "Serial line");
dlg_editbox_set(ctrl, dlg, conf_get_str(conf, CONF_serline));
} else {
dlg_label_change(ctrl, dlg, HOST_BOX_TITLE);
dlg_editbox_set(ctrl, dlg, conf_get_str(conf, CONF_host));
}
} else if (event == EVENT_VALCHANGE) {
char *s = dlg_editbox_get(ctrl, dlg);
if (conf_get_int(conf, CONF_protocol) == PROT_SERIAL)
conf_set_str(conf, CONF_serline, s);
else
conf_set_str(conf, CONF_host, s);
sfree(s);
}
}
static void config_port_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
Conf *conf = (Conf *)data;
char buf[80];
/*
* This function works similarly to the standard edit box handler,
* only it has to choose the control's label and text from two
* different places depending on the protocol.
*/
if (event == EVENT_REFRESH) {
if (conf_get_int(conf, CONF_protocol) == PROT_SERIAL) {
/*
* This label text is carefully chosen to contain a p,
* since that's the shortcut for the port control.
*/
dlg_label_change(ctrl, dlg, "Speed");
sprintf(buf, "%d", conf_get_int(conf, CONF_serspeed));
} else {
dlg_label_change(ctrl, dlg, PORT_BOX_TITLE);
if (conf_get_int(conf, CONF_port) != 0)
sprintf(buf, "%d", conf_get_int(conf, CONF_port));
else
/* Display an (invalid) port of 0 as blank */
buf[0] = '\0';
}
dlg_editbox_set(ctrl, dlg, buf);
} else if (event == EVENT_VALCHANGE) {
char *s = dlg_editbox_get(ctrl, dlg);
int i = atoi(s);
sfree(s);
if (conf_get_int(conf, CONF_protocol) == PROT_SERIAL)
conf_set_int(conf, CONF_serspeed, i);
else
conf_set_int(conf, CONF_port, i);
}
}
struct hostport {
union control *host, *port;
};
static void config_protocolbuttons_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
int button;
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
Conf *conf = (Conf *)data;
struct hostport *hp = (struct hostport *)ctrl->radio.context.p;
/*
* This function works just like the standard radio-button
* handler, except that it also has to change the setting of
* the port box, and refresh both host and port boxes when. We
* expect the context parameter to point at a hostport
* structure giving the `union control's for both.
*/
if (event == EVENT_REFRESH) {
int protocol = conf_get_int(conf, CONF_protocol);
for (button = 0; button < ctrl->radio.nbuttons; button++)
if (protocol == ctrl->radio.buttondata[button].i)
break;
/* We expected that `break' to happen, in all circumstances. */
assert(button < ctrl->radio.nbuttons);
dlg_radiobutton_set(ctrl, dlg, button);
} else if (event == EVENT_VALCHANGE) {
int oldproto = conf_get_int(conf, CONF_protocol);
int newproto, port;
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
button = dlg_radiobutton_get(ctrl, dlg);
assert(button >= 0 && button < ctrl->radio.nbuttons);
newproto = ctrl->radio.buttondata[button].i;
conf_set_int(conf, CONF_protocol, newproto);
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
if (oldproto != newproto) {
const struct BackendVtable *ovt = backend_vt_from_proto(oldproto);
const struct BackendVtable *nvt = backend_vt_from_proto(newproto);
assert(ovt);
assert(nvt);
/* Iff the user hasn't changed the port from the old protocol's
* default, update it with the new protocol's default.
* (This includes a "default" of 0, implying that there is no
* sensible default for that protocol; in this case it's
* displayed as a blank.)
* This helps with the common case of tabbing through the
* controls in order and setting a non-default port before
* getting to the protocol; we want that non-default port
* to be preserved. */
port = conf_get_int(conf, CONF_port);
if (port == ovt->default_port)
conf_set_int(conf, CONF_port, nvt->default_port);
}
dlg_refresh(hp->host, dlg);
dlg_refresh(hp->port, dlg);
}
}
static void loggingbuttons_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
int button;
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
Conf *conf = (Conf *)data;
/* This function works just like the standard radio-button handler,
* but it has to fall back to "no logging" in situations where the
* configured logging type isn't applicable.
*/
if (event == EVENT_REFRESH) {
int logtype = conf_get_int(conf, CONF_logtype);
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
for (button = 0; button < ctrl->radio.nbuttons; button++)
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
if (logtype == ctrl->radio.buttondata[button].i)
break;
/* We fell off the end, so we lack the configured logging type */
if (button == ctrl->radio.nbuttons) {
button = 0;
conf_set_int(conf, CONF_logtype, LGTYP_NONE);
}
dlg_radiobutton_set(ctrl, dlg, button);
} else if (event == EVENT_VALCHANGE) {
button = dlg_radiobutton_get(ctrl, dlg);
assert(button >= 0 && button < ctrl->radio.nbuttons);
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
conf_set_int(conf, CONF_logtype, ctrl->radio.buttondata[button].i);
}
}
static void numeric_keypad_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
int button;
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
Conf *conf = (Conf *)data;
/*
* This function works much like the standard radio button
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
* handler, but it has to handle two fields in Conf.
*/
if (event == EVENT_REFRESH) {
if (conf_get_bool(conf, CONF_nethack_keypad))
button = 2;
else if (conf_get_bool(conf, CONF_app_keypad))
button = 1;
else
button = 0;
assert(button < ctrl->radio.nbuttons);
dlg_radiobutton_set(ctrl, dlg, button);
} else if (event == EVENT_VALCHANGE) {
button = dlg_radiobutton_get(ctrl, dlg);
assert(button >= 0 && button < ctrl->radio.nbuttons);
if (button == 2) {
conf_set_bool(conf, CONF_app_keypad, false);
conf_set_bool(conf, CONF_nethack_keypad, true);
} else {
conf_set_bool(conf, CONF_app_keypad, (button != 0));
conf_set_bool(conf, CONF_nethack_keypad, false);
}
}
}
static void cipherlist_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
Conf *conf = (Conf *)data;
if (event == EVENT_REFRESH) {
int i;
static const struct { const char *s; int c; } ciphers[] = {
{ "ChaCha20 (SSH-2 only)", CIPHER_CHACHA20 },
{ "3DES", CIPHER_3DES },
{ "Blowfish", CIPHER_BLOWFISH },
{ "DES", CIPHER_DES },
{ "AES (SSH-2 only)", CIPHER_AES },
{ "Arcfour (SSH-2 only)", CIPHER_ARCFOUR },
{ "-- warn below here --", CIPHER_WARN }
};
/* Set up the "selected ciphers" box. */
/* (cipherlist assumed to contain all ciphers) */
dlg_update_start(ctrl, dlg);
dlg_listbox_clear(ctrl, dlg);
for (i = 0; i < CIPHER_MAX; i++) {
int c = conf_get_int_int(conf, CONF_ssh_cipherlist, i);
int j;
const char *cstr = NULL;
for (j = 0; j < (sizeof ciphers) / (sizeof ciphers[0]); j++) {
if (ciphers[j].c == c) {
cstr = ciphers[j].s;
break;
}
}
dlg_listbox_addwithid(ctrl, dlg, cstr, c);
}
dlg_update_done(ctrl, dlg);
} else if (event == EVENT_VALCHANGE) {
int i;
/* Update array to match the list box. */
for (i=0; i < CIPHER_MAX; i++)
conf_set_int_int(conf, CONF_ssh_cipherlist, i,
dlg_listbox_getid(ctrl, dlg, i));
}
}
#ifndef NO_GSSAPI
static void gsslist_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
Conf *conf = (Conf *)data;
if (event == EVENT_REFRESH) {
int i;
dlg_update_start(ctrl, dlg);
dlg_listbox_clear(ctrl, dlg);
for (i = 0; i < ngsslibs; i++) {
int id = conf_get_int_int(conf, CONF_ssh_gsslist, i);
assert(id >= 0 && id < ngsslibs);
dlg_listbox_addwithid(ctrl, dlg, gsslibnames[id], id);
}
dlg_update_done(ctrl, dlg);
} else if (event == EVENT_VALCHANGE) {
int i;
/* Update array to match the list box. */
for (i=0; i < ngsslibs; i++)
conf_set_int_int(conf, CONF_ssh_gsslist, i,
dlg_listbox_getid(ctrl, dlg, i));
}
}
#endif
static void kexlist_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
Conf *conf = (Conf *)data;
if (event == EVENT_REFRESH) {
int i;
static const struct { const char *s; int k; } kexes[] = {
{ "Diffie-Hellman group 1", KEX_DHGROUP1 },
{ "Diffie-Hellman group 14", KEX_DHGROUP14 },
{ "Diffie-Hellman group exchange", KEX_DHGEX },
{ "RSA-based key exchange", KEX_RSA },
{ "ECDH key exchange", KEX_ECDH },
{ "-- warn below here --", KEX_WARN }
};
/* Set up the "kex preference" box. */
/* (kexlist assumed to contain all algorithms) */
dlg_update_start(ctrl, dlg);
dlg_listbox_clear(ctrl, dlg);
for (i = 0; i < KEX_MAX; i++) {
int k = conf_get_int_int(conf, CONF_ssh_kexlist, i);
int j;
const char *kstr = NULL;
for (j = 0; j < (sizeof kexes) / (sizeof kexes[0]); j++) {
if (kexes[j].k == k) {
kstr = kexes[j].s;
break;
}
}
dlg_listbox_addwithid(ctrl, dlg, kstr, k);
}
dlg_update_done(ctrl, dlg);
} else if (event == EVENT_VALCHANGE) {
int i;
/* Update array to match the list box. */
for (i=0; i < KEX_MAX; i++)
conf_set_int_int(conf, CONF_ssh_kexlist, i,
dlg_listbox_getid(ctrl, dlg, i));
}
}
static void hklist_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
Conf *conf = (Conf *)data;
if (event == EVENT_REFRESH) {
int i;
static const struct { const char *s; int k; } hks[] = {
{ "Ed25519", HK_ED25519 },
{ "Ed448", HK_ED448 },
{ "ECDSA", HK_ECDSA },
{ "DSA", HK_DSA },
{ "RSA", HK_RSA },
{ "-- warn below here --", HK_WARN }
};
/* Set up the "host key preference" box. */
/* (hklist assumed to contain all algorithms) */
dlg_update_start(ctrl, dlg);
dlg_listbox_clear(ctrl, dlg);
for (i = 0; i < HK_MAX; i++) {
int k = conf_get_int_int(conf, CONF_ssh_hklist, i);
int j;
const char *kstr = NULL;
for (j = 0; j < lenof(hks); j++) {
if (hks[j].k == k) {
kstr = hks[j].s;
break;
}
}
dlg_listbox_addwithid(ctrl, dlg, kstr, k);
}
dlg_update_done(ctrl, dlg);
} else if (event == EVENT_VALCHANGE) {
int i;
/* Update array to match the list box. */
for (i=0; i < HK_MAX; i++)
conf_set_int_int(conf, CONF_ssh_hklist, i,
dlg_listbox_getid(ctrl, dlg, i));
}
}
static void printerbox_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
Conf *conf = (Conf *)data;
if (event == EVENT_REFRESH) {
int nprinters, i;
printer_enum *pe;
const char *printer;
dlg_update_start(ctrl, dlg);
/*
* Some backends may wish to disable the drop-down list on
* this edit box. Be prepared for this.
*/
if (ctrl->editbox.has_list) {
dlg_listbox_clear(ctrl, dlg);
dlg_listbox_add(ctrl, dlg, PRINTER_DISABLED_STRING);
pe = printer_start_enum(&nprinters);
for (i = 0; i < nprinters; i++)
dlg_listbox_add(ctrl, dlg, printer_get_name(pe, i));
printer_finish_enum(pe);
}
printer = conf_get_str(conf, CONF_printer);
if (!printer)
printer = PRINTER_DISABLED_STRING;
dlg_editbox_set(ctrl, dlg, printer);
dlg_update_done(ctrl, dlg);
} else if (event == EVENT_VALCHANGE) {
char *printer = dlg_editbox_get(ctrl, dlg);
if (!strcmp(printer, PRINTER_DISABLED_STRING))
printer[0] = '\0';
conf_set_str(conf, CONF_printer, printer);
sfree(printer);
}
}
static void codepage_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
Conf *conf = (Conf *)data;
if (event == EVENT_REFRESH) {
int i;
const char *cp, *thiscp;
dlg_update_start(ctrl, dlg);
thiscp = cp_name(decode_codepage(conf_get_str(conf,
CONF_line_codepage)));
dlg_listbox_clear(ctrl, dlg);
for (i = 0; (cp = cp_enumerate(i)) != NULL; i++)
dlg_listbox_add(ctrl, dlg, cp);
dlg_editbox_set(ctrl, dlg, thiscp);
conf_set_str(conf, CONF_line_codepage, thiscp);
dlg_update_done(ctrl, dlg);
} else if (event == EVENT_VALCHANGE) {
char *codepage = dlg_editbox_get(ctrl, dlg);
conf_set_str(conf, CONF_line_codepage,
cp_name(decode_codepage(codepage)));
sfree(codepage);
}
}
static void sshbug_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
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 (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;
}
dlg_update_done(ctrl, dlg);
} else if (event == EVENT_SELCHANGE) {
int i = dlg_listbox_index(ctrl, dlg);
if (i < 0)
i = AUTO;
else
i = dlg_listbox_getid(ctrl, dlg, i);
conf_set_int(conf, ctrl->listbox.context.i, i);
}
}
struct sessionsaver_data {
union control *editbox, *listbox, *loadbutton, *savebutton, *delbutton;
union control *okbutton, *cancelbutton;
struct sesslist sesslist;
Convert a lot of 'int' variables to 'bool'. My normal habit these days, in new code, is to treat int and bool as _almost_ completely separate types. I'm still willing to use C's implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine, no need to spell it out as blob.len != 0), but generally, if a variable is going to be conceptually a boolean, I like to declare it bool and assign to it using 'true' or 'false' rather than 0 or 1. PuTTY is an exception, because it predates the C99 bool, and I've stuck to its existing coding style even when adding new code to it. But it's been annoying me more and more, so now that I've decided C99 bool is an acceptable thing to require from our toolchain in the first place, here's a quite thorough trawl through the source doing 'boolification'. Many variables and function parameters are now typed as bool rather than int; many assignments of 0 or 1 to those variables are now spelled 'true' or 'false'. I managed this thorough conversion with the help of a custom clang plugin that I wrote to trawl the AST and apply heuristics to point out where things might want changing. So I've even managed to do a decent job on parts of the code I haven't looked at in years! To make the plugin's work easier, I pushed platform front ends generally in the direction of using standard 'bool' in preference to platform-specific boolean types like Windows BOOL or GTK's gboolean; I've left the platform booleans in places they _have_ to be for the platform APIs to work right, but variables only used by my own code have been converted wherever I found them. In a few places there are int values that look very like booleans in _most_ of the places they're used, but have a rarely-used third value, or a distinction between different nonzero values that most users don't care about. In these cases, I've _removed_ uses of 'true' and 'false' for the return values, to emphasise that there's something more subtle going on than a simple boolean answer: - the 'multisel' field in dialog.h's list box structure, for which the GTK front end in particular recognises a difference between 1 and 2 but nearly everything else treats as boolean - the 'urgent' parameter to plug_receive, where 1 vs 2 tells you something about the specific location of the urgent pointer, but most clients only care about 0 vs 'something nonzero' - the return value of wc_match, where -1 indicates a syntax error in the wildcard. - the return values from SSH-1 RSA-key loading functions, which use -1 for 'wrong passphrase' and 0 for all other failures (so any caller which already knows it's not loading an _encrypted private_ key can treat them as boolean) - term->esc_query, and the 'query' parameter in toggle_mode in terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h, but can also hold -1 for some other intervening character that we don't support. In a few places there's an integer that I haven't turned into a bool even though it really _can_ only take values 0 or 1 (and, as above, tried to make the call sites consistent in not calling those values true and false), on the grounds that I thought it would make it more confusing to imply that the 0 value was in some sense 'negative' or bad and the 1 positive or good: - the return value of plug_accepting uses the POSIXish convention of 0=success and nonzero=error; I think if I made it bool then I'd also want to reverse its sense, and that's a job for a separate piece of work. - the 'screen' parameter to lineptr() in terminal.c, where 0 and 1 represent the default and alternate screens. There's no obvious reason why one of those should be considered 'true' or 'positive' or 'success' - they're just indices - so I've left it as int. ssh_scp_recv had particularly confusing semantics for its previous int return value: its call sites used '<= 0' to check for error, but it never actually returned a negative number, just 0 or 1. Now the function and its call sites agree that it's a bool. In a couple of places I've renamed variables called 'ret', because I don't like that name any more - it's unclear whether it means the return value (in preparation) for the _containing_ function or the return value received from a subroutine call, and occasionally I've accidentally used the same variable for both and introduced a bug. So where one of those got in my way, I've renamed it to 'toret' or 'retd' (the latter short for 'returned') in line with my usual modern practice, but I haven't done a thorough job of finding all of them. Finally, one amusing side effect of doing this is that I've had to separate quite a few chained assignments. It used to be perfectly fine to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a the 'true' defined by stdbool.h, that idiom provokes a warning from gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
bool midsession;
char *savedsession; /* the current contents of ssd->editbox */
};
static void sessionsaver_data_free(void *ssdv)
{
struct sessionsaver_data *ssd = (struct sessionsaver_data *)ssdv;
get_sesslist(&ssd->sesslist, false);
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.
*/
Convert a lot of 'int' variables to 'bool'. My normal habit these days, in new code, is to treat int and bool as _almost_ completely separate types. I'm still willing to use C's implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine, no need to spell it out as blob.len != 0), but generally, if a variable is going to be conceptually a boolean, I like to declare it bool and assign to it using 'true' or 'false' rather than 0 or 1. PuTTY is an exception, because it predates the C99 bool, and I've stuck to its existing coding style even when adding new code to it. But it's been annoying me more and more, so now that I've decided C99 bool is an acceptable thing to require from our toolchain in the first place, here's a quite thorough trawl through the source doing 'boolification'. Many variables and function parameters are now typed as bool rather than int; many assignments of 0 or 1 to those variables are now spelled 'true' or 'false'. I managed this thorough conversion with the help of a custom clang plugin that I wrote to trawl the AST and apply heuristics to point out where things might want changing. So I've even managed to do a decent job on parts of the code I haven't looked at in years! To make the plugin's work easier, I pushed platform front ends generally in the direction of using standard 'bool' in preference to platform-specific boolean types like Windows BOOL or GTK's gboolean; I've left the platform booleans in places they _have_ to be for the platform APIs to work right, but variables only used by my own code have been converted wherever I found them. In a few places there are int values that look very like booleans in _most_ of the places they're used, but have a rarely-used third value, or a distinction between different nonzero values that most users don't care about. In these cases, I've _removed_ uses of 'true' and 'false' for the return values, to emphasise that there's something more subtle going on than a simple boolean answer: - the 'multisel' field in dialog.h's list box structure, for which the GTK front end in particular recognises a difference between 1 and 2 but nearly everything else treats as boolean - the 'urgent' parameter to plug_receive, where 1 vs 2 tells you something about the specific location of the urgent pointer, but most clients only care about 0 vs 'something nonzero' - the return value of wc_match, where -1 indicates a syntax error in the wildcard. - the return values from SSH-1 RSA-key loading functions, which use -1 for 'wrong passphrase' and 0 for all other failures (so any caller which already knows it's not loading an _encrypted private_ key can treat them as boolean) - term->esc_query, and the 'query' parameter in toggle_mode in terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h, but can also hold -1 for some other intervening character that we don't support. In a few places there's an integer that I haven't turned into a bool even though it really _can_ only take values 0 or 1 (and, as above, tried to make the call sites consistent in not calling those values true and false), on the grounds that I thought it would make it more confusing to imply that the 0 value was in some sense 'negative' or bad and the 1 positive or good: - the return value of plug_accepting uses the POSIXish convention of 0=success and nonzero=error; I think if I made it bool then I'd also want to reverse its sense, and that's a job for a separate piece of work. - the 'screen' parameter to lineptr() in terminal.c, where 0 and 1 represent the default and alternate screens. There's no obvious reason why one of those should be considered 'true' or 'positive' or 'success' - they're just indices - so I've left it as int. ssh_scp_recv had particularly confusing semantics for its previous int return value: its call sites used '<= 0' to check for error, but it never actually returned a negative number, just 0 or 1. Now the function and its call sites agree that it's a bool. In a couple of places I've renamed variables called 'ret', because I don't like that name any more - it's unclear whether it means the return value (in preparation) for the _containing_ function or the return value received from a subroutine call, and occasionally I've accidentally used the same variable for both and introduced a bug. So where one of those got in my way, I've renamed it to 'toret' or 'retd' (the latter short for 'returned') in line with my usual modern practice, but I haven't done a thorough job of finding all of them. Finally, one amusing side effect of doing this is that I've had to separate quite a few chained assignments. It used to be perfectly fine to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a the 'true' defined by stdbool.h, that idiom provokes a warning from gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
static bool load_selected_session(
struct sessionsaver_data *ssd,
dlgparam *dlg, Conf *conf, bool *maybe_launch)
{
int i = dlg_listbox_index(ssd->listbox, dlg);
Convert a lot of 'int' variables to 'bool'. My normal habit these days, in new code, is to treat int and bool as _almost_ completely separate types. I'm still willing to use C's implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine, no need to spell it out as blob.len != 0), but generally, if a variable is going to be conceptually a boolean, I like to declare it bool and assign to it using 'true' or 'false' rather than 0 or 1. PuTTY is an exception, because it predates the C99 bool, and I've stuck to its existing coding style even when adding new code to it. But it's been annoying me more and more, so now that I've decided C99 bool is an acceptable thing to require from our toolchain in the first place, here's a quite thorough trawl through the source doing 'boolification'. Many variables and function parameters are now typed as bool rather than int; many assignments of 0 or 1 to those variables are now spelled 'true' or 'false'. I managed this thorough conversion with the help of a custom clang plugin that I wrote to trawl the AST and apply heuristics to point out where things might want changing. So I've even managed to do a decent job on parts of the code I haven't looked at in years! To make the plugin's work easier, I pushed platform front ends generally in the direction of using standard 'bool' in preference to platform-specific boolean types like Windows BOOL or GTK's gboolean; I've left the platform booleans in places they _have_ to be for the platform APIs to work right, but variables only used by my own code have been converted wherever I found them. In a few places there are int values that look very like booleans in _most_ of the places they're used, but have a rarely-used third value, or a distinction between different nonzero values that most users don't care about. In these cases, I've _removed_ uses of 'true' and 'false' for the return values, to emphasise that there's something more subtle going on than a simple boolean answer: - the 'multisel' field in dialog.h's list box structure, for which the GTK front end in particular recognises a difference between 1 and 2 but nearly everything else treats as boolean - the 'urgent' parameter to plug_receive, where 1 vs 2 tells you something about the specific location of the urgent pointer, but most clients only care about 0 vs 'something nonzero' - the return value of wc_match, where -1 indicates a syntax error in the wildcard. - the return values from SSH-1 RSA-key loading functions, which use -1 for 'wrong passphrase' and 0 for all other failures (so any caller which already knows it's not loading an _encrypted private_ key can treat them as boolean) - term->esc_query, and the 'query' parameter in toggle_mode in terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h, but can also hold -1 for some other intervening character that we don't support. In a few places there's an integer that I haven't turned into a bool even though it really _can_ only take values 0 or 1 (and, as above, tried to make the call sites consistent in not calling those values true and false), on the grounds that I thought it would make it more confusing to imply that the 0 value was in some sense 'negative' or bad and the 1 positive or good: - the return value of plug_accepting uses the POSIXish convention of 0=success and nonzero=error; I think if I made it bool then I'd also want to reverse its sense, and that's a job for a separate piece of work. - the 'screen' parameter to lineptr() in terminal.c, where 0 and 1 represent the default and alternate screens. There's no obvious reason why one of those should be considered 'true' or 'positive' or 'success' - they're just indices - so I've left it as int. ssh_scp_recv had particularly confusing semantics for its previous int return value: its call sites used '<= 0' to check for error, but it never actually returned a negative number, just 0 or 1. Now the function and its call sites agree that it's a bool. In a couple of places I've renamed variables called 'ret', because I don't like that name any more - it's unclear whether it means the return value (in preparation) for the _containing_ function or the return value received from a subroutine call, and occasionally I've accidentally used the same variable for both and introduced a bug. So where one of those got in my way, I've renamed it to 'toret' or 'retd' (the latter short for 'returned') in line with my usual modern practice, but I haven't done a thorough job of finding all of them. Finally, one amusing side effect of doing this is that I've had to separate quite a few chained assignments. It used to be perfectly fine to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a the 'true' defined by stdbool.h, that idiom provokes a warning from gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
bool isdef;
if (i < 0) {
dlg_beep(dlg);
return false;
}
isdef = !strcmp(ssd->sesslist.sessions[i], "Default Settings");
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
load_settings(ssd->sesslist.sessions[i], conf);
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. */
dlg_listbox_select(ssd->listbox, dlg, i);
Convert a lot of 'int' variables to 'bool'. My normal habit these days, in new code, is to treat int and bool as _almost_ completely separate types. I'm still willing to use C's implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine, no need to spell it out as blob.len != 0), but generally, if a variable is going to be conceptually a boolean, I like to declare it bool and assign to it using 'true' or 'false' rather than 0 or 1. PuTTY is an exception, because it predates the C99 bool, and I've stuck to its existing coding style even when adding new code to it. But it's been annoying me more and more, so now that I've decided C99 bool is an acceptable thing to require from our toolchain in the first place, here's a quite thorough trawl through the source doing 'boolification'. Many variables and function parameters are now typed as bool rather than int; many assignments of 0 or 1 to those variables are now spelled 'true' or 'false'. I managed this thorough conversion with the help of a custom clang plugin that I wrote to trawl the AST and apply heuristics to point out where things might want changing. So I've even managed to do a decent job on parts of the code I haven't looked at in years! To make the plugin's work easier, I pushed platform front ends generally in the direction of using standard 'bool' in preference to platform-specific boolean types like Windows BOOL or GTK's gboolean; I've left the platform booleans in places they _have_ to be for the platform APIs to work right, but variables only used by my own code have been converted wherever I found them. In a few places there are int values that look very like booleans in _most_ of the places they're used, but have a rarely-used third value, or a distinction between different nonzero values that most users don't care about. In these cases, I've _removed_ uses of 'true' and 'false' for the return values, to emphasise that there's something more subtle going on than a simple boolean answer: - the 'multisel' field in dialog.h's list box structure, for which the GTK front end in particular recognises a difference between 1 and 2 but nearly everything else treats as boolean - the 'urgent' parameter to plug_receive, where 1 vs 2 tells you something about the specific location of the urgent pointer, but most clients only care about 0 vs 'something nonzero' - the return value of wc_match, where -1 indicates a syntax error in the wildcard. - the return values from SSH-1 RSA-key loading functions, which use -1 for 'wrong passphrase' and 0 for all other failures (so any caller which already knows it's not loading an _encrypted private_ key can treat them as boolean) - term->esc_query, and the 'query' parameter in toggle_mode in terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h, but can also hold -1 for some other intervening character that we don't support. In a few places there's an integer that I haven't turned into a bool even though it really _can_ only take values 0 or 1 (and, as above, tried to make the call sites consistent in not calling those values true and false), on the grounds that I thought it would make it more confusing to imply that the 0 value was in some sense 'negative' or bad and the 1 positive or good: - the return value of plug_accepting uses the POSIXish convention of 0=success and nonzero=error; I think if I made it bool then I'd also want to reverse its sense, and that's a job for a separate piece of work. - the 'screen' parameter to lineptr() in terminal.c, where 0 and 1 represent the default and alternate screens. There's no obvious reason why one of those should be considered 'true' or 'positive' or 'success' - they're just indices - so I've left it as int. ssh_scp_recv had particularly confusing semantics for its previous int return value: its call sites used '<= 0' to check for error, but it never actually returned a negative number, just 0 or 1. Now the function and its call sites agree that it's a bool. In a couple of places I've renamed variables called 'ret', because I don't like that name any more - it's unclear whether it means the return value (in preparation) for the _containing_ function or the return value received from a subroutine call, and occasionally I've accidentally used the same variable for both and introduced a bug. So where one of those got in my way, I've renamed it to 'toret' or 'retd' (the latter short for 'returned') in line with my usual modern practice, but I haven't done a thorough job of finding all of them. Finally, one amusing side effect of doing this is that I've had to separate quite a few chained assignments. It used to be perfectly fine to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a the 'true' defined by stdbool.h, that idiom provokes a warning from gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
return true;
}
static void sessionsaver_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
Conf *conf = (Conf *)data;
struct sessionsaver_data *ssd =
(struct sessionsaver_data *)ctrl->generic.context.p;
if (event == EVENT_REFRESH) {
if (ctrl == ssd->editbox) {
dlg_editbox_set(ctrl, dlg, ssd->savedsession);
} else if (ctrl == ssd->listbox) {
int i;
dlg_update_start(ctrl, dlg);
dlg_listbox_clear(ctrl, dlg);
for (i = 0; i < ssd->sesslist.nsessions; i++)
dlg_listbox_add(ctrl, dlg, ssd->sesslist.sessions[i]);
dlg_update_done(ctrl, dlg);
}
} else if (event == EVENT_VALCHANGE) {
int top, bottom, halfway, i;
if (ctrl == ssd->editbox) {
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(ssd->savedsession, ssd->sesslist.sessions[halfway]);
if (i <= 0 ) {
top = halfway;
} else {
bottom = halfway;
}
}
if (top == ssd->sesslist.nsessions) {
top -= 1;
}
dlg_listbox_select(ssd->listbox, dlg, top);
}
} else if (event == EVENT_ACTION) {
bool mbl = false;
if (!ssd->midsession &&
(ctrl == ssd->listbox ||
(ssd->loadbutton && ctrl == ssd->loadbutton))) {
/*
* The user has double-clicked a session, or hit Load.
* We must load the selected session, and then
* terminate the configuration dialog _if_ there was a
* double-click on the list box _and_ that session
* contains a hostname.
*/
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) {
bool 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");
sfree(ssd->savedsession);
ssd->savedsession = dupstr(isdef ? "" :
ssd->sesslist.sessions[i]);
}
{
char *errmsg = save_settings(ssd->savedsession, conf);
if (errmsg) {
dlg_error_msg(dlg, errmsg);
sfree(errmsg);
}
}
get_sesslist(&ssd->sesslist, false);
get_sesslist(&ssd->sesslist, true);
dlg_refresh(ssd->editbox, dlg);
dlg_refresh(ssd->listbox, dlg);
} else if (!ssd->midsession &&
ssd->delbutton && ctrl == ssd->delbutton) {
int i = dlg_listbox_index(ssd->listbox, dlg);
if (i <= 0) {
dlg_beep(dlg);
} else {
del_settings(ssd->sesslist.sessions[i]);
get_sesslist(&ssd->sesslist, false);
get_sesslist(&ssd->sesslist, true);
dlg_refresh(ssd->listbox, dlg);
}
} else if (ctrl == ssd->okbutton) {
if (ssd->midsession) {
/* In a mid-session Change Settings, Apply is always OK. */
dlg_end(dlg, 1);
return;
}
/*
* Annoying special case. If the `Open' button is
* pressed while no host name is currently set, _and_
* the session list previously had the focus, _and_
* there was a session selected in that which had a
* valid host name in it, then load it and go.
*/
if (dlg_last_focused(ctrl, dlg) == ssd->listbox &&
!conf_launchable(conf) && dlg_is_visible(ssd->listbox, dlg)) {
Conf *conf2 = conf_new();
bool mbl = false;
if (!load_selected_session(ssd, dlg, conf2, &mbl)) {
dlg_beep(dlg);
conf_free(conf2);
return;
}
/* If at this point we have a valid session, go! */
if (mbl && conf_launchable(conf2)) {
conf_copy_into(conf, conf2);
dlg_end(dlg, 1);
} else
dlg_beep(dlg);
conf_free(conf2);
return;
}
/*
* Otherwise, do the normal thing: if we have a valid
* session, get going.
*/
if (conf_launchable(conf)) {
dlg_end(dlg, 1);
} else
dlg_beep(dlg);
} else if (ctrl == ssd->cancelbutton) {
dlg_end(dlg, 0);
}
}
}
struct charclass_data {
union control *listbox, *editbox, *button;
};
static void charclass_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
Conf *conf = (Conf *)data;
struct charclass_data *ccd =
(struct charclass_data *)ctrl->generic.context.p;
if (event == EVENT_REFRESH) {
if (ctrl == ccd->listbox) {
int i;
dlg_update_start(ctrl, dlg);
dlg_listbox_clear(ctrl, dlg);
for (i = 0; i < 128; i++) {
char str[100];
sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
(i >= 0x21 && i != 0x7F) ? i : ' ',
conf_get_int_int(conf, CONF_wordness, i));
dlg_listbox_add(ctrl, dlg, str);
}
dlg_update_done(ctrl, dlg);
}
} else if (event == EVENT_ACTION) {
if (ctrl == ccd->button) {
char *str;
int i, n;
str = dlg_editbox_get(ccd->editbox, dlg);
n = atoi(str);
sfree(str);
for (i = 0; i < 128; i++) {
if (dlg_listbox_issel(ccd->listbox, dlg, i))
conf_set_int_int(conf, CONF_wordness, i, n);
}
dlg_refresh(ccd->listbox, dlg);
}
}
}
struct colour_data {
union control *listbox, *redit, *gedit, *bedit, *button;
};
static const char *const colours[] = {
"Default Foreground", "Default Bold Foreground",
"Default Background", "Default Bold Background",
"Cursor Text", "Cursor Colour",
"ANSI Black", "ANSI Black Bold",
"ANSI Red", "ANSI Red Bold",
"ANSI Green", "ANSI Green Bold",
"ANSI Yellow", "ANSI Yellow Bold",
"ANSI Blue", "ANSI Blue Bold",
"ANSI Magenta", "ANSI Magenta Bold",
"ANSI Cyan", "ANSI Cyan Bold",
"ANSI White", "ANSI White Bold"
};
static void colour_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
Conf *conf = (Conf *)data;
struct colour_data *cd =
(struct colour_data *)ctrl->generic.context.p;
Convert a lot of 'int' variables to 'bool'. My normal habit these days, in new code, is to treat int and bool as _almost_ completely separate types. I'm still willing to use C's implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine, no need to spell it out as blob.len != 0), but generally, if a variable is going to be conceptually a boolean, I like to declare it bool and assign to it using 'true' or 'false' rather than 0 or 1. PuTTY is an exception, because it predates the C99 bool, and I've stuck to its existing coding style even when adding new code to it. But it's been annoying me more and more, so now that I've decided C99 bool is an acceptable thing to require from our toolchain in the first place, here's a quite thorough trawl through the source doing 'boolification'. Many variables and function parameters are now typed as bool rather than int; many assignments of 0 or 1 to those variables are now spelled 'true' or 'false'. I managed this thorough conversion with the help of a custom clang plugin that I wrote to trawl the AST and apply heuristics to point out where things might want changing. So I've even managed to do a decent job on parts of the code I haven't looked at in years! To make the plugin's work easier, I pushed platform front ends generally in the direction of using standard 'bool' in preference to platform-specific boolean types like Windows BOOL or GTK's gboolean; I've left the platform booleans in places they _have_ to be for the platform APIs to work right, but variables only used by my own code have been converted wherever I found them. In a few places there are int values that look very like booleans in _most_ of the places they're used, but have a rarely-used third value, or a distinction between different nonzero values that most users don't care about. In these cases, I've _removed_ uses of 'true' and 'false' for the return values, to emphasise that there's something more subtle going on than a simple boolean answer: - the 'multisel' field in dialog.h's list box structure, for which the GTK front end in particular recognises a difference between 1 and 2 but nearly everything else treats as boolean - the 'urgent' parameter to plug_receive, where 1 vs 2 tells you something about the specific location of the urgent pointer, but most clients only care about 0 vs 'something nonzero' - the return value of wc_match, where -1 indicates a syntax error in the wildcard. - the return values from SSH-1 RSA-key loading functions, which use -1 for 'wrong passphrase' and 0 for all other failures (so any caller which already knows it's not loading an _encrypted private_ key can treat them as boolean) - term->esc_query, and the 'query' parameter in toggle_mode in terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h, but can also hold -1 for some other intervening character that we don't support. In a few places there's an integer that I haven't turned into a bool even though it really _can_ only take values 0 or 1 (and, as above, tried to make the call sites consistent in not calling those values true and false), on the grounds that I thought it would make it more confusing to imply that the 0 value was in some sense 'negative' or bad and the 1 positive or good: - the return value of plug_accepting uses the POSIXish convention of 0=success and nonzero=error; I think if I made it bool then I'd also want to reverse its sense, and that's a job for a separate piece of work. - the 'screen' parameter to lineptr() in terminal.c, where 0 and 1 represent the default and alternate screens. There's no obvious reason why one of those should be considered 'true' or 'positive' or 'success' - they're just indices - so I've left it as int. ssh_scp_recv had particularly confusing semantics for its previous int return value: its call sites used '<= 0' to check for error, but it never actually returned a negative number, just 0 or 1. Now the function and its call sites agree that it's a bool. In a couple of places I've renamed variables called 'ret', because I don't like that name any more - it's unclear whether it means the return value (in preparation) for the _containing_ function or the return value received from a subroutine call, and occasionally I've accidentally used the same variable for both and introduced a bug. So where one of those got in my way, I've renamed it to 'toret' or 'retd' (the latter short for 'returned') in line with my usual modern practice, but I haven't done a thorough job of finding all of them. Finally, one amusing side effect of doing this is that I've had to separate quite a few chained assignments. It used to be perfectly fine to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a the 'true' defined by stdbool.h, that idiom provokes a warning from gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
bool update = false, clear = false;
int r, g, b;
if (event == EVENT_REFRESH) {
if (ctrl == cd->listbox) {
int i;
dlg_update_start(ctrl, dlg);
dlg_listbox_clear(ctrl, dlg);
for (i = 0; i < lenof(colours); i++)
dlg_listbox_add(ctrl, dlg, colours[i]);
dlg_update_done(ctrl, dlg);
clear = true;
update = true;
}
} else if (event == EVENT_SELCHANGE) {
if (ctrl == cd->listbox) {
/* The user has selected a colour. Update the RGB text. */
int i = dlg_listbox_index(ctrl, dlg);
if (i < 0) {
clear = true;
} else {
clear = false;
r = conf_get_int_int(conf, CONF_colours, i*3+0);
g = conf_get_int_int(conf, CONF_colours, i*3+1);
b = conf_get_int_int(conf, CONF_colours, i*3+2);
}
update = true;
}
} else if (event == EVENT_VALCHANGE) {
if (ctrl == cd->redit || ctrl == cd->gedit || ctrl == cd->bedit) {
/* The user has changed the colour using the edit boxes. */
char *str;
int i, cval;
str = dlg_editbox_get(ctrl, dlg);
cval = atoi(str);
sfree(str);
if (cval > 255) cval = 255;
if (cval < 0) cval = 0;
i = dlg_listbox_index(cd->listbox, dlg);
if (i >= 0) {
if (ctrl == cd->redit)
conf_set_int_int(conf, CONF_colours, i*3+0, cval);
else if (ctrl == cd->gedit)
conf_set_int_int(conf, CONF_colours, i*3+1, cval);
else if (ctrl == cd->bedit)
conf_set_int_int(conf, CONF_colours, i*3+2, cval);
}
}
} else if (event == EVENT_ACTION) {
if (ctrl == cd->button) {
int i = dlg_listbox_index(cd->listbox, dlg);
if (i < 0) {
dlg_beep(dlg);
return;
}
/*
* Start a colour selector, which will send us an
* EVENT_CALLBACK when it's finished and allow us to
* pick up the results.
*/
dlg_coloursel_start(ctrl, dlg,
conf_get_int_int(conf, CONF_colours, i*3+0),
conf_get_int_int(conf, CONF_colours, i*3+1),
conf_get_int_int(conf, CONF_colours, i*3+2));
}
} else if (event == EVENT_CALLBACK) {
if (ctrl == cd->button) {
int i = dlg_listbox_index(cd->listbox, dlg);
/*
* Collect the results of the colour selector. Will
* return nonzero on success, or zero if the colour
* selector did nothing (user hit Cancel, for example).
*/
if (dlg_coloursel_results(ctrl, dlg, &r, &g, &b)) {
conf_set_int_int(conf, CONF_colours, i*3+0, r);
conf_set_int_int(conf, CONF_colours, i*3+1, g);
conf_set_int_int(conf, CONF_colours, i*3+2, b);
clear = false;
update = true;
}
}
}
if (update) {
if (clear) {
dlg_editbox_set(cd->redit, dlg, "");
dlg_editbox_set(cd->gedit, dlg, "");
dlg_editbox_set(cd->bedit, dlg, "");
} else {
char buf[40];
sprintf(buf, "%d", r); dlg_editbox_set(cd->redit, dlg, buf);
sprintf(buf, "%d", g); dlg_editbox_set(cd->gedit, dlg, buf);
sprintf(buf, "%d", b); dlg_editbox_set(cd->bedit, dlg, buf);
}
}
}
struct ttymodes_data {
union control *valradio, *valbox, *setbutton, *listbox;
};
static void ttymodes_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
Conf *conf = (Conf *)data;
struct ttymodes_data *td =
(struct ttymodes_data *)ctrl->generic.context.p;
if (event == EVENT_REFRESH) {
if (ctrl == td->listbox) {
char *key, *val;
dlg_update_start(ctrl, dlg);
dlg_listbox_clear(ctrl, dlg);
for (val = conf_get_str_strs(conf, CONF_ttymodes, NULL, &key);
val != NULL;
val = conf_get_str_strs(conf, CONF_ttymodes, key, &key)) {
char *disp = dupprintf("%s\t%s", key,
(val[0] == 'A') ? "(auto)" :
((val[0] == 'N') ? "(don't send)"
: val+1));
dlg_listbox_add(ctrl, dlg, disp);
sfree(disp);
}
dlg_update_done(ctrl, dlg);
} else if (ctrl == td->valradio) {
dlg_radiobutton_set(ctrl, dlg, 0);
}
} else if (event == EVENT_SELCHANGE) {
if (ctrl == td->listbox) {
int ind = dlg_listbox_index(td->listbox, dlg);
char *val;
if (ind < 0) {
return; /* no item selected */
}
val = conf_get_str_str(conf, CONF_ttymodes,
conf_get_str_nthstrkey(conf, CONF_ttymodes,
ind));
assert(val != NULL);
/* Do this first to defuse side-effects on radio buttons: */
dlg_editbox_set(td->valbox, dlg, val+1);
dlg_radiobutton_set(td->valradio, dlg,
val[0] == 'A' ? 0 : (val[0] == 'N' ? 1 : 2));
}
} else if (event == EVENT_VALCHANGE) {
if (ctrl == td->valbox) {
/* If they're editing the text box, we assume they want its
* value to be used. */
dlg_radiobutton_set(td->valradio, dlg, 2);
}
} else if (event == EVENT_ACTION) {
if (ctrl == td->setbutton) {
int ind = dlg_listbox_index(td->listbox, dlg);
const char *key;
char *str, *val;
char type;
{
const char types[] = {'A', 'N', 'V'};
int button = dlg_radiobutton_get(td->valradio, dlg);
assert(button >= 0 && button < lenof(types));
type = types[button];
}
/* Construct new entry */
if (ind >= 0) {
key = conf_get_str_nthstrkey(conf, CONF_ttymodes, ind);
str = (type == 'V' ? dlg_editbox_get(td->valbox, dlg)
: dupstr(""));
val = dupprintf("%c%s", type, str);
sfree(str);
conf_set_str_str(conf, CONF_ttymodes, key, val);
sfree(val);
dlg_refresh(td->listbox, dlg);
dlg_listbox_select(td->listbox, dlg, ind);
} else {
/* Not a multisel listbox, so this means nothing selected */
dlg_beep(dlg);
}
}
}
}
struct environ_data {
union control *varbox, *valbox, *addbutton, *rembutton, *listbox;
};
static void environ_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
Conf *conf = (Conf *)data;
struct environ_data *ed =
(struct environ_data *)ctrl->generic.context.p;
if (event == EVENT_REFRESH) {
if (ctrl == ed->listbox) {
char *key, *val;
dlg_update_start(ctrl, dlg);
dlg_listbox_clear(ctrl, dlg);
for (val = conf_get_str_strs(conf, CONF_environmt, NULL, &key);
val != NULL;
val = conf_get_str_strs(conf, CONF_environmt, key, &key)) {
char *p = dupprintf("%s\t%s", key, val);
dlg_listbox_add(ctrl, dlg, p);
sfree(p);
}
dlg_update_done(ctrl, dlg);
}
} else if (event == EVENT_ACTION) {
if (ctrl == ed->addbutton) {
char *key, *val, *str;
key = dlg_editbox_get(ed->varbox, dlg);
if (!*key) {
sfree(key);
dlg_beep(dlg);
return;
}
val = dlg_editbox_get(ed->valbox, dlg);
if (!*val) {
sfree(key);
sfree(val);
dlg_beep(dlg);
return;
}
conf_set_str_str(conf, CONF_environmt, key, val);
str = dupcat(key, "\t", val);
dlg_editbox_set(ed->varbox, dlg, "");
dlg_editbox_set(ed->valbox, dlg, "");
sfree(str);
sfree(key);
sfree(val);
dlg_refresh(ed->listbox, dlg);
} else if (ctrl == ed->rembutton) {
int i = dlg_listbox_index(ed->listbox, dlg);
if (i < 0) {
dlg_beep(dlg);
} else {
char *key, *val;
key = conf_get_str_nthstrkey(conf, CONF_environmt, i);
if (key) {
/* Populate controls with the entry we're about to delete
* for ease of editing */
val = conf_get_str_str(conf, CONF_environmt, key);
dlg_editbox_set(ed->varbox, dlg, key);
dlg_editbox_set(ed->valbox, dlg, val);
/* And delete it */
conf_del_str_str(conf, CONF_environmt, key);
}
}
dlg_refresh(ed->listbox, dlg);
}
}
}
struct portfwd_data {
union control *addbutton, *rembutton, *listbox;
union control *sourcebox, *destbox, *direction;
#ifndef NO_IPV6
union control *addressfamily;
#endif
};
static void portfwd_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
Conf *conf = (Conf *)data;
struct portfwd_data *pfd =
(struct portfwd_data *)ctrl->generic.context.p;
if (event == EVENT_REFRESH) {
if (ctrl == pfd->listbox) {
char *key, *val;
dlg_update_start(ctrl, dlg);
dlg_listbox_clear(ctrl, dlg);
for (val = conf_get_str_strs(conf, CONF_portfwd, NULL, &key);
val != NULL;
val = conf_get_str_strs(conf, CONF_portfwd, key, &key)) {
char *p;
if (!strcmp(val, "D")) {
char *L;
/*
* A dynamic forwarding is stored as L12345=D or
* 6L12345=D (since it's mutually exclusive with
* L12345=anything else), but displayed as D12345
* to match the fiction that 'Local', 'Remote' and
* 'Dynamic' are three distinct modes and also to
* align with OpenSSH's command line option syntax
* that people will already be used to. So, for
* display purposes, find the L in the key string
* and turn it into a D.
*/
p = dupprintf("%s\t", key);
L = strchr(p, 'L');
if (L) *L = 'D';
} else
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
p = dupprintf("%s\t%s", key, val);
dlg_listbox_add(ctrl, dlg, p);
sfree(p);
}
dlg_update_done(ctrl, dlg);
} else if (ctrl == pfd->direction) {
/*
* Default is Local.
*/
dlg_radiobutton_set(ctrl, dlg, 0);
#ifndef NO_IPV6
} else if (ctrl == pfd->addressfamily) {
dlg_radiobutton_set(ctrl, dlg, 0);
#endif
}
} else if (event == EVENT_ACTION) {
if (ctrl == pfd->addbutton) {
const char *family, *type;
char *src, *key, *val;
int whichbutton;
#ifndef NO_IPV6
whichbutton = dlg_radiobutton_get(pfd->addressfamily, dlg);
if (whichbutton == 1)
family = "4";
else if (whichbutton == 2)
family = "6";
else
#endif
family = "";
whichbutton = dlg_radiobutton_get(pfd->direction, dlg);
if (whichbutton == 0)
type = "L";
else if (whichbutton == 1)
type = "R";
else
type = "D";
src = dlg_editbox_get(pfd->sourcebox, dlg);
if (!*src) {
dlg_error_msg(dlg, "You need to specify a source port number");
sfree(src);
return;
}
if (*type != 'D') {
val = dlg_editbox_get(pfd->destbox, dlg);
if (!*val || !host_strchr(val, ':')) {
dlg_error_msg(dlg,
"You need to specify a destination address\n"
"in the form \"host.name:port\"");
sfree(src);
sfree(val);
return;
}
} else {
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
type = "L";
val = dupstr("D"); /* special case */
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
}
key = dupcat(family, type, src);
sfree(src);
if (conf_get_str_str_opt(conf, CONF_portfwd, key)) {
dlg_error_msg(dlg, "Specified forwarding already exists");
} else {
conf_set_str_str(conf, CONF_portfwd, key, val);
}
sfree(key);
sfree(val);
dlg_refresh(pfd->listbox, dlg);
} else if (ctrl == pfd->rembutton) {
int i = dlg_listbox_index(pfd->listbox, dlg);
if (i < 0) {
dlg_beep(dlg);
} else {
char *key, *p;
const char *val;
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
key = conf_get_str_nthstrkey(conf, CONF_portfwd, i);
if (key) {
static const char *const afs = "A46";
static const char *const dirs = "LRD";
const char *afp;
int dir;
#ifndef NO_IPV6
int idx;
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
#endif
/* Populate controls with the entry we're about to delete
* for ease of editing */
p = key;
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
afp = strchr(afs, *p);
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
#ifndef NO_IPV6
idx = afp ? afp-afs : 0;
#endif
if (afp)
p++;
#ifndef NO_IPV6
dlg_radiobutton_set(pfd->addressfamily, dlg, idx);
#endif
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
dir = *p;
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
val = conf_get_str_str(conf, CONF_portfwd, key);
if (!strcmp(val, "D")) {
Post-release destabilisation! Completely remove the struct type 'Config' in putty.h, which stores all PuTTY's settings and includes an arbitrary length limit on every single one of those settings which is stored in string form. In place of it is 'Conf', an opaque data type everywhere outside the new file conf.c, which stores a list of (key, value) pairs in which every key contains an integer identifying a configuration setting, and for some of those integers the key also contains extra parts (so that, for instance, CONF_environmt is a string-to-string mapping). Everywhere that a Config was previously used, a Conf is now; everywhere there was a Config structure copy, conf_copy() is called; every lookup, adjustment, load and save operation on a Config has been rewritten; and there's a mechanism for serialising a Conf into a binary blob and back for use with Duplicate Session. User-visible effects of this change _should_ be minimal, though I don't doubt I've introduced one or two bugs here and there which will eventually be found. The _intended_ visible effects of this change are that all arbitrary limits on configuration strings and lists (e.g. limit on number of port forwardings) should now disappear; that list boxes in the configuration will now be displayed in a sorted order rather than the arbitrary order in which they were added to the list (since the underlying data structure is now a sorted tree234 rather than an ad-hoc comma-separated string); and one more specific change, which is that local and dynamic port forwardings on the same port number are now mutually exclusive in the configuration (putting 'D' in the key rather than the value was a mistake in the first place). One other reorganisation as a result of this is that I've moved all the dialog.c standard handlers (dlg_stdeditbox_handler and friends) out into config.c, because I can't really justify calling them generic any more. When they took a pointer to an arbitrary structure type and the offset of a field within that structure, they were independent of whether that structure was a Config or something completely different, but now they really do expect to talk to a Conf, which can _only_ be used for PuTTY configuration, so I've renamed them all things like conf_editbox_handler and moved them out of the nominally independent dialog-box management module into the PuTTY-specific config.c. [originally from svn r9214]
2011-07-14 18:52:21 +00:00
dir = 'D';
val = "";
}
dlg_radiobutton_set(pfd->direction, dlg,
strchr(dirs, dir) - dirs);
p++;
dlg_editbox_set(pfd->sourcebox, dlg, p);
dlg_editbox_set(pfd->destbox, dlg, val);
/* And delete it */
conf_del_str_str(conf, CONF_portfwd, key);
}
}
dlg_refresh(pfd->listbox, dlg);
}
}
}
struct manual_hostkey_data {
union control *addbutton, *rembutton, *listbox, *keybox;
};
static void manual_hostkey_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
Conf *conf = (Conf *)data;
struct manual_hostkey_data *mh =
(struct manual_hostkey_data *)ctrl->generic.context.p;
if (event == EVENT_REFRESH) {
if (ctrl == mh->listbox) {
char *key, *val;
dlg_update_start(ctrl, dlg);
dlg_listbox_clear(ctrl, dlg);
for (val = conf_get_str_strs(conf, CONF_ssh_manual_hostkeys,
NULL, &key);
val != NULL;
val = conf_get_str_strs(conf, CONF_ssh_manual_hostkeys,
key, &key)) {
dlg_listbox_add(ctrl, dlg, key);
}
dlg_update_done(ctrl, dlg);
}
} else if (event == EVENT_ACTION) {
if (ctrl == mh->addbutton) {
char *key;
key = dlg_editbox_get(mh->keybox, dlg);
if (!*key) {
dlg_error_msg(dlg, "You need to specify a host key or "
"fingerprint");
sfree(key);
return;
}
if (!validate_manual_hostkey(key)) {
dlg_error_msg(dlg, "Host key is not in a valid format");
} else if (conf_get_str_str_opt(conf, CONF_ssh_manual_hostkeys,
key)) {
dlg_error_msg(dlg, "Specified host key is already listed");
} else {
conf_set_str_str(conf, CONF_ssh_manual_hostkeys, key, "");
}
sfree(key);
dlg_refresh(mh->listbox, dlg);
} else if (ctrl == mh->rembutton) {
int i = dlg_listbox_index(mh->listbox, dlg);
if (i < 0) {
dlg_beep(dlg);
} else {
char *key;
key = conf_get_str_nthstrkey(conf, CONF_ssh_manual_hostkeys, i);
if (key) {
dlg_editbox_set(mh->keybox, dlg, key);
/* And delete it */
conf_del_str_str(conf, CONF_ssh_manual_hostkeys, key);
}
}
dlg_refresh(mh->listbox, dlg);
}
}
}
static void clipboard_selector_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
Conf *conf = (Conf *)data;
int setting = ctrl->generic.context.i;
#ifdef NAMED_CLIPBOARDS
int strsetting = ctrl->editbox.context2.i;
#endif
static const struct {
const char *name;
int id;
} options[] = {
{"No action", CLIPUI_NONE},
{CLIPNAME_IMPLICIT, CLIPUI_IMPLICIT},
{CLIPNAME_EXPLICIT, CLIPUI_EXPLICIT},
};
if (event == EVENT_REFRESH) {
int i, val = conf_get_int(conf, setting);
dlg_update_start(ctrl, dlg);
dlg_listbox_clear(ctrl, dlg);
#ifdef NAMED_CLIPBOARDS
for (i = 0; i < lenof(options); i++)
dlg_listbox_add(ctrl, dlg, options[i].name);
if (val == CLIPUI_CUSTOM) {
const char *sval = conf_get_str(conf, strsetting);
for (i = 0; i < lenof(options); i++)
if (!strcmp(sval, options[i].name))
break; /* needs escaping */
if (i < lenof(options) || sval[0] == '=') {
char *escaped = dupcat("=", sval);
dlg_editbox_set(ctrl, dlg, escaped);
sfree(escaped);
} else {
dlg_editbox_set(ctrl, dlg, sval);
}
} else {
dlg_editbox_set(ctrl, dlg, options[0].name); /* fallback */
for (i = 0; i < lenof(options); i++)
if (val == options[i].id)
dlg_editbox_set(ctrl, dlg, options[i].name);
}
#else
for (i = 0; i < lenof(options); i++)
dlg_listbox_addwithid(ctrl, dlg, options[i].name, options[i].id);
dlg_listbox_select(ctrl, dlg, 0); /* fallback */
for (i = 0; i < lenof(options); i++)
if (val == options[i].id)
dlg_listbox_select(ctrl, dlg, i);
#endif
dlg_update_done(ctrl, dlg);
} else if (event == EVENT_SELCHANGE
#ifdef NAMED_CLIPBOARDS
|| event == EVENT_VALCHANGE
#endif
) {
#ifdef NAMED_CLIPBOARDS
char *sval = dlg_editbox_get(ctrl, dlg);
int i;
for (i = 0; i < lenof(options); i++)
if (!strcmp(sval, options[i].name)) {
conf_set_int(conf, setting, options[i].id);
conf_set_str(conf, strsetting, "");
break;
}
if (i == lenof(options)) {
conf_set_int(conf, setting, CLIPUI_CUSTOM);
if (sval[0] == '=')
sval++;
conf_set_str(conf, strsetting, sval);
}
sfree(sval);
#else
int index = dlg_listbox_index(ctrl, dlg);
if (index >= 0) {
int val = dlg_listbox_getid(ctrl, dlg, index);
conf_set_int(conf, setting, val);
}
#endif
}
}
static void clipboard_control(struct controlset *s, const char *label,
char shortcut, int percentage, intorptr helpctx,
int setting, int strsetting)
{
#ifdef NAMED_CLIPBOARDS
ctrl_combobox(s, label, shortcut, percentage, helpctx,
clipboard_selector_handler, I(setting), I(strsetting));
#else
/* strsetting isn't needed in this case */
ctrl_droplist(s, label, shortcut, percentage, helpctx,
clipboard_selector_handler, I(setting));
#endif
}
static void serial_parity_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
static const struct {
const char *name;
int val;
} parities[] = {
{"None", SER_PAR_NONE},
{"Odd", SER_PAR_ODD},
{"Even", SER_PAR_EVEN},
{"Mark", SER_PAR_MARK},
{"Space", SER_PAR_SPACE},
};
int mask = ctrl->listbox.context.i;
int i, j;
Conf *conf = (Conf *)data;
if (event == EVENT_REFRESH) {
/* Fetching this once at the start of the function ensures we
* remember what the right value is supposed to be when
* operations below cause reentrant calls to this function. */
int oldparity = conf_get_int(conf, CONF_serparity);
dlg_update_start(ctrl, dlg);
dlg_listbox_clear(ctrl, dlg);
for (i = 0; i < lenof(parities); i++) {
if (mask & (1 << parities[i].val))
dlg_listbox_addwithid(ctrl, dlg, parities[i].name,
parities[i].val);
}
for (i = j = 0; i < lenof(parities); i++) {
if (mask & (1 << parities[i].val)) {
if (oldparity == parities[i].val) {
dlg_listbox_select(ctrl, dlg, j);
break;
}
j++;
}
}
if (i == lenof(parities)) { /* an unsupported setting was chosen */
dlg_listbox_select(ctrl, dlg, 0);
oldparity = SER_PAR_NONE;
}
dlg_update_done(ctrl, dlg);
conf_set_int(conf, CONF_serparity, oldparity); /* restore */
} else if (event == EVENT_SELCHANGE) {
int i = dlg_listbox_index(ctrl, dlg);
if (i < 0)
i = SER_PAR_NONE;
else
i = dlg_listbox_getid(ctrl, dlg, i);
conf_set_int(conf, CONF_serparity, i);
}
}
static void serial_flow_handler(union control *ctrl, dlgparam *dlg,
void *data, int event)
{
static const struct {
const char *name;
int val;
} flows[] = {
{"None", SER_FLOW_NONE},
{"XON/XOFF", SER_FLOW_XONXOFF},
{"RTS/CTS", SER_FLOW_RTSCTS},
{"DSR/DTR", SER_FLOW_DSRDTR},
};
int mask = ctrl->listbox.context.i;
int i, j;
Conf *conf = (Conf *)data;
if (event == EVENT_REFRESH) {
/* Fetching this once at the start of the function ensures we
* remember what the right value is supposed to be when
* operations below cause reentrant calls to this function. */
int oldflow = conf_get_int(conf, CONF_serflow);
dlg_update_start(ctrl, dlg);
dlg_listbox_clear(ctrl, dlg);
for (i = 0; i < lenof(flows); i++) {
if (mask & (1 << flows[i].val))
dlg_listbox_addwithid(ctrl, dlg, flows[i].name, flows[i].val);
}
for (i = j = 0; i < lenof(flows); i++) {
if (mask & (1 << flows[i].val)) {
if (oldflow == flows[i].val) {
dlg_listbox_select(ctrl, dlg, j);
break;
}
j++;
}
}
if (i == lenof(flows)) { /* an unsupported setting was chosen */
dlg_listbox_select(ctrl, dlg, 0);
oldflow = SER_FLOW_NONE;
}
dlg_update_done(ctrl, dlg);
conf_set_int(conf, CONF_serflow, oldflow);/* restore */
} else if (event == EVENT_SELCHANGE) {
int i = dlg_listbox_index(ctrl, dlg);
if (i < 0)
i = SER_FLOW_NONE;
else
i = dlg_listbox_getid(ctrl, dlg, i);
conf_set_int(conf, CONF_serflow, i);
}
}
Convert a lot of 'int' variables to 'bool'. My normal habit these days, in new code, is to treat int and bool as _almost_ completely separate types. I'm still willing to use C's implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine, no need to spell it out as blob.len != 0), but generally, if a variable is going to be conceptually a boolean, I like to declare it bool and assign to it using 'true' or 'false' rather than 0 or 1. PuTTY is an exception, because it predates the C99 bool, and I've stuck to its existing coding style even when adding new code to it. But it's been annoying me more and more, so now that I've decided C99 bool is an acceptable thing to require from our toolchain in the first place, here's a quite thorough trawl through the source doing 'boolification'. Many variables and function parameters are now typed as bool rather than int; many assignments of 0 or 1 to those variables are now spelled 'true' or 'false'. I managed this thorough conversion with the help of a custom clang plugin that I wrote to trawl the AST and apply heuristics to point out where things might want changing. So I've even managed to do a decent job on parts of the code I haven't looked at in years! To make the plugin's work easier, I pushed platform front ends generally in the direction of using standard 'bool' in preference to platform-specific boolean types like Windows BOOL or GTK's gboolean; I've left the platform booleans in places they _have_ to be for the platform APIs to work right, but variables only used by my own code have been converted wherever I found them. In a few places there are int values that look very like booleans in _most_ of the places they're used, but have a rarely-used third value, or a distinction between different nonzero values that most users don't care about. In these cases, I've _removed_ uses of 'true' and 'false' for the return values, to emphasise that there's something more subtle going on than a simple boolean answer: - the 'multisel' field in dialog.h's list box structure, for which the GTK front end in particular recognises a difference between 1 and 2 but nearly everything else treats as boolean - the 'urgent' parameter to plug_receive, where 1 vs 2 tells you something about the specific location of the urgent pointer, but most clients only care about 0 vs 'something nonzero' - the return value of wc_match, where -1 indicates a syntax error in the wildcard. - the return values from SSH-1 RSA-key loading functions, which use -1 for 'wrong passphrase' and 0 for all other failures (so any caller which already knows it's not loading an _encrypted private_ key can treat them as boolean) - term->esc_query, and the 'query' parameter in toggle_mode in terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h, but can also hold -1 for some other intervening character that we don't support. In a few places there's an integer that I haven't turned into a bool even though it really _can_ only take values 0 or 1 (and, as above, tried to make the call sites consistent in not calling those values true and false), on the grounds that I thought it would make it more confusing to imply that the 0 value was in some sense 'negative' or bad and the 1 positive or good: - the return value of plug_accepting uses the POSIXish convention of 0=success and nonzero=error; I think if I made it bool then I'd also want to reverse its sense, and that's a job for a separate piece of work. - the 'screen' parameter to lineptr() in terminal.c, where 0 and 1 represent the default and alternate screens. There's no obvious reason why one of those should be considered 'true' or 'positive' or 'success' - they're just indices - so I've left it as int. ssh_scp_recv had particularly confusing semantics for its previous int return value: its call sites used '<= 0' to check for error, but it never actually returned a negative number, just 0 or 1. Now the function and its call sites agree that it's a bool. In a couple of places I've renamed variables called 'ret', because I don't like that name any more - it's unclear whether it means the return value (in preparation) for the _containing_ function or the return value received from a subroutine call, and occasionally I've accidentally used the same variable for both and introduced a bug. So where one of those got in my way, I've renamed it to 'toret' or 'retd' (the latter short for 'returned') in line with my usual modern practice, but I haven't done a thorough job of finding all of them. Finally, one amusing side effect of doing this is that I've had to separate quite a few chained assignments. It used to be perfectly fine to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a the 'true' defined by stdbool.h, that idiom provokes a warning from gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
void setup_config_box(struct controlbox *b, bool midsession,
int protocol, int protcfginfo)
{
const struct BackendVtable *backvt;
struct controlset *s;
struct sessionsaver_data *ssd;
struct charclass_data *ccd;
struct colour_data *cd;
struct ttymodes_data *td;
struct environ_data *ed;
struct portfwd_data *pfd;
struct manual_hostkey_data *mh;
union control *c;
bool resize_forbidden = false;
char *str;
ssd = (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;
/*
* The standard panel that appears at the bottom of all panels:
* Open, Cancel, Apply etc.
*/
s = ctrl_getset(b, "", "", "");
ctrl_columns(s, 5, 20, 20, 20, 20, 20);
ssd->okbutton = ctrl_pushbutton(s,
(midsession ? "Apply" : "Open"),
(char)(midsession ? 'a' : 'o'),
HELPCTX(no_help),
sessionsaver_handler, P(ssd));
ssd->okbutton->button.isdefault = true;
ssd->okbutton->generic.column = 3;
ssd->cancelbutton = ctrl_pushbutton(s, "Cancel", 'c', HELPCTX(no_help),
sessionsaver_handler, P(ssd));
ssd->cancelbutton->button.iscancel = true;
ssd->cancelbutton->generic.column = 4;
/* We carefully don't close the 5-column part, so that platform-
* specific add-ons can put extra buttons alongside Open and Cancel. */
/*
* The Session panel.
*/
str = dupprintf("Basic options for your %s session", appname);
ctrl_settitle(b, "Session", str);
sfree(str);
if (!midsession) {
struct hostport *hp = (struct hostport *)
ctrl_alloc(b, sizeof(struct hostport));
s = ctrl_getset(b, "Session", "hostport",
"Specify the destination you want to connect to");
ctrl_columns(s, 2, 75, 25);
c = ctrl_editbox(s, HOST_BOX_TITLE, 'n', 100,
HELPCTX(session_hostname),
config_host_handler, I(0), I(0));
c->generic.column = 0;
hp->host = c;
c = ctrl_editbox(s, PORT_BOX_TITLE, 'p', 100,
HELPCTX(session_hostname),
config_port_handler, I(0), I(0));
c->generic.column = 1;
hp->port = c;
ctrl_columns(s, 1, 100);
c = ctrl_radiobuttons(s, "Connection type:", NO_SHORTCUT, 4,
HELPCTX(session_hostname),
config_protocolbuttons_handler, P(hp), NULL);
c->radio.buttons = sresize(c->radio.buttons, PROTOCOL_LIMIT, char *);
c->radio.shortcuts = sresize(c->radio.shortcuts, PROTOCOL_LIMIT, char);
c->radio.buttondata = sresize(c->radio.buttondata, PROTOCOL_LIMIT,
intorptr);
assert(c->radio.nbuttons == 0);
for (int pass = 0; pass < 4; pass++) {
for (size_t i = 0; backends[i]; i++) {
int pass_needed = (
backends[i]->protocol == be_default_protocol ? 0 :
backends[i]->protocol == PROT_SERIAL ? 1 :
backends[i]->protocol == PROT_RAW ? 2 : 3);
if (pass != pass_needed)
continue;
c->radio.buttons[c->radio.nbuttons] =
dupstr(backends[i]->displayname);
c->radio.shortcuts[c->radio.nbuttons] =
(backends[i]->protocol == PROT_SSH ? 's' :
backends[i]->protocol == PROT_SERIAL ? 'r' :
backends[i]->protocol == PROT_RAW ? 'w' :
NO_SHORTCUT);
c->radio.buttondata[c->radio.nbuttons] =
I(backends[i]->protocol);
c->radio.nbuttons++;
}
}
}
/*
* The Load/Save panel is available even in mid-session.
*/
s = ctrl_getset(b, "Session", "savedsessions",
midsession ? "Save the current session settings" :
"Load, save or delete a stored session");
ctrl_columns(s, 2, 75, 25);
get_sesslist(&ssd->sesslist, true);
ssd->editbox = ctrl_editbox(s, "Saved Sessions", 'e', 100,
HELPCTX(session_saved),
sessionsaver_handler, P(ssd), P(NULL));
ssd->editbox->generic.column = 0;
/* Reset columns so that the buttons are alongside the list, rather
* than alongside that edit box. */
ctrl_columns(s, 1, 100);
ctrl_columns(s, 2, 75, 25);
ssd->listbox = ctrl_listbox(s, NULL, NO_SHORTCUT,
HELPCTX(session_saved),
sessionsaver_handler, P(ssd));
ssd->listbox->generic.column = 0;
ssd->listbox->listbox.height = 7;
if (!midsession) {
ssd->loadbutton = ctrl_pushbutton(s, "Load", 'l',
HELPCTX(session_saved),
sessionsaver_handler, P(ssd));
ssd->loadbutton->generic.column = 1;
} else {
/* We can't offer the Load button mid-session, as it would allow the
* user to load and subsequently save settings they can't see. (And
* also change otherwise immutable settings underfoot; that probably
* shouldn't be a problem, but.) */
ssd->loadbutton = NULL;
}
/* "Save" button is permitted mid-session. */
ssd->savebutton = ctrl_pushbutton(s, "Save", 'v',
HELPCTX(session_saved),
sessionsaver_handler, P(ssd));
ssd->savebutton->generic.column = 1;
if (!midsession) {
ssd->delbutton = ctrl_pushbutton(s, "Delete", 'd',
HELPCTX(session_saved),
sessionsaver_handler, P(ssd));
ssd->delbutton->generic.column = 1;
} else {
/* Disable the Delete button mid-session too, for UI consistency. */
ssd->delbutton = NULL;
}
ctrl_columns(s, 1, 100);
s = ctrl_getset(b, "Session", "otheropts", NULL);
ctrl_radiobuttons(s, "Close window on exit:", 'x', 4,
HELPCTX(session_coe),
conf_radiobutton_handler,
I(CONF_close_on_exit),
"Always", I(FORCE_ON),
"Never", I(FORCE_OFF),
"Only on clean exit", I(AUTO), NULL);
/*
* The Session/Logging panel.
*/
ctrl_settitle(b, "Session/Logging", "Options controlling session logging");
s = ctrl_getset(b, "Session/Logging", "main", NULL);
/*
* The logging buttons change depending on whether SSH packet
* logging can sensibly be available.
*/
{
const char *sshlogname, *sshrawlogname;
if ((midsession && protocol == PROT_SSH) ||
(!midsession && backend_vt_from_proto(PROT_SSH))) {
sshlogname = "SSH packets";
sshrawlogname = "SSH packets and raw data";
} else {
sshlogname = NULL; /* this will disable both buttons */
sshrawlogname = NULL; /* this will just placate optimisers */
}
ctrl_radiobuttons(s, "Session logging:", NO_SHORTCUT, 2,
HELPCTX(logging_main),
loggingbuttons_handler,
I(CONF_logtype),
"None", 't', I(LGTYP_NONE),
"Printable output", 'p', I(LGTYP_ASCII),
"All session output", 'l', I(LGTYP_DEBUG),
sshlogname, 's', I(LGTYP_PACKETS),
sshrawlogname, 'r', I(LGTYP_SSHRAW),
NULL);
}
ctrl_filesel(s, "Log file name:", 'f',
NULL, true, "Select session log file name",
HELPCTX(logging_filename),
conf_filesel_handler, I(CONF_logfilename));
ctrl_text(s, "(Log file name can contain &Y, &M, &D for date,"
" &T for time, &H for host name, and &P for port number)",
HELPCTX(logging_filename));
ctrl_radiobuttons(s, "What to do if the log file already exists:", 'e', 1,
HELPCTX(logging_exists),
conf_radiobutton_handler, I(CONF_logxfovr),
"Always overwrite it", I(LGXF_OVR),
"Always append to the end of it", I(LGXF_APN),
"Ask the user every time", I(LGXF_ASK), NULL);
ctrl_checkbox(s, "Flush log file frequently", 'u',
HELPCTX(logging_flush),
conf_checkbox_handler, I(CONF_logflush));
ctrl_checkbox(s, "Include header", 'i',
HELPCTX(logging_header),
conf_checkbox_handler, I(CONF_logheader));
if ((midsession && protocol == PROT_SSH) ||
(!midsession && backend_vt_from_proto(PROT_SSH))) {
s = ctrl_getset(b, "Session/Logging", "ssh",
"Options specific to SSH packet logging");
ctrl_checkbox(s, "Omit known password fields", 'k',
HELPCTX(logging_ssh_omit_password),
conf_checkbox_handler, I(CONF_logomitpass));
ctrl_checkbox(s, "Omit session data", 'd',
HELPCTX(logging_ssh_omit_data),
conf_checkbox_handler, I(CONF_logomitdata));
}
/*
* The Terminal panel.
*/
ctrl_settitle(b, "Terminal", "Options controlling the terminal emulation");
s = ctrl_getset(b, "Terminal", "general", "Set various terminal options");
ctrl_checkbox(s, "Auto wrap mode initially on", 'w',
HELPCTX(terminal_autowrap),
conf_checkbox_handler, I(CONF_wrap_mode));
ctrl_checkbox(s, "DEC Origin Mode initially on", 'd',
HELPCTX(terminal_decom),
conf_checkbox_handler, I(CONF_dec_om));
ctrl_checkbox(s, "Implicit CR in every LF", 'r',
HELPCTX(terminal_lfhascr),
conf_checkbox_handler, I(CONF_lfhascr));
ctrl_checkbox(s, "Implicit LF in every CR", 'f',
HELPCTX(terminal_crhaslf),
conf_checkbox_handler, I(CONF_crhaslf));
ctrl_checkbox(s, "Use background colour to erase screen", 'e',
HELPCTX(terminal_bce),
conf_checkbox_handler, I(CONF_bce));
ctrl_checkbox(s, "Enable blinking text", 'n',
HELPCTX(terminal_blink),
conf_checkbox_handler, I(CONF_blinktext));
ctrl_editbox(s, "Answerback to ^E:", 's', 100,
HELPCTX(terminal_answerback),
conf_editbox_handler, I(CONF_answerback), I(1));
s = ctrl_getset(b, "Terminal", "ldisc", "Line discipline options");
ctrl_radiobuttons(s, "Local echo:", 'l', 3,
HELPCTX(terminal_localecho),
conf_radiobutton_handler,I(CONF_localecho),
"Auto", I(AUTO),
"Force on", I(FORCE_ON),
"Force off", I(FORCE_OFF), NULL);
ctrl_radiobuttons(s, "Local line editing:", 't', 3,
HELPCTX(terminal_localedit),
conf_radiobutton_handler,I(CONF_localedit),
"Auto", I(AUTO),
"Force on", I(FORCE_ON),
"Force off", I(FORCE_OFF), NULL);
s = ctrl_getset(b, "Terminal", "printing", "Remote-controlled printing");
ctrl_combobox(s, "Printer to send ANSI printer output to:", 'p', 100,
HELPCTX(terminal_printing),
printerbox_handler, P(NULL), P(NULL));
/*
* The Terminal/Keyboard panel.
*/
ctrl_settitle(b, "Terminal/Keyboard",
"Options controlling the effects of keys");
s = ctrl_getset(b, "Terminal/Keyboard", "mappings",
"Change the sequences sent by:");
ctrl_radiobuttons(s, "The Backspace key", 'b', 2,
HELPCTX(keyboard_backspace),
conf_radiobutton_bool_handler,
I(CONF_bksp_is_delete),
"Control-H", I(0), "Control-? (127)", I(1), NULL);
ctrl_radiobuttons(s, "The Home and End keys", 'e', 2,
HELPCTX(keyboard_homeend),
conf_radiobutton_bool_handler,
I(CONF_rxvt_homeend),
"Standard", I(false), "rxvt", I(true), NULL);
ctrl_radiobuttons(s, "The Function keys and keypad", 'f', 3,
HELPCTX(keyboard_funkeys),
conf_radiobutton_handler,
I(CONF_funky_type),
"ESC[n~", I(0), "Linux", I(1), "Xterm R6", I(2),
"VT400", I(3), "VT100+", I(4), "SCO", I(5), NULL);
s = ctrl_getset(b, "Terminal/Keyboard", "appkeypad",
"Application keypad settings:");
ctrl_radiobuttons(s, "Initial state of cursor keys:", 'r', 3,
HELPCTX(keyboard_appcursor),
conf_radiobutton_bool_handler,
I(CONF_app_cursor),
"Normal", I(0), "Application", I(1), NULL);
ctrl_radiobuttons(s, "Initial state of numeric keypad:", 'n', 3,
HELPCTX(keyboard_appkeypad),
numeric_keypad_handler, P(NULL),
"Normal", I(0), "Application", I(1), "NetHack", I(2),
NULL);
/*
* The Terminal/Bell panel.
*/
ctrl_settitle(b, "Terminal/Bell",
"Options controlling the terminal bell");
s = ctrl_getset(b, "Terminal/Bell", "style", "Set the style of bell");
ctrl_radiobuttons(s, "Action to happen when a bell occurs:", 'b', 1,
HELPCTX(bell_style),
conf_radiobutton_handler, I(CONF_beep),
"None (bell disabled)", I(BELL_DISABLED),
"Make default system alert sound", I(BELL_DEFAULT),
"Visual bell (flash window)", I(BELL_VISUAL), NULL);
s = ctrl_getset(b, "Terminal/Bell", "overload",
"Control the bell overload behaviour");
ctrl_checkbox(s, "Bell is temporarily disabled when over-used", 'd',
HELPCTX(bell_overload),
conf_checkbox_handler, I(CONF_bellovl));
ctrl_editbox(s, "Over-use means this many bells...", 'm', 20,
HELPCTX(bell_overload),
conf_editbox_handler, I(CONF_bellovl_n), I(-1));
ctrl_editbox(s, "... in this many seconds", 't', 20,
HELPCTX(bell_overload),
conf_editbox_handler, I(CONF_bellovl_t),
I(-TICKSPERSEC));
ctrl_text(s, "The bell is re-enabled after a few seconds of silence.",
HELPCTX(bell_overload));
ctrl_editbox(s, "Seconds of silence required", 's', 20,
HELPCTX(bell_overload),
conf_editbox_handler, I(CONF_bellovl_s),
I(-TICKSPERSEC));
/*
* The Terminal/Features panel.
*/
ctrl_settitle(b, "Terminal/Features",
"Enabling and disabling advanced terminal features");
s = ctrl_getset(b, "Terminal/Features", "main", NULL);
ctrl_checkbox(s, "Disable application cursor keys mode", 'u',
HELPCTX(features_application),
conf_checkbox_handler, I(CONF_no_applic_c));
ctrl_checkbox(s, "Disable application keypad mode", 'k',
HELPCTX(features_application),
conf_checkbox_handler, I(CONF_no_applic_k));
ctrl_checkbox(s, "Disable xterm-style mouse reporting", 'x',
HELPCTX(features_mouse),
conf_checkbox_handler, I(CONF_no_mouse_rep));
ctrl_checkbox(s, "Disable remote-controlled terminal resizing", 's',
HELPCTX(features_resize),
conf_checkbox_handler,
I(CONF_no_remote_resize));
ctrl_checkbox(s, "Disable switching to alternate terminal screen", 'w',
HELPCTX(features_altscreen),
conf_checkbox_handler, I(CONF_no_alt_screen));
ctrl_checkbox(s, "Disable remote-controlled window title changing", 't',
HELPCTX(features_retitle),
conf_checkbox_handler,
I(CONF_no_remote_wintitle));
ctrl_radiobuttons(s, "Response to remote title query (SECURITY):", 'q', 3,
HELPCTX(features_qtitle),
conf_radiobutton_handler,
I(CONF_remote_qtitle_action),
"None", I(TITLE_NONE),
"Empty string", I(TITLE_EMPTY),
"Window title", I(TITLE_REAL), NULL);
ctrl_checkbox(s, "Disable remote-controlled clearing of scrollback", 'e',
HELPCTX(features_clearscroll),
conf_checkbox_handler,
I(CONF_no_remote_clearscroll));
ctrl_checkbox(s, "Disable destructive backspace on server sending ^?",'b',
HELPCTX(features_dbackspace),
conf_checkbox_handler, I(CONF_no_dbackspace));
ctrl_checkbox(s, "Disable remote-controlled character set configuration",
'r', HELPCTX(features_charset), conf_checkbox_handler,
I(CONF_no_remote_charset));
ctrl_checkbox(s, "Disable Arabic text shaping",
'l', HELPCTX(features_arabicshaping), conf_checkbox_handler,
I(CONF_no_arabicshaping));
ctrl_checkbox(s, "Disable bidirectional text display",
'd', HELPCTX(features_bidi), conf_checkbox_handler,
I(CONF_no_bidi));
/*
* The Window panel.
*/
str = dupprintf("Options controlling %s's window", appname);
ctrl_settitle(b, "Window", str);
sfree(str);
backvt = backend_vt_from_proto(protocol);
if (backvt)
resize_forbidden = (backvt->flags & BACKEND_RESIZE_FORBIDDEN);
if (!resize_forbidden || !midsession) {
s = ctrl_getset(b, "Window", "size", "Set the size of the window");
ctrl_columns(s, 2, 50, 50);
c = ctrl_editbox(s, "Columns", 'm', 100,
HELPCTX(window_size),
conf_editbox_handler, I(CONF_width), I(-1));
c->generic.column = 0;
c = ctrl_editbox(s, "Rows", 'r', 100,
HELPCTX(window_size),
conf_editbox_handler, I(CONF_height),I(-1));
c->generic.column = 1;
ctrl_columns(s, 1, 100);
}
s = ctrl_getset(b, "Window", "scrollback",
"Control the scrollback in the window");
ctrl_editbox(s, "Lines of scrollback", 's', 50,
HELPCTX(window_scrollback),
conf_editbox_handler, I(CONF_savelines), I(-1));
ctrl_checkbox(s, "Display scrollbar", 'd',
HELPCTX(window_scrollback),
conf_checkbox_handler, I(CONF_scrollbar));
ctrl_checkbox(s, "Reset scrollback on keypress", 'k',
HELPCTX(window_scrollback),
conf_checkbox_handler, I(CONF_scroll_on_key));
ctrl_checkbox(s, "Reset scrollback on display activity", 'p',
HELPCTX(window_scrollback),
conf_checkbox_handler, I(CONF_scroll_on_disp));
ctrl_checkbox(s, "Push erased text into scrollback", 'e',
HELPCTX(window_erased),
conf_checkbox_handler,
I(CONF_erase_to_scrollback));
/*
* The Window/Appearance panel.
*/
str = dupprintf("Configure the appearance of %s's window", appname);
ctrl_settitle(b, "Window/Appearance", str);
sfree(str);
s = ctrl_getset(b, "Window/Appearance", "cursor",
"Adjust the use of the cursor");
ctrl_radiobuttons(s, "Cursor appearance:", NO_SHORTCUT, 3,
HELPCTX(appearance_cursor),
conf_radiobutton_handler,
I(CONF_cursor_type),
"Block", 'l', I(0),
"Underline", 'u', I(1),
"Vertical line", 'v', I(2), NULL);
ctrl_checkbox(s, "Cursor blinks", 'b',
HELPCTX(appearance_cursor),
conf_checkbox_handler, I(CONF_blink_cur));
s = ctrl_getset(b, "Window/Appearance", "font",
"Font settings");
ctrl_fontsel(s, "Font used in the terminal window", 'n',
HELPCTX(appearance_font),
conf_fontsel_handler, I(CONF_font));
s = ctrl_getset(b, "Window/Appearance", "mouse",
"Adjust the use of the mouse pointer");
ctrl_checkbox(s, "Hide mouse pointer when typing in window", 'p',
HELPCTX(appearance_hidemouse),
conf_checkbox_handler, I(CONF_hide_mouseptr));
s = ctrl_getset(b, "Window/Appearance", "border",
"Adjust the window border");
ctrl_editbox(s, "Gap between text and window edge:", 'e', 20,
HELPCTX(appearance_border),
conf_editbox_handler,
I(CONF_window_border), I(-1));
/*
* The Window/Behaviour panel.
*/
str = dupprintf("Configure the behaviour of %s's window", appname);
ctrl_settitle(b, "Window/Behaviour", str);
sfree(str);
s = ctrl_getset(b, "Window/Behaviour", "title",
"Adjust the behaviour of the window title");
ctrl_editbox(s, "Window title:", 't', 100,
HELPCTX(appearance_title),
conf_editbox_handler, I(CONF_wintitle), I(1));
ctrl_checkbox(s, "Separate window and icon titles", 'i',
HELPCTX(appearance_title),
conf_checkbox_handler,
I(CHECKBOX_INVERT | CONF_win_name_always));
s = ctrl_getset(b, "Window/Behaviour", "main", NULL);
ctrl_checkbox(s, "Warn before closing window", 'w',
HELPCTX(behaviour_closewarn),
conf_checkbox_handler, I(CONF_warn_on_close));
/*
* The Window/Translation panel.
*/
ctrl_settitle(b, "Window/Translation",
"Options controlling character set translation");
s = ctrl_getset(b, "Window/Translation", "trans",
"Character set translation");
ctrl_combobox(s, "Remote character set:",
'r', 100, HELPCTX(translation_codepage),
codepage_handler, P(NULL), P(NULL));
s = ctrl_getset(b, "Window/Translation", "tweaks", NULL);
ctrl_checkbox(s, "Treat CJK ambiguous characters as wide", 'w',
HELPCTX(translation_cjk_ambig_wide),
conf_checkbox_handler, I(CONF_cjk_ambig_wide));
str = dupprintf("Adjust how %s handles line drawing characters", appname);
s = ctrl_getset(b, "Window/Translation", "linedraw", str);
sfree(str);
ctrl_radiobuttons(s, "Handling of line drawing characters:", NO_SHORTCUT,1,
HELPCTX(translation_linedraw),
conf_radiobutton_handler,
I(CONF_vtmode),
"Use Unicode line drawing code points",'u',I(VT_UNICODE),
"Poor man's line drawing (+, - and |)",'p',I(VT_POORMAN),
NULL);
ctrl_checkbox(s, "Copy and paste line drawing characters as lqqqk",'d',
HELPCTX(selection_linedraw),
conf_checkbox_handler, I(CONF_rawcnp));
Option to support VT100 line drawing in UTF-8 mode. Thanks to Jiri Kaspar for sending this patch (apart from the new docs section, which is in my own words), which implements a feature we've had as a wishlist item ('utf8-plus-vt100') for a long time. I was actually surprised it was possible to implement it in so few lines of code! I'd forgotten, or possibly never noticed in the first place, that even in UTF-8 mode PuTTY not only accepts but still _processes_ all the ISO 2022 control sequences and shift characters, and keeps running track of all the same state in term->cset and term->cset_attrs that it tracks in IS0-2022-enabled modes. It's just that in UTF-8 mode, at the very last minute when a character+attribute pair is about to be written into the terminal's character buffer, it deliberately ignores the contents of those variables. So all that was needed was a new flag checked at that last moment which causes it not quite to ignore them after all, and bingo, utf8-plus-vt100 is supported. And it works no matter which ISO 2022 sequences you're using; whether you're using ESC ( 0 to select the line drawing set directly into GL and ESC ( B to get back when you're done, or whether you send a preliminary ESC ( B ESC ) 0 to get GL/GR to be ASCII and line drawing respectively so you can use SI and SO as one-byte mode switches thereafter, both work just as well. This implementation strategy has a couple of consequences, which I don't think matter very much one way or the other but I document them just in case they turn out to be important later: - if an application expecting this mode has already filled your terminal window with lqqqqqqqqk, then enabling this mode in Change Settings won't retroactively turn them into the line drawing characters you wanted, because no memory is preserved in the screen buffer of what the ISO 2022 state was when they were printed. So the application still has to do a screen refresh. - on the other hand, if you already sent the ESC ( 0 or whatever to put the terminal _into_ line drawing mode, and then you turn on this mode in Change Settings, you _will_ still be in line drawing mode, because the system _does_ remember your current ISO 2022 state at all times, whether it's currently applying it to output printing characters or not.
2018-05-12 07:43:52 +00:00
ctrl_checkbox(s, "Enable VT100 line drawing even in UTF-8 mode",'8',
HELPCTX(translation_utf8linedraw),
conf_checkbox_handler, I(CONF_utf8linedraw));
/*
* The Window/Selection panel.
*/
ctrl_settitle(b, "Window/Selection", "Options controlling copy and paste");
s = ctrl_getset(b, "Window/Selection", "mouse",
"Control use of mouse");
ctrl_checkbox(s, "Shift overrides application's use of mouse", 'p',
HELPCTX(selection_shiftdrag),
conf_checkbox_handler, I(CONF_mouse_override));
ctrl_radiobuttons(s,
"Default selection mode (Alt+drag does the other one):",
NO_SHORTCUT, 2,
HELPCTX(selection_rect),
conf_radiobutton_bool_handler,
I(CONF_rect_select),
"Normal", 'n', I(false),
"Rectangular block", 'r', I(true), NULL);
s = ctrl_getset(b, "Window/Selection", "clipboards",
"Assign copy/paste actions to clipboards");
ctrl_checkbox(s, "Auto-copy selected text to "
CLIPNAME_EXPLICIT_OBJECT,
NO_SHORTCUT, HELPCTX(selection_autocopy),
conf_checkbox_handler, I(CONF_mouseautocopy));
clipboard_control(s, "Mouse paste action:", NO_SHORTCUT, 60,
HELPCTX(selection_clipactions),
CONF_mousepaste, CONF_mousepaste_custom);
clipboard_control(s, "{Ctrl,Shift} + Ins:", NO_SHORTCUT, 60,
HELPCTX(selection_clipactions),
CONF_ctrlshiftins, CONF_ctrlshiftins_custom);
clipboard_control(s, "Ctrl + Shift + {C,V}:", NO_SHORTCUT, 60,
HELPCTX(selection_clipactions),
CONF_ctrlshiftcv, CONF_ctrlshiftcv_custom);
2018-03-11 17:40:42 +00:00
s = ctrl_getset(b, "Window/Selection", "paste",
"Control pasting of text from clipboard to terminal");
2018-03-11 17:40:42 +00:00
ctrl_checkbox(s, "Permit control characters in pasted text",
NO_SHORTCUT, HELPCTX(selection_pastectrl),
2018-03-11 17:40:42 +00:00
conf_checkbox_handler, I(CONF_paste_controls));
/*
* The Window/Selection/Copy panel.
*/
ctrl_settitle(b, "Window/Selection/Copy",
"Options controlling copying from terminal to clipboard");
s = ctrl_getset(b, "Window/Selection/Copy", "charclass",
"Classes of character that group together");
ccd = (struct charclass_data *)
ctrl_alloc(b, sizeof(struct charclass_data));
ccd->listbox = ctrl_listbox(s, "Character classes:", 'e',
HELPCTX(copy_charclasses),
charclass_handler, P(ccd));
ccd->listbox->listbox.multisel = 1;
ccd->listbox->listbox.ncols = 4;
ccd->listbox->listbox.percentages = snewn(4, int);
ccd->listbox->listbox.percentages[0] = 15;
ccd->listbox->listbox.percentages[1] = 25;
ccd->listbox->listbox.percentages[2] = 20;
ccd->listbox->listbox.percentages[3] = 40;
ctrl_columns(s, 2, 67, 33);
ccd->editbox = ctrl_editbox(s, "Set to class", 't', 50,
HELPCTX(copy_charclasses),
charclass_handler, P(ccd), P(NULL));
ccd->editbox->generic.column = 0;
ccd->button = ctrl_pushbutton(s, "Set", 's',
HELPCTX(copy_charclasses),
charclass_handler, P(ccd));
ccd->button->generic.column = 1;
ctrl_columns(s, 1, 100);
/*
* The Window/Colours panel.
*/
ctrl_settitle(b, "Window/Colours", "Options controlling use of colours");
s = ctrl_getset(b, "Window/Colours", "general",
"General options for colour usage");
ctrl_checkbox(s, "Allow terminal to specify ANSI colours", 'i',
HELPCTX(colours_ansi),
conf_checkbox_handler, I(CONF_ansi_colour));
ctrl_checkbox(s, "Allow terminal to use xterm 256-colour mode", '2',
HELPCTX(colours_xterm256), conf_checkbox_handler,
I(CONF_xterm_256_colour));
ctrl_checkbox(s, "Allow terminal to use 24-bit colours", '4',
HELPCTX(colours_truecolour), conf_checkbox_handler,
I(CONF_true_colour));
ctrl_radiobuttons(s, "Indicate bolded text by changing:", 'b', 3,
HELPCTX(colours_bold),
conf_radiobutton_handler, I(CONF_bold_style),
"The font", I(1),
"The colour", I(2),
"Both", I(3),
NULL);
str = dupprintf("Adjust the precise colours %s displays", appname);
s = ctrl_getset(b, "Window/Colours", "adjust", str);
sfree(str);
ctrl_text(s, "Select a colour from the list, and then click the"
" Modify button to change its appearance.",
HELPCTX(colours_config));
ctrl_columns(s, 2, 67, 33);
cd = (struct colour_data *)ctrl_alloc(b, sizeof(struct colour_data));
cd->listbox = ctrl_listbox(s, "Select a colour to adjust:", 'u',
HELPCTX(colours_config), colour_handler, P(cd));
cd->listbox->generic.column = 0;
cd->listbox->listbox.height = 7;
c = ctrl_text(s, "RGB value:", HELPCTX(colours_config));
c->generic.column = 1;
cd->redit = ctrl_editbox(s, "Red", 'r', 50, HELPCTX(colours_config),
colour_handler, P(cd), P(NULL));
cd->redit->generic.column = 1;
cd->gedit = ctrl_editbox(s, "Green", 'n', 50, HELPCTX(colours_config),
colour_handler, P(cd), P(NULL));
cd->gedit->generic.column = 1;
cd->bedit = ctrl_editbox(s, "Blue", 'e', 50, HELPCTX(colours_config),
colour_handler, P(cd), P(NULL));
cd->bedit->generic.column = 1;
cd->button = ctrl_pushbutton(s, "Modify", 'm', HELPCTX(colours_config),
colour_handler, P(cd));
cd->button->generic.column = 1;
ctrl_columns(s, 1, 100);
/*
* The Connection panel. This doesn't show up if we're in a
* non-network utility such as pterm. We tell this by being
* passed a protocol < 0.
*/
if (protocol >= 0) {
ctrl_settitle(b, "Connection", "Options controlling the connection");
s = ctrl_getset(b, "Connection", "keepalive",
"Sending of null packets to keep session active");
ctrl_editbox(s, "Seconds between keepalives (0 to turn off)", 'k', 20,
HELPCTX(connection_keepalive),
conf_editbox_handler, I(CONF_ping_interval),
I(-1));
if (!midsession) {
s = ctrl_getset(b, "Connection", "tcp",
"Low-level TCP connection options");
ctrl_checkbox(s, "Disable Nagle's algorithm (TCP_NODELAY option)",
'n', HELPCTX(connection_nodelay),
conf_checkbox_handler,
I(CONF_tcp_nodelay));
ctrl_checkbox(s, "Enable TCP keepalives (SO_KEEPALIVE option)",
'p', HELPCTX(connection_tcpkeepalive),
conf_checkbox_handler,
I(CONF_tcp_keepalives));
#ifndef NO_IPV6
s = ctrl_getset(b, "Connection", "ipversion",
"Internet protocol version");
ctrl_radiobuttons(s, NULL, NO_SHORTCUT, 3,
HELPCTX(connection_ipversion),
conf_radiobutton_handler,
I(CONF_addressfamily),
"Auto", 'u', I(ADDRTYPE_UNSPEC),
"IPv4", '4', I(ADDRTYPE_IPV4),
"IPv6", '6', I(ADDRTYPE_IPV6),
NULL);
#endif
{
const char *label = backend_vt_from_proto(PROT_SSH) ?
"Logical name of remote host (e.g. for SSH key lookup):" :
"Logical name of remote host:";
s = ctrl_getset(b, "Connection", "identity",
"Logical name of remote host");
ctrl_editbox(s, label, 'm', 100,
HELPCTX(connection_loghost),
conf_editbox_handler, I(CONF_loghost), I(1));
}
}
/*
* A sub-panel Connection/Data, containing options that
* decide on data to send to the server.
*/
if (!midsession) {
ctrl_settitle(b, "Connection/Data", "Data to send to the server");
s = ctrl_getset(b, "Connection/Data", "login",
"Login details");
ctrl_editbox(s, "Auto-login username", 'u', 50,
HELPCTX(connection_username),
conf_editbox_handler, I(CONF_username), I(1));
{
/* We assume the local username is sufficiently stable
* to include on the dialog box. */
char *user = get_username();
char *userlabel = dupprintf("Use system username (%s)",
user ? user : "");
sfree(user);
ctrl_radiobuttons(s, "When username is not specified:", 'n', 4,
HELPCTX(connection_username_from_env),
conf_radiobutton_bool_handler,
I(CONF_username_from_env),
"Prompt", I(false),
userlabel, I(true),
NULL);
sfree(userlabel);
}
s = ctrl_getset(b, "Connection/Data", "term",
"Terminal details");
ctrl_editbox(s, "Terminal-type string", 't', 50,
HELPCTX(connection_termtype),
conf_editbox_handler, I(CONF_termtype), I(1));
ctrl_editbox(s, "Terminal speeds", 's', 50,
HELPCTX(connection_termspeed),
conf_editbox_handler, I(CONF_termspeed), I(1));
s = ctrl_getset(b, "Connection/Data", "env",
"Environment variables");
ctrl_columns(s, 2, 80, 20);
ed = (struct environ_data *)
ctrl_alloc(b, sizeof(struct environ_data));
ed->varbox = ctrl_editbox(s, "Variable", 'v', 60,
HELPCTX(telnet_environ),
environ_handler, P(ed), P(NULL));
ed->varbox->generic.column = 0;
ed->valbox = ctrl_editbox(s, "Value", 'l', 60,
HELPCTX(telnet_environ),
environ_handler, P(ed), P(NULL));
ed->valbox->generic.column = 0;
ed->addbutton = ctrl_pushbutton(s, "Add", 'd',
HELPCTX(telnet_environ),
environ_handler, P(ed));
ed->addbutton->generic.column = 1;
ed->rembutton = ctrl_pushbutton(s, "Remove", 'r',
HELPCTX(telnet_environ),
environ_handler, P(ed));
ed->rembutton->generic.column = 1;
ctrl_columns(s, 1, 100);
ed->listbox = ctrl_listbox(s, NULL, NO_SHORTCUT,
HELPCTX(telnet_environ),
environ_handler, P(ed));
ed->listbox->listbox.height = 3;
ed->listbox->listbox.ncols = 2;
ed->listbox->listbox.percentages = snewn(2, int);
ed->listbox->listbox.percentages[0] = 30;
ed->listbox->listbox.percentages[1] = 70;
}
}
if (!midsession) {
/*
* The Connection/Proxy panel.
*/
ctrl_settitle(b, "Connection/Proxy",
"Options controlling proxy usage");
s = ctrl_getset(b, "Connection/Proxy", "basics", NULL);
ctrl_radiobuttons(s, "Proxy type:", 't', 3,
HELPCTX(proxy_type),
conf_radiobutton_handler,
I(CONF_proxy_type),
"None", I(PROXY_NONE),
"SOCKS 4", I(PROXY_SOCKS4),
"SOCKS 5", I(PROXY_SOCKS5),
"HTTP", I(PROXY_HTTP),
"Telnet", I(PROXY_TELNET),
NULL);
ctrl_columns(s, 2, 80, 20);
c = ctrl_editbox(s, "Proxy hostname", 'y', 100,
HELPCTX(proxy_main),
conf_editbox_handler,
I(CONF_proxy_host), I(1));
c->generic.column = 0;
c = ctrl_editbox(s, "Port", 'p', 100,
HELPCTX(proxy_main),
conf_editbox_handler,
I(CONF_proxy_port),
I(-1));
c->generic.column = 1;
ctrl_columns(s, 1, 100);
ctrl_editbox(s, "Exclude Hosts/IPs", 'e', 100,
HELPCTX(proxy_exclude),
conf_editbox_handler,
I(CONF_proxy_exclude_list), I(1));
ctrl_checkbox(s, "Consider proxying local host connections", 'x',
HELPCTX(proxy_exclude),
conf_checkbox_handler,
I(CONF_even_proxy_localhost));
ctrl_radiobuttons(s, "Do DNS name lookup at proxy end:", 'd', 3,
HELPCTX(proxy_dns),
conf_radiobutton_handler,
I(CONF_proxy_dns),
"No", I(FORCE_OFF),
"Auto", I(AUTO),
"Yes", I(FORCE_ON), NULL);
ctrl_editbox(s, "Username", 'u', 60,
HELPCTX(proxy_auth),
conf_editbox_handler,
I(CONF_proxy_username), I(1));
c = ctrl_editbox(s, "Password", 'w', 60,
HELPCTX(proxy_auth),
conf_editbox_handler,
I(CONF_proxy_password), I(1));
c->editbox.password = true;
ctrl_editbox(s, "Telnet command", 'm', 100,
HELPCTX(proxy_command),
conf_editbox_handler,
I(CONF_proxy_telnet_command), I(1));
ctrl_radiobuttons(s, "Print proxy diagnostics "
"in the terminal window", 'r', 5,
HELPCTX(proxy_logging),
conf_radiobutton_handler,
I(CONF_proxy_log_to_term),
"No", I(FORCE_OFF),
"Yes", I(FORCE_ON),
"Only until session starts", I(AUTO), NULL);
}
/*
* Each per-protocol configuration GUI panel is conditionally
* displayed. We don't display it if this binary doesn't contain a
* backend for its protocol at all; we don't display it if we're
* already in mid-session with a different protocol selected; and
* even if we _do_ have this protocol selected, we don't display
* the panel if the protocol doesn't permit any mid-session
* reconfiguration anyway.
*/
#define DISPLAY_RECONFIGURABLE_PROTOCOL(which_proto) \
(backend_vt_from_proto(which_proto) && \
(!midsession || protocol == (which_proto)))
#define DISPLAY_NON_RECONFIGURABLE_PROTOCOL(which_proto) \
(backend_vt_from_proto(which_proto) && !midsession)
if (DISPLAY_RECONFIGURABLE_PROTOCOL(PROT_SSH) ||
DISPLAY_RECONFIGURABLE_PROTOCOL(PROT_SSHCONN)) {
/*
* The Connection/SSH panel.
*/
ctrl_settitle(b, "Connection/SSH",
"Options controlling SSH connections");
/* SSH-1 or connection-sharing downstream */
if (midsession && (protcfginfo == 1 || protcfginfo == -1)) {
s = ctrl_getset(b, "Connection/SSH", "disclaimer", NULL);
ctrl_text(s, "Nothing on this panel may be reconfigured in mid-"
"session; it is only here so that sub-panels of it can "
"exist without looking strange.", HELPCTX(no_help));
}
if (!midsession) {
s = ctrl_getset(b, "Connection/SSH", "data",
"Data to send to the server");
ctrl_editbox(s, "Remote command:", 'r', 100,
HELPCTX(ssh_command),
conf_editbox_handler, I(CONF_remote_cmd), I(1));
s = ctrl_getset(b, "Connection/SSH", "protocol", "Protocol options");
ctrl_checkbox(s, "Don't start a shell or command at all", 'n',
HELPCTX(ssh_noshell),
conf_checkbox_handler,
I(CONF_ssh_no_shell));
}
if (!midsession || !(protcfginfo == 1 || protcfginfo == -1)) {
s = ctrl_getset(b, "Connection/SSH", "protocol", "Protocol options");
ctrl_checkbox(s, "Enable compression", 'e',
HELPCTX(ssh_compress),
conf_checkbox_handler,
I(CONF_compression));
}
if (!midsession) {
s = ctrl_getset(b, "Connection/SSH", "sharing", "Sharing an SSH connection between PuTTY tools");
ctrl_checkbox(s, "Share SSH connections if possible", 's',
HELPCTX(ssh_share),
conf_checkbox_handler,
I(CONF_ssh_connection_sharing));
ctrl_text(s, "Permitted roles in a shared connection:",
HELPCTX(ssh_share));
ctrl_checkbox(s, "Upstream (connecting to the real server)", 'u',
HELPCTX(ssh_share),
conf_checkbox_handler,
I(CONF_ssh_connection_sharing_upstream));
ctrl_checkbox(s, "Downstream (connecting to the upstream PuTTY)", 'd',
HELPCTX(ssh_share),
conf_checkbox_handler,
I(CONF_ssh_connection_sharing_downstream));
}
if (!midsession) {
s = ctrl_getset(b, "Connection/SSH", "protocol", "Protocol options");
ctrl_radiobuttons(s, "SSH protocol version:", NO_SHORTCUT, 2,
HELPCTX(ssh_protocol),
conf_radiobutton_handler,
I(CONF_sshprot),
"2", '2', I(3),
"1 (INSECURE)", '1', I(0), NULL);
}
/*
* The Connection/SSH/Kex panel. (Owing to repeat key
* exchange, much of this is meaningful in mid-session _if_
* we're using SSH-2 and are not a connection-sharing
* downstream, or haven't decided yet.)
*/
if (protcfginfo != 1 && protcfginfo != -1) {
ctrl_settitle(b, "Connection/SSH/Kex",
"Options controlling SSH key exchange");
s = ctrl_getset(b, "Connection/SSH/Kex", "main",
"Key exchange algorithm options");
c = ctrl_draglist(s, "Algorithm selection policy:", 's',
HELPCTX(ssh_kexlist),
kexlist_handler, P(NULL));
c->listbox.height = KEX_MAX;
#ifndef NO_GSSAPI
ctrl_checkbox(s, "Attempt GSSAPI key exchange",
'k', HELPCTX(ssh_gssapi),
conf_checkbox_handler,
I(CONF_try_gssapi_kex));
#endif
s = ctrl_getset(b, "Connection/SSH/Kex", "repeat",
"Options controlling key re-exchange");
ctrl_editbox(s, "Max minutes before rekey (0 for no limit)", 't', 20,
HELPCTX(ssh_kex_repeat),
conf_editbox_handler,
I(CONF_ssh_rekey_time),
I(-1));
#ifndef NO_GSSAPI
Support GSS key exchange, for Kerberos 5 only. This is a heavily edited (by me) version of a patch originally due to Nico Williams and Viktor Dukhovni. Their comments: * Don't delegate credentials when rekeying unless there's a new TGT or the old service ticket is nearly expired. * Check for the above conditions more frequently (every two minutes by default) and rekey when we would delegate credentials. * Do not rekey with very short service ticket lifetimes; some GSSAPI libraries may lose the race to use an almost expired ticket. Adjust the timing of rekey checks to try to avoid this possibility. My further comments: The most interesting thing about this patch to me is that the use of GSS key exchange causes a switch over to a completely different model of what host keys are for. This comes from RFC 4462 section 2.1: the basic idea is that when your session is mostly bidirectionally authenticated by the GSSAPI exchanges happening in initial kex and every rekey, host keys become more or less vestigial, and their remaining purpose is to allow a rekey to happen if the requirements of the SSH protocol demand it at an awkward moment when the GSS credentials are not currently available (e.g. timed out and haven't been renewed yet). As such, there's no need for host keys to be _permanent_ or to be a reliable identifier of a particular host, and RFC 4462 allows for the possibility that they might be purely transient and only for this kind of emergency fallback purpose. Therefore, once PuTTY has done a GSS key exchange, it disconnects itself completely from the permanent host key cache functions in storage.h, and instead switches to a _transient_ host key cache stored in memory with the lifetime of just that SSH session. That cache is populated with keys received from the server as a side effect of GSS kex (via the optional SSH2_MSG_KEXGSS_HOSTKEY message), and used if later in the session we have to fall back to a non-GSS key exchange. However, in practice servers we've tested against do not send a host key in that way, so we also have a fallback method of populating the transient cache by triggering an immediate non-GSS rekey straight after userauth (reusing the code path we also use to turn on OpenSSH delayed encryption without the race condition).
2018-04-26 06:18:59 +00:00
ctrl_editbox(s, "Minutes between GSS checks (0 for never)", NO_SHORTCUT, 20,
HELPCTX(ssh_kex_repeat),
conf_editbox_handler,
I(CONF_gssapirekey),
I(-1));
#endif
ctrl_editbox(s, "Max data before rekey (0 for no limit)", 'x', 20,
HELPCTX(ssh_kex_repeat),
conf_editbox_handler,
I(CONF_ssh_rekey_data),
I(16));
ctrl_text(s, "(Use 1M for 1 megabyte, 1G for 1 gigabyte etc)",
HELPCTX(ssh_kex_repeat));
}
/*
* The 'Connection/SSH/Host keys' panel.
*/
if (protcfginfo != 1 && protcfginfo != -1) {
ctrl_settitle(b, "Connection/SSH/Host keys",
"Options controlling SSH host keys");
s = ctrl_getset(b, "Connection/SSH/Host keys", "main",
"Host key algorithm preference");
c = ctrl_draglist(s, "Algorithm selection policy:", 's',
HELPCTX(ssh_hklist),
hklist_handler, P(NULL));
c->listbox.height = 5;
ctrl_checkbox(s, "Prefer algorithms for which a host key is known",
'p', HELPCTX(ssh_hk_known), conf_checkbox_handler,
I(CONF_ssh_prefer_known_hostkeys));
}
/*
* Manual host key configuration is irrelevant mid-session,
* as we enforce that the host key for rekeys is the
* same as that used at the start of the session.
*/
if (!midsession) {
s = ctrl_getset(b, "Connection/SSH/Host keys", "hostkeys",
"Manually configure host keys for this connection");
ctrl_columns(s, 2, 75, 25);
c = ctrl_text(s, "Host keys or fingerprints to accept:",
HELPCTX(ssh_kex_manual_hostkeys));
c->generic.column = 0;
/* You want to select from the list, _then_ hit Remove. So
* tab order should be that way round. */
mh = (struct manual_hostkey_data *)
ctrl_alloc(b,sizeof(struct manual_hostkey_data));
mh->rembutton = ctrl_pushbutton(s, "Remove", 'r',
HELPCTX(ssh_kex_manual_hostkeys),
manual_hostkey_handler, P(mh));
mh->rembutton->generic.column = 1;
Convert a lot of 'int' variables to 'bool'. My normal habit these days, in new code, is to treat int and bool as _almost_ completely separate types. I'm still willing to use C's implicit test for zero on an integer (e.g. 'if (!blob.len)' is fine, no need to spell it out as blob.len != 0), but generally, if a variable is going to be conceptually a boolean, I like to declare it bool and assign to it using 'true' or 'false' rather than 0 or 1. PuTTY is an exception, because it predates the C99 bool, and I've stuck to its existing coding style even when adding new code to it. But it's been annoying me more and more, so now that I've decided C99 bool is an acceptable thing to require from our toolchain in the first place, here's a quite thorough trawl through the source doing 'boolification'. Many variables and function parameters are now typed as bool rather than int; many assignments of 0 or 1 to those variables are now spelled 'true' or 'false'. I managed this thorough conversion with the help of a custom clang plugin that I wrote to trawl the AST and apply heuristics to point out where things might want changing. So I've even managed to do a decent job on parts of the code I haven't looked at in years! To make the plugin's work easier, I pushed platform front ends generally in the direction of using standard 'bool' in preference to platform-specific boolean types like Windows BOOL or GTK's gboolean; I've left the platform booleans in places they _have_ to be for the platform APIs to work right, but variables only used by my own code have been converted wherever I found them. In a few places there are int values that look very like booleans in _most_ of the places they're used, but have a rarely-used third value, or a distinction between different nonzero values that most users don't care about. In these cases, I've _removed_ uses of 'true' and 'false' for the return values, to emphasise that there's something more subtle going on than a simple boolean answer: - the 'multisel' field in dialog.h's list box structure, for which the GTK front end in particular recognises a difference between 1 and 2 but nearly everything else treats as boolean - the 'urgent' parameter to plug_receive, where 1 vs 2 tells you something about the specific location of the urgent pointer, but most clients only care about 0 vs 'something nonzero' - the return value of wc_match, where -1 indicates a syntax error in the wildcard. - the return values from SSH-1 RSA-key loading functions, which use -1 for 'wrong passphrase' and 0 for all other failures (so any caller which already knows it's not loading an _encrypted private_ key can treat them as boolean) - term->esc_query, and the 'query' parameter in toggle_mode in terminal.c, which _usually_ hold 0 for ESC[123h or 1 for ESC[?123h, but can also hold -1 for some other intervening character that we don't support. In a few places there's an integer that I haven't turned into a bool even though it really _can_ only take values 0 or 1 (and, as above, tried to make the call sites consistent in not calling those values true and false), on the grounds that I thought it would make it more confusing to imply that the 0 value was in some sense 'negative' or bad and the 1 positive or good: - the return value of plug_accepting uses the POSIXish convention of 0=success and nonzero=error; I think if I made it bool then I'd also want to reverse its sense, and that's a job for a separate piece of work. - the 'screen' parameter to lineptr() in terminal.c, where 0 and 1 represent the default and alternate screens. There's no obvious reason why one of those should be considered 'true' or 'positive' or 'success' - they're just indices - so I've left it as int. ssh_scp_recv had particularly confusing semantics for its previous int return value: its call sites used '<= 0' to check for error, but it never actually returned a negative number, just 0 or 1. Now the function and its call sites agree that it's a bool. In a couple of places I've renamed variables called 'ret', because I don't like that name any more - it's unclear whether it means the return value (in preparation) for the _containing_ function or the return value received from a subroutine call, and occasionally I've accidentally used the same variable for both and introduced a bug. So where one of those got in my way, I've renamed it to 'toret' or 'retd' (the latter short for 'returned') in line with my usual modern practice, but I haven't done a thorough job of finding all of them. Finally, one amusing side effect of doing this is that I've had to separate quite a few chained assignments. It used to be perfectly fine to write 'a = b = c = TRUE' when a,b,c were int and TRUE was just a the 'true' defined by stdbool.h, that idiom provokes a warning from gcc: 'suggest parentheses around assignment used as truth value'!
2018-11-02 19:23:19 +00:00
mh->rembutton->generic.tabdelay = true;
mh->listbox = ctrl_listbox(s, NULL, NO_SHORTCUT,
HELPCTX(ssh_kex_manual_hostkeys),
manual_hostkey_handler, P(mh));
/* This list box can't be very tall, because there's not
* much room in the pane on Windows at least. This makes
* it become really unhelpful if a horizontal scrollbar
* appears, so we suppress that. */
mh->listbox->listbox.height = 2;
mh->listbox->listbox.hscroll = false;
ctrl_tabdelay(s, mh->rembutton);
mh->keybox = ctrl_editbox(s, "Key", 'k', 80,
HELPCTX(ssh_kex_manual_hostkeys),
manual_hostkey_handler, P(mh), P(NULL));
mh->keybox->generic.column = 0;
mh->addbutton = ctrl_pushbutton(s, "Add key", 'y',
HELPCTX(ssh_kex_manual_hostkeys),
manual_hostkey_handler, P(mh));
mh->addbutton->generic.column = 1;
ctrl_columns(s, 1, 100);
}
if (!midsession || !(protcfginfo == 1 || protcfginfo == -1)) {
/*
* The Connection/SSH/Cipher panel.
*/
ctrl_settitle(b, "Connection/SSH/Cipher",
"Options controlling SSH encryption");
s = ctrl_getset(b, "Connection/SSH/Cipher",
"encryption", "Encryption options");
c = ctrl_draglist(s, "Encryption cipher selection policy:", 's',
HELPCTX(ssh_ciphers),
cipherlist_handler, P(NULL));
c->listbox.height = 6;
ctrl_checkbox(s, "Enable legacy use of single-DES in SSH-2", 'i',
HELPCTX(ssh_ciphers),
conf_checkbox_handler,
I(CONF_ssh2_des_cbc));
}
if (!midsession) {
/*
* The Connection/SSH/Auth panel.
*/
ctrl_settitle(b, "Connection/SSH/Auth",
"Options controlling SSH authentication");
s = ctrl_getset(b, "Connection/SSH/Auth", "main", NULL);
ctrl_checkbox(s, "Display pre-authentication banner (SSH-2 only)",
'd', HELPCTX(ssh_auth_banner),
conf_checkbox_handler,
I(CONF_ssh_show_banner));
ctrl_checkbox(s, "Bypass authentication entirely (SSH-2 only)", 'b',
HELPCTX(ssh_auth_bypass),
conf_checkbox_handler,
I(CONF_ssh_no_userauth));
s = ctrl_getset(b, "Connection/SSH/Auth", "methods",
"Authentication methods");
ctrl_checkbox(s, "Attempt authentication using Pageant", 'p',
HELPCTX(ssh_auth_pageant),
conf_checkbox_handler,
I(CONF_tryagent));
ctrl_checkbox(s, "Attempt TIS or CryptoCard auth (SSH-1)", 'm',
HELPCTX(ssh_auth_tis),
conf_checkbox_handler,
I(CONF_try_tis_auth));
ctrl_checkbox(s, "Attempt \"keyboard-interactive\" auth (SSH-2)",
'i', HELPCTX(ssh_auth_ki),
conf_checkbox_handler,
I(CONF_try_ki_auth));
s = ctrl_getset(b, "Connection/SSH/Auth", "params",
"Authentication parameters");
ctrl_checkbox(s, "Allow agent forwarding", 'f',
HELPCTX(ssh_auth_agentfwd),
conf_checkbox_handler, I(CONF_agentfwd));
ctrl_checkbox(s, "Allow attempted changes of username in SSH-2", NO_SHORTCUT,
HELPCTX(ssh_auth_changeuser),
conf_checkbox_handler,
I(CONF_change_username));
ctrl_filesel(s, "Private key file for authentication:", 'k',
FILTER_KEY_FILES, false, "Select private key file",
HELPCTX(ssh_auth_privkey),
conf_filesel_handler, I(CONF_keyfile));
#ifndef NO_GSSAPI
/*
* Connection/SSH/Auth/GSSAPI, which sadly won't fit on
* the main Auth panel.
*/
ctrl_settitle(b, "Connection/SSH/Auth/GSSAPI",
"Options controlling GSSAPI authentication");
s = ctrl_getset(b, "Connection/SSH/Auth/GSSAPI", "gssapi", NULL);
ctrl_checkbox(s, "Attempt GSSAPI authentication (SSH-2 only)",
't', HELPCTX(ssh_gssapi),
conf_checkbox_handler,
I(CONF_try_gssapi_auth));
ctrl_checkbox(s, "Attempt GSSAPI key exchange (SSH-2 only)",
'k', HELPCTX(ssh_gssapi),
conf_checkbox_handler,
I(CONF_try_gssapi_kex));
ctrl_checkbox(s, "Allow GSSAPI credential delegation", 'l',
HELPCTX(ssh_gssapi_delegation),
conf_checkbox_handler,
I(CONF_gssapifwd));
/*
* GSSAPI library selection.
*/
if (ngsslibs > 1) {
c = ctrl_draglist(s, "Preference order for GSSAPI libraries:",
'p', HELPCTX(ssh_gssapi_libraries),
gsslist_handler, P(NULL));
c->listbox.height = ngsslibs;
/*
* I currently assume that if more than one GSS
* library option is available, then one of them is
* 'user-supplied' and so we should present the
* following file selector. This is at least half-
* reasonable, because if we're using statically
* linked GSSAPI then there will only be one option
* and no way to load from a user-supplied library,
* whereas if we're using dynamic libraries then
* there will almost certainly be some default
* option in addition to a user-supplied path. If
* anyone ever ports PuTTY to a system on which
* dynamic-library GSSAPI is available but there is
* absolutely no consensus on where to keep the
* libraries, there'll need to be a flag alongside
* ngsslibs to control whether the file selector is
* displayed.
*/
ctrl_filesel(s, "User-supplied GSSAPI library path:", 's',
FILTER_DYNLIB_FILES, false, "Select library file",
HELPCTX(ssh_gssapi_libraries),
conf_filesel_handler,
I(CONF_ssh_gss_custom));
}
#endif
}
if (!midsession) {
/*
* The Connection/SSH/TTY panel.
*/
ctrl_settitle(b, "Connection/SSH/TTY", "Remote terminal settings");
s = ctrl_getset(b, "Connection/SSH/TTY", "sshtty", NULL);
ctrl_checkbox(s, "Don't allocate a pseudo-terminal", 'p',
HELPCTX(ssh_nopty),
conf_checkbox_handler,
I(CONF_nopty));
s = ctrl_getset(b, "Connection/SSH/TTY", "ttymodes",
"Terminal modes");
td = (struct ttymodes_data *)
ctrl_alloc(b, sizeof(struct ttymodes_data));
ctrl_text(s, "Terminal modes to send:", HELPCTX(ssh_ttymodes));
td->listbox = ctrl_listbox(s, NULL, NO_SHORTCUT,
HELPCTX(ssh_ttymodes),
ttymodes_handler, P(td));
td->listbox->listbox.height = 8;
td->listbox->listbox.ncols = 2;
td->listbox->listbox.percentages = snewn(2, int);
td->listbox->listbox.percentages[0] = 40;
td->listbox->listbox.percentages[1] = 60;
ctrl_columns(s, 2, 75, 25);
c = ctrl_text(s, "For selected mode, send:", HELPCTX(ssh_ttymodes));
c->generic.column = 0;
td->setbutton = ctrl_pushbutton(s, "Set", 's',
HELPCTX(ssh_ttymodes),
ttymodes_handler, P(td));
td->setbutton->generic.column = 1;
td->setbutton->generic.tabdelay = true;
ctrl_columns(s, 1, 100); /* column break */
/* Bit of a hack to get the value radio buttons and
* edit-box on the same row. */
ctrl_columns(s, 2, 75, 25);
td->valradio = ctrl_radiobuttons(s, NULL, NO_SHORTCUT, 3,
HELPCTX(ssh_ttymodes),
ttymodes_handler, P(td),
"Auto", NO_SHORTCUT, P(NULL),
"Nothing", NO_SHORTCUT, P(NULL),
"This:", NO_SHORTCUT, P(NULL),
NULL);
td->valradio->generic.column = 0;
td->valbox = ctrl_editbox(s, NULL, NO_SHORTCUT, 100,
HELPCTX(ssh_ttymodes),
ttymodes_handler, P(td), P(NULL));
td->valbox->generic.column = 1;
ctrl_tabdelay(s, td->setbutton);
}
if (!midsession) {
/*
* The Connection/SSH/X11 panel.
*/
ctrl_settitle(b, "Connection/SSH/X11",
"Options controlling SSH X11 forwarding");
s = ctrl_getset(b, "Connection/SSH/X11", "x11", "X11 forwarding");
ctrl_checkbox(s, "Enable X11 forwarding", 'e',
HELPCTX(ssh_tunnels_x11),
conf_checkbox_handler,I(CONF_x11_forward));
ctrl_editbox(s, "X display location", 'x', 50,
HELPCTX(ssh_tunnels_x11),
conf_editbox_handler, I(CONF_x11_display), I(1));
ctrl_radiobuttons(s, "Remote X11 authentication protocol", 'u', 2,
HELPCTX(ssh_tunnels_x11auth),
conf_radiobutton_handler,
I(CONF_x11_auth),
"MIT-Magic-Cookie-1", I(X11_MIT),
"XDM-Authorization-1", I(X11_XDM), NULL);
}
/*
* The Tunnels panel _is_ still available in mid-session.
*/
ctrl_settitle(b, "Connection/SSH/Tunnels",
"Options controlling SSH port forwarding");
s = ctrl_getset(b, "Connection/SSH/Tunnels", "portfwd",
"Port forwarding");
ctrl_checkbox(s, "Local ports accept connections from other hosts",'t',
HELPCTX(ssh_tunnels_portfwd_localhost),
conf_checkbox_handler,
I(CONF_lport_acceptall));
ctrl_checkbox(s, "Remote ports do the same (SSH-2 only)", 'p',
HELPCTX(ssh_tunnels_portfwd_localhost),
conf_checkbox_handler,
I(CONF_rport_acceptall));
ctrl_columns(s, 3, 55, 20, 25);
c = ctrl_text(s, "Forwarded ports:", HELPCTX(ssh_tunnels_portfwd));
c->generic.column = COLUMN_FIELD(0,2);
/* You want to select from the list, _then_ hit Remove. So tab order
* should be that way round. */
pfd = (struct portfwd_data *)ctrl_alloc(b,sizeof(struct portfwd_data));
pfd->rembutton = ctrl_pushbutton(s, "Remove", 'r',
HELPCTX(ssh_tunnels_portfwd),
portfwd_handler, P(pfd));
pfd->rembutton->generic.column = 2;
pfd->rembutton->generic.tabdelay = true;
pfd->listbox = ctrl_listbox(s, NULL, NO_SHORTCUT,
HELPCTX(ssh_tunnels_portfwd),
portfwd_handler, P(pfd));
pfd->listbox->listbox.height = 3;
pfd->listbox->listbox.ncols = 2;
pfd->listbox->listbox.percentages = snewn(2, int);
pfd->listbox->listbox.percentages[0] = 20;
pfd->listbox->listbox.percentages[1] = 80;
ctrl_tabdelay(s, pfd->rembutton);
ctrl_text(s, "Add new forwarded port:", HELPCTX(ssh_tunnels_portfwd));
/* You want to enter source, destination and type, _then_ hit Add.
* Again, we adjust the tab order to reflect this. */
pfd->addbutton = ctrl_pushbutton(s, "Add", 'd',
HELPCTX(ssh_tunnels_portfwd),
portfwd_handler, P(pfd));
pfd->addbutton->generic.column = 2;
pfd->addbutton->generic.tabdelay = true;
pfd->sourcebox = ctrl_editbox(s, "Source port", 's', 40,
HELPCTX(ssh_tunnels_portfwd),
portfwd_handler, P(pfd), P(NULL));
pfd->sourcebox->generic.column = 0;
pfd->destbox = ctrl_editbox(s, "Destination", 'i', 67,
HELPCTX(ssh_tunnels_portfwd),
portfwd_handler, P(pfd), P(NULL));
pfd->direction = ctrl_radiobuttons(s, NULL, NO_SHORTCUT, 3,
HELPCTX(ssh_tunnels_portfwd),
portfwd_handler, P(pfd),
"Local", 'l', P(NULL),
"Remote", 'm', P(NULL),
"Dynamic", 'y', P(NULL),
NULL);
#ifndef NO_IPV6
pfd->addressfamily =
ctrl_radiobuttons(s, NULL, NO_SHORTCUT, 3,
HELPCTX(ssh_tunnels_portfwd_ipversion),
portfwd_handler, P(pfd),
"Auto", 'u', I(ADDRTYPE_UNSPEC),
"IPv4", '4', I(ADDRTYPE_IPV4),
"IPv6", '6', I(ADDRTYPE_IPV6),
NULL);
#endif
ctrl_tabdelay(s, pfd->addbutton);
ctrl_columns(s, 1, 100);
if (!midsession) {
/*
* The Connection/SSH/Bugs panels.
*/
ctrl_settitle(b, "Connection/SSH/Bugs",
"Workarounds for SSH server bugs");
s = ctrl_getset(b, "Connection/SSH/Bugs", "main",
"Detection of known bugs in SSH servers");
ctrl_droplist(s, "Chokes on SSH-2 ignore messages", '2', 20,
HELPCTX(ssh_bugs_ignore2),
sshbug_handler, I(CONF_sshbug_ignore2));
ctrl_droplist(s, "Handles SSH-2 key re-exchange badly", 'k', 20,
HELPCTX(ssh_bugs_rekey2),
sshbug_handler, I(CONF_sshbug_rekey2));
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, "Replies to requests on closed channels", 'q', 20,
HELPCTX(ssh_bugs_chanreq),
sshbug_handler, I(CONF_sshbug_chanreq));
ctrl_droplist(s, "Ignores SSH-2 maximum packet size", 'x', 20,
HELPCTX(ssh_bugs_maxpkt2),
sshbug_handler, I(CONF_sshbug_maxpkt2));
ctrl_settitle(b, "Connection/SSH/More bugs",
"Further workarounds for SSH server bugs");
s = ctrl_getset(b, "Connection/SSH/More bugs", "main",
"Detection of known bugs in SSH servers");
ctrl_droplist(s, "Requires padding on SSH-2 RSA signatures", 'p', 20,
HELPCTX(ssh_bugs_rsapad2),
sshbug_handler, I(CONF_sshbug_rsapad2));
ctrl_droplist(s, "Only supports pre-RFC4419 SSH-2 DH GEX", 'd', 20,
HELPCTX(ssh_bugs_oldgex2),
sshbug_handler, I(CONF_sshbug_oldgex2));
ctrl_droplist(s, "Miscomputes SSH-2 HMAC keys", 'm', 20,
HELPCTX(ssh_bugs_hmac2),
sshbug_handler, I(CONF_sshbug_hmac2));
ctrl_droplist(s, "Misuses the session ID in SSH-2 PK auth", 'n', 20,
HELPCTX(ssh_bugs_pksessid2),
sshbug_handler, I(CONF_sshbug_pksessid2));
ctrl_droplist(s, "Miscomputes SSH-2 encryption keys", 'e', 20,
HELPCTX(ssh_bugs_derivekey2),
sshbug_handler, I(CONF_sshbug_derivekey2));
ctrl_droplist(s, "Chokes on SSH-1 ignore messages", 'i', 20,
HELPCTX(ssh_bugs_ignore1),
sshbug_handler, I(CONF_sshbug_ignore1));
ctrl_droplist(s, "Refuses all SSH-1 password camouflage", 's', 20,
HELPCTX(ssh_bugs_plainpw1),
sshbug_handler, I(CONF_sshbug_plainpw1));
ctrl_droplist(s, "Chokes on SSH-1 RSA authentication", 'r', 20,
HELPCTX(ssh_bugs_rsa1),
sshbug_handler, I(CONF_sshbug_rsa1));
}
}
if (DISPLAY_RECONFIGURABLE_PROTOCOL(PROT_SERIAL)) {
const BackendVtable *ser_vt = backend_vt_from_proto(PROT_SERIAL);
/*
* The Connection/Serial panel.
*/
ctrl_settitle(b, "Connection/Serial",
"Options controlling local serial lines");
if (!midsession) {
/*
* We don't permit switching to a different serial port in
* midflight, although we do allow all other
* reconfiguration.
*/
s = ctrl_getset(b, "Connection/Serial", "serline",
"Select a serial line");
ctrl_editbox(s, "Serial line to connect to", 'l', 40,
HELPCTX(serial_line),
conf_editbox_handler, I(CONF_serline), I(1));
}
s = ctrl_getset(b, "Connection/Serial", "sercfg", "Configure the serial line");
ctrl_editbox(s, "Speed (baud)", 's', 40,
HELPCTX(serial_speed),
conf_editbox_handler, I(CONF_serspeed), I(-1));
ctrl_editbox(s, "Data bits", 'b', 40,
HELPCTX(serial_databits),
conf_editbox_handler, I(CONF_serdatabits), I(-1));
/*
* Stop bits come in units of one half.
*/
ctrl_editbox(s, "Stop bits", 't', 40,
HELPCTX(serial_stopbits),
conf_editbox_handler, I(CONF_serstopbits), I(-2));
ctrl_droplist(s, "Parity", 'p', 40,
HELPCTX(serial_parity), serial_parity_handler,
I(ser_vt->serial_parity_mask));
ctrl_droplist(s, "Flow control", 'f', 40,
HELPCTX(serial_flow), serial_flow_handler,
I(ser_vt->serial_flow_mask));
}
if (DISPLAY_RECONFIGURABLE_PROTOCOL(PROT_TELNET)) {
/*
* The Connection/Telnet panel.
*/
ctrl_settitle(b, "Connection/Telnet",
"Options controlling Telnet connections");
s = ctrl_getset(b, "Connection/Telnet", "protocol",
"Telnet protocol adjustments");
if (!midsession) {
ctrl_radiobuttons(s, "Handling of OLD_ENVIRON ambiguity:",
NO_SHORTCUT, 2,
HELPCTX(telnet_oldenviron),
conf_radiobutton_bool_handler,
I(CONF_rfc_environ),
"BSD (commonplace)", 'b', I(false),
"RFC 1408 (unusual)", 'f', I(true), NULL);
ctrl_radiobuttons(s, "Telnet negotiation mode:", 't', 2,
HELPCTX(telnet_passive),
conf_radiobutton_bool_handler,
I(CONF_passive_telnet),
"Passive", I(true), "Active", I(false), NULL);
}
ctrl_checkbox(s, "Keyboard sends Telnet special commands", 'k',
HELPCTX(telnet_specialkeys),
conf_checkbox_handler,
I(CONF_telnet_keyboard));
ctrl_checkbox(s, "Return key sends Telnet New Line instead of ^M",
'm', HELPCTX(telnet_newline),
conf_checkbox_handler,
I(CONF_telnet_newline));
}
if (DISPLAY_NON_RECONFIGURABLE_PROTOCOL(PROT_RLOGIN)) {
/*
* The Connection/Rlogin panel.
*/
ctrl_settitle(b, "Connection/Rlogin",
"Options controlling Rlogin connections");
s = ctrl_getset(b, "Connection/Rlogin", "data",
"Data to send to the server");
ctrl_editbox(s, "Local username:", 'l', 50,
HELPCTX(rlogin_localuser),
conf_editbox_handler, I(CONF_localusername), I(1));
}
if (DISPLAY_NON_RECONFIGURABLE_PROTOCOL(PROT_SUPDUP)) {
/*
* The Connection/SUPDUP panel.
*/
ctrl_settitle(b, "Connection/SUPDUP",
"Enabling and disabling SUPDUP user options");
s = ctrl_getset(b, "Connection/SUPDUP", "main", NULL);
ctrl_editbox(s, "Location string", 'l', 70,
HELPCTX(supdup_location),
conf_editbox_handler, I(CONF_supdup_location),
I(1));
ctrl_radiobuttons(s, "Extended ASCII Character set:", 'z', 4,
HELPCTX(supdup_ascii),
conf_radiobutton_handler,
I(CONF_supdup_ascii_set),
"None", I(SUPDUP_CHARSET_ASCII),
"ITS", I(SUPDUP_CHARSET_ITS),
"WAITS", I(SUPDUP_CHARSET_WAITS), NULL);
ctrl_checkbox(s, "**MORE** processing", 'm',
HELPCTX(supdup_more),
conf_checkbox_handler,
I(CONF_supdup_more));
ctrl_checkbox(s, "Terminal scrolling", 's',
HELPCTX(supdup_scroll),
conf_checkbox_handler,
I(CONF_supdup_scroll));
}
}