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;
if (infile) {
infilename = filename_from_str(infile);
- intype = key_type(&infilename);
+ intype = key_type(infilename);
switch (intype) {
/*
* 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.
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;
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;
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)
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;
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;
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;
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;
}
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")) {
union {
int intval;
char *stringval;
- Filename fileval;
+ Filename *fileval;
FontSpec *fontval;
} u;
};
{
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);
}
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);
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)
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);
}
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);
*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);
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 =
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);
}
}
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.
*/
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);
/*
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;
* 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);
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;
* 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);
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
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);
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) {
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;
}
logfclose(ctx);
bufchain_clear(&ctx->queue);
+ if (ctx->currlogfilename)
+ filename_free(ctx->currlogfilename);
sfree(ctx);
}
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;
*
* "&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. */
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;
}
* 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);
/*
* - 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);
/*
/*
* 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 */
/*
* 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)
}
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)
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));
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));
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)
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);
* 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));
* 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));
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;
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 */
*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;
/*
* 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))
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;
public_blob = NULL;
- fp = f_open(*filename, "rb", FALSE);
+ fp = f_open(filename, "rb", FALSE);
if (!fp) {
error = "can't open file";
goto error;
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)
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);
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);
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);
* 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);
}
}
-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)
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[] =
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,
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)
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;
#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 */
* 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[] =
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);
{
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
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);
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)
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; }
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)
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)
* 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;
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);
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)
{
}
}
-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)
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)
* 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[] =
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,
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)
}
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;
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)) {
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 {
*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)
}
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",
/*
* 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;
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));
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));
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);
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);
} 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)
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)
#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;