1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-25 01:02:24 +00:00

Turn 'Filename' into a dynamically allocated type with no arbitrary

length limit, just as I did to FontSpec yesterday.

[originally from svn r9316]
This commit is contained in:
Simon Tatham 2011-10-02 11:01:57 +00:00
parent 342690f7cb
commit 62cbc7dc0b
29 changed files with 289 additions and 234 deletions

View File

@ -257,10 +257,9 @@ static char *blobfp(char *alg, int bits, unsigned char *blob, int bloblen)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
char *infile = NULL; char *infile = NULL;
Filename infilename; Filename *infilename, *outfilename;
enum { NOKEYGEN, RSA1, RSA2, DSA } keytype = NOKEYGEN; enum { NOKEYGEN, RSA1, RSA2, DSA } keytype = NOKEYGEN;
char *outfile = NULL, *outfiletmp = NULL; char *outfile = NULL, *outfiletmp = NULL;
Filename outfilename;
enum { PRIVATE, PUBLIC, PUBLICO, FP, OPENSSH, SSHCOM } outtype = PRIVATE; enum { PRIVATE, PUBLIC, PUBLICO, FP, OPENSSH, SSHCOM } outtype = PRIVATE;
int bits = 1024; int bits = 1024;
char *comment = NULL, *origcomment = NULL; char *comment = NULL, *origcomment = NULL;
@ -536,7 +535,7 @@ int main(int argc, char **argv)
if (infile) { if (infile) {
infilename = filename_from_str(infile); infilename = filename_from_str(infile);
intype = key_type(&infilename); intype = key_type(infilename);
switch (intype) { switch (intype) {
/* /*
@ -707,11 +706,11 @@ int main(int argc, char **argv)
* Find out whether the input key is encrypted. * Find out whether the input key is encrypted.
*/ */
if (intype == SSH_KEYTYPE_SSH1) if (intype == SSH_KEYTYPE_SSH1)
encrypted = rsakey_encrypted(&infilename, &origcomment); encrypted = rsakey_encrypted(infilename, &origcomment);
else if (intype == SSH_KEYTYPE_SSH2) else if (intype == SSH_KEYTYPE_SSH2)
encrypted = ssh2_userkey_encrypted(&infilename, &origcomment); encrypted = ssh2_userkey_encrypted(infilename, &origcomment);
else else
encrypted = import_encrypted(&infilename, intype, &origcomment); encrypted = import_encrypted(infilename, intype, &origcomment);
/* /*
* If so, ask for a passphrase. * If so, ask for a passphrase.
@ -746,7 +745,7 @@ int main(int argc, char **argv)
unsigned char *blob; unsigned char *blob;
int n, l, bloblen; int n, l, bloblen;
ret = rsakey_pubblob(&infilename, &vblob, &bloblen, ret = rsakey_pubblob(infilename, &vblob, &bloblen,
&origcomment, &error); &origcomment, &error);
blob = (unsigned char *)vblob; blob = (unsigned char *)vblob;
@ -768,7 +767,7 @@ int main(int argc, char **argv)
ssh1key->comment = dupstr(origcomment); ssh1key->comment = dupstr(origcomment);
ssh1key->private_exponent = NULL; ssh1key->private_exponent = NULL;
} else { } else {
ret = loadrsakey(&infilename, ssh1key, passphrase, &error); ret = loadrsakey(infilename, ssh1key, passphrase, &error);
} }
if (ret > 0) if (ret > 0)
error = NULL; error = NULL;
@ -778,7 +777,7 @@ int main(int argc, char **argv)
case SSH_KEYTYPE_SSH2: case SSH_KEYTYPE_SSH2:
if (!load_encrypted) { if (!load_encrypted) {
ssh2blob = ssh2_userkey_loadpub(&infilename, &ssh2alg, ssh2blob = ssh2_userkey_loadpub(infilename, &ssh2alg,
&ssh2bloblen, NULL, &error); &ssh2bloblen, NULL, &error);
ssh2algf = find_pubkey_alg(ssh2alg); ssh2algf = find_pubkey_alg(ssh2alg);
if (ssh2algf) if (ssh2algf)
@ -786,7 +785,7 @@ int main(int argc, char **argv)
else else
bits = -1; bits = -1;
} else { } else {
ssh2key = ssh2_load_userkey(&infilename, passphrase, &error); ssh2key = ssh2_load_userkey(infilename, passphrase, &error);
} }
if ((ssh2key && ssh2key != SSH2_WRONG_PASSPHRASE) || ssh2blob) if ((ssh2key && ssh2key != SSH2_WRONG_PASSPHRASE) || ssh2blob)
error = NULL; error = NULL;
@ -800,7 +799,7 @@ int main(int argc, char **argv)
case SSH_KEYTYPE_OPENSSH: case SSH_KEYTYPE_OPENSSH:
case SSH_KEYTYPE_SSHCOM: case SSH_KEYTYPE_SSHCOM:
ssh2key = import_ssh2(&infilename, intype, passphrase, &error); ssh2key = import_ssh2(infilename, intype, passphrase, &error);
if (ssh2key) { if (ssh2key) {
if (ssh2key != SSH2_WRONG_PASSPHRASE) if (ssh2key != SSH2_WRONG_PASSPHRASE)
error = NULL; error = NULL;
@ -892,14 +891,14 @@ int main(int argc, char **argv)
case PRIVATE: case PRIVATE:
if (sshver == 1) { if (sshver == 1) {
assert(ssh1key); assert(ssh1key);
ret = saversakey(&outfilename, ssh1key, passphrase); ret = saversakey(outfilename, ssh1key, passphrase);
if (!ret) { if (!ret) {
fprintf(stderr, "puttygen: unable to save SSH-1 private key\n"); fprintf(stderr, "puttygen: unable to save SSH-1 private key\n");
return 1; return 1;
} }
} else { } else {
assert(ssh2key); assert(ssh2key);
ret = ssh2_save_userkey(&outfilename, ssh2key, passphrase); ret = ssh2_save_userkey(outfilename, ssh2key, passphrase);
if (!ret) { if (!ret) {
fprintf(stderr, "puttygen: unable to save SSH-2 private key\n"); fprintf(stderr, "puttygen: unable to save SSH-2 private key\n");
return 1; return 1;
@ -1023,7 +1022,7 @@ int main(int argc, char **argv)
case SSHCOM: case SSHCOM:
assert(sshver == 2); assert(sshver == 2);
assert(ssh2key); assert(ssh2key);
ret = export_ssh2(&outfilename, outtype, ssh2key, passphrase); ret = export_ssh2(outfilename, outtype, ssh2key, passphrase);
if (!ret) { if (!ret) {
fprintf(stderr, "puttygen: unable to export key\n"); fprintf(stderr, "puttygen: unable to export key\n");
return 1; return 1;

View File

@ -457,12 +457,13 @@ int cmdline_process_param(char *p, char *value, int need_save, Conf *conf)
} }
if (!strcmp(p, "-i")) { if (!strcmp(p, "-i")) {
Filename fn; Filename *fn;
RETURN(2); RETURN(2);
UNAVAILABLE_IN(TOOLTYPE_NONNETWORK); UNAVAILABLE_IN(TOOLTYPE_NONNETWORK);
SAVEABLE(0); SAVEABLE(0);
fn = filename_from_str(value); 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")) { if (!strcmp(p, "-4") || !strcmp(p, "-ipv4")) {

26
conf.c
View File

@ -43,7 +43,7 @@ struct value {
union { union {
int intval; int intval;
char *stringval; char *stringval;
Filename fileval; Filename *fileval;
FontSpec *fontval; FontSpec *fontval;
} u; } u;
}; };
@ -125,6 +125,8 @@ static void free_value(struct value *val, int type)
{ {
if (type == TYPE_STR) if (type == TYPE_STR)
sfree(val->u.stringval); sfree(val->u.stringval);
else if (type == TYPE_FILENAME)
filename_free(val->u.fileval);
else if (type == TYPE_FONT) else if (type == TYPE_FONT)
fontspec_free(val->u.fontval); 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); to->u.stringval = dupstr(from->u.stringval);
break; break;
case TYPE_FILENAME: case TYPE_FILENAME:
to->u.fileval = from->u.fileval; to->u.fileval = filename_copy(from->u.fileval);
break; break;
case TYPE_FONT: case TYPE_FONT:
to->u.fontval = fontspec_copy(from->u.fontval); to->u.fontval = fontspec_copy(from->u.fontval);
@ -332,7 +334,7 @@ Filename *conf_get_filename(Conf *conf, int primary)
key.primary = primary; key.primary = primary;
entry = find234(conf->tree, &key, NULL); entry = find234(conf->tree, &key, NULL);
assert(entry); assert(entry);
return &entry->value.u.fileval; return entry->value.u.fileval;
} }
FontSpec *conf_get_fontspec(Conf *conf, int primary) 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(subkeytypes[primary] == TYPE_NONE);
assert(valuetypes[primary] == TYPE_FILENAME); assert(valuetypes[primary] == TYPE_FILENAME);
entry->key.primary = primary; entry->key.primary = primary;
entry->value.u.fileval = *value; /* structure copy */ entry->value.u.fileval = filename_copy(value);
conf_insert(conf, entry); conf_insert(conf, entry);
} }
@ -457,7 +459,7 @@ int conf_serialised_size(Conf *conf)
size += 1 + strlen(entry->value.u.stringval); size += 1 + strlen(entry->value.u.stringval);
break; break;
case TYPE_FILENAME: case TYPE_FILENAME:
size += sizeof(entry->value.u.fileval); size += filename_serialise(entry->value.u.fileval, NULL);
break; break;
case TYPE_FONT: case TYPE_FONT:
size += fontspec_serialise(entry->value.u.fontval, NULL); size += fontspec_serialise(entry->value.u.fontval, NULL);
@ -504,9 +506,7 @@ void conf_serialise(Conf *conf, void *vdata)
*data++ = 0; *data++ = 0;
break; break;
case TYPE_FILENAME: case TYPE_FILENAME:
memcpy(data, &entry->value.u.fileval, data += filename_serialise(entry->value.u.fileval, data);
sizeof(entry->value.u.fileval));
data += sizeof(entry->value.u.fileval);
break; break;
case TYPE_FONT: case TYPE_FONT:
data += fontspec_serialise(entry->value.u.fontval, data); data += fontspec_serialise(entry->value.u.fontval, data);
@ -580,16 +580,16 @@ int conf_deserialise(Conf *conf, void *vdata, int maxsize)
data = zero + 1; data = zero + 1;
break; break;
case TYPE_FILENAME: 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) if (subkeytypes[entry->key.primary] == TYPE_STR)
sfree(entry->key.secondary.s); sfree(entry->key.secondary.s);
sfree(entry); sfree(entry);
goto done; goto done;
} }
memcpy(&entry->value.u.fileval, data, data += used;
sizeof(entry->value.u.fileval)); maxsize -= used;
data += sizeof(entry->value.u.fileval);
maxsize -= sizeof(entry->value.u.fileval);
break; break;
case TYPE_FONT: case TYPE_FONT:
entry->value.u.fontval = entry->value.u.fontval =

View File

@ -131,12 +131,11 @@ void conf_filesel_handler(union control *ctrl, void *dlg,
Conf *conf = (Conf *)data; Conf *conf = (Conf *)data;
if (event == EVENT_REFRESH) { 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) { } else if (event == EVENT_VALCHANGE) {
Filename filename; Filename *filename = dlg_filesel_get(ctrl, dlg);
dlg_filesel_get(ctrl, dlg, &filename); conf_set_filename(conf, key, filename);
conf_set_filename(conf, key, &filename); filename_free(filename);
/* If Filenames ever become dynamic, free this one. */
} }
} }

View File

@ -521,21 +521,6 @@ union control *ctrl_checkbox(struct controlset *, char *label, char shortcut,
handler_fn handler, intorptr context); handler_fn handler, intorptr context);
union control *ctrl_tabdelay(struct controlset *, union control *); 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 * Routines the platform-independent dialog code can call to read
* and write the values of controls. * 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); int dlg_listbox_issel(union control *ctrl, void *dlg, int index);
void dlg_listbox_select(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_text_set(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);
void dlg_filesel_get(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); void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec *fn);
FontSpec *dlg_fontsel_get(union control *ctrl, void *dlg); FontSpec *dlg_fontsel_get(union control *ctrl, void *dlg);
/* /*

View File

@ -334,7 +334,7 @@ static struct openssh_key *load_openssh_key(const Filename *filename,
ret->encrypted = 0; ret->encrypted = 0;
memset(ret->iv, 0, sizeof(ret->iv)); memset(ret->iv, 0, sizeof(ret->iv));
fp = f_open(*filename, "r", FALSE); fp = f_open(filename, "r", FALSE);
if (!fp) { if (!fp) {
errmsg = "unable to open key file"; errmsg = "unable to open key file";
goto error; 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 * And save it. We'll use Unix line endings just in case it's
* subsequently transferred in binary mode. * 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) if (!fp)
goto error; goto error;
fputs(header, fp); fputs(header, fp);
@ -1053,7 +1053,7 @@ static struct sshcom_key *load_sshcom_key(const Filename *filename,
ret->keyblob = NULL; ret->keyblob = NULL;
ret->keyblob_len = ret->keyblob_size = 0; ret->keyblob_len = ret->keyblob_size = 0;
fp = f_open(*filename, "r", FALSE); fp = f_open(filename, "r", FALSE);
if (!fp) { if (!fp) {
errmsg = "unable to open key file"; errmsg = "unable to open key file";
goto error; 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 * And save it. We'll use Unix line endings just in case it's
* subsequently transferred in binary mode. * 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) if (!fp)
goto error; goto error;
fputs("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----\n", fp); fputs("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----\n", fp);

View File

@ -16,13 +16,13 @@ struct LogContext {
FILE *lgfp; FILE *lgfp;
enum { L_CLOSED, L_OPENING, L_OPEN, L_ERROR } state; enum { L_CLOSED, L_OPENING, L_OPEN, L_ERROR } state;
bufchain queue; bufchain queue;
Filename currlogfilename; Filename *currlogfilename;
void *frontend; void *frontend;
Conf *conf; Conf *conf;
int logtype; /* cached out of 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 * 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_PACKETS ? "SSH packets" :
ctx->logtype == LGTYP_SSHRAW ? "SSH raw data" : ctx->logtype == LGTYP_SSHRAW ? "SSH raw data" :
"unknown"), "unknown"),
filename_to_str(&ctx->currlogfilename)); filename_to_str(ctx->currlogfilename));
logevent(ctx->frontend, event); logevent(ctx->frontend, event);
sfree(event); sfree(event);
@ -155,9 +155,11 @@ void logfopen(void *handle)
tm = ltime(); tm = ltime();
/* substitute special codes in file name */ /* substitute special codes in file name */
xlatlognam(&ctx->currlogfilename, if (ctx->currlogfilename)
*conf_get_filename(ctx->conf, CONF_logfilename), filename_free(ctx->currlogfilename);
conf_get_str(ctx->conf, CONF_host), &tm); 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? */ ctx->lgfp = f_open(ctx->currlogfilename, "r", FALSE); /* file already present? */
if (ctx->lgfp) { if (ctx->lgfp) {
@ -338,6 +340,7 @@ void *log_init(void *frontend, Conf *conf)
ctx->frontend = frontend; ctx->frontend = frontend;
ctx->conf = conf_copy(conf); ctx->conf = conf_copy(conf);
ctx->logtype = conf_get_int(ctx->conf, CONF_logtype); ctx->logtype = conf_get_int(ctx->conf, CONF_logtype);
ctx->currlogfilename = NULL;
bufchain_init(&ctx->queue); bufchain_init(&ctx->queue);
return ctx; return ctx;
} }
@ -348,6 +351,8 @@ void log_free(void *handle)
logfclose(ctx); logfclose(ctx);
bufchain_clear(&ctx->queue); bufchain_clear(&ctx->queue);
if (ctx->currlogfilename)
filename_free(ctx->currlogfilename);
sfree(ctx); sfree(ctx);
} }
@ -356,8 +361,8 @@ void log_reconfig(void *handle, Conf *conf)
struct LogContext *ctx = (struct LogContext *)handle; struct LogContext *ctx = (struct LogContext *)handle;
int reset_logging; int reset_logging;
if (!filename_equal(*conf_get_filename(ctx->conf, CONF_logfilename), if (!filename_equal(conf_get_filename(ctx->conf, CONF_logfilename),
*conf_get_filename(conf, CONF_logfilename)) || conf_get_filename(conf, CONF_logfilename)) ||
conf_get_int(ctx->conf, CONF_logtype) != conf_get_int(ctx->conf, CONF_logtype) !=
conf_get_int(conf, CONF_logtype)) conf_get_int(conf, CONF_logtype))
reset_logging = TRUE; reset_logging = TRUE;
@ -382,17 +387,19 @@ void log_reconfig(void *handle, Conf *conf)
* *
* "&Y":YYYY "&m":MM "&d":DD "&T":hhmmss "&h":<hostname> "&&":& * "&Y":YYYY "&m":MM "&d":DD "&T":hhmmss "&h":<hostname> "&&":&
*/ */
static void xlatlognam(Filename *dest, Filename src, static Filename *xlatlognam(Filename *src, char *hostname, struct tm *tm)
char *hostname, struct tm *tm) { {
char buf[10], *bufp; char buf[10], *bufp;
int size; int size;
char buffer[FILENAME_MAX]; char *buffer;
int len = sizeof(buffer)-1; int buflen, bufsize;
char *d;
const char *s; const char *s;
Filename *ret;
d = buffer; bufsize = FILENAME_MAX;
s = filename_to_str(&src); buffer = snewn(bufsize, char);
buflen = 0;
s = filename_to_str(src);
while (*s) { while (*s) {
/* Let (bufp, len) be the string to append. */ /* Let (bufp, len) be the string to append. */
@ -428,13 +435,16 @@ static void xlatlognam(Filename *dest, Filename src,
buf[0] = *s++; buf[0] = *s++;
size = 1; size = 1;
} }
if (size > len) if (bufsize <= buflen + size) {
size = len; bufsize = (buflen + size) * 5 / 4 + 512;
memcpy(d, bufp, size); buffer = sresize(buffer, bufsize, char);
d += size; }
len -= size; 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;
} }

22
putty.h
View File

@ -932,12 +932,13 @@ void registry_cleanup(void);
* Filename and FontSpec functions are _not allowed_ to fail to * Filename and FontSpec functions are _not allowed_ to fail to
* return, since these defaults _must_ be per-platform.) * return, since these defaults _must_ be per-platform.)
* *
* The 'FontSpec *' returned by platform_default_fontspec has * The 'Filename *' returned by platform_default_filename, and the
* ownership transferred to the caller, and must be freed. * 'FontSpec *' returned by platform_default_fontspec, have ownership
* transferred to the caller, and must be freed.
*/ */
char *platform_default_s(const char *name); char *platform_default_s(const char *name);
int platform_default_i(const char *name, int def); 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); 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 * - 0 means cancel logging for this session
* - -1 means please wait. * - -1 means please wait.
*/ */
int askappend(void *frontend, Filename filename, int askappend(void *frontend, Filename *filename,
void (*callback)(void *ctx, int result), void *ctx); 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. * 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); const char *filename_to_str(const Filename *fn);
int filename_equal(Filename f1, Filename f2); int filename_equal(const Filename *f1, const Filename *f2);
int filename_is_null(Filename fn); 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_username(void); /* return value needs freeing */
char *get_random_data(int bytes); /* used in cmdgen.c */ char *get_random_data(int bytes); /* used in cmdgen.c */

View 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 * 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. * platform-dependent functions MUST return some sort of value.
*/ */
static void gppfont(void *handle, const char *name, Conf *conf, int primary) 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) static void gppfile(void *handle, const char *name, Conf *conf, int primary)
{ {
Filename result; Filename *result = read_setting_filename(handle, name);
if (!read_setting_filename(handle, name, &result)) if (!result)
result = platform_default_filename(name); 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) 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_i(sesskey, "Present", 1);
write_setting_s(sesskey, "HostName", conf_get_str(conf, CONF_host)); 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, "LogType", conf_get_int(conf, CONF_logtype));
write_setting_i(sesskey, "LogFileClash", conf_get_int(conf, CONF_logxfovr)); 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, "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)); write_setting_i(sesskey, "AuthGSSAPI", conf_get_int(conf, CONF_try_gssapi_auth));
#ifndef NO_GSSAPI #ifndef NO_GSSAPI
wprefs(sesskey, "GSSLibs", gsslibkeywords, ngsslibs, conf, CONF_ssh_gsslist); 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 #endif
write_setting_i(sesskey, "SshNoShell", conf_get_int(conf, CONF_ssh_no_shell)); 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_i(sesskey, "SshProt", conf_get_int(conf, CONF_sshprot));
write_setting_s(sesskey, "LogHost", conf_get_str(conf, CONF_loghost)); 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_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_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, "RFCEnviron", conf_get_int(conf, CONF_rfc_environ));
write_setting_i(sesskey, "PassiveTelnet", conf_get_int(conf, CONF_passive_telnet)); 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, "BlinkCur", conf_get_int(conf, CONF_blink_cur));
write_setting_i(sesskey, "Beep", conf_get_int(conf, CONF_beep)); 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_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, "BellOverload", conf_get_int(conf, CONF_bellovl));
write_setting_i(sesskey, "BellOverloadN", conf_get_int(conf, CONF_bellovl_n)); 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, "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_i(sesskey, "X11Forward", conf_get_int(conf, CONF_x11_forward));
write_setting_s(sesskey, "X11Display", conf_get_str(conf, CONF_x11_display)); 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_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, "LocalPortAcceptAll", conf_get_int(conf, CONF_lport_acceptall));
write_setting_i(sesskey, "RemotePortAcceptAll", conf_get_int(conf, CONF_rport_acceptall)); write_setting_i(sesskey, "RemotePortAcceptAll", conf_get_int(conf, CONF_rport_acceptall));
wmap(sesskey, "PortForwardings", conf, CONF_portfwd); wmap(sesskey, "PortForwardings", conf, CONF_portfwd);

4
ssh.c
View File

@ -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. * Load the public half of any configured keyfile for later use.
*/ */
s->keyfile = conf_get_filename(ssh->conf, CONF_keyfile); s->keyfile = conf_get_filename(ssh->conf, CONF_keyfile);
if (!filename_is_null(*s->keyfile)) { if (!filename_is_null(s->keyfile)) {
int keytype; int keytype;
logeventf(ssh, "Reading private key file \"%.150s\"", logeventf(ssh, "Reading private key file \"%.150s\"",
filename_to_str(s->keyfile)); filename_to_str(s->keyfile));
@ -7529,7 +7529,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
* for later use. * for later use.
*/ */
s->keyfile = conf_get_filename(ssh->conf, CONF_keyfile); s->keyfile = conf_get_filename(ssh->conf, CONF_keyfile);
if (!filename_is_null(*s->keyfile)) { if (!filename_is_null(s->keyfile)) {
int keytype; int keytype;
logeventf(ssh, "Reading private key file \"%.150s\"", logeventf(ssh, "Reading private key file \"%.150s\"",
filename_to_str(s->keyfile)); filename_to_str(s->keyfile));

View File

@ -162,7 +162,7 @@ int loadrsakey(const Filename *filename, struct RSAKey *key, char *passphrase,
int ret = 0; int ret = 0;
const char *error = NULL; const char *error = NULL;
fp = f_open(*filename, "rb", FALSE); fp = f_open(filename, "rb", FALSE);
if (!fp) { if (!fp) {
error = "can't open file"; error = "can't open file";
goto end; goto end;
@ -203,7 +203,7 @@ int rsakey_encrypted(const Filename *filename, char **comment)
FILE *fp; FILE *fp;
char buf[64]; char buf[64];
fp = f_open(*filename, "rb", FALSE); fp = f_open(filename, "rb", FALSE);
if (!fp) if (!fp)
return 0; /* doesn't even exist */ return 0; /* doesn't even exist */
@ -241,7 +241,7 @@ int rsakey_pubblob(const Filename *filename, void **blob, int *bloblen,
*bloblen = 0; *bloblen = 0;
ret = 0; ret = 0;
fp = f_open(*filename, "rb", FALSE); fp = f_open(filename, "rb", FALSE);
if (!fp) { if (!fp) {
error = "can't open file"; error = "can't open file";
goto end; goto end;
@ -364,7 +364,7 @@ int saversakey(const Filename *filename, struct RSAKey *key, char *passphrase)
/* /*
* Done. Write the result to the file. * Done. Write the result to the file.
*/ */
fp = f_open(*filename, "wb", TRUE); fp = f_open(filename, "wb", TRUE);
if (fp) { if (fp) {
int ret = (fwrite(buf, 1, p - buf, fp) == (size_t) (p - buf)); int ret = (fwrite(buf, 1, p - buf, fp) == (size_t) (p - buf));
if (fclose(fp)) if (fclose(fp))
@ -632,7 +632,7 @@ struct ssh2_userkey *ssh2_load_userkey(const Filename *filename,
encryption = comment = mac = NULL; encryption = comment = mac = NULL;
public_blob = private_blob = NULL; public_blob = private_blob = NULL;
fp = f_open(*filename, "rb", FALSE); fp = f_open(filename, "rb", FALSE);
if (!fp) { if (!fp) {
error = "can't open file"; error = "can't open file";
goto error; goto error;
@ -881,7 +881,7 @@ unsigned char *ssh2_userkey_loadpub(const Filename *filename, char **algorithm,
public_blob = NULL; public_blob = NULL;
fp = f_open(*filename, "rb", FALSE); fp = f_open(filename, "rb", FALSE);
if (!fp) { if (!fp) {
error = "can't open file"; error = "can't open file";
goto error; goto error;
@ -962,7 +962,7 @@ int ssh2_userkey_encrypted(const Filename *filename, char **commentptr)
if (commentptr) if (commentptr)
*commentptr = NULL; *commentptr = NULL;
fp = f_open(*filename, "rb", FALSE); fp = f_open(filename, "rb", FALSE);
if (!fp) if (!fp)
return 0; return 0;
if (!read_header(fp, header) 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)); memset(&s, 0, sizeof(s));
} }
fp = f_open(*filename, "w", TRUE); fp = f_open(filename, "w", TRUE);
if (!fp) if (!fp)
return 0; return 0;
fprintf(fp, "PuTTY-User-Key-File-2: %s\n", key->alg->name); 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 "; const char openssh_sig[] = "-----BEGIN ";
int i; int i;
fp = f_open(*filename, "r", FALSE); fp = f_open(filename, "r", FALSE);
if (!fp) if (!fp)
return SSH_KEYTYPE_UNOPENABLE; return SSH_KEYTYPE_UNOPENABLE;
i = fread(buf, 1, sizeof(buf), fp); i = fread(buf, 1, sizeof(buf), fp);

View File

@ -31,7 +31,7 @@
void *open_settings_w(const char *sessionname, char **errmsg); void *open_settings_w(const char *sessionname, char **errmsg);
void write_setting_s(void *handle, const char *key, const char *value); 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_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 write_setting_fontspec(void *handle, const char *key, FontSpec *font);
void close_settings_w(void *handle); void close_settings_w(void *handle);
@ -42,20 +42,19 @@ void close_settings_w(void *handle);
* then close it using close_settings_r(). * then close it using close_settings_r().
* *
* read_setting_s() returns a dynamically allocated string which the * 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, * If a particular string setting is not present in the session,
* read_setting_s() can return NULL, in which case the caller * read_setting_s() can return NULL, in which case the caller
* should invent a sensible default. If an integer setting is not * should invent a sensible default. If an integer setting is not
* present, read_setting_i() returns its provided default. * 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); void *open_settings_r(const char *sessionname);
char *read_setting_s(void *handle, const char *key); char *read_setting_s(void *handle, const char *key);
int read_setting_i(void *handle, const char *key, int defvalue); 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); FontSpec *read_setting_fontspec(void *handle, const char *key);
void close_settings_r(void *handle); void close_settings_r(void *handle);

View 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 dlgparam *dp = (struct dlgparam *)dlg;
struct uctrl *uc = dlg_find_byctrl(dp, ctrl); struct uctrl *uc = dlg_find_byctrl(dp, ctrl);
assert(uc->ctrl->generic.type == CTRL_FILESELECT); assert(uc->ctrl->generic.type == CTRL_FILESELECT);
assert(uc->entry != NULL); 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 dlgparam *dp = (struct dlgparam *)dlg;
struct uctrl *uc = dlg_find_byctrl(dp, ctrl); struct uctrl *uc = dlg_find_byctrl(dp, ctrl);
assert(uc->ctrl->generic.type == CTRL_FILESELECT); assert(uc->ctrl->generic.type == CTRL_FILESELECT);
assert(uc->entry != NULL); assert(uc->entry != NULL);
strncpy(fn->path, gtk_entry_get_text(GTK_ENTRY(uc->entry)), return filename_from_str(gtk_entry_get_text(GTK_ENTRY(uc->entry)));
lenof(fn->path));
fn->path[lenof(fn->path)-1] = '\0';
} }
void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec *fs) 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++; es->nevents++;
} }
int askappend(void *frontend, Filename filename, int askappend(void *frontend, Filename *filename,
void (*callback)(void *ctx, int result), void *ctx) void (*callback)(void *ctx, int result), void *ctx)
{ {
static const char msgtemplate[] = static const char msgtemplate[] =
@ -3753,7 +3751,7 @@ int askappend(void *frontend, Filename filename,
char *mbtitle; char *mbtitle;
int mbret; int mbret;
message = dupprintf(msgtemplate, FILENAME_MAX, filename.path); message = dupprintf(msgtemplate, FILENAME_MAX, filename->path);
mbtitle = dupprintf("%s Log to File", appname); mbtitle = dupprintf("%s Log to File", appname);
mbret = messagebox(get_window(frontend), mbtitle, message, mbret = messagebox(get_window(frontend), mbtitle, message,

View File

@ -159,14 +159,12 @@ FontSpec *platform_default_fontspec(const char *name)
return fontspec_new(""); return fontspec_new("");
} }
Filename platform_default_filename(const char *name) Filename *platform_default_filename(const char *name)
{ {
Filename ret;
if (!strcmp(name, "LogFileName")) if (!strcmp(name, "LogFileName"))
strcpy(ret.path, "putty.log"); return filename_from_str("putty.log");
else else
*ret.path = '\0'; return filename_from_str("");
return ret;
} }
char *platform_default_s(const char *name) 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); conf_set_str(conf, CONF_wintitle, val);
} else if (!strcmp(p, "-log")) { } else if (!strcmp(p, "-log")) {
Filename fn; Filename *fn;
EXPECTS_ARG; EXPECTS_ARG;
SECOND_PASS_ONLY; SECOND_PASS_ONLY;
strncpy(fn.path, val, sizeof(fn.path)); fn = filename_from_str(val);
fn.path[sizeof(fn.path)-1] = '\0'; conf_set_filename(conf, CONF_logfilename, fn);
conf_set_filename(conf, CONF_logfilename, &fn);
conf_set_int(conf, CONF_logtype, LGTYP_DEBUG); conf_set_int(conf, CONF_logtype, LGTYP_DEBUG);
filename_free(fn);
} else if (!strcmp(p, "-ut-") || !strcmp(p, "+ut")) { } else if (!strcmp(p, "-ut-") || !strcmp(p, "+ut")) {
SECOND_PASS_ONLY; SECOND_PASS_ONLY;

View File

@ -13,9 +13,9 @@
#include "charset.h" #include "charset.h"
struct Filename { 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 { struct FontSpec {
char *name; /* may be "" to indicate no selected font at all */ char *name; /* may be "" to indicate no selected font at all */

View 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. * 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). * 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) void (*callback)(void *ctx, int result), void *ctx)
{ {
static const char msgtemplate[] = static const char msgtemplate[] =
@ -256,11 +256,11 @@ int askappend(void *frontend, Filename filename,
premsg(&cf); premsg(&cf);
if (console_batch_mode) { if (console_batch_mode) {
fprintf(stderr, msgtemplate_batch, FILENAME_MAX, filename.path); fprintf(stderr, msgtemplate_batch, FILENAME_MAX, filename->path);
fflush(stderr); fflush(stderr);
return 0; return 0;
} }
fprintf(stderr, msgtemplate, FILENAME_MAX, filename.path); fprintf(stderr, msgtemplate, FILENAME_MAX, filename->path);
fflush(stderr); fflush(stderr);
{ {

View File

@ -27,27 +27,58 @@ unsigned long getticks(void)
return tv.tv_sec * 1000 + tv.tv_usec / 1000 + tickcount_offset; 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; Filename *ret = snew(Filename);
strncpy(ret.path, str, sizeof(ret.path)); ret->path = dupstr(str);
ret.path[sizeof(ret.path)-1] = '\0';
return ret; return ret;
} }
Filename *filename_copy(const Filename *fn)
{
return filename_from_str(fn->path);
}
const char *filename_to_str(const Filename *fn) const char *filename_to_str(const Filename *fn)
{ {
return fn->path; 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); return !strcmp(f1->path, f2->path);
} }
int filename_is_null(Filename fn) int filename_is_null(const Filename *fn)
{ {
return !*fn.path; return !fn->path[0];
}
void filename_free(Filename *fn)
{
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);
} }
#ifdef DEBUG #ifdef DEBUG
@ -135,16 +166,15 @@ int cloexec(int fd) {
return fcntl(fd, F_SETFD, fdflags | FD_CLOEXEC); 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) { if (!is_private) {
return fopen(filename.path, mode); return fopen(filename->path, mode);
} else { } else {
int fd; int fd;
assert(mode[0] == 'w'); /* is_private is meaningless for read, assert(mode[0] == 'w'); /* is_private is meaningless for read,
and tricky for append */ and tricky for append */
fd = open(filename.path, O_WRONLY | O_CREAT | O_TRUNC, fd = open(filename->path, O_WRONLY | O_CREAT | O_TRUNC, 0700);
0700);
if (fd < 0) if (fd < 0)
return NULL; return NULL;
return fdopen(fd, mode); return fdopen(fd, mode);

View File

@ -130,14 +130,12 @@ FontSpec *platform_default_fontspec(const char *name)
return fontspec_new(""); return fontspec_new("");
} }
Filename platform_default_filename(const char *name) Filename *platform_default_filename(const char *name)
{ {
Filename ret;
if (!strcmp(name, "LogFileName")) if (!strcmp(name, "LogFileName"))
strcpy(ret.path, "putty.log"); return filename_from_str("putty.log");
else else
*ret.path = '\0'; return filename_from_str("");
return ret;
} }
char *x_get_default(const char *key) char *x_get_default(const char *key)

View File

@ -58,14 +58,12 @@ FontSpec *platform_default_fontspec(const char *name)
return fontspec_new(""); return fontspec_new("");
} }
Filename platform_default_filename(const char *name) Filename *platform_default_filename(const char *name)
{ {
Filename ret;
if (!strcmp(name, "LogFileName")) if (!strcmp(name, "LogFileName"))
strcpy(ret.path, "putty.log"); return filename_from_str("putty.log");
else else
*ret.path = '\0'; return filename_from_str("");
return ret;
} }
char *get_ttymode(void *frontend, const char *mode) { return NULL; } char *get_ttymode(void *frontend, const char *mode) { return NULL; }

View File

@ -395,16 +395,15 @@ FontSpec *read_setting_fontspec(void *handle, const char *name)
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); char *tmp = read_setting_s(handle, name);
if (tmp) { if (tmp) {
strncpy(result->path, tmp, sizeof(result->path)-1); Filename *ret = filename_from_str(tmp);
result->path[sizeof(result->path)-1] = '\0';
sfree(tmp); sfree(tmp);
return TRUE; return ret;
} else } else
return FALSE; return NULL;
} }
void write_setting_fontspec(void *handle, const char *name, FontSpec *fs) 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); write_setting_s(handle, suffname, fs->name);
sfree(suffname); 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) void close_settings_r(void *handle)

View 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. * 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). * 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) void (*callback)(void *ctx, int result), void *ctx)
{ {
HANDLE hin; HANDLE hin;
@ -223,11 +223,11 @@ int askappend(void *frontend, Filename filename,
char line[32]; char line[32];
if (console_batch_mode) { if (console_batch_mode) {
fprintf(stderr, msgtemplate_batch, FILENAME_MAX, filename.path); fprintf(stderr, msgtemplate_batch, FILENAME_MAX, filename->path);
fflush(stderr); fflush(stderr);
return 0; return 0;
} }
fprintf(stderr, msgtemplate, FILENAME_MAX, filename.path); fprintf(stderr, msgtemplate, FILENAME_MAX, filename->path);
fflush(stderr); fflush(stderr);
hin = GetStdHandle(STD_INPUT_HANDLE); hin = GetStdHandle(STD_INPUT_HANDLE);

View File

@ -2098,23 +2098,26 @@ void dlg_editbox_set(union control *ctrl, void *dlg, char const *text)
SetDlgItemText(dp->hwnd, c->base_id+1, text); SetDlgItemText(dp->hwnd, c->base_id+1, text);
} }
static char *getdlgitemtext_alloc(HWND hwnd, int id)
{
char *ret = NULL;
int size = 0;
do {
size = size * 4 / 3 + 512;
ret = sresize(ret, size, char);
GetDlgItemText(hwnd, id, ret, size);
} while (!memchr(ret, '\0', size-1));
return ret;
}
char *dlg_editbox_get(union control *ctrl, void *dlg) char *dlg_editbox_get(union control *ctrl, void *dlg)
{ {
struct dlgparam *dp = (struct dlgparam *)dlg; struct dlgparam *dp = (struct dlgparam *)dlg;
struct winctrl *c = dlg_findbyctrl(dp, ctrl); struct winctrl *c = dlg_findbyctrl(dp, ctrl);
char *ret;
int size;
assert(c && c->ctrl->generic.type == CTRL_EDITBOX); assert(c && c->ctrl->generic.type == CTRL_EDITBOX);
return getdlgitemtext_alloc(dp->hwnd, c->base_id+1);
size = 0;
ret = NULL;
do {
size = size * 4 / 3 + 512;
ret = sresize(ret, size, char);
GetDlgItemText(dp->hwnd, c->base_id+1, ret, size);
} while (!memchr(ret, '\0', size-1));
return ret;
} }
/* The `listbox' functions can also apply to combo boxes. */ /* The `listbox' functions can also apply to combo boxes. */
@ -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 dlgparam *dp = (struct dlgparam *)dlg;
struct winctrl *c = dlg_findbyctrl(dp, ctrl); struct winctrl *c = dlg_findbyctrl(dp, ctrl);
assert(c && c->ctrl->generic.type == CTRL_FILESELECT); 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 dlgparam *dp = (struct dlgparam *)dlg;
struct winctrl *c = dlg_findbyctrl(dp, ctrl); struct winctrl *c = dlg_findbyctrl(dp, ctrl);
char *tmp;
Filename *ret;
assert(c && c->ctrl->generic.type == CTRL_FILESELECT); assert(c && c->ctrl->generic.type == CTRL_FILESELECT);
GetDlgItemText(dp->hwnd, c->base_id+1, fn->path, lenof(fn->path)); tmp = getdlgitemtext_alloc(dp->hwnd, c->base_id+1);
fn->path[lenof(fn->path)-1] = '\0'; ret = filename_from_str(tmp);
sfree(tmp);
return ret;
} }
void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec *fs) void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec *fs)

View File

@ -14,14 +14,12 @@ FontSpec *platform_default_fontspec(const char *name)
return fontspec_new("", 0, 0, 0); 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")) if (!strcmp(name, "LogFileName"))
strcpy(ret.path, "putty.log"); return filename_from_str("putty.log");
else else
*ret.path = '\0'; return filename_from_str("");
return ret;
} }
char *platform_default_s(const char *name) char *platform_default_s(const char *name)

View 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. * 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). * 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) void (*callback)(void *ctx, int result), void *ctx)
{ {
static const char msgtemplate[] = static const char msgtemplate[] =
@ -872,7 +872,7 @@ int askappend(void *frontend, Filename filename,
char *mbtitle; char *mbtitle;
int mbret; int mbret;
message = dupprintf(msgtemplate, FILENAME_MAX, filename.path); message = dupprintf(msgtemplate, FILENAME_MAX, filename->path);
mbtitle = dupprintf("%s Log to File", appname); mbtitle = dupprintf("%s Log to File", appname);
mbret = MessageBox(NULL, message, mbtitle, mbret = MessageBox(NULL, message, mbtitle,

View File

@ -14,27 +14,58 @@ char *platform_get_x_display(void) {
return dupstr(getenv("DISPLAY")); return dupstr(getenv("DISPLAY"));
} }
Filename filename_from_str(const char *str) Filename *filename_from_str(const char *str)
{ {
Filename ret; Filename *ret = snew(Filename);
strncpy(ret.path, str, sizeof(ret.path)); ret->path = dupstr(str);
ret.path[sizeof(ret.path)-1] = '\0';
return ret; return ret;
} }
Filename *filename_copy(const Filename *fn)
{
return filename_from_str(fn->path);
}
const char *filename_to_str(const Filename *fn) const char *filename_to_str(const Filename *fn)
{ {
return fn->path; 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); return !strcmp(f1->path, f2->path);
} }
int filename_is_null(Filename fn) int filename_is_null(const Filename *fn)
{ {
return !*fn.path; return !*fn->path;
}
void filename_free(Filename *fn)
{
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) char *get_username(void)

View 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, 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]; char passphrase[PASSPHRASE_MAXLEN];
int needs_pass; int needs_pass;
@ -627,7 +627,7 @@ void load_key_file(HWND hwnd, struct MainDlgState *state,
struct RSAKey newkey1; struct RSAKey newkey1;
struct ssh2_userkey *newkey2 = NULL; struct ssh2_userkey *newkey2 = NULL;
type = realtype = key_type(&filename); type = realtype = key_type(filename);
if (type != SSH_KEYTYPE_SSH1 && if (type != SSH_KEYTYPE_SSH1 &&
type != SSH_KEYTYPE_SSH2 && type != SSH_KEYTYPE_SSH2 &&
!import_possible(type)) { !import_possible(type)) {
@ -647,13 +647,11 @@ void load_key_file(HWND hwnd, struct MainDlgState *state,
comment = NULL; comment = NULL;
if (realtype == SSH_KEYTYPE_SSH1) if (realtype == SSH_KEYTYPE_SSH1)
needs_pass = rsakey_encrypted(&filename, &comment); needs_pass = rsakey_encrypted(filename, &comment);
else if (realtype == SSH_KEYTYPE_SSH2) else if (realtype == SSH_KEYTYPE_SSH2)
needs_pass = needs_pass = ssh2_userkey_encrypted(filename, &comment);
ssh2_userkey_encrypted(&filename, &comment);
else else
needs_pass = import_encrypted(&filename, realtype, needs_pass = import_encrypted(filename, realtype, &comment);
&comment);
pps.passphrase = passphrase; pps.passphrase = passphrase;
pps.comment = comment; pps.comment = comment;
do { do {
@ -671,18 +669,15 @@ void load_key_file(HWND hwnd, struct MainDlgState *state,
*passphrase = '\0'; *passphrase = '\0';
if (type == SSH_KEYTYPE_SSH1) { if (type == SSH_KEYTYPE_SSH1) {
if (realtype == type) if (realtype == type)
ret = loadrsakey(&filename, &newkey1, ret = loadrsakey(filename, &newkey1, passphrase, &errmsg);
passphrase, &errmsg);
else else
ret = import_ssh1(&filename, realtype, ret = import_ssh1(filename, realtype, &newkey1,
&newkey1, passphrase, &errmsg); passphrase, &errmsg);
} else { } else {
if (realtype == type) if (realtype == type)
newkey2 = ssh2_load_userkey(&filename, newkey2 = ssh2_load_userkey(filename, passphrase, &errmsg);
passphrase, &errmsg);
else else
newkey2 = import_ssh2(&filename, realtype, newkey2 = import_ssh2(filename, realtype, passphrase, &errmsg);
passphrase, &errmsg);
if (newkey2 == SSH2_WRONG_PASSPHRASE) if (newkey2 == SSH2_WRONG_PASSPHRASE)
ret = -1; ret = -1;
else if (!newkey2) else if (!newkey2)
@ -1166,22 +1161,24 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
} }
if (state->ssh2) { if (state->ssh2) {
Filename fn = filename_from_str(filename); Filename *fn = filename_from_str(filename);
if (type != realtype) if (type != realtype)
ret = export_ssh2(&fn, type, &state->ssh2key, ret = export_ssh2(fn, type, &state->ssh2key,
*passphrase ? passphrase : NULL); *passphrase ? passphrase : NULL);
else else
ret = ssh2_save_userkey(&fn, &state->ssh2key, ret = ssh2_save_userkey(fn, &state->ssh2key,
*passphrase ? passphrase : *passphrase ? passphrase :
NULL); NULL);
filename_free(fn);
} else { } else {
Filename fn = filename_from_str(filename); Filename *fn = filename_from_str(filename);
if (type != realtype) if (type != realtype)
ret = export_ssh1(&fn, type, &state->key, ret = export_ssh1(fn, type, &state->key,
*passphrase ? passphrase : NULL); *passphrase ? passphrase : NULL);
else else
ret = saversakey(&fn, &state->key, ret = saversakey(fn, &state->key,
*passphrase ? passphrase : NULL); *passphrase ? passphrase : NULL);
filename_free(fn);
} }
if (ret <= 0) { if (ret <= 0) {
MessageBox(hwnd, "Unable to save key file", MessageBox(hwnd, "Unable to save key file",

View File

@ -385,7 +385,7 @@ static void keylist_update(void)
/* /*
* This function loads a key from a file and adds it. * 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]; char passphrase[PASSPHRASE_MAXLEN];
struct RSAKey *rkey = NULL; struct RSAKey *rkey = NULL;
@ -399,7 +399,7 @@ static void add_keyfile(Filename filename)
int type; int type;
int original_pass; int original_pass;
type = key_type(&filename); type = key_type(filename);
if (type != SSH_KEYTYPE_SSH1 && type != SSH_KEYTYPE_SSH2) { if (type != SSH_KEYTYPE_SSH1 && type != SSH_KEYTYPE_SSH2) {
char *msg = dupprintf("Couldn't load this key (%s)", char *msg = dupprintf("Couldn't load this key (%s)",
key_type_to_str(type)); key_type_to_str(type));
@ -419,7 +419,7 @@ static void add_keyfile(Filename filename)
int i, nkeys, bloblen, keylistlen; int i, nkeys, bloblen, keylistlen;
if (type == SSH_KEYTYPE_SSH1) { 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); char *msg = dupprintf("Couldn't load private key (%s)", error);
message_box(msg, APPNAME, MB_OK | MB_ICONERROR, message_box(msg, APPNAME, MB_OK | MB_ICONERROR,
HELPCTXID(errors_cantloadkey)); HELPCTXID(errors_cantloadkey));
@ -429,7 +429,7 @@ static void add_keyfile(Filename filename)
keylist = get_keylist1(&keylistlen); keylist = get_keylist1(&keylistlen);
} else { } else {
unsigned char *blob2; unsigned char *blob2;
blob = ssh2_userkey_loadpub(&filename, NULL, &bloblen, blob = ssh2_userkey_loadpub(filename, NULL, &bloblen,
NULL, &error); NULL, &error);
if (!blob) { if (!blob) {
char *msg = dupprintf("Couldn't load private key (%s)", error); char *msg = dupprintf("Couldn't load private key (%s)", error);
@ -517,9 +517,9 @@ static void add_keyfile(Filename filename)
error = NULL; error = NULL;
if (type == SSH_KEYTYPE_SSH1) if (type == SSH_KEYTYPE_SSH1)
needs_pass = rsakey_encrypted(&filename, &comment); needs_pass = rsakey_encrypted(filename, &comment);
else else
needs_pass = ssh2_userkey_encrypted(&filename, &comment); needs_pass = ssh2_userkey_encrypted(filename, &comment);
attempts = 0; attempts = 0;
if (type == SSH_KEYTYPE_SSH1) if (type == SSH_KEYTYPE_SSH1)
rkey = snew(struct RSAKey); rkey = snew(struct RSAKey);
@ -549,9 +549,9 @@ static void add_keyfile(Filename filename)
} else } else
*passphrase = '\0'; *passphrase = '\0';
if (type == SSH_KEYTYPE_SSH1) if (type == SSH_KEYTYPE_SSH1)
ret = loadrsakey(&filename, rkey, passphrase, &error); ret = loadrsakey(filename, rkey, passphrase, &error);
else { else {
skey = ssh2_load_userkey(&filename, passphrase, &error); skey = ssh2_load_userkey(filename, passphrase, &error);
if (skey == SSH2_WRONG_PASSPHRASE) if (skey == SSH2_WRONG_PASSPHRASE)
ret = -1; ret = -1;
else if (!skey) else if (!skey)

View File

@ -230,21 +230,20 @@ void write_setting_fontspec(void *handle, const char *name, FontSpec *font)
sfree(settingname); 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); char *tmp = read_setting_s(handle, name);
if (tmp) { if (tmp) {
strncpy(result->path, tmp, sizeof(result->path)-1); Filename *ret = filename_from_str(tmp);
result->path[sizeof(result->path)-1] = '\0';
sfree(tmp); sfree(tmp);
return TRUE; return ret;
} else } 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) void close_settings_r(void *handle)

View File

@ -16,9 +16,9 @@
#include "winhelp.h" #include "winhelp.h"
struct Filename { 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 { struct FontSpec {
char *name; char *name;