Turn 'Filename' into a dynamically allocated type with no arbitrary
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sun, 2 Oct 2011 11:01:57 +0000 (11:01 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Sun, 2 Oct 2011 11:01:57 +0000 (11:01 +0000)
length limit, just as I did to FontSpec yesterday.

git-svn-id: svn://svn.tartarus.org/sgt/putty@9316 cda61777-01e9-0310-a592-d414129be87e

29 files changed:
cmdgen.c
cmdline.c
conf.c
config.c
dialog.h
import.c
logging.c
putty.h
settings.c
ssh.c
sshpubk.c
storage.h
unix/gtkdlg.c
unix/gtkwin.c
unix/unix.h
unix/uxcons.c
unix/uxmisc.c
unix/uxplink.c
unix/uxsftp.c
unix/uxstore.c
windows/wincons.c
windows/winctrls.c
windows/windefs.c
windows/windlg.c
windows/winmisc.c
windows/winpgen.c
windows/winpgnt.c
windows/winstore.c
windows/winstuff.h

index 9911db1..9cd5b52 100644 (file)
--- a/cmdgen.c
+++ b/cmdgen.c
@@ -257,10 +257,9 @@ static char *blobfp(char *alg, int bits, unsigned char *blob, int bloblen)
 int main(int argc, char **argv)
 {
     char *infile = NULL;
-    Filename infilename;
+    Filename *infilename, *outfilename;
     enum { NOKEYGEN, RSA1, RSA2, DSA } keytype = NOKEYGEN;    
     char *outfile = NULL, *outfiletmp = NULL;
-    Filename outfilename;
     enum { PRIVATE, PUBLIC, PUBLICO, FP, OPENSSH, SSHCOM } outtype = PRIVATE;
     int bits = 1024;
     char *comment = NULL, *origcomment = NULL;
@@ -536,7 +535,7 @@ int main(int argc, char **argv)
     if (infile) {
        infilename = filename_from_str(infile);
 
-       intype = key_type(&infilename);
+       intype = key_type(infilename);
 
        switch (intype) {
            /*
@@ -707,11 +706,11 @@ int main(int argc, char **argv)
         * Find out whether the input key is encrypted.
         */
        if (intype == SSH_KEYTYPE_SSH1)
-           encrypted = rsakey_encrypted(&infilename, &origcomment);
+           encrypted = rsakey_encrypted(infilename, &origcomment);
        else if (intype == SSH_KEYTYPE_SSH2)
-           encrypted = ssh2_userkey_encrypted(&infilename, &origcomment);
+           encrypted = ssh2_userkey_encrypted(infilename, &origcomment);
        else
-           encrypted = import_encrypted(&infilename, intype, &origcomment);
+           encrypted = import_encrypted(infilename, intype, &origcomment);
 
        /*
         * If so, ask for a passphrase.
@@ -746,7 +745,7 @@ int main(int argc, char **argv)
                unsigned char *blob;
                int n, l, bloblen;
 
-               ret = rsakey_pubblob(&infilename, &vblob, &bloblen,
+               ret = rsakey_pubblob(infilename, &vblob, &bloblen,
                                     &origcomment, &error);
                blob = (unsigned char *)vblob;
 
@@ -768,7 +767,7 @@ int main(int argc, char **argv)
                ssh1key->comment = dupstr(origcomment);
                ssh1key->private_exponent = NULL;
            } else {
-               ret = loadrsakey(&infilename, ssh1key, passphrase, &error);
+               ret = loadrsakey(infilename, ssh1key, passphrase, &error);
            }
            if (ret > 0)
                error = NULL;
@@ -778,7 +777,7 @@ int main(int argc, char **argv)
 
          case SSH_KEYTYPE_SSH2:
            if (!load_encrypted) {
-               ssh2blob = ssh2_userkey_loadpub(&infilename, &ssh2alg,
+               ssh2blob = ssh2_userkey_loadpub(infilename, &ssh2alg,
                                                &ssh2bloblen, NULL, &error);
                ssh2algf = find_pubkey_alg(ssh2alg);
                if (ssh2algf)
@@ -786,7 +785,7 @@ int main(int argc, char **argv)
                else
                    bits = -1;
            } else {
-               ssh2key = ssh2_load_userkey(&infilename, passphrase, &error);
+               ssh2key = ssh2_load_userkey(infilename, passphrase, &error);
            }
            if ((ssh2key && ssh2key != SSH2_WRONG_PASSPHRASE) || ssh2blob)
                error = NULL;
@@ -800,7 +799,7 @@ int main(int argc, char **argv)
 
          case SSH_KEYTYPE_OPENSSH:
          case SSH_KEYTYPE_SSHCOM:
-           ssh2key = import_ssh2(&infilename, intype, passphrase, &error);
+           ssh2key = import_ssh2(infilename, intype, passphrase, &error);
            if (ssh2key) {
                if (ssh2key != SSH2_WRONG_PASSPHRASE)
                    error = NULL;
@@ -892,14 +891,14 @@ int main(int argc, char **argv)
       case PRIVATE:
        if (sshver == 1) {
            assert(ssh1key);
-           ret = saversakey(&outfilename, ssh1key, passphrase);
+           ret = saversakey(outfilename, ssh1key, passphrase);
            if (!ret) {
                fprintf(stderr, "puttygen: unable to save SSH-1 private key\n");
                return 1;
            }
        } else {
            assert(ssh2key);
-           ret = ssh2_save_userkey(&outfilename, ssh2key, passphrase);
+           ret = ssh2_save_userkey(outfilename, ssh2key, passphrase);
            if (!ret) {
                fprintf(stderr, "puttygen: unable to save SSH-2 private key\n");
                return 1;
@@ -1023,7 +1022,7 @@ int main(int argc, char **argv)
       case SSHCOM:
        assert(sshver == 2);
        assert(ssh2key);
-       ret = export_ssh2(&outfilename, outtype, ssh2key, passphrase);
+       ret = export_ssh2(outfilename, outtype, ssh2key, passphrase);
        if (!ret) {
            fprintf(stderr, "puttygen: unable to export key\n");
            return 1;
index 599673f..9c87350 100644 (file)
--- a/cmdline.c
+++ b/cmdline.c
@@ -457,12 +457,13 @@ int cmdline_process_param(char *p, char *value, int need_save, Conf *conf)
     }
 
     if (!strcmp(p, "-i")) {
-       Filename fn;
+       Filename *fn;
        RETURN(2);
        UNAVAILABLE_IN(TOOLTYPE_NONNETWORK);
        SAVEABLE(0);
        fn = filename_from_str(value);
-       conf_set_filename(conf, CONF_keyfile, &fn);
+       conf_set_filename(conf, CONF_keyfile, fn);
+        filename_free(fn);
     }
 
     if (!strcmp(p, "-4") || !strcmp(p, "-ipv4")) {
diff --git a/conf.c b/conf.c
index e3ce258..7b6a013 100644 (file)
--- a/conf.c
+++ b/conf.c
@@ -43,7 +43,7 @@ struct value {
     union {
        int intval;
        char *stringval;
-       Filename fileval;
+       Filename *fileval;
        FontSpec *fontval;
     } u;
 };
@@ -125,6 +125,8 @@ static void free_value(struct value *val, int type)
 {
     if (type == TYPE_STR)
        sfree(val->u.stringval);
+    else if (type == TYPE_FILENAME)
+       filename_free(val->u.fileval);
     else if (type == TYPE_FONT)
        fontspec_free(val->u.fontval);
 }
@@ -143,7 +145,7 @@ static void copy_value(struct value *to, struct value *from, int type)
        to->u.stringval = dupstr(from->u.stringval);
        break;
       case TYPE_FILENAME:
-       to->u.fileval = from->u.fileval;
+       to->u.fileval = filename_copy(from->u.fileval);
        break;
       case TYPE_FONT:
        to->u.fontval = fontspec_copy(from->u.fontval);
@@ -332,7 +334,7 @@ Filename *conf_get_filename(Conf *conf, int primary)
     key.primary = primary;
     entry = find234(conf->tree, &key, NULL);
     assert(entry);
-    return &entry->value.u.fileval;
+    return entry->value.u.fileval;
 }
 
 FontSpec *conf_get_fontspec(Conf *conf, int primary)
@@ -418,7 +420,7 @@ void conf_set_filename(Conf *conf, int primary, const Filename *value)
     assert(subkeytypes[primary] == TYPE_NONE);
     assert(valuetypes[primary] == TYPE_FILENAME);
     entry->key.primary = primary;
-    entry->value.u.fileval = *value;   /* structure copy */
+    entry->value.u.fileval = filename_copy(value);
     conf_insert(conf, entry);
 }
 
@@ -457,7 +459,7 @@ int conf_serialised_size(Conf *conf)
            size += 1 + strlen(entry->value.u.stringval);
            break;
          case TYPE_FILENAME:
-           size += sizeof(entry->value.u.fileval);
+           size += filename_serialise(entry->value.u.fileval, NULL);
            break;
          case TYPE_FONT:
            size += fontspec_serialise(entry->value.u.fontval, NULL);
@@ -504,9 +506,7 @@ void conf_serialise(Conf *conf, void *vdata)
            *data++ = 0;
            break;
          case TYPE_FILENAME:
-           memcpy(data, &entry->value.u.fileval,
-                  sizeof(entry->value.u.fileval));
-           data += sizeof(entry->value.u.fileval);
+            data += filename_serialise(entry->value.u.fileval, data);
            break;
          case TYPE_FONT:
             data += fontspec_serialise(entry->value.u.fontval, data);
@@ -580,16 +580,16 @@ int conf_deserialise(Conf *conf, void *vdata, int maxsize)
            data = zero + 1;
            break;
          case TYPE_FILENAME:
-           if (maxsize < sizeof(entry->value.u.fileval)) {
+            entry->value.u.fileval =
+                filename_deserialise(data, maxsize, &used);
+            if (!entry->value.u.fileval) {
                if (subkeytypes[entry->key.primary] == TYPE_STR)
                    sfree(entry->key.secondary.s);
                sfree(entry);
                goto done;
            }
-           memcpy(&entry->value.u.fileval, data,
-                  sizeof(entry->value.u.fileval));
-           data += sizeof(entry->value.u.fileval);
-           maxsize -= sizeof(entry->value.u.fileval);
+           data += used;
+           maxsize -= used;
            break;
          case TYPE_FONT:
             entry->value.u.fontval =
index a7236d1..87cff8c 100644 (file)
--- a/config.c
+++ b/config.c
@@ -131,12 +131,11 @@ void conf_filesel_handler(union control *ctrl, void *dlg,
     Conf *conf = (Conf *)data;
 
     if (event == EVENT_REFRESH) {
-       dlg_filesel_set(ctrl, dlg, *conf_get_filename(conf, key));
+       dlg_filesel_set(ctrl, dlg, conf_get_filename(conf, key));
     } else if (event == EVENT_VALCHANGE) {
-       Filename filename;
-       dlg_filesel_get(ctrl, dlg, &filename);
-       conf_set_filename(conf, key, &filename);
-       /* If Filenames ever become dynamic, free this one. */
+       Filename *filename = dlg_filesel_get(ctrl, dlg);
+       conf_set_filename(conf, key, filename);
+        filename_free(filename);
     }
 }
 
index eb7ce0e..5977413 100644 (file)
--- a/dialog.h
+++ b/dialog.h
@@ -522,21 +522,6 @@ union control *ctrl_checkbox(struct controlset *, char *label, char shortcut,
 union control *ctrl_tabdelay(struct controlset *, union control *);
 
 /*
- * The standard file-selector handler expects the main `context'
- * field to contain the `offsetof' a Filename field in the
- * structure pointed to by `data'.
- */
-void dlg_stdfilesel_handler(union control *ctrl, void *dlg,
-                           void *data, int event);
-/*
- * The standard font-selector handler expects the main `context'
- * field to contain the `offsetof' a Font field in the structure
- * pointed to by `data'.
- */
-void dlg_stdfontsel_handler(union control *ctrl, void *dlg,
-                           void *data, int event);
-
-/*
  * Routines the platform-independent dialog code can call to read
  * and write the values of controls.
  */
@@ -565,8 +550,8 @@ int dlg_listbox_index(union control *ctrl, void *dlg);
 int dlg_listbox_issel(union control *ctrl, void *dlg, int index);
 void dlg_listbox_select(union control *ctrl, void *dlg, int index);
 void dlg_text_set(union control *ctrl, void *dlg, char const *text);
-void dlg_filesel_set(union control *ctrl, void *dlg, Filename fn);
-void dlg_filesel_get(union control *ctrl, void *dlg, Filename *fn);
+void dlg_filesel_set(union control *ctrl, void *dlg, Filename *fn);
+Filename *dlg_filesel_get(union control *ctrl, void *dlg);
 void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec *fn);
 FontSpec *dlg_fontsel_get(union control *ctrl, void *dlg);
 /*
index 20a77e5..55e3be2 100644 (file)
--- a/import.c
+++ b/import.c
@@ -334,7 +334,7 @@ static struct openssh_key *load_openssh_key(const Filename *filename,
     ret->encrypted = 0;
     memset(ret->iv, 0, sizeof(ret->iv));
 
-    fp = f_open(*filename, "r", FALSE);
+    fp = f_open(filename, "r", FALSE);
     if (!fp) {
        errmsg = "unable to open key file";
        goto error;
@@ -919,7 +919,7 @@ int openssh_write(const Filename *filename, struct ssh2_userkey *key,
      * And save it. We'll use Unix line endings just in case it's
      * subsequently transferred in binary mode.
      */
-    fp = f_open(*filename, "wb", TRUE);      /* ensure Unix line endings */
+    fp = f_open(filename, "wb", TRUE);      /* ensure Unix line endings */
     if (!fp)
        goto error;
     fputs(header, fp);
@@ -1053,7 +1053,7 @@ static struct sshcom_key *load_sshcom_key(const Filename *filename,
     ret->keyblob = NULL;
     ret->keyblob_len = ret->keyblob_size = 0;
 
-    fp = f_open(*filename, "r", FALSE);
+    fp = f_open(filename, "r", FALSE);
     if (!fp) {
        errmsg = "unable to open key file";
        goto error;
@@ -1672,7 +1672,7 @@ int sshcom_write(const Filename *filename, struct ssh2_userkey *key,
      * And save it. We'll use Unix line endings just in case it's
      * subsequently transferred in binary mode.
      */
-    fp = f_open(*filename, "wb", TRUE);      /* ensure Unix line endings */
+    fp = f_open(filename, "wb", TRUE);      /* ensure Unix line endings */
     if (!fp)
        goto error;
     fputs("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----\n", fp);
index b2401c3..6252364 100644 (file)
--- a/logging.c
+++ b/logging.c
@@ -16,13 +16,13 @@ struct LogContext {
     FILE *lgfp;
     enum { L_CLOSED, L_OPENING, L_OPEN, L_ERROR } state;
     bufchain queue;
-    Filename currlogfilename;
+    Filename *currlogfilename;
     void *frontend;
     Conf *conf;
     int logtype;                      /* cached out of conf */
 };
 
-static void xlatlognam(Filename *d, Filename s, char *hostname, struct tm *tm);
+static Filename *xlatlognam(Filename *s, char *hostname, struct tm *tm);
 
 /*
  * Internal wrapper function which must be called for _all_ output
@@ -116,7 +116,7 @@ static void logfopen_callback(void *handle, int mode)
                       ctx->logtype == LGTYP_PACKETS ? "SSH packets" :
                       ctx->logtype == LGTYP_SSHRAW ? "SSH raw data" :
                       "unknown"),
-                     filename_to_str(&ctx->currlogfilename));
+                     filename_to_str(ctx->currlogfilename));
     logevent(ctx->frontend, event);
     sfree(event);
 
@@ -155,9 +155,11 @@ void logfopen(void *handle)
     tm = ltime();
 
     /* substitute special codes in file name */
-    xlatlognam(&ctx->currlogfilename,
-              *conf_get_filename(ctx->conf, CONF_logfilename),
-              conf_get_str(ctx->conf, CONF_host), &tm);
+    if (ctx->currlogfilename)
+        filename_free(ctx->currlogfilename);
+    ctx->currlogfilename = 
+        xlatlognam(conf_get_filename(ctx->conf, CONF_logfilename),
+                   conf_get_str(ctx->conf, CONF_host), &tm);
 
     ctx->lgfp = f_open(ctx->currlogfilename, "r", FALSE);  /* file already present? */
     if (ctx->lgfp) {
@@ -338,6 +340,7 @@ void *log_init(void *frontend, Conf *conf)
     ctx->frontend = frontend;
     ctx->conf = conf_copy(conf);
     ctx->logtype = conf_get_int(ctx->conf, CONF_logtype);
+    ctx->currlogfilename = NULL;
     bufchain_init(&ctx->queue);
     return ctx;
 }
@@ -348,6 +351,8 @@ void log_free(void *handle)
 
     logfclose(ctx);
     bufchain_clear(&ctx->queue);
+    if (ctx->currlogfilename)
+        filename_free(ctx->currlogfilename);
     sfree(ctx);
 }
 
@@ -356,8 +361,8 @@ void log_reconfig(void *handle, Conf *conf)
     struct LogContext *ctx = (struct LogContext *)handle;
     int reset_logging;
 
-    if (!filename_equal(*conf_get_filename(ctx->conf, CONF_logfilename),
-                       *conf_get_filename(conf, CONF_logfilename)) ||
+    if (!filename_equal(conf_get_filename(ctx->conf, CONF_logfilename),
+                       conf_get_filename(conf, CONF_logfilename)) ||
        conf_get_int(ctx->conf, CONF_logtype) !=
        conf_get_int(conf, CONF_logtype))
        reset_logging = TRUE;
@@ -382,17 +387,19 @@ void log_reconfig(void *handle, Conf *conf)
  *
  * "&Y":YYYY   "&m":MM   "&d":DD   "&T":hhmmss   "&h":<hostname>   "&&":&
  */
-static void xlatlognam(Filename *dest, Filename src,
-                      char *hostname, struct tm *tm) {
+static Filename *xlatlognam(Filename *src, char *hostname, struct tm *tm)
+{
     char buf[10], *bufp;
     int size;
-    char buffer[FILENAME_MAX];
-    int len = sizeof(buffer)-1;
-    char *d;
+    char *buffer;
+    int buflen, bufsize;
     const char *s;
+    Filename *ret;
 
-    d = buffer;
-    s = filename_to_str(&src);
+    bufsize = FILENAME_MAX;
+    buffer = snewn(bufsize, char);
+    buflen = 0;
+    s = filename_to_str(src);
 
     while (*s) {
        /* Let (bufp, len) be the string to append. */
@@ -428,13 +435,16 @@ static void xlatlognam(Filename *dest, Filename src,
            buf[0] = *s++;
            size = 1;
        }
-       if (size > len)
-           size = len;
-       memcpy(d, bufp, size);
-       d += size;
-       len -= size;
+        if (bufsize <= buflen + size) {
+            bufsize = (buflen + size) * 5 / 4 + 512;
+            buffer = sresize(buffer, bufsize, char);
+        }
+       memcpy(buffer + buflen, bufp, size);
+       buflen += size;
     }
-    *d = '\0';
+    buffer[buflen] = '\0';
 
-    *dest = filename_from_str(buffer);
+    ret = filename_from_str(buffer);
+    sfree(buffer);
+    return ret;
 }
diff --git a/putty.h b/putty.h
index b1c30c8..e4d3e77 100644 (file)
--- a/putty.h
+++ b/putty.h
@@ -932,12 +932,13 @@ void registry_cleanup(void);
  * Filename and FontSpec functions are _not allowed_ to fail to
  * return, since these defaults _must_ be per-platform.)
  *
- * The 'FontSpec *' returned by platform_default_fontspec has
- * ownership transferred to the caller, and must be freed.
+ * The 'Filename *' returned by platform_default_filename, and the
+ * 'FontSpec *' returned by platform_default_fontspec, have ownership
+ * transferred to the caller, and must be freed.
  */
 char *platform_default_s(const char *name);
 int platform_default_i(const char *name, int def);
-Filename platform_default_filename(const char *name);
+Filename *platform_default_filename(const char *name);
 FontSpec *platform_default_fontspec(const char *name);
 
 /*
@@ -1181,7 +1182,7 @@ int askalg(void *frontend, const char *algtype, const char *algname,
  *  - 0 means cancel logging for this session
  *  - -1 means please wait.
  */
-int askappend(void *frontend, Filename filename,
+int askappend(void *frontend, Filename *filename,
              void (*callback)(void *ctx, int result), void *ctx);
 
 /*
@@ -1263,11 +1264,18 @@ extern const char *const x11_authnames[];  /* declared in x11fwd.c */
 
 /*
  * Miscellaneous exports from the platform-specific code.
+ *
+ * filename_serialise and filename_deserialise have the same semantics
+ * as fontspec_serialise and fontspec_deserialise above.
  */
-Filename filename_from_str(const char *string);
+Filename *filename_from_str(const char *string);
 const char *filename_to_str(const Filename *fn);
-int filename_equal(Filename f1, Filename f2);
-int filename_is_null(Filename fn);
+int filename_equal(const Filename *f1, const Filename *f2);
+int filename_is_null(const Filename *fn);
+Filename *filename_copy(const Filename *fn);
+void filename_free(Filename *fn);
+int filename_serialise(const Filename *f, void *data);
+Filename *filename_deserialise(void *data, int maxsize, int *used);
 char *get_username(void);             /* return value needs freeing */
 char *get_random_data(int bytes);      /* used in cmdgen.c */
 
index 7a2bd37..c189ad3 100644 (file)
@@ -103,7 +103,7 @@ static void gpps(void *handle, const char *name, const char *def,
 
 /*
  * gppfont and gppfile cannot have local defaults, since the very
- * format of a Filename or Font is platform-dependent. So the
+ * format of a Filename or FontSpec is platform-dependent. So the
  * platform-dependent functions MUST return some sort of value.
  */
 static void gppfont(void *handle, const char *name, Conf *conf, int primary)
@@ -116,10 +116,11 @@ static void gppfont(void *handle, const char *name, Conf *conf, int primary)
 }
 static void gppfile(void *handle, const char *name, Conf *conf, int primary)
 {
-    Filename result;
-    if (!read_setting_filename(handle, name, &result))
+    Filename *result = read_setting_filename(handle, name);
+    if (!result)
        result = platform_default_filename(name);
-    conf_set_filename(conf, primary, &result);
+    conf_set_filename(conf, primary, result);
+    filename_free(result);
 }
 
 static int gppi_raw(void *handle, char *name, int def)
@@ -426,7 +427,7 @@ void save_open_settings(void *sesskey, Conf *conf)
 
     write_setting_i(sesskey, "Present", 1);
     write_setting_s(sesskey, "HostName", conf_get_str(conf, CONF_host));
-    write_setting_filename(sesskey, "LogFileName", *conf_get_filename(conf, CONF_logfilename));
+    write_setting_filename(sesskey, "LogFileName", conf_get_filename(conf, CONF_logfilename));
     write_setting_i(sesskey, "LogType", conf_get_int(conf, CONF_logtype));
     write_setting_i(sesskey, "LogFileClash", conf_get_int(conf, CONF_logxfovr));
     write_setting_i(sesskey, "LogFlush", conf_get_int(conf, CONF_logflush));
@@ -486,13 +487,13 @@ void save_open_settings(void *sesskey, Conf *conf)
     write_setting_i(sesskey, "AuthGSSAPI", conf_get_int(conf, CONF_try_gssapi_auth));
 #ifndef NO_GSSAPI
     wprefs(sesskey, "GSSLibs", gsslibkeywords, ngsslibs, conf, CONF_ssh_gsslist);
-    write_setting_filename(sesskey, "GSSCustom", *conf_get_filename(conf, CONF_ssh_gss_custom));
+    write_setting_filename(sesskey, "GSSCustom", conf_get_filename(conf, CONF_ssh_gss_custom));
 #endif
     write_setting_i(sesskey, "SshNoShell", conf_get_int(conf, CONF_ssh_no_shell));
     write_setting_i(sesskey, "SshProt", conf_get_int(conf, CONF_sshprot));
     write_setting_s(sesskey, "LogHost", conf_get_str(conf, CONF_loghost));
     write_setting_i(sesskey, "SSH2DES", conf_get_int(conf, CONF_ssh2_des_cbc));
-    write_setting_filename(sesskey, "PublicKeyFile", *conf_get_filename(conf, CONF_keyfile));
+    write_setting_filename(sesskey, "PublicKeyFile", conf_get_filename(conf, CONF_keyfile));
     write_setting_s(sesskey, "RemoteCommand", conf_get_str(conf, CONF_remote_cmd));
     write_setting_i(sesskey, "RFCEnviron", conf_get_int(conf, CONF_rfc_environ));
     write_setting_i(sesskey, "PassiveTelnet", conf_get_int(conf, CONF_passive_telnet));
@@ -530,7 +531,7 @@ void save_open_settings(void *sesskey, Conf *conf)
     write_setting_i(sesskey, "BlinkCur", conf_get_int(conf, CONF_blink_cur));
     write_setting_i(sesskey, "Beep", conf_get_int(conf, CONF_beep));
     write_setting_i(sesskey, "BeepInd", conf_get_int(conf, CONF_beep_ind));
-    write_setting_filename(sesskey, "BellWaveFile", *conf_get_filename(conf, CONF_bell_wavefile));
+    write_setting_filename(sesskey, "BellWaveFile", conf_get_filename(conf, CONF_bell_wavefile));
     write_setting_i(sesskey, "BellOverload", conf_get_int(conf, CONF_bellovl));
     write_setting_i(sesskey, "BellOverloadN", conf_get_int(conf, CONF_bellovl_n));
     write_setting_i(sesskey, "BellOverloadT", conf_get_int(conf, CONF_bellovl_t)
@@ -605,7 +606,7 @@ void save_open_settings(void *sesskey, Conf *conf)
     write_setting_i(sesskey, "X11Forward", conf_get_int(conf, CONF_x11_forward));
     write_setting_s(sesskey, "X11Display", conf_get_str(conf, CONF_x11_display));
     write_setting_i(sesskey, "X11AuthType", conf_get_int(conf, CONF_x11_auth));
-    write_setting_filename(sesskey, "X11AuthFile", *conf_get_filename(conf, CONF_xauthfile));
+    write_setting_filename(sesskey, "X11AuthFile", conf_get_filename(conf, CONF_xauthfile));
     write_setting_i(sesskey, "LocalPortAcceptAll", conf_get_int(conf, CONF_lport_acceptall));
     write_setting_i(sesskey, "RemotePortAcceptAll", conf_get_int(conf, CONF_rport_acceptall));
     wmap(sesskey, "PortForwardings", conf, CONF_portfwd);
diff --git a/ssh.c b/ssh.c
index 7deb90c..b17a57d 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -3573,7 +3573,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen,
      * Load the public half of any configured keyfile for later use.
      */
     s->keyfile = conf_get_filename(ssh->conf, CONF_keyfile);
-    if (!filename_is_null(*s->keyfile)) {
+    if (!filename_is_null(s->keyfile)) {
        int keytype;
        logeventf(ssh, "Reading private key file \"%.150s\"",
                  filename_to_str(s->keyfile));
@@ -7529,7 +7529,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
         * for later use.
         */
        s->keyfile = conf_get_filename(ssh->conf, CONF_keyfile);
-       if (!filename_is_null(*s->keyfile)) {
+       if (!filename_is_null(s->keyfile)) {
            int keytype;
            logeventf(ssh, "Reading private key file \"%.150s\"",
                      filename_to_str(s->keyfile));
index 4536e85..88ff179 100644 (file)
--- a/sshpubk.c
+++ b/sshpubk.c
@@ -162,7 +162,7 @@ int loadrsakey(const Filename *filename, struct RSAKey *key, char *passphrase,
     int ret = 0;
     const char *error = NULL;
 
-    fp = f_open(*filename, "rb", FALSE);
+    fp = f_open(filename, "rb", FALSE);
     if (!fp) {
        error = "can't open file";
        goto end;
@@ -203,7 +203,7 @@ int rsakey_encrypted(const Filename *filename, char **comment)
     FILE *fp;
     char buf[64];
 
-    fp = f_open(*filename, "rb", FALSE);
+    fp = f_open(filename, "rb", FALSE);
     if (!fp)
        return 0;                      /* doesn't even exist */
 
@@ -241,7 +241,7 @@ int rsakey_pubblob(const Filename *filename, void **blob, int *bloblen,
     *bloblen = 0;
     ret = 0;
 
-    fp = f_open(*filename, "rb", FALSE);
+    fp = f_open(filename, "rb", FALSE);
     if (!fp) {
        error = "can't open file";
        goto end;
@@ -364,7 +364,7 @@ int saversakey(const Filename *filename, struct RSAKey *key, char *passphrase)
     /*
      * Done. Write the result to the file.
      */
-    fp = f_open(*filename, "wb", TRUE);
+    fp = f_open(filename, "wb", TRUE);
     if (fp) {
        int ret = (fwrite(buf, 1, p - buf, fp) == (size_t) (p - buf));
         if (fclose(fp))
@@ -632,7 +632,7 @@ struct ssh2_userkey *ssh2_load_userkey(const Filename *filename,
     encryption = comment = mac = NULL;
     public_blob = private_blob = NULL;
 
-    fp = f_open(*filename, "rb", FALSE);
+    fp = f_open(filename, "rb", FALSE);
     if (!fp) {
        error = "can't open file";
        goto error;
@@ -881,7 +881,7 @@ unsigned char *ssh2_userkey_loadpub(const Filename *filename, char **algorithm,
 
     public_blob = NULL;
 
-    fp = f_open(*filename, "rb", FALSE);
+    fp = f_open(filename, "rb", FALSE);
     if (!fp) {
        error = "can't open file";
        goto error;
@@ -962,7 +962,7 @@ int ssh2_userkey_encrypted(const Filename *filename, char **commentptr)
     if (commentptr)
        *commentptr = NULL;
 
-    fp = f_open(*filename, "rb", FALSE);
+    fp = f_open(filename, "rb", FALSE);
     if (!fp)
        return 0;
     if (!read_header(fp, header)
@@ -1143,7 +1143,7 @@ int ssh2_save_userkey(const Filename *filename, struct ssh2_userkey *key,
        memset(&s, 0, sizeof(s));
     }
 
-    fp = f_open(*filename, "w", TRUE);
+    fp = f_open(filename, "w", TRUE);
     if (!fp)
        return 0;
     fprintf(fp, "PuTTY-User-Key-File-2: %s\n", key->alg->name);
@@ -1179,7 +1179,7 @@ int key_type(const Filename *filename)
     const char openssh_sig[] = "-----BEGIN ";
     int i;
 
-    fp = f_open(*filename, "r", FALSE);
+    fp = f_open(filename, "r", FALSE);
     if (!fp)
        return SSH_KEYTYPE_UNOPENABLE;
     i = fread(buf, 1, sizeof(buf), fp);
index f7fe613..8e07ef0 100644 (file)
--- a/storage.h
+++ b/storage.h
@@ -31,7 +31,7 @@
 void *open_settings_w(const char *sessionname, char **errmsg);
 void write_setting_s(void *handle, const char *key, const char *value);
 void write_setting_i(void *handle, const char *key, int value);
-void write_setting_filename(void *handle, const char *key, Filename value);
+void write_setting_filename(void *handle, const char *key, Filename *value);
 void write_setting_fontspec(void *handle, const char *key, FontSpec *font);
 void close_settings_w(void *handle);
 
@@ -42,20 +42,19 @@ void close_settings_w(void *handle);
  * then close it using close_settings_r().
  * 
  * read_setting_s() returns a dynamically allocated string which the
- * caller must free.
+ * caller must free. read_setting_filename() and
+ * read_setting_fontspec() likewise return dynamically allocated
+ * structures.
  * 
  * If a particular string setting is not present in the session,
  * read_setting_s() can return NULL, in which case the caller
  * should invent a sensible default. If an integer setting is not
  * present, read_setting_i() returns its provided default.
- * 
- * read_setting_filename() and read_setting_fontspec() each read into
- * the provided buffer, and return zero if they failed to.
  */
 void *open_settings_r(const char *sessionname);
 char *read_setting_s(void *handle, const char *key);
 int read_setting_i(void *handle, const char *key, int defvalue);
-int read_setting_filename(void *handle, const char *key, Filename *value);
+Filename *read_setting_filename(void *handle, const char *key);
 FontSpec *read_setting_fontspec(void *handle, const char *key);
 void close_settings_r(void *handle);
 
index 84c9d3a..2781db7 100644 (file)
@@ -906,24 +906,22 @@ void dlg_label_change(union control *ctrl, void *dlg, char const *text)
     }
 }
 
-void dlg_filesel_set(union control *ctrl, void *dlg, Filename fn)
+void dlg_filesel_set(union control *ctrl, void *dlg, Filename *fn)
 {
     struct dlgparam *dp = (struct dlgparam *)dlg;
     struct uctrl *uc = dlg_find_byctrl(dp, ctrl);
     assert(uc->ctrl->generic.type == CTRL_FILESELECT);
     assert(uc->entry != NULL);
-    gtk_entry_set_text(GTK_ENTRY(uc->entry), fn.path);
+    gtk_entry_set_text(GTK_ENTRY(uc->entry), fn->path);
 }
 
-void dlg_filesel_get(union control *ctrl, void *dlg, Filename *fn)
+Filename *dlg_filesel_get(union control *ctrl, void *dlg)
 {
     struct dlgparam *dp = (struct dlgparam *)dlg;
     struct uctrl *uc = dlg_find_byctrl(dp, ctrl);
     assert(uc->ctrl->generic.type == CTRL_FILESELECT);
     assert(uc->entry != NULL);
-    strncpy(fn->path, gtk_entry_get_text(GTK_ENTRY(uc->entry)),
-           lenof(fn->path));
-    fn->path[lenof(fn->path)-1] = '\0';
+    return filename_from_str(gtk_entry_get_text(GTK_ENTRY(uc->entry)));
 }
 
 void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec *fs)
@@ -3741,7 +3739,7 @@ void logevent_dlg(void *estuff, const char *string)
     es->nevents++;
 }
 
-int askappend(void *frontend, Filename filename,
+int askappend(void *frontend, Filename *filename,
              void (*callback)(void *ctx, int result), void *ctx)
 {
     static const char msgtemplate[] =
@@ -3753,7 +3751,7 @@ int askappend(void *frontend, Filename filename,
     char *mbtitle;
     int mbret;
 
-    message = dupprintf(msgtemplate, FILENAME_MAX, filename.path);
+    message = dupprintf(msgtemplate, FILENAME_MAX, filename->path);
     mbtitle = dupprintf("%s Log to File", appname);
 
     mbret = messagebox(get_window(frontend), mbtitle, message,
index e2e672e..334decb 100644 (file)
@@ -159,14 +159,12 @@ FontSpec *platform_default_fontspec(const char *name)
         return fontspec_new("");
 }
 
-Filename platform_default_filename(const char *name)
+Filename *platform_default_filename(const char *name)
 {
-    Filename ret;
     if (!strcmp(name, "LogFileName"))
-       strcpy(ret.path, "putty.log");
+       return filename_from_str("putty.log");
     else
-       *ret.path = '\0';
-    return ret;
+       return filename_from_str("");
 }
 
 char *platform_default_s(const char *name)
@@ -2648,13 +2646,13 @@ int do_cmdline(int argc, char **argv, int do_everything, int *allow_launch,
            conf_set_str(conf, CONF_wintitle, val);
 
        } else if (!strcmp(p, "-log")) {
-           Filename fn;
+           Filename *fn;
            EXPECTS_ARG;
            SECOND_PASS_ONLY;
-           strncpy(fn.path, val, sizeof(fn.path));
-           fn.path[sizeof(fn.path)-1] = '\0';
-           conf_set_filename(conf, CONF_logfilename, &fn);
+            fn = filename_from_str(val);
+           conf_set_filename(conf, CONF_logfilename, fn);
            conf_set_int(conf, CONF_logtype, LGTYP_DEBUG);
+            filename_free(fn);
 
        } else if (!strcmp(p, "-ut-") || !strcmp(p, "+ut")) {
            SECOND_PASS_ONLY;
index aa44c9b..37649d5 100644 (file)
@@ -13,9 +13,9 @@
 #include "charset.h"
 
 struct Filename {
-    char path[FILENAME_MAX];
+    char *path;
 };
-FILE *f_open(struct Filename, char const *, int);
+FILE *f_open(const struct Filename *, char const *, int);
 
 struct FontSpec {
     char *name;    /* may be "" to indicate no selected font at all */
index 4c14eb6..9ceed0d 100644 (file)
@@ -235,7 +235,7 @@ int askalg(void *frontend, const char *algtype, const char *algname,
  * Ask whether to wipe a session log file before writing to it.
  * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
  */
-int askappend(void *frontend, Filename filename,
+int askappend(void *frontend, Filename *filename,
              void (*callback)(void *ctx, int result), void *ctx)
 {
     static const char msgtemplate[] =
@@ -256,11 +256,11 @@ int askappend(void *frontend, Filename filename,
 
     premsg(&cf);
     if (console_batch_mode) {
-       fprintf(stderr, msgtemplate_batch, FILENAME_MAX, filename.path);
+       fprintf(stderr, msgtemplate_batch, FILENAME_MAX, filename->path);
        fflush(stderr);
        return 0;
     }
-    fprintf(stderr, msgtemplate, FILENAME_MAX, filename.path);
+    fprintf(stderr, msgtemplate, FILENAME_MAX, filename->path);
     fflush(stderr);
 
     {
index 222d559..7d577f9 100644 (file)
@@ -27,27 +27,58 @@ unsigned long getticks(void)
     return tv.tv_sec * 1000 + tv.tv_usec / 1000 + tickcount_offset;
 }
 
-Filename filename_from_str(const char *str)
+Filename *filename_from_str(const char *str)
 {
-    Filename ret;
-    strncpy(ret.path, str, sizeof(ret.path));
-    ret.path[sizeof(ret.path)-1] = '\0';
+    Filename *ret = snew(Filename);
+    ret->path = dupstr(str);
     return ret;
 }
 
+Filename *filename_copy(const Filename *fn)
+{
+    return filename_from_str(fn->path);
+}
+
 const char *filename_to_str(const Filename *fn)
 {
     return fn->path;
 }
 
-int filename_equal(Filename f1, Filename f2)
+int filename_equal(const Filename *f1, const Filename *f2)
+{
+    return !strcmp(f1->path, f2->path);
+}
+
+int filename_is_null(const Filename *fn)
+{
+    return !fn->path[0];
+}
+
+void filename_free(Filename *fn)
 {
-    return !strcmp(f1.path, f2.path);
+    sfree(fn->path);
+    sfree(fn);
 }
 
-int filename_is_null(Filename fn)
+int filename_serialise(const Filename *f, void *vdata)
+{
+    char *data = (char *)vdata;
+    int len = strlen(f->path) + 1;     /* include trailing NUL */
+    if (data) {
+        strcpy(data, f->path);
+    }
+    return len;
+}
+Filename *filename_deserialise(void *vdata, int maxsize, int *used)
 {
-    return !*fn.path;
+    char *data = (char *)vdata;
+    char *end;
+    end = memchr(data, '\0', maxsize);
+    if (!end)
+        return NULL;
+    end++;
+    *used = end - data;
+    return filename_from_str(data);
 }
 
 #ifdef DEBUG
@@ -135,16 +166,15 @@ int cloexec(int fd) {
     return fcntl(fd, F_SETFD, fdflags | FD_CLOEXEC);
 }
 
-FILE *f_open(struct Filename filename, char const *mode, int is_private)
+FILE *f_open(const Filename *filename, char const *mode, int is_private)
 {
     if (!is_private) {
-       return fopen(filename.path, mode);
+       return fopen(filename->path, mode);
     } else {
        int fd;
        assert(mode[0] == 'w');        /* is_private is meaningless for read,
                                          and tricky for append */
-       fd = open(filename.path, O_WRONLY | O_CREAT | O_TRUNC,
-                     0700);
+       fd = open(filename->path, O_WRONLY | O_CREAT | O_TRUNC, 0700);
        if (fd < 0)
            return NULL;
        return fdopen(fd, mode);
index fc8100c..37c8533 100644 (file)
@@ -130,14 +130,12 @@ FontSpec *platform_default_fontspec(const char *name)
     return fontspec_new("");
 }
 
-Filename platform_default_filename(const char *name)
+Filename *platform_default_filename(const char *name)
 {
-    Filename ret;
     if (!strcmp(name, "LogFileName"))
-       strcpy(ret.path, "putty.log");
+       return filename_from_str("putty.log");
     else
-       *ret.path = '\0';
-    return ret;
+       return filename_from_str("");
 }
 
 char *x_get_default(const char *key)
index c19df12..61847d8 100644 (file)
@@ -58,14 +58,12 @@ FontSpec *platform_default_fontspec(const char *name)
     return fontspec_new("");
 }
 
-Filename platform_default_filename(const char *name)
+Filename *platform_default_filename(const char *name)
 {
-    Filename ret;
     if (!strcmp(name, "LogFileName"))
-       strcpy(ret.path, "putty.log");
+       return filename_from_str("putty.log");
     else
-       *ret.path = '\0';
-    return ret;
+       return filename_from_str("");
 }
 
 char *get_ttymode(void *frontend, const char *mode) { return NULL; }
index d9f6013..9d10157 100644 (file)
@@ -395,16 +395,15 @@ FontSpec *read_setting_fontspec(void *handle, const char *name)
        return NULL;
     }
 }
-int read_setting_filename(void *handle, const char *name, Filename *result)
+Filename *read_setting_filename(void *handle, const char *name)
 {
     char *tmp = read_setting_s(handle, name);
     if (tmp) {
-       strncpy(result->path, tmp, sizeof(result->path)-1);
-       result->path[sizeof(result->path)-1] = '\0';
+        Filename *ret = filename_from_str(tmp);
        sfree(tmp);
-       return TRUE;
+       return ret;
     } else
-       return FALSE;
+       return NULL;
 }
 
 void write_setting_fontspec(void *handle, const char *name, FontSpec *fs)
@@ -418,9 +417,9 @@ void write_setting_fontspec(void *handle, const char *name, FontSpec *fs)
     write_setting_s(handle, suffname, fs->name);
     sfree(suffname);
 }
-void write_setting_filename(void *handle, const char *name, Filename result)
+void write_setting_filename(void *handle, const char *name, Filename *result)
 {
-    write_setting_s(handle, name, result.path);
+    write_setting_s(handle, name, result->path);
 }
 
 void close_settings_r(void *handle)
index 5694884..da5bac5 100644 (file)
@@ -201,7 +201,7 @@ int askalg(void *frontend, const char *algtype, const char *algname,
  * Ask whether to wipe a session log file before writing to it.
  * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
  */
-int askappend(void *frontend, Filename filename,
+int askappend(void *frontend, Filename *filename,
              void (*callback)(void *ctx, int result), void *ctx)
 {
     HANDLE hin;
@@ -223,11 +223,11 @@ int askappend(void *frontend, Filename filename,
     char line[32];
 
     if (console_batch_mode) {
-       fprintf(stderr, msgtemplate_batch, FILENAME_MAX, filename.path);
+       fprintf(stderr, msgtemplate_batch, FILENAME_MAX, filename->path);
        fflush(stderr);
        return 0;
     }
-    fprintf(stderr, msgtemplate, FILENAME_MAX, filename.path);
+    fprintf(stderr, msgtemplate, FILENAME_MAX, filename->path);
     fflush(stderr);
 
     hin = GetStdHandle(STD_INPUT_HANDLE);
index 4afd3d0..fa79e64 100644 (file)
@@ -2098,25 +2098,28 @@ void dlg_editbox_set(union control *ctrl, void *dlg, char const *text)
     SetDlgItemText(dp->hwnd, c->base_id+1, text);
 }
 
-char *dlg_editbox_get(union control *ctrl, void *dlg)
+static char *getdlgitemtext_alloc(HWND hwnd, int id)
 {
-    struct dlgparam *dp = (struct dlgparam *)dlg;
-    struct winctrl *c = dlg_findbyctrl(dp, ctrl);
-    char *ret;
-    int size;
-    assert(c && c->ctrl->generic.type == CTRL_EDITBOX);
+    char *ret = NULL;
+    int size = 0;
 
-    size = 0;
-    ret = NULL;
     do {
        size = size * 4 / 3 + 512;
        ret = sresize(ret, size, char);
-       GetDlgItemText(dp->hwnd, c->base_id+1, ret, size);
+       GetDlgItemText(hwnd, id, ret, size);
     } while (!memchr(ret, '\0', size-1));
 
     return ret;
 }
 
+char *dlg_editbox_get(union control *ctrl, void *dlg)
+{
+    struct dlgparam *dp = (struct dlgparam *)dlg;
+    struct winctrl *c = dlg_findbyctrl(dp, ctrl);
+    assert(c && c->ctrl->generic.type == CTRL_EDITBOX);
+    return getdlgitemtext_alloc(dp->hwnd, c->base_id+1);
+}
+
 /* The `listbox' functions can also apply to combo boxes. */
 void dlg_listbox_clear(union control *ctrl, void *dlg)
 {
@@ -2294,21 +2297,25 @@ void dlg_label_change(union control *ctrl, void *dlg, char const *text)
     }
 }
 
-void dlg_filesel_set(union control *ctrl, void *dlg, Filename fn)
+void dlg_filesel_set(union control *ctrl, void *dlg, Filename *fn)
 {
     struct dlgparam *dp = (struct dlgparam *)dlg;
     struct winctrl *c = dlg_findbyctrl(dp, ctrl);
     assert(c && c->ctrl->generic.type == CTRL_FILESELECT);
-    SetDlgItemText(dp->hwnd, c->base_id+1, fn.path);
+    SetDlgItemText(dp->hwnd, c->base_id+1, fn->path);
 }
 
-void dlg_filesel_get(union control *ctrl, void *dlg, Filename *fn)
+Filename *dlg_filesel_get(union control *ctrl, void *dlg)
 {
     struct dlgparam *dp = (struct dlgparam *)dlg;
     struct winctrl *c = dlg_findbyctrl(dp, ctrl);
+    char *tmp;
+    Filename *ret;
     assert(c && c->ctrl->generic.type == CTRL_FILESELECT);
-    GetDlgItemText(dp->hwnd, c->base_id+1, fn->path, lenof(fn->path));
-    fn->path[lenof(fn->path)-1] = '\0';
+    tmp = getdlgitemtext_alloc(dp->hwnd, c->base_id+1);
+    ret = filename_from_str(tmp);
+    sfree(tmp);
+    return ret;
 }
 
 void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec *fs)
index 4296bb0..24a2ea4 100644 (file)
@@ -14,14 +14,12 @@ FontSpec *platform_default_fontspec(const char *name)
         return fontspec_new("", 0, 0, 0);
 }
 
-Filename platform_default_filename(const char *name)
+Filename *platform_default_filename(const char *name)
 {
-    Filename ret;
     if (!strcmp(name, "LogFileName"))
-       strcpy(ret.path, "putty.log");
+       return filename_from_str("putty.log");
     else
-       *ret.path = '\0';
-    return ret;
+       return filename_from_str("");
 }
 
 char *platform_default_s(const char *name)
index c24ec58..aadf88e 100644 (file)
@@ -858,7 +858,7 @@ int askalg(void *frontend, const char *algtype, const char *algname,
  * Ask whether to wipe a session log file before writing to it.
  * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
  */
-int askappend(void *frontend, Filename filename,
+int askappend(void *frontend, Filename *filename,
              void (*callback)(void *ctx, int result), void *ctx)
 {
     static const char msgtemplate[] =
@@ -872,7 +872,7 @@ int askappend(void *frontend, Filename filename,
     char *mbtitle;
     int mbret;
 
-    message = dupprintf(msgtemplate, FILENAME_MAX, filename.path);
+    message = dupprintf(msgtemplate, FILENAME_MAX, filename->path);
     mbtitle = dupprintf("%s Log to File", appname);
 
     mbret = MessageBox(NULL, message, mbtitle,
index a7ac0e5..f54e8a4 100644 (file)
@@ -14,27 +14,58 @@ char *platform_get_x_display(void) {
     return dupstr(getenv("DISPLAY"));
 }
 
-Filename filename_from_str(const char *str)
+Filename *filename_from_str(const char *str)
 {
-    Filename ret;
-    strncpy(ret.path, str, sizeof(ret.path));
-    ret.path[sizeof(ret.path)-1] = '\0';
+    Filename *ret = snew(Filename);
+    ret->path = dupstr(str);
     return ret;
 }
 
+Filename *filename_copy(const Filename *fn)
+{
+    return filename_from_str(fn->path);
+}
+
 const char *filename_to_str(const Filename *fn)
 {
     return fn->path;
 }
 
-int filename_equal(Filename f1, Filename f2)
+int filename_equal(const Filename *f1, const Filename *f2)
+{
+    return !strcmp(f1->path, f2->path);
+}
+
+int filename_is_null(const Filename *fn)
 {
-    return !strcmp(f1.path, f2.path);
+    return !*fn->path;
 }
 
-int filename_is_null(Filename fn)
+void filename_free(Filename *fn)
 {
-    return !*fn.path;
+    sfree(fn->path);
+    sfree(fn);
+}
+
+int filename_serialise(const Filename *f, void *vdata)
+{
+    char *data = (char *)vdata;
+    int len = strlen(f->path) + 1;     /* include trailing NUL */
+    if (data) {
+        strcpy(data, f->path);
+    }
+    return len;
+}
+Filename *filename_deserialise(void *vdata, int maxsize, int *used)
+{
+    char *data = (char *)vdata;
+    char *end;
+    end = memchr(data, '\0', maxsize);
+    if (!end)
+        return NULL;
+    end++;
+    *used = end - data;
+    return filename_from_str(data);
 }
 
 char *get_username(void)
index 550cdfc..1e39105 100644 (file)
@@ -615,7 +615,7 @@ void ui_set_state(HWND hwnd, struct MainDlgState *state, int status)
 }
 
 void load_key_file(HWND hwnd, struct MainDlgState *state,
-                  Filename filename, int was_import_cmd)
+                  Filename *filename, int was_import_cmd)
 {
     char passphrase[PASSPHRASE_MAXLEN];
     int needs_pass;
@@ -627,7 +627,7 @@ void load_key_file(HWND hwnd, struct MainDlgState *state,
     struct RSAKey newkey1;
     struct ssh2_userkey *newkey2 = NULL;
 
-    type = realtype = key_type(&filename);
+    type = realtype = key_type(filename);
     if (type != SSH_KEYTYPE_SSH1 &&
        type != SSH_KEYTYPE_SSH2 &&
        !import_possible(type)) {
@@ -647,13 +647,11 @@ void load_key_file(HWND hwnd, struct MainDlgState *state,
 
     comment = NULL;
     if (realtype == SSH_KEYTYPE_SSH1)
-       needs_pass = rsakey_encrypted(&filename, &comment);
+       needs_pass = rsakey_encrypted(filename, &comment);
     else if (realtype == SSH_KEYTYPE_SSH2)
-       needs_pass =
-       ssh2_userkey_encrypted(&filename, &comment);
+       needs_pass = ssh2_userkey_encrypted(filename, &comment);
     else
-       needs_pass = import_encrypted(&filename, realtype,
-                                     &comment);
+       needs_pass = import_encrypted(filename, realtype, &comment);
     pps.passphrase = passphrase;
     pps.comment = comment;
     do {
@@ -671,18 +669,15 @@ void load_key_file(HWND hwnd, struct MainDlgState *state,
            *passphrase = '\0';
        if (type == SSH_KEYTYPE_SSH1) {
            if (realtype == type)
-               ret = loadrsakey(&filename, &newkey1,
-                                passphrase, &errmsg);
+               ret = loadrsakey(filename, &newkey1, passphrase, &errmsg);
            else
-               ret = import_ssh1(&filename, realtype,
-                                 &newkey1, passphrase, &errmsg);
+               ret = import_ssh1(filename, realtype, &newkey1,
+                                  passphrase, &errmsg);
        } else {
            if (realtype == type)
-               newkey2 = ssh2_load_userkey(&filename,
-                                           passphrase, &errmsg);
+               newkey2 = ssh2_load_userkey(filename, passphrase, &errmsg);
            else
-               newkey2 = import_ssh2(&filename, realtype,
-                                     passphrase, &errmsg);
+               newkey2 = import_ssh2(filename, realtype, passphrase, &errmsg);
            if (newkey2 == SSH2_WRONG_PASSPHRASE)
                ret = -1;
            else if (!newkey2)
@@ -1166,22 +1161,24 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
                    }
 
                    if (state->ssh2) {
-                       Filename fn = filename_from_str(filename);
+                       Filename *fn = filename_from_str(filename);
                         if (type != realtype)
-                            ret = export_ssh2(&fn, type, &state->ssh2key,
+                            ret = export_ssh2(fn, type, &state->ssh2key,
                                               *passphrase ? passphrase : NULL);
                         else
-                            ret = ssh2_save_userkey(&fn, &state->ssh2key,
+                            ret = ssh2_save_userkey(fn, &state->ssh2key,
                                                     *passphrase ? passphrase :
                                                     NULL);
+                        filename_free(fn);
                    } else {
-                       Filename fn = filename_from_str(filename);
+                       Filename *fn = filename_from_str(filename);
                         if (type != realtype)
-                            ret = export_ssh1(&fn, type, &state->key,
+                            ret = export_ssh1(fn, type, &state->key,
                                               *passphrase ? passphrase : NULL);
                         else
-                            ret = saversakey(&fn, &state->key,
+                            ret = saversakey(fn, &state->key,
                                              *passphrase ? passphrase : NULL);
+                        filename_free(fn);
                    }
                    if (ret <= 0) {
                        MessageBox(hwnd, "Unable to save key file",
index eee99f5..9d59327 100644 (file)
@@ -385,7 +385,7 @@ static void keylist_update(void)
 /*
  * This function loads a key from a file and adds it.
  */
-static void add_keyfile(Filename filename)
+static void add_keyfile(Filename *filename)
 {
     char passphrase[PASSPHRASE_MAXLEN];
     struct RSAKey *rkey = NULL;
@@ -399,7 +399,7 @@ static void add_keyfile(Filename filename)
     int type;
     int original_pass;
        
-    type = key_type(&filename);
+    type = key_type(filename);
     if (type != SSH_KEYTYPE_SSH1 && type != SSH_KEYTYPE_SSH2) {
        char *msg = dupprintf("Couldn't load this key (%s)",
                              key_type_to_str(type));
@@ -419,7 +419,7 @@ static void add_keyfile(Filename filename)
        int i, nkeys, bloblen, keylistlen;
 
        if (type == SSH_KEYTYPE_SSH1) {
-           if (!rsakey_pubblob(&filename, &blob, &bloblen, NULL, &error)) {
+           if (!rsakey_pubblob(filename, &blob, &bloblen, NULL, &error)) {
                char *msg = dupprintf("Couldn't load private key (%s)", error);
                message_box(msg, APPNAME, MB_OK | MB_ICONERROR,
                            HELPCTXID(errors_cantloadkey));
@@ -429,7 +429,7 @@ static void add_keyfile(Filename filename)
            keylist = get_keylist1(&keylistlen);
        } else {
            unsigned char *blob2;
-           blob = ssh2_userkey_loadpub(&filename, NULL, &bloblen,
+           blob = ssh2_userkey_loadpub(filename, NULL, &bloblen,
                                        NULL, &error);
            if (!blob) {
                char *msg = dupprintf("Couldn't load private key (%s)", error);
@@ -517,9 +517,9 @@ static void add_keyfile(Filename filename)
 
     error = NULL;
     if (type == SSH_KEYTYPE_SSH1)
-       needs_pass = rsakey_encrypted(&filename, &comment);
+       needs_pass = rsakey_encrypted(filename, &comment);
     else
-       needs_pass = ssh2_userkey_encrypted(&filename, &comment);
+       needs_pass = ssh2_userkey_encrypted(filename, &comment);
     attempts = 0;
     if (type == SSH_KEYTYPE_SSH1)
        rkey = snew(struct RSAKey);
@@ -549,9 +549,9 @@ static void add_keyfile(Filename filename)
        } else
            *passphrase = '\0';
        if (type == SSH_KEYTYPE_SSH1)
-           ret = loadrsakey(&filename, rkey, passphrase, &error);
+           ret = loadrsakey(filename, rkey, passphrase, &error);
        else {
-           skey = ssh2_load_userkey(&filename, passphrase, &error);
+           skey = ssh2_load_userkey(filename, passphrase, &error);
            if (skey == SSH2_WRONG_PASSPHRASE)
                ret = -1;
            else if (!skey)
index c165676..76c73d0 100644 (file)
@@ -230,21 +230,20 @@ void write_setting_fontspec(void *handle, const char *name, FontSpec *font)
     sfree(settingname);
 }
 
-int read_setting_filename(void *handle, const char *name, Filename *result)
+Filename *read_setting_filename(void *handle, const char *name)
 {
     char *tmp = read_setting_s(handle, name);
     if (tmp) {
-       strncpy(result->path, tmp, sizeof(result->path)-1);
-       result->path[sizeof(result->path)-1] = '\0';
+        Filename *ret = filename_from_str(tmp);
        sfree(tmp);
-       return TRUE;
+       return ret;
     } else
-       return FALSE;
+       return NULL;
 }
 
-void write_setting_filename(void *handle, const char *name, Filename result)
+void write_setting_filename(void *handle, const char *name, Filename *result)
 {
-    write_setting_s(handle, name, result.path);
+    write_setting_s(handle, name, result->path);
 }
 
 void close_settings_r(void *handle)
index e23ed4e..e8b70d4 100644 (file)
@@ -16,9 +16,9 @@
 #include "winhelp.h"
 
 struct Filename {
-    char path[FILENAME_MAX];
+    char *path;
 };
-#define f_open(filename, mode, isprivate) ( fopen((filename).path, (mode)) )
+#define f_open(filename, mode, isprivate) ( fopen((filename)->path, (mode)) )
 
 struct FontSpec {
     char *name;