]> asedeno.scripts.mit.edu Git - PuTTY_svn.git/blobdiff - config.c
Enable xterm mouse reporting of wheel actions in GTK.
[PuTTY_svn.git] / config.c
index b0b0092c77f452972ec911f17fe109155da5859f..2960cab37a5bfebc2e13abbc9a594e61f56b7b36 100644 (file)
--- a/config.c
+++ b/config.c
@@ -557,22 +557,27 @@ static void sshbug_handler(union control *ctrl, void *dlg,
     }
 }
 
-#define SAVEDSESSION_LEN 2048
-
 struct sessionsaver_data {
     union control *editbox, *listbox, *loadbutton, *savebutton, *delbutton;
     union control *okbutton, *cancelbutton;
     struct sesslist sesslist;
     int midsession;
+    char *savedsession;     /* the current contents of ssd->editbox */
 };
 
+static void sessionsaver_data_free(void *ssdv)
+{
+    struct sessionsaver_data *ssd = (struct sessionsaver_data *)ssdv;
+    sfree(ssd->savedsession);
+    sfree(ssd);
+}
+
 /* 
  * Helper function to load the session selected in the list box, if
  * any, as this is done in more than one place below. Returns 0 for
  * failure.
  */
 static int load_selected_session(struct sessionsaver_data *ssd,
-                                char *savedsession,
                                 void *dlg, Conf *conf, int *maybe_launch)
 {
     int i = dlg_listbox_index(ssd->listbox, dlg);
@@ -583,17 +588,10 @@ static int load_selected_session(struct sessionsaver_data *ssd,
     }
     isdef = !strcmp(ssd->sesslist.sessions[i], "Default Settings");
     load_settings(ssd->sesslist.sessions[i], conf);
-    if (!isdef) {
-       strncpy(savedsession, ssd->sesslist.sessions[i],
-               SAVEDSESSION_LEN);
-       savedsession[SAVEDSESSION_LEN-1] = '\0';
-       if (maybe_launch)
-           *maybe_launch = TRUE;
-    } else {
-       savedsession[0] = '\0';
-       if (maybe_launch)
-           *maybe_launch = FALSE;
-    }
+    sfree(ssd->savedsession);
+    ssd->savedsession = dupstr(isdef ? "" : ssd->sesslist.sessions[i]);
+    if (maybe_launch)
+        *maybe_launch = !isdef;
     dlg_refresh(NULL, dlg);
     /* Restore the selection, which might have been clobbered by
      * changing the value of the edit box. */
@@ -607,33 +605,10 @@ static void sessionsaver_handler(union control *ctrl, void *dlg,
     Conf *conf = (Conf *)data;
     struct sessionsaver_data *ssd =
        (struct sessionsaver_data *)ctrl->generic.context.p;
-    char *savedsession;
-
-    /*
-     * The first time we're called in a new dialog, we must
-     * allocate space to store the current contents of the saved
-     * session edit box (since it must persist even when we switch
-     * panels, but is not part of the Conf).
-     *
-     * FIXME: this is disgusting, and we'd do much better to have
-     * the persistent storage be dynamically allocated and get rid
-     * of the arbitrary limit SAVEDSESSION_LEN. To do that would
-     * require a means of making sure the memory gets freed at the
-     * appropriate moment.
-     */
-    if (!ssd->editbox) {
-        savedsession = NULL;
-    } else if (!dlg_get_privdata(ssd->editbox, dlg)) {
-       savedsession = (char *)
-           dlg_alloc_privdata(ssd->editbox, dlg, SAVEDSESSION_LEN);
-       savedsession[0] = '\0';
-    } else {
-       savedsession = dlg_get_privdata(ssd->editbox, dlg);
-    }
 
     if (event == EVENT_REFRESH) {
        if (ctrl == ssd->editbox) {
-           dlg_editbox_set(ctrl, dlg, savedsession);
+           dlg_editbox_set(ctrl, dlg, ssd->savedsession);
        } else if (ctrl == ssd->listbox) {
            int i;
            dlg_update_start(ctrl, dlg);
@@ -645,14 +620,13 @@ static void sessionsaver_handler(union control *ctrl, void *dlg,
     } else if (event == EVENT_VALCHANGE) {
         int top, bottom, halfway, i;
        if (ctrl == ssd->editbox) {
-           char *tmp = dlg_editbox_get(ctrl, dlg);
-           strncpy(savedsession, tmp, SAVEDSESSION_LEN);
-           sfree(tmp);
+            sfree(ssd->savedsession);
+            ssd->savedsession = dlg_editbox_get(ctrl, dlg);
            top = ssd->sesslist.nsessions;
            bottom = -1;
            while (top-bottom > 1) {
                halfway = (top+bottom)/2;
-               i = strcmp(savedsession, ssd->sesslist.sessions[halfway]);
+               i = strcmp(ssd->savedsession, ssd->sesslist.sessions[halfway]);
                if (i <= 0 ) {
                    top = halfway;
                } else {
@@ -676,29 +650,25 @@ static void sessionsaver_handler(union control *ctrl, void *dlg,
             * double-click on the list box _and_ that session
             * contains a hostname.
             */
-           if (load_selected_session(ssd, savedsession, dlg, conf, &mbl) &&
+           if (load_selected_session(ssd, dlg, conf, &mbl) &&
                (mbl && ctrl == ssd->listbox && conf_launchable(conf))) {
                dlg_end(dlg, 1);       /* it's all over, and succeeded */
            }
        } else if (ctrl == ssd->savebutton) {
-           int isdef = !strcmp(savedsession, "Default Settings");
-           if (!savedsession[0]) {
+           int isdef = !strcmp(ssd->savedsession, "Default Settings");
+           if (!ssd->savedsession[0]) {
                int i = dlg_listbox_index(ssd->listbox, dlg);
                if (i < 0) {
                    dlg_beep(dlg);
                    return;
                }
                isdef = !strcmp(ssd->sesslist.sessions[i], "Default Settings");
-               if (!isdef) {
-                   strncpy(savedsession, ssd->sesslist.sessions[i],
-                           SAVEDSESSION_LEN);
-                   savedsession[SAVEDSESSION_LEN-1] = '\0';
-               } else {
-                   savedsession[0] = '\0';
-               }
+                sfree(ssd->savedsession);
+                ssd->savedsession = dupstr(isdef ? "" :
+                                           ssd->sesslist.sessions[i]);
            }
             {
-                char *errmsg = save_settings(savedsession, conf);
+                char *errmsg = save_settings(ssd->savedsession, conf);
                 if (errmsg) {
                     dlg_error_msg(dlg, errmsg);
                     sfree(errmsg);
@@ -736,8 +706,7 @@ static void sessionsaver_handler(union control *ctrl, void *dlg,
                !conf_launchable(conf)) {
                Conf *conf2 = conf_new();
                int mbl = FALSE;
-               if (!load_selected_session(ssd, savedsession, dlg,
-                                          conf2, &mbl)) {
+               if (!load_selected_session(ssd, dlg, conf2, &mbl)) {
                    dlg_beep(dlg);
                    conf_free(conf2);
                    return;
@@ -1114,9 +1083,23 @@ static void portfwd_handler(union control *ctrl, void *dlg,
                 val != NULL;
                 val = conf_get_str_strs(conf, CONF_portfwd, key, &key)) {
                char *p;
-                if (!strcmp(val, "D"))
-                    p = dupprintf("D%s\t", key+1);
-                else
+                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
                     p = dupprintf("%s\t%s", key, val);
                dlg_listbox_add(ctrl, dlg, p);
                sfree(p);
@@ -1144,8 +1127,8 @@ static void portfwd_handler(union control *ctrl, void *dlg,
            else if (whichbutton == 2)
                family = "6";
            else
-               family = "";
 #endif
+               family = "";
 
            whichbutton = dlg_radiobutton_get(pfd->direction, dlg);
            if (whichbutton == 0)
@@ -1163,7 +1146,7 @@ static void portfwd_handler(union control *ctrl, void *dlg,
            }
            if (*type != 'D') {
                val = dlg_editbox_get(pfd->destbox, dlg);
-               if (!*val || !strchr(val, ':')) {
+               if (!*val || !host_strchr(val, ':')) {
                    dlg_error_msg(dlg,
                                  "You need to specify a destination address\n"
                                  "in the form \"host.name:port\"");
@@ -1256,8 +1239,10 @@ void setup_config_box(struct controlbox *b, int midsession,
     char *str;
 
     ssd = (struct sessionsaver_data *)
-       ctrl_alloc(b, sizeof(struct sessionsaver_data));
+       ctrl_alloc_with_free(b, sizeof(struct sessionsaver_data),
+                             sessionsaver_data_free);
     memset(ssd, 0, sizeof(*ssd));
+    ssd->savedsession = dupstr("");
     ssd->midsession = midsession;
 
     /*
@@ -1376,13 +1361,13 @@ void setup_config_box(struct controlbox *b, int midsession,
     ctrl_columns(s, 1, 100);
 
     s = ctrl_getset(b, "Session", "otheropts", NULL);
-    c = 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);
+    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.
@@ -2114,6 +2099,26 @@ void setup_config_box(struct controlbox *b, int midsession,
                          I(CONF_compression));
        }
 
+       if (!midsession || protcfginfo != 1) {
+           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");
 
@@ -2127,19 +2132,6 @@ void setup_config_box(struct controlbox *b, int midsession,
                              "2 only", 'y', I(3), NULL);
        }
 
-       if (!midsession || protcfginfo != 1) {
-           s = ctrl_getset(b, "Connection/SSH", "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));
-       }
-
        /*
         * The Connection/SSH/Kex panel. (Owing to repeat key
         * exchange, this is all meaningful in mid-session _if_
@@ -2173,6 +2165,26 @@ void setup_config_box(struct controlbox *b, int midsession,
                      HELPCTX(ssh_kex_repeat));
        }
 
+       if (!midsession || 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) {
 
            /*