1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-06-30 19:12:48 -05:00

Rework mungestr() and unmungestr().

For a start, they now have different names on Windows and Unix,
reflecting their different roles: on Windows they apply escaping to
any string that's going to be used as a registry key (be it a session
name, or a host name for host key storage), whereas on Unix they're
for constructing saved-session file names in particular (and also
handle the special case of filling in "Default Settings" for NULL).

Also, they now produce output by writing to a strbuf, which simplifies
a lot of the call sites. In particular, the strbuf output idiom is
passed on to enum_settings_next, which is especially nice because its
only actual caller was doing an ad-hoc realloc loop that I can now get
rid of completely.

Thirdly, on Windows they're centralised into winmisc.c instead of
living in winstore.c, because that way Pageant can use the unescape
function too. (It was spotting the duplication there that made me
think of doing this in the first place, but once I'd started, I had to
keep unravelling the thread...)
This commit is contained in:
Simon Tatham
2018-11-03 08:58:41 +00:00
parent 9248f5c994
commit c089827ea0
7 changed files with 123 additions and 173 deletions

View File

@ -33,15 +33,11 @@ enum {
static const char hex[16] = "0123456789ABCDEF";
static char *mungestr(const char *in)
static void make_session_filename(const char *in, strbuf *out)
{
char *out, *ret;
if (!in || !*in)
in = "Default Settings";
ret = out = snewn(3*strlen(in)+1, char);
while (*in) {
/*
* There are remarkably few punctuation characters that
@ -54,21 +50,17 @@ static char *mungestr(const char *in)
!(*in >= '0' && *in <= '9') &&
!(*in >= 'A' && *in <= 'Z') &&
!(*in >= 'a' && *in <= 'z')) {
*out++ = '%';
*out++ = hex[((unsigned char) *in) >> 4];
*out++ = hex[((unsigned char) *in) & 15];
put_byte(out, '%');
put_byte(out, hex[((unsigned char) *in) >> 4]);
put_byte(out, hex[((unsigned char) *in) & 15]);
} else
*out++ = *in;
put_byte(out, *in);
in++;
}
*out = '\0';
return ret;
}
static char *unmungestr(const char *in)
static void decode_session_filename(const char *in, strbuf *out)
{
char *out, *ret;
out = ret = snewn(strlen(in)+1, char);
while (*in) {
if (*in == '%' && in[1] && in[2]) {
int i, j;
@ -78,14 +70,12 @@ static char *unmungestr(const char *in)
j = in[2] - '0';
j -= (j > 9 ? 7 : 0);
*out++ = (i << 4) + j;
put_byte(out, (i << 4) + j);
in += 3;
} else {
*out++ = *in++;
put_byte(out, *in++);
}
}
*out = '\0';
return ret;
}
static char *make_filename(int index, const char *subname)
@ -181,12 +171,12 @@ static char *make_filename(int index, const char *subname)
return ret;
}
if (index == INDEX_SESSION) {
char *munged = mungestr(subname);
strbuf *sb = strbuf_new();
tmp = make_filename(INDEX_SESSIONDIR, NULL);
ret = dupprintf("%s/%s", tmp, munged);
strbuf_catf(sb, "%s/", tmp);
sfree(tmp);
sfree(munged);
return ret;
make_session_filename(subname, sb);
return strbuf_to_str(sb);
}
if (index == INDEX_HOSTKEYS) {
env = getenv("PUTTYSSHHOSTKEYS");
@ -554,13 +544,12 @@ settings_e *enum_settings_start(void)
return toret;
}
char *enum_settings_next(settings_e *handle, char *buffer, int buflen)
bool enum_settings_next(settings_e *handle, strbuf *out)
{
struct dirent *de;
struct stat st;
char *fullpath;
int maxlen, thislen, len;
char *unmunged;
if (!handle->dp)
return NULL;
@ -581,16 +570,13 @@ char *enum_settings_next(settings_e *handle, char *buffer, int buflen)
if (stat(fullpath, &st) < 0 || !S_ISREG(st.st_mode))
continue; /* try another one */
unmunged = unmungestr(de->d_name);
strncpy(buffer, unmunged, buflen);
buffer[buflen-1] = '\0';
sfree(unmunged);
decode_session_filename(de->d_name, out);
sfree(fullpath);
return buffer;
return true;
}
sfree(fullpath);
return NULL;
return false;
}
void enum_settings_finish(settings_e *handle)