diff --git a/Recipe b/Recipe index 7327c66b..cbf8cefa 100644 --- a/Recipe +++ b/Recipe @@ -115,7 +115,7 @@ SFTP = sftp int64 logging # Pageant or PuTTYgen). WINMISC = misc version winstore settings tree234 winnet proxy cmdline + windefs winmisc -UXMISC = misc version uxstore settings tree234 uxnet proxy cmdline +UXMISC = misc version uxstore settings tree234 uxnet proxy cmdline uxmisc MACMISC = misc version macstore settings tree234 macnet mtcpnet otnet proxy # Character set library, for use in pterm. @@ -140,11 +140,11 @@ pscp : [C] scp console WINSSH be_none SFTP wildcard WINMISC scp.res LIBS1 psftp : [C] psftp console WINSSH be_none SFTP WINMISC scp.res LIBS1 pageant : [G] pageant sshrsa sshpubk sshdes sshbn sshmd5 version tree234 - + misc sshaes sshsha pageantc sshdss sshsh512 winutils + + misc sshaes sshsha pageantc sshdss sshsh512 winutils winmisc + pageant.res LIBS puttygen : [G] puttygen sshrsag sshdssg sshprime sshdes sshbn sshmd5 version - + sshrand noise sshsha winstore misc winctrls sshrsa sshdss + + sshrand noise sshsha winstore misc winctrls sshrsa sshdss winmisc + sshpubk sshaes sshsh512 import winutils puttygen.res LIBS pterm : [X] pterm terminal wcwidth uxucs uxmisc tree234 misc ldisc ldiscucs diff --git a/cmdline.c b/cmdline.c index 7c251724..0361b884 100644 --- a/cmdline.c +++ b/cmdline.c @@ -307,8 +307,7 @@ int cmdline_process_param(char *p, char *value, int need_save, Config *cfg) if (!strcmp(p, "-i")) { RETURN(2); SAVEABLE(1); - strncpy(cfg->keyfile, value, sizeof(cfg->keyfile)); - cfg->keyfile[sizeof(cfg->keyfile)-1] = '\0'; + cfg->keyfile = filename_from_str(value); } return ret; /* unrecognised */ diff --git a/console.c b/console.c index 27366dee..b51e7e77 100644 --- a/console.c +++ b/console.c @@ -192,7 +192,7 @@ void askcipher(void *frontend, char *ciphername, int cs) * 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, char *filename) +int askappend(void *frontend, Filename filename) { HANDLE hin; DWORD savemode, i; @@ -213,11 +213,11 @@ int askappend(void *frontend, char *filename) char line[32]; if (console_batch_mode) { - fprintf(stderr, msgtemplate_batch, FILENAME_MAX, filename); + fprintf(stderr, msgtemplate_batch, FILENAME_MAX, filename.path); fflush(stderr); return 0; } - fprintf(stderr, msgtemplate, FILENAME_MAX, filename); + fprintf(stderr, msgtemplate, FILENAME_MAX, filename.path); fflush(stderr); hin = GetStdHandle(STD_INPUT_HANDLE); diff --git a/import.c b/import.c index 2ec1fa2d..ce304e28 100644 --- a/import.c +++ b/import.c @@ -8,6 +8,7 @@ #include #include +#include "putty.h" #include "ssh.h" #include "misc.h" @@ -23,13 +24,15 @@ ((unsigned long)(unsigned char)(cp)[2] << 8) | \ ((unsigned long)(unsigned char)(cp)[3])) -int openssh_encrypted(char *filename); -struct ssh2_userkey *openssh_read(char *filename, char *passphrase); -int openssh_write(char *filename, struct ssh2_userkey *key, char *passphrase); +int openssh_encrypted(const Filename *filename); +struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase); +int openssh_write(const Filename *filename, struct ssh2_userkey *key, + char *passphrase); -int sshcom_encrypted(char *filename, char **comment); -struct ssh2_userkey *sshcom_read(char *filename, char *passphrase); -int sshcom_write(char *filename, struct ssh2_userkey *key, char *passphrase); +int sshcom_encrypted(const Filename *filename, char **comment); +struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase); +int sshcom_write(const Filename *filename, struct ssh2_userkey *key, + char *passphrase); /* * Given a key type, determine whether we know how to import it. @@ -59,10 +62,11 @@ int import_target_type(int type) /* * Determine whether a foreign key is encrypted. */ -int import_encrypted(char *filename, int type, char **comment) +int import_encrypted(const Filename *filename, int type, char **comment) { if (type == SSH_KEYTYPE_OPENSSH) { - *comment = dupstr(filename); /* OpenSSH doesn't do key comments */ + /* OpenSSH doesn't do key comments */ + *comment = dupstr(filename_to_str(*filename)); return openssh_encrypted(filename); } if (type == SSH_KEYTYPE_SSHCOM) { @@ -74,7 +78,8 @@ int import_encrypted(char *filename, int type, char **comment) /* * Import an SSH1 key. */ -int import_ssh1(char *filename, int type, struct RSAKey *key, char *passphrase) +int import_ssh1(const Filename *filename, int type, + struct RSAKey *key, char *passphrase) { return 0; } @@ -82,7 +87,8 @@ int import_ssh1(char *filename, int type, struct RSAKey *key, char *passphrase) /* * Import an SSH2 key. */ -struct ssh2_userkey *import_ssh2(char *filename, int type, char *passphrase) +struct ssh2_userkey *import_ssh2(const Filename *filename, int type, + char *passphrase) { if (type == SSH_KEYTYPE_OPENSSH) return openssh_read(filename, passphrase); @@ -94,7 +100,8 @@ struct ssh2_userkey *import_ssh2(char *filename, int type, char *passphrase) /* * Export an SSH1 key. */ -int export_ssh1(char *filename, int type, struct RSAKey *key, char *passphrase) +int export_ssh1(const Filename *filename, int type, struct RSAKey *key, + char *passphrase) { return 0; } @@ -102,7 +109,7 @@ int export_ssh1(char *filename, int type, struct RSAKey *key, char *passphrase) /* * Export an SSH2 key. */ -int export_ssh2(char *filename, int type, +int export_ssh2(const Filename *filename, int type, struct ssh2_userkey *key, char *passphrase) { if (type == SSH_KEYTYPE_OPENSSH) @@ -309,7 +316,7 @@ struct openssh_key { int keyblob_len, keyblob_size; }; -struct openssh_key *load_openssh_key(char *filename) +struct openssh_key *load_openssh_key(const Filename *filename) { struct openssh_key *ret; FILE *fp; @@ -325,7 +332,7 @@ struct openssh_key *load_openssh_key(char *filename) ret->encrypted = 0; memset(ret->iv, 0, sizeof(ret->iv)); - fp = fopen(filename, "r"); + fp = f_open(*filename, "r"); if (!fp) { errmsg = "Unable to open key file"; goto error; @@ -451,7 +458,7 @@ struct openssh_key *load_openssh_key(char *filename) return NULL; } -int openssh_encrypted(char *filename) +int openssh_encrypted(const Filename *filename) { struct openssh_key *key = load_openssh_key(filename); int ret; @@ -466,7 +473,7 @@ int openssh_encrypted(char *filename) return ret; } -struct ssh2_userkey *openssh_read(char *filename, char *passphrase) +struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase) { struct openssh_key *key = load_openssh_key(filename); struct ssh2_userkey *retkey; @@ -655,7 +662,8 @@ struct ssh2_userkey *openssh_read(char *filename, char *passphrase) return retval; } -int openssh_write(char *filename, struct ssh2_userkey *key, char *passphrase) +int openssh_write(const Filename *filename, struct ssh2_userkey *key, + char *passphrase) { unsigned char *pubblob, *privblob, *spareblob; int publen, privlen, sparelen; @@ -860,7 +868,7 @@ int openssh_write(char *filename, struct ssh2_userkey *key, char *passphrase) * And save it. We'll use Unix line endings just in case it's * subsequently transferred in binary mode. */ - fp = fopen(filename, "wb"); /* ensure Unix line endings */ + fp = f_open(*filename, "wb"); /* ensure Unix line endings */ if (!fp) goto error; fputs(header, fp); @@ -977,7 +985,7 @@ struct sshcom_key { int keyblob_len, keyblob_size; }; -struct sshcom_key *load_sshcom_key(char *filename) +struct sshcom_key *load_sshcom_key(const Filename *filename) { struct sshcom_key *ret; FILE *fp; @@ -993,7 +1001,7 @@ struct sshcom_key *load_sshcom_key(char *filename) ret->keyblob = NULL; ret->keyblob_len = ret->keyblob_size = 0; - fp = fopen(filename, "r"); + fp = f_open(*filename, "r"); if (!fp) { errmsg = "Unable to open key file"; goto error; @@ -1095,7 +1103,7 @@ struct sshcom_key *load_sshcom_key(char *filename) return NULL; } -int sshcom_encrypted(char *filename, char **comment) +int sshcom_encrypted(const Filename *filename, char **comment) { struct sshcom_key *key = load_sshcom_key(filename); int pos, len, answer; @@ -1177,7 +1185,7 @@ static int sshcom_put_mpint(void *target, void *data, int len) return len+4; } -struct ssh2_userkey *sshcom_read(char *filename, char *passphrase) +struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase) { struct sshcom_key *key = load_sshcom_key(filename); char *errmsg; @@ -1407,7 +1415,8 @@ struct ssh2_userkey *sshcom_read(char *filename, char *passphrase) return ret; } -int sshcom_write(char *filename, struct ssh2_userkey *key, char *passphrase) +int sshcom_write(const Filename *filename, struct ssh2_userkey *key, + char *passphrase) { unsigned char *pubblob, *privblob; int publen, privlen; @@ -1571,7 +1580,7 @@ int sshcom_write(char *filename, struct ssh2_userkey *key, char *passphrase) * And save it. We'll use Unix line endings just in case it's * subsequently transferred in binary mode. */ - fp = fopen(filename, "wb"); /* ensure Unix line endings */ + fp = f_open(*filename, "wb"); /* ensure Unix line endings */ if (!fp) goto error; fputs("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----\n", fp); diff --git a/logging.c b/logging.c index 652eb9df..d27c727d 100644 --- a/logging.c +++ b/logging.c @@ -10,12 +10,12 @@ /* log session to file stuff ... */ struct LogContext { FILE *lgfp; - char currlogfilename[FILENAME_MAX]; + Filename currlogfilename; void *frontend; Config cfg; }; -static void xlatlognam(char *d, char *s, char *hostname, struct tm *tm); +static void xlatlognam(Filename *d, Filename s, char *hostname, struct tm *tm); /* * Log session traffic. @@ -113,9 +113,9 @@ void logfopen(void *handle) tm = *localtime(&t); /* substitute special codes in file name */ - xlatlognam(ctx->currlogfilename, ctx->cfg.logfilename,ctx->cfg.host, &tm); + xlatlognam(&ctx->currlogfilename, ctx->cfg.logfilename,ctx->cfg.host, &tm); - ctx->lgfp = fopen(ctx->currlogfilename, "r"); /* file already present? */ + ctx->lgfp = f_open(ctx->currlogfilename, "r"); /* file already present? */ if (ctx->lgfp) { int i; fclose(ctx->lgfp); @@ -132,7 +132,7 @@ void logfopen(void *handle) } } - ctx->lgfp = fopen(ctx->currlogfilename, writemod); + ctx->lgfp = f_open(ctx->currlogfilename, writemod); if (ctx->lgfp) { /* enter into event log */ /* --- write header line into log file */ fputs("=~=~=~=~=~=~=~=~=~=~=~= PuTTY log ", ctx->lgfp); @@ -146,7 +146,7 @@ void logfopen(void *handle) ctx->cfg.logtype == LGTYP_DEBUG ? "raw" : ctx->cfg.logtype == LGTYP_PACKETS ? "SSH packets" : "")); /* Make sure we do not exceed the output buffer size */ - strncat(buf, ctx->currlogfilename, 128); + strncat(buf, filename_to_str(ctx->currlogfilename), 128); buf[strlen(buf)] = '\0'; logevent(ctx->frontend, buf); } @@ -183,7 +183,7 @@ void log_reconfig(void *handle, Config *cfg) struct LogContext *ctx = (struct LogContext *)handle; int reset_logging; - if (strcmp(ctx->cfg.logfilename, cfg->logfilename) || + if (!filename_equal(ctx->cfg.logfilename, cfg->logfilename) || ctx->cfg.logtype != cfg->logtype) reset_logging = TRUE; else @@ -204,10 +204,16 @@ void log_reconfig(void *handle, Config *cfg) * * "&Y":YYYY "&m":MM "&d":DD "&T":hhmm "&h": "&&":& */ -static void xlatlognam(char *d, char *s, char *hostname, struct tm *tm) { +static void xlatlognam(Filename *dest, Filename src, + char *hostname, struct tm *tm) { char buf[10], *bufp; int size; - int len = FILENAME_MAX-1; + char buffer[FILENAME_MAX]; + int len = sizeof(buffer)-1; + char *d, *s; + + d = buffer; + s = filename_to_str(src); while (*s) { /* Let (bufp, len) be the string to append. */ @@ -250,4 +256,6 @@ static void xlatlognam(char *d, char *s, char *hostname, struct tm *tm) { len -= size; } *d = '\0'; + + *dest = filename_from_str(s); } diff --git a/mac/mac.c b/mac/mac.c index 3a0f065d..32a7ecee 100644 --- a/mac/mac.c +++ b/mac/mac.c @@ -1,4 +1,4 @@ -/* $Id: mac.c,v 1.37 2003/01/25 15:15:40 ben Exp $ */ +/* $Id: mac.c,v 1.38 2003/02/01 12:54:40 simon Exp $ */ /* * Copyright (c) 1999 Ben Harris * All rights reserved. @@ -741,8 +741,9 @@ void old_keyfile_warning(void) } -char *platform_default_s(char const *name) +FontSpec platform_default_font(char const *name) { + FontSpec ret; long smfs; Str255 pname; static char cname[256]; @@ -754,12 +755,33 @@ char *platform_default_s(char const *name) if (smfs != 0) { GetFontName(HiWord(smfs), pname); if (pname[0] == 0) - return "Monaco"; - p2cstrcpy(cname, pname); - return cname; - } else - return "Monaco"; + strcpy(ret.name, "Monaco"); + ret.height = LoWord(smfs); + p2cstrcpy(ret.name, pname); + } else { + strcpy(ret.name, "Monaco"); + ret.height = 9; + } + ret.isbold = 0; + } else { + ret.name[0] = '\0'; } + + return ret; +} + +Filename platform_default_filename(const char *name) +{ + Filename ret; + if (!strcmp(name, "LogFileName")) + strcpy(ret.path, "putty.log"); + else + *ret.path = '\0'; + return ret; +} + +char *platform_default_s(char const *name) +{ return NULL; } @@ -767,16 +789,6 @@ int platform_default_i(char const *name, int def) { long smfs; - if (!strcmp(name, "FontHeight")) { - smfs = GetScriptVariable(smSystemScript, smScriptMonoFondSize); - if (smfs == 0) - smfs = GetScriptVariable(smRoman, smScriptMonoFondSize); - if (smfs != 0) - return LoWord(smfs); - else - return 9; - } - /* Non-raw cut and paste of line-drawing chars works badly on the * current Unix stub implementation of the Unicode functions. * So I'm going to temporarily set the default to raw mode so @@ -793,6 +805,29 @@ void platform_get_x11_auth(char *display, int *proto, /* SGT: I have no idea whether Mac X servers need anything here. */ } +Filename filename_from_str(char *str) +{ + Filename ret; + strncpy(ret.path, str, sizeof(ret.path)); + ret.path[sizeof(ret.path)-1] = '\0'; + return ret; +} + +char *filename_to_str(Filename fn) +{ + return fn.path; +} + +int filename_equal(Filename f1, Filename f2) +{ + return !strcmp(f1.path, f2.path); +} + +int filename_is_null(Filename fn) +{ + return !*fn.path; +} + /* * Local Variables: * c-file-style: "simon" diff --git a/mac/mac.h b/mac/mac.h index 50ed142a..2d7771e6 100644 --- a/mac/mac.h +++ b/mac/mac.h @@ -13,8 +13,21 @@ #include #include +#include /* for FILENAME_MAX */ + #include "charset.h" +struct Filename { + char path[FILENAME_MAX]; +}; +#define f_open(filename, mode) ( fopen((filename).path, (mode)) ) + +struct FontSpec { + char name[64]; + int isbold; + int height; +}; + #define PUTTY_CREATOR FOUR_CHAR_CODE('pTTY') #define INTERNAL_CREATOR FOUR_CHAR_CODE('pTTI') #define SESS_TYPE FOUR_CHAR_CODE('Sess') diff --git a/mac/macstore.c b/mac/macstore.c index 29e9f365..0ffff0bf 100644 --- a/mac/macstore.c +++ b/mac/macstore.c @@ -1,4 +1,4 @@ -/* $Id: macstore.c,v 1.12 2003/01/21 00:27:24 ben Exp $ */ +/* $Id: macstore.c,v 1.13 2003/02/01 12:54:40 simon Exp $ */ /* * macstore.c: Macintosh-specific impementation of the interface @@ -323,6 +323,49 @@ int read_setting_i(void *handle, char const *key, int defvalue) { return defvalue; } +int read_setting_fontspec(void *handle, const char *name, FontSpec *result) +{ + char *settingname; + FontSpec ret; + + if (!read_setting_s(handle, name, ret.name, sizeof(ret.name))) + return 0; + settingname = dupcat(name, "IsBold", NULL); + ret.isbold = read_setting_i(handle, settingname, -1); + sfree(settingname); + if (ret.isbold == -1) return 0; + if (ret.charset == -1) return 0; + settingname = dupcat(name, "Height", NULL); + ret.height = read_setting_i(handle, settingname, INT_MIN); + sfree(settingname); + if (ret.height == INT_MIN) return 0; + *result = ret; + return 1; +} + +void write_setting_fontspec(void *handle, const char *name, FontSpec font) +{ + char *settingname; + + write_setting_s(handle, name, font.name); + settingname = dupcat(name, "IsBold", NULL); + write_setting_i(handle, settingname, font.isbold); + sfree(settingname); + settingname = dupcat(name, "Height", NULL); + write_setting_i(handle, settingname, font.height); + sfree(settingname); +} + +int read_setting_filename(void *handle, const char *name, Filename *result) +{ + return !!read_setting_s(handle, name, result->path, sizeof(result->path)); +} + +void write_setting_filename(void *handle, const char *name, Filename result) +{ + write_setting_s(handle, name, result.path); +} + void close_settings_r(void *handle) { int fd; diff --git a/mac/macterm.c b/mac/macterm.c index 17008c0c..685d9fe2 100644 --- a/mac/macterm.c +++ b/mac/macterm.c @@ -1,4 +1,4 @@ -/* $Id: macterm.c,v 1.61 2003/02/01 12:26:33 ben Exp $ */ +/* $Id: macterm.c,v 1.62 2003/02/01 12:54:40 simon Exp $ */ /* * Copyright (c) 1999 Simon Tatham * Copyright (c) 1999, 2002 Ben Harris @@ -213,11 +213,11 @@ static void mac_initfont(Session *s) { OptionBits fbflags; SetPort(s->window); - c2pstrcpy(macfont, s->cfg.font); + c2pstrcpy(macfont, s->cfg.font.name); GetFNum(macfont, &s->fontnum); TextFont(s->fontnum); - TextFace(s->cfg.fontisbold ? bold : 0); - TextSize(s->cfg.fontheight); + TextFace(s->cfg.font.isbold ? bold : 0); + TextSize(s->cfg.font.height); GetFontInfo(&fi); s->font_width = CharWidth('W'); /* Well, it's what NCSA uses. */ s->font_ascent = fi.ascent; @@ -227,10 +227,10 @@ static void mac_initfont(Session *s) { &s->font_stdnumer, &s->font_stddenom); mac_workoutfontscale(s, s->font_width * 2, &s->font_widenumer, &s->font_widedenom); - TextSize(s->cfg.fontheight * 2); + TextSize(s->cfg.font.height * 2); mac_workoutfontscale(s, s->font_width * 2, &s->font_bignumer, &s->font_bigdenom); - TextSize(s->cfg.fontheight); + TextSize(s->cfg.font.height); if (!s->cfg.bold_colour) { TextFace(bold); s->font_boldadjust = s->font_width - CharWidth('W'); @@ -262,7 +262,7 @@ static void mac_initfont(Session *s) { s->font_charset = charset_from_macenc(FontToScript(s->fontnum), GetScriptManagerVariable(smRegionCode), - mac_gestalts.sysvers, s->cfg.font); + mac_gestalts.sysvers, s->cfg.font.name); } mac_adjustsize(s, s->term->rows, s->term->cols); @@ -581,7 +581,7 @@ void write_clip(void *cookie, wchar_t *data, int len, int must_deselect) stsc->scrpStyleTab[0].scrpAscent = s->font_ascent; stsc->scrpStyleTab[0].scrpFont = s->fontnum; stsc->scrpStyleTab[0].scrpFace = 0; - stsc->scrpStyleTab[0].scrpSize = s->cfg.fontheight; + stsc->scrpStyleTab[0].scrpSize = s->cfg.font.height; stsc->scrpStyleTab[0].scrpColor.red = 0; stsc->scrpStyleTab[0].scrpColor.green = 0; stsc->scrpStyleTab[0].scrpColor.blue = 0; @@ -1029,25 +1029,25 @@ void do_text(Context ctx, int x, int y, char *text, int len, a.lattr = lattr; switch (lattr & LATTR_MODE) { case LATTR_NORM: - TextSize(s->cfg.fontheight); + TextSize(s->cfg.font.height); a.numer = s->font_stdnumer; a.denom = s->font_stddenom; break; case LATTR_WIDE: - TextSize(s->cfg.fontheight); + TextSize(s->cfg.font.height); a.numer = s->font_widenumer; a.denom = s->font_widedenom; break; case LATTR_TOP: case LATTR_BOT: - TextSize(s->cfg.fontheight * 2); + TextSize(s->cfg.font.height * 2); a.numer = s->font_bignumer; a.denom = s->font_bigdenom; break; } SetPort(s->window); TextFont(s->fontnum); - if (s->cfg.fontisbold || (attr & ATTR_BOLD) && !s->cfg.bold_colour) + if (s->cfg.font.isbold || (attr & ATTR_BOLD) && !s->cfg.bold_colour) style |= bold; if (attr & ATTR_UNDER) style |= underline; @@ -1594,7 +1594,7 @@ void frontend_keypress(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, char *filename) +int askappend(void *frontend, Filename filename) { /* FIXME: not implemented yet. */ diff --git a/misc.h b/misc.h index 456cda06..aa723629 100644 --- a/misc.h +++ b/misc.h @@ -12,6 +12,9 @@ #define TRUE 1 #endif +typedef struct Filename Filename; +typedef struct FontSpec FontSpec; + char *dupstr(const char *s); char *dupcat(const char *s1, ...); char *dupprintf(const char *fmt, ...); diff --git a/pageant.c b/pageant.c index 8fc14e7e..73e950c7 100644 --- a/pageant.c +++ b/pageant.c @@ -12,6 +12,7 @@ #include #include +#include "putty.h" #include "ssh.h" #include "misc.h" #include "tree234.h" @@ -390,7 +391,7 @@ static void keylist_update(void) /* * This function loads a key from a file and adds it. */ -static void add_keyfile(char *filename) +static void add_keyfile(Filename filename) { char passphrase[PASSPHRASE_MAXLEN]; struct RSAKey *rkey = NULL; @@ -403,7 +404,7 @@ static void add_keyfile(char *filename) int type; int original_pass; - type = key_type(filename); + type = key_type(&filename); if (type != SSH_KEYTYPE_SSH1 && type != SSH_KEYTYPE_SSH2) { char msg[256]; sprintf(msg, "Couldn't load this key (%s)", key_type_to_str(type)); @@ -421,7 +422,7 @@ static void add_keyfile(char *filename) int i, nkeys, bloblen; if (type == SSH_KEYTYPE_SSH1) { - if (!rsakey_pubblob(filename, &blob, &bloblen)) { + if (!rsakey_pubblob(&filename, &blob, &bloblen)) { MessageBox(NULL, "Couldn't load private key.", APPNAME, MB_OK | MB_ICONERROR); return; @@ -429,7 +430,7 @@ static void add_keyfile(char *filename) keylist = get_keylist1(); } else { unsigned char *blob2; - blob = ssh2_userkey_loadpub(filename, NULL, &bloblen); + blob = ssh2_userkey_loadpub(&filename, NULL, &bloblen); if (!blob) { MessageBox(NULL, "Couldn't load private key.", APPNAME, MB_OK | MB_ICONERROR); @@ -471,9 +472,9 @@ static void add_keyfile(char *filename) } 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 = smalloc(sizeof(*rkey)); @@ -503,9 +504,9 @@ static void add_keyfile(char *filename) } else *passphrase = '\0'; if (type == SSH_KEYTYPE_SSH1) - ret = loadrsakey(filename, rkey, passphrase); + ret = loadrsakey(&filename, rkey, passphrase); else { - skey = ssh2_load_userkey(filename, passphrase); + skey = ssh2_load_userkey(&filename, passphrase); if (skey == SSH2_WRONG_PASSPHRASE) ret = -1; else if (!skey) @@ -1264,7 +1265,7 @@ static void prompt_add_keyfile(void) if (GetOpenFileName(&of)) { if(strlen(filelist) > of.nFileOffset) /* Only one filename returned? */ - add_keyfile(filelist); + add_keyfile(filename_from_str(filelist)); else { /* we are returned a bunch of strings, end to * end. first string is the directory, the @@ -1292,7 +1293,7 @@ static void prompt_add_keyfile(void) memcpy(filename + dirlen, filewalker, n); filewalker += n; - add_keyfile(filename); + add_keyfile(filename_from_str(filename)); } } @@ -1968,7 +1969,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) command = ""; break; } else { - add_keyfile(argv[i]); + add_keyfile(filename_from_str(argv[i])); added_keys = TRUE; } } diff --git a/putty.h b/putty.h index a9bca42b..5116210d 100644 --- a/putty.h +++ b/putty.h @@ -1,7 +1,6 @@ #ifndef PUTTY_PUTTY_H #define PUTTY_PUTTY_H -#include /* for FILENAME_MAX */ #include /* for wchar_t */ /* @@ -26,6 +25,7 @@ typedef struct terminal_tag Terminal; #include "puttyps.h" #include "network.h" +#include "misc.h" /* Three attribute types: * The ATTRs (normal attributes) are stored with the characters in @@ -339,7 +339,7 @@ struct config_tag { int agentfwd; int change_username; /* allow username switching in SSH2 */ int ssh_cipherlist[CIPHER_MAX]; - char keyfile[FILENAME_MAX]; + Filename keyfile; int sshprot; /* use v1 or v2 when both available */ int ssh2_des_cbc; /* "des-cbc" nonstandard SSH2 cipher */ int try_tis_auth; @@ -396,7 +396,7 @@ struct config_tag { int bellovl_n; /* number of bells to cause overload */ int bellovl_t; /* time interval for overload (seconds) */ int bellovl_s; /* period of silence to re-enable bell (s) */ - char bell_wavefile[FILENAME_MAX]; + Filename bell_wavefile; int scrollbar; int scrollbar_in_fullscreen; int resize_action; @@ -404,11 +404,8 @@ struct config_tag { int blinktext; int win_name_always; int width, height; - char font[256]; - int fontisbold; - int fontheight; - int fontcharset; - char logfilename[FILENAME_MAX]; + FontSpec font; + Filename logfilename; int logtype; int logxfovr; int hide_mouseptr; @@ -447,9 +444,9 @@ struct config_tag { int stamp_utmp; int login_shell; int scrollbar_on_left; - char boldfont[256]; - char widefont[256]; - char wideboldfont[256]; + FontSpec boldfont; + FontSpec widefont; + FontSpec wideboldfont; int shadowboldoffset; }; @@ -563,10 +560,14 @@ void registry_cleanup(void); * (The integer one is expected to return `def' if it has no clear * opinion of its own. This is because there's no integer value * which I can reliably set aside to indicate `nil'. The string - * function is perfectly all right returning NULL, of course.) + * function is perfectly all right returning NULL, of course. The + * Filename and FontSpec functions are _not allowed_ to fail to + * return, since these defaults _must_ be per-platform.) */ char *platform_default_s(const char *name); int platform_default_i(const char *name, int def); +Filename platform_default_filename(const char *name); +FontSpec platform_default_fontspec(const char *name); /* * Exports from terminal.c. @@ -740,7 +741,7 @@ void logevent(void *frontend, char *); void verify_ssh_host_key(void *frontend, char *host, int port, char *keytype, char *keystr, char *fingerprint); void askcipher(void *frontend, char *ciphername, int cs); -int askappend(void *frontend, char *filename); +int askappend(void *frontend, Filename filename); /* * Exports from console.c (that aren't equivalents to things in @@ -786,4 +787,12 @@ enum { }; extern const char *const x11_authnames[]; /* declared in x11fwd.c */ +/* + * Miscellaneous exports from the platform-specific code. + */ +Filename filename_from_str(char *string); +char *filename_to_str(Filename fn); +int filename_equal(Filename f1, Filename f2); +int filename_is_null(Filename fn); + #endif diff --git a/puttygen.c b/puttygen.c index fd713e0f..42af3976 100644 --- a/puttygen.c +++ b/puttygen.c @@ -621,7 +621,7 @@ void ui_set_state(HWND hwnd, struct MainDlgState *state, int status) } void load_key_file(HWND hwnd, struct MainDlgState *state, - char *filename, int was_import_cmd) + Filename filename, int was_import_cmd) { char passphrase[PASSPHRASE_MAXLEN]; int needs_pass; @@ -632,7 +632,7 @@ void load_key_file(HWND hwnd, struct MainDlgState *state, struct RSAKey newkey1; struct ssh2_userkey *newkey2 = NULL; - type = realtype = key_type(filename); + type = realtype = key_type(&filename); if (type != SSH_KEYTYPE_SSH1 && type != SSH_KEYTYPE_SSH2 && !import_possible(type)) { @@ -652,12 +652,12 @@ void load_key_file(HWND hwnd, struct MainDlgState *state, comment = NULL; if (realtype == SSH_KEYTYPE_SSH1) - needs_pass = rsakey_encrypted(filename, &comment); + needs_pass = rsakey_encrypted(&filename, &comment); else if (realtype == SSH_KEYTYPE_SSH2) needs_pass = - ssh2_userkey_encrypted(filename, &comment); + ssh2_userkey_encrypted(&filename, &comment); else - needs_pass = import_encrypted(filename, realtype, + needs_pass = import_encrypted(&filename, realtype, &comment); pps.passphrase = passphrase; pps.comment = comment; @@ -676,17 +676,17 @@ void load_key_file(HWND hwnd, struct MainDlgState *state, *passphrase = '\0'; if (type == SSH_KEYTYPE_SSH1) { if (realtype == type) - ret = loadrsakey(filename, &newkey1, + ret = loadrsakey(&filename, &newkey1, passphrase); else - ret = import_ssh1(filename, realtype, + ret = import_ssh1(&filename, realtype, &newkey1, passphrase); } else { if (realtype == type) - newkey2 = ssh2_load_userkey(filename, + newkey2 = ssh2_load_userkey(&filename, passphrase); else - newkey2 = import_ssh2(filename, realtype, + newkey2 = import_ssh2(&filename, realtype, passphrase); if (newkey2 == SSH2_WRONG_PASSPHRASE) ret = -1; @@ -940,7 +940,7 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg, * Load a key file if one was provided on the command line. */ if (cmdline_keyfile) - load_key_file(hwnd, state, cmdline_keyfile, 0); + load_key_file(hwnd, state, filename_from_str(cmdline_keyfile), 0); return 1; case WM_MOUSEMOVE: @@ -1166,19 +1166,21 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg, } if (state->ssh2) { + Filename fn = filename_from_str(filename); if (type != realtype) - ret = export_ssh2(filename, type, &state->ssh2key, + ret = export_ssh2(&fn, type, &state->ssh2key, *passphrase ? passphrase : NULL); else - ret = ssh2_save_userkey(filename, &state->ssh2key, + ret = ssh2_save_userkey(&fn, &state->ssh2key, *passphrase ? passphrase : NULL); } else { + Filename fn = filename_from_str(filename); if (type != realtype) - ret = export_ssh1(filename, type, &state->key, + ret = export_ssh1(&fn, type, &state->key, *passphrase ? passphrase : NULL); else - ret = saversakey(filename, &state->key, + ret = saversakey(&fn, &state->key, *passphrase ? passphrase : NULL); } if (ret <= 0) { @@ -1228,7 +1230,7 @@ static int CALLBACK MainDlgProc(HWND hwnd, UINT msg, char filename[FILENAME_MAX]; if (prompt_keyfile(hwnd, "Load private key:", filename, 0, LOWORD(wParam)==IDC_LOAD)) - load_key_file(hwnd, state, filename, + load_key_file(hwnd, state, filename_from_str(filename), LOWORD(wParam) != IDC_LOAD); } break; diff --git a/settings.c b/settings.c index 2dadfa01..a4c514f0 100644 --- a/settings.c +++ b/settings.c @@ -37,6 +37,22 @@ static void gpps(void *handle, const char *name, const char *def, } } +/* + * gppfont and gppfile cannot have local defaults, since the very + * format of a Filename or Font is platform-dependent. So the + * platform-dependent functions MUST return some sort of value. + */ +static void gppfont(void *handle, const char *name, FontSpec *result) +{ + if (!read_setting_fontspec(handle, name, result)) + *result = platform_default_fontspec(name); +} +static void gppfile(void *handle, const char *name, Filename *result) +{ + if (!read_setting_filename(handle, name, result)) + *result = platform_default_filename(name); +} + static void gppi(void *handle, char *name, int def, int *i) { def = platform_default_i(name, def); @@ -144,7 +160,7 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg) write_setting_i(sesskey, "Present", 1); if (do_host) { write_setting_s(sesskey, "HostName", cfg->host); - write_setting_s(sesskey, "LogFileName", cfg->logfilename); + write_setting_filename(sesskey, "LogFileName", cfg->logfilename); write_setting_i(sesskey, "LogType", cfg->logtype); write_setting_i(sesskey, "LogFileClash", cfg->logxfovr); } @@ -209,7 +225,7 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg) write_setting_i(sesskey, "AuthKI", cfg->try_ki_auth); write_setting_i(sesskey, "SshProt", cfg->sshprot); write_setting_i(sesskey, "SSH2DES", cfg->ssh2_des_cbc); - write_setting_s(sesskey, "PublicKeyFile", cfg->keyfile); + write_setting_filename(sesskey, "PublicKeyFile", cfg->keyfile); write_setting_s(sesskey, "RemoteCommand", cfg->remote_cmd); write_setting_i(sesskey, "RFCEnviron", cfg->rfc_environ); write_setting_i(sesskey, "PassiveTelnet", cfg->passive_telnet); @@ -246,7 +262,7 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg) write_setting_i(sesskey, "BlinkCur", cfg->blink_cur); write_setting_i(sesskey, "Beep", cfg->beep); write_setting_i(sesskey, "BeepInd", cfg->beep_ind); - write_setting_s(sesskey, "BellWaveFile", cfg->bell_wavefile); + write_setting_filename(sesskey, "BellWaveFile", cfg->bell_wavefile); write_setting_i(sesskey, "BellOverload", cfg->bellovl); write_setting_i(sesskey, "BellOverloadN", cfg->bellovl_n); write_setting_i(sesskey, "BellOverloadT", cfg->bellovl_t); @@ -259,10 +275,7 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg) write_setting_s(sesskey, "WinTitle", cfg->wintitle); write_setting_i(sesskey, "TermWidth", cfg->width); write_setting_i(sesskey, "TermHeight", cfg->height); - write_setting_s(sesskey, "Font", cfg->font); - write_setting_i(sesskey, "FontIsBold", cfg->fontisbold); - write_setting_i(sesskey, "FontCharSet", cfg->fontcharset); - write_setting_i(sesskey, "FontHeight", cfg->fontheight); + write_setting_fontspec(sesskey, "Font", cfg->font); write_setting_i(sesskey, "FontVTMode", cfg->vtmode); write_setting_i(sesskey, "TryPalette", cfg->try_palette); write_setting_i(sesskey, "BoldAsColour", cfg->bold_colour); @@ -333,7 +346,7 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg) write_setting_i(sesskey, "StampUtmp", cfg->stamp_utmp); write_setting_i(sesskey, "LoginShell", cfg->login_shell); write_setting_i(sesskey, "ScrollbarOnLeft", cfg->scrollbar_on_left); - write_setting_s(sesskey, "BoldFont", cfg->boldfont); + write_setting_fontspec(sesskey, "BoldFont", cfg->boldfont); write_setting_i(sesskey, "ShadowBoldOffset", cfg->shadowboldoffset); } @@ -360,8 +373,7 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg) } else { cfg->host[0] = '\0'; /* blank hostname */ } - gpps(sesskey, "LogFileName", "putty.log", - cfg->logfilename, sizeof(cfg->logfilename)); + gppfile(sesskey, "LogFileName", &cfg->logfilename); gppi(sesskey, "LogType", 0, &cfg->logtype); gppi(sesskey, "LogFileClash", LGXF_ASK, &cfg->logxfovr); @@ -442,7 +454,7 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg) gppi(sesskey, "SSH2DES", 0, &cfg->ssh2_des_cbc); gppi(sesskey, "AuthTIS", 0, &cfg->try_tis_auth); gppi(sesskey, "AuthKI", 1, &cfg->try_ki_auth); - gpps(sesskey, "PublicKeyFile", "", cfg->keyfile, sizeof(cfg->keyfile)); + gppfile(sesskey, "PublicKeyFile", &cfg->keyfile); gpps(sesskey, "RemoteCommand", "", cfg->remote_cmd, sizeof(cfg->remote_cmd)); gppi(sesskey, "RFCEnviron", 0, &cfg->rfc_environ); @@ -482,8 +494,7 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg) /* pedantic compiler tells me I can't use &cfg->beep as an int * :-) */ gppi(sesskey, "Beep", 1, &cfg->beep); gppi(sesskey, "BeepInd", 0, &cfg->beep_ind); - gpps(sesskey, "BellWaveFile", "", cfg->bell_wavefile, - sizeof(cfg->bell_wavefile)); + gppfile(sesskey, "BellWaveFile", &cfg->bell_wavefile); gppi(sesskey, "BellOverload", 1, &cfg->bellovl); gppi(sesskey, "BellOverloadN", 5, &cfg->bellovl_n); gppi(sesskey, "BellOverloadT", 2*TICKSPERSEC, &cfg->bellovl_t); @@ -496,24 +507,7 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg) gpps(sesskey, "WinTitle", "", cfg->wintitle, sizeof(cfg->wintitle)); gppi(sesskey, "TermWidth", 80, &cfg->width); gppi(sesskey, "TermHeight", 24, &cfg->height); - gpps(sesskey, "Font", "XXX", cfg->font, sizeof(cfg->font)); - gppi(sesskey, "FontIsBold", 0, &cfg->fontisbold); - gppi(sesskey, "FontCharSet", 0, &cfg->fontcharset); - gppi(sesskey, "FontHeight", 10, &cfg->fontheight); -#ifdef _WINDOWS - if (cfg->fontheight < 0) { - int oldh, newh; - HDC hdc = GetDC(NULL); - int logpix = GetDeviceCaps(hdc, LOGPIXELSY); - ReleaseDC(NULL, hdc); - - oldh = -cfg->fontheight; - newh = MulDiv(oldh, 72, logpix) + 1; - if (MulDiv(newh, logpix, 72) > oldh) - newh--; - cfg->fontheight = newh; - } -#endif + gppfont(sesskey, "Font", &cfg->font); gppi(sesskey, "FontVTMode", VT_UNICODE, (int *) &cfg->vtmode); gppi(sesskey, "TryPalette", 0, &cfg->try_palette); gppi(sesskey, "BoldAsColour", 1, &cfg->bold_colour); @@ -625,7 +619,7 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg) gppi(sesskey, "StampUtmp", 1, &cfg->stamp_utmp); gppi(sesskey, "LoginShell", 1, &cfg->login_shell); gppi(sesskey, "ScrollbarOnLeft", 0, &cfg->scrollbar_on_left); - gpps(sesskey, "BoldFont", "", cfg->boldfont, sizeof(cfg->boldfont)); + gppfont(sesskey, "BoldFont", &cfg->boldfont); gppi(sesskey, "ShadowBoldOffset", 1, &cfg->shadowboldoffset); } diff --git a/ssh.c b/ssh.c index a968e60e..9ffb47e9 100644 --- a/ssh.c +++ b/ssh.c @@ -2457,8 +2457,8 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt) } s->tis_auth_refused = s->ccard_auth_refused = 0; /* Load the public half of ssh->cfg.keyfile so we notice if it's in Pageant */ - if (*ssh->cfg.keyfile) { - if (!rsakey_pubblob(ssh->cfg.keyfile, + if (!filename_is_null(ssh->cfg.keyfile)) { + if (!rsakey_pubblob(&ssh->cfg.keyfile, &s->publickey_blob, &s->publickey_bloblen)) s->publickey_blob = NULL; } else @@ -2586,7 +2586,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt) if (s->authed) break; } - if (*ssh->cfg.keyfile && !s->tried_publickey) + if (!filename_is_null(ssh->cfg.keyfile) && !s->tried_publickey) s->pwpkt_type = SSH1_CMSG_AUTH_RSA; if (ssh->cfg.try_tis_auth && @@ -2652,7 +2652,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt) if (flags & FLAG_VERBOSE) c_write_str(ssh, "Trying public key authentication.\r\n"); logeventf(ssh, "Trying public key \"%s\"", ssh->cfg.keyfile); - type = key_type(ssh->cfg.keyfile); + type = key_type(&ssh->cfg.keyfile); if (type != SSH_KEYTYPE_SSH1) { sprintf(msgbuf, "Key is of wrong type (%s)", key_type_to_str(type)); @@ -2662,7 +2662,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt) s->tried_publickey = 1; continue; } - if (!rsakey_encrypted(ssh->cfg.keyfile, &comment)) { + if (!rsakey_encrypted(&ssh->cfg.keyfile, &comment)) { if (flags & FLAG_VERBOSE) c_write_str(ssh, "No passphrase required.\r\n"); goto tryauth; @@ -2718,10 +2718,10 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt) s->tried_publickey = 1; { - int ret = loadrsakey(ssh->cfg.keyfile, &s->key, s->password); + int ret = loadrsakey(&ssh->cfg.keyfile, &s->key, s->password); if (ret == 0) { c_write_str(ssh, "Couldn't load private key from "); - c_write_str(ssh, ssh->cfg.keyfile); + c_write_str(ssh, filename_to_str(ssh->cfg.keyfile)); c_write_str(ssh, ".\r\n"); continue; /* go and try password */ } @@ -4388,13 +4388,13 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) s->tried_keyb_inter = FALSE; s->kbd_inter_running = FALSE; /* Load the pub half of ssh->cfg.keyfile so we notice if it's in Pageant */ - if (*ssh->cfg.keyfile) { + if (!filename_is_null(ssh->cfg.keyfile)) { int keytype; logeventf(ssh, "Reading private key file \"%.150s\"", ssh->cfg.keyfile); - keytype = key_type(ssh->cfg.keyfile); + keytype = key_type(&ssh->cfg.keyfile); if (keytype == SSH_KEYTYPE_SSH2) { s->publickey_blob = - ssh2_userkey_loadpub(ssh->cfg.keyfile, NULL, + ssh2_userkey_loadpub(&ssh->cfg.keyfile, NULL, &s->publickey_bloblen); } else { char *msgbuf; @@ -4692,7 +4692,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) * willing to accept it. */ pub_blob = - (unsigned char *)ssh2_userkey_loadpub(ssh->cfg.keyfile, + (unsigned char *)ssh2_userkey_loadpub(&ssh->cfg.keyfile, &algorithm, &pub_blob_len); if (pub_blob) { @@ -4720,7 +4720,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) * Actually attempt a serious authentication using * the key. */ - if (ssh2_userkey_encrypted(ssh->cfg.keyfile, &comment)) { + if (ssh2_userkey_encrypted(&ssh->cfg.keyfile, &comment)) { sprintf(s->pwprompt, "Passphrase for key \"%.100s\": ", comment); @@ -4872,7 +4872,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt) */ struct ssh2_userkey *key; - key = ssh2_load_userkey(ssh->cfg.keyfile, s->password); + key = ssh2_load_userkey(&ssh->cfg.keyfile, s->password); if (key == SSH2_WRONG_PASSPHRASE || key == NULL) { if (key == SSH2_WRONG_PASSPHRASE) { c_write_str(ssh, "Wrong passphrase\r\n"); diff --git a/ssh.h b/ssh.h index c819c552..766e2e3c 100644 --- a/ssh.h +++ b/ssh.h @@ -4,6 +4,7 @@ #include "puttymem.h" #include "network.h" #include "int64.h" +#include "misc.h" struct ssh_channel; @@ -319,11 +320,12 @@ void dh_cleanup(void *); Bignum dh_create_e(void *, int nbits); Bignum dh_find_K(void *, Bignum f); -int loadrsakey(char *filename, struct RSAKey *key, char *passphrase); -int rsakey_encrypted(char *filename, char **comment); -int rsakey_pubblob(char *filename, void **blob, int *bloblen); +int loadrsakey(const Filename *filename, struct RSAKey *key, + char *passphrase); +int rsakey_encrypted(const Filename *filename, char **comment); +int rsakey_pubblob(const Filename *filename, void **blob, int *bloblen); -int saversakey(char *filename, struct RSAKey *key, char *passphrase); +int saversakey(const Filename *filename, struct RSAKey *key, char *passphrase); extern int base64_decode_atom(char *atom, unsigned char *out); extern int base64_lines(int datalen); @@ -334,11 +336,12 @@ extern void base64_encode(FILE *fp, unsigned char *data, int datalen, int cpl); extern struct ssh2_userkey ssh2_wrong_passphrase; #define SSH2_WRONG_PASSPHRASE (&ssh2_wrong_passphrase) -int ssh2_userkey_encrypted(char *filename, char **comment); -struct ssh2_userkey *ssh2_load_userkey(char *filename, char *passphrase); -char *ssh2_userkey_loadpub(char *filename, char **algorithm, +int ssh2_userkey_encrypted(const Filename *filename, char **comment); +struct ssh2_userkey *ssh2_load_userkey(const Filename *filename, + char *passphrase); +char *ssh2_userkey_loadpub(const Filename *filename, char **algorithm, int *pub_blob_len); -int ssh2_save_userkey(char *filename, struct ssh2_userkey *key, +int ssh2_save_userkey(const Filename *filename, struct ssh2_userkey *key, char *passphrase); enum { @@ -347,16 +350,19 @@ enum { SSH_KEYTYPE_SSH1, SSH_KEYTYPE_SSH2, SSH_KEYTYPE_OPENSSH, SSH_KEYTYPE_SSHCOM }; -int key_type(char *filename); +int key_type(const Filename *filename); char *key_type_to_str(int type); int import_possible(int type); int import_target_type(int type); -int import_encrypted(char *filename, int type, char **comment); -int import_ssh1(char *filename, int type, struct RSAKey *key,char *passphrase); -struct ssh2_userkey *import_ssh2(char *filename, int type, char *passphrase); -int export_ssh1(char *filename, int type, struct RSAKey *key,char *passphrase); -int export_ssh2(char *filename, int type, +int import_encrypted(const Filename *filename, int type, char **comment); +int import_ssh1(const Filename *filename, int type, + struct RSAKey *key, char *passphrase); +struct ssh2_userkey *import_ssh2(const Filename *filename, int type, + char *passphrase); +int export_ssh1(const Filename *filename, int type, + struct RSAKey *key, char *passphrase); +int export_ssh2(const Filename *filename, int type, struct ssh2_userkey *key, char *passphrase); void des3_decrypt_pubkey(unsigned char *key, unsigned char *blk, int len); diff --git a/sshpubk.c b/sshpubk.c index f8cb38b0..8bcbbc76 100644 --- a/sshpubk.c +++ b/sshpubk.c @@ -9,6 +9,7 @@ #include #include +#include "putty.h" #include "ssh.h" #include "misc.h" @@ -152,12 +153,12 @@ static int loadrsakey_main(FILE * fp, struct RSAKey *key, int pub_only, return ret; } -int loadrsakey(char *filename, struct RSAKey *key, char *passphrase) +int loadrsakey(const Filename *filename, struct RSAKey *key, char *passphrase) { FILE *fp; char buf[64]; - fp = fopen(filename, "rb"); + fp = f_open(*filename, "rb"); if (!fp) return 0; /* doesn't even exist */ @@ -180,12 +181,12 @@ int loadrsakey(char *filename, struct RSAKey *key, char *passphrase) * See whether an RSA key is encrypted. Return its comment field as * well. */ -int rsakey_encrypted(char *filename, char **comment) +int rsakey_encrypted(const Filename *filename, char **comment) { FILE *fp; char buf[64]; - fp = fopen(filename, "rb"); + fp = f_open(*filename, "rb"); if (!fp) return 0; /* doesn't even exist */ @@ -205,7 +206,7 @@ int rsakey_encrypted(char *filename, char **comment) * an RSA key, as given in the agent protocol (modulus bits, * exponent, modulus). */ -int rsakey_pubblob(char *filename, void **blob, int *bloblen) +int rsakey_pubblob(const Filename *filename, void **blob, int *bloblen) { FILE *fp; char buf[64]; @@ -217,7 +218,7 @@ int rsakey_pubblob(char *filename, void **blob, int *bloblen) *bloblen = 0; ret = 0; - fp = fopen(filename, "rb"); + fp = f_open(*filename, "rb"); if (!fp) return 0; /* doesn't even exist */ @@ -240,7 +241,7 @@ int rsakey_pubblob(char *filename, void **blob, int *bloblen) /* * Save an RSA key file. Return nonzero on success. */ -int saversakey(char *filename, struct RSAKey *key, char *passphrase) +int saversakey(const Filename *filename, struct RSAKey *key, char *passphrase) { unsigned char buf[16384]; unsigned char keybuf[16]; @@ -330,7 +331,7 @@ int saversakey(char *filename, struct RSAKey *key, char *passphrase) /* * Done. Write the result to the file. */ - fp = fopen(filename, "wb"); + fp = f_open(*filename, "wb"); if (fp) { int ret = (fwrite(buf, 1, p - buf, fp) == (size_t) (p - buf)); ret = ret && (fclose(fp) == 0); @@ -573,7 +574,8 @@ struct ssh2_userkey ssh2_wrong_passphrase = { NULL, NULL, NULL }; -struct ssh2_userkey *ssh2_load_userkey(char *filename, char *passphrase) +struct ssh2_userkey *ssh2_load_userkey(const Filename *filename, + char *passphrase) { FILE *fp; char header[40], *b, *encryption, *comment, *mac; @@ -589,7 +591,7 @@ struct ssh2_userkey *ssh2_load_userkey(char *filename, char *passphrase) comment = mac = NULL; public_blob = private_blob = NULL; - fp = fopen(filename, "rb"); + fp = f_open(*filename, "rb"); if (!fp) goto error; @@ -810,7 +812,7 @@ struct ssh2_userkey *ssh2_load_userkey(char *filename, char *passphrase) return ret; } -char *ssh2_userkey_loadpub(char *filename, char **algorithm, +char *ssh2_userkey_loadpub(const Filename *filename, char **algorithm, int *pub_blob_len) { FILE *fp; @@ -822,7 +824,7 @@ char *ssh2_userkey_loadpub(char *filename, char **algorithm, public_blob = NULL; - fp = fopen(filename, "rb"); + fp = f_open(*filename, "rb"); if (!fp) goto error; @@ -886,7 +888,7 @@ char *ssh2_userkey_loadpub(char *filename, char **algorithm, return NULL; } -int ssh2_userkey_encrypted(char *filename, char **commentptr) +int ssh2_userkey_encrypted(const Filename *filename, char **commentptr) { FILE *fp; char header[40], *b, *comment; @@ -895,7 +897,7 @@ int ssh2_userkey_encrypted(char *filename, char **commentptr) if (commentptr) *commentptr = NULL; - fp = fopen(filename, "rb"); + fp = f_open(*filename, "rb"); if (!fp) return 0; if (!read_header(fp, header) @@ -972,7 +974,7 @@ void base64_encode(FILE * fp, unsigned char *data, int datalen, int cpl) fputc('\n', fp); } -int ssh2_save_userkey(char *filename, struct ssh2_userkey *key, +int ssh2_save_userkey(const Filename *filename, struct ssh2_userkey *key, char *passphrase) { FILE *fp; @@ -1076,7 +1078,7 @@ int ssh2_save_userkey(char *filename, struct ssh2_userkey *key, memset(&s, 0, sizeof(s)); } - fp = fopen(filename, "w"); + fp = f_open(*filename, "w"); if (!fp) return 0; fprintf(fp, "PuTTY-User-Key-File-2: %s\n", key->alg->name); @@ -1103,7 +1105,7 @@ int ssh2_save_userkey(char *filename, struct ssh2_userkey *key, * A function to determine the type of a private key file. Returns * 0 on failure, 1 or 2 on success. */ -int key_type(char *filename) +int key_type(const Filename *filename) { FILE *fp; char buf[32]; @@ -1112,7 +1114,7 @@ int key_type(char *filename) const char openssh_sig[] = "-----BEGIN "; int i; - fp = fopen(filename, "r"); + fp = f_open(*filename, "r"); if (!fp) return SSH_KEYTYPE_UNOPENABLE; i = fread(buf, 1, sizeof(buf), fp); diff --git a/storage.h b/storage.h index 46e63505..560ad600 100644 --- a/storage.h +++ b/storage.h @@ -29,6 +29,8 @@ void *open_settings_w(const char *sessionname); 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_fontspec(void *handle, const char *key, FontSpec font); void close_settings_w(void *handle); /* @@ -44,10 +46,15 @@ void close_settings_w(void *handle); * 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, char *buffer, int buflen); int read_setting_i(void *handle, const char *key, int defvalue); +int read_setting_filename(void *handle, const char *key, Filename *value); +int read_setting_fontspec(void *handle, const char *key, FontSpec *font); void close_settings_r(void *handle); /* diff --git a/unix/pterm.c b/unix/pterm.c index 5a48dd03..66b55ffc 100644 --- a/unix/pterm.c +++ b/unix/pterm.c @@ -88,10 +88,28 @@ char *x_get_default(const char *key) /* * Default settings that are specific to pterm. */ +FontSpec platform_default_fontspec(const char *name) +{ + FontSpec ret; + if (!strcmp(name, "Font")) + strcpy(ret.name, "fixed"); + else + *ret.name = '\0'; + return ret; +} + +Filename platform_default_filename(const char *name) +{ + Filename ret; + if (!strcmp(name, "LogFileName")) + strcpy(ret.path, "putty.log"); + else + *ret.path = '\0'; + return ret; +} + char *platform_default_s(const char *name) { - if (!strcmp(name, "Font")) - return "fixed"; return NULL; } @@ -112,7 +130,7 @@ void ldisc_update(void *frontend, int echo, int edit) */ } -int askappend(void *frontend, char *filename) +int askappend(void *frontend, Filename filename) { /* * Logging in an xterm-alike is liable to be something you only @@ -2022,26 +2040,26 @@ int do_cmdline(int argc, char **argv, int do_everything, Config *cfg) if (!strcmp(p, "-fn") || !strcmp(p, "-font")) { EXPECTS_ARG; SECOND_PASS_ONLY; - strncpy(cfg->font, val, sizeof(cfg->font)); - cfg->font[sizeof(cfg->font)-1] = '\0'; + strncpy(cfg->font.name, val, sizeof(cfg->font.name)); + cfg->font.name[sizeof(cfg->font.name)-1] = '\0'; } else if (!strcmp(p, "-fb")) { EXPECTS_ARG; SECOND_PASS_ONLY; - strncpy(cfg->boldfont, val, sizeof(cfg->boldfont)); - cfg->boldfont[sizeof(cfg->boldfont)-1] = '\0'; + strncpy(cfg->boldfont.name, val, sizeof(cfg->boldfont.name)); + cfg->boldfont.name[sizeof(cfg->boldfont.name)-1] = '\0'; } else if (!strcmp(p, "-fw")) { EXPECTS_ARG; SECOND_PASS_ONLY; - strncpy(cfg->widefont, val, sizeof(cfg->widefont)); - cfg->widefont[sizeof(cfg->widefont)-1] = '\0'; + strncpy(cfg->widefont.name, val, sizeof(cfg->widefont.name)); + cfg->widefont.name[sizeof(cfg->widefont.name)-1] = '\0'; } else if (!strcmp(p, "-fwb")) { EXPECTS_ARG; SECOND_PASS_ONLY; - strncpy(cfg->wideboldfont, val, sizeof(cfg->wideboldfont)); - cfg->wideboldfont[sizeof(cfg->wideboldfont)-1] = '\0'; + strncpy(cfg->wideboldfont.name, val, sizeof(cfg->wideboldfont.name)); + cfg->wideboldfont.name[sizeof(cfg->wideboldfont.name)-1] = '\0'; } else if (!strcmp(p, "-cs")) { EXPECTS_ARG; @@ -2122,8 +2140,8 @@ int do_cmdline(int argc, char **argv, int do_everything, Config *cfg) } else if (!strcmp(p, "-log")) { EXPECTS_ARG; SECOND_PASS_ONLY; - strncpy(cfg->logfilename, val, sizeof(cfg->logfilename)); - cfg->logfilename[sizeof(cfg->logfilename)-1] = '\0'; + strncpy(cfg->logfilename.path, val, sizeof(cfg->logfilename.path)); + cfg->logfilename.path[sizeof(cfg->logfilename.path)-1] = '\0'; cfg->logtype = LGTYP_DEBUG; } else if (!strcmp(p, "-ut-") || !strcmp(p, "+ut")) { @@ -2278,37 +2296,38 @@ int main(int argc, char **argv) if (do_cmdline(argc, argv, 1, &inst->cfg)) exit(1); /* post-defaults, do everything */ - inst->fonts[0] = gdk_font_load(inst->cfg.font); + inst->fonts[0] = gdk_font_load(inst->cfg.font.name); if (!inst->fonts[0]) { - fprintf(stderr, "pterm: unable to load font \"%s\"\n", inst->cfg.font); + fprintf(stderr, "pterm: unable to load font \"%s\"\n", + inst->cfg.font.name); exit(1); } font_charset = set_font_info(inst, 0); - if (inst->cfg.boldfont[0]) { - inst->fonts[1] = gdk_font_load(inst->cfg.boldfont); + if (inst->cfg.boldfont.name[0]) { + inst->fonts[1] = gdk_font_load(inst->cfg.boldfont.name); if (!inst->fonts[1]) { fprintf(stderr, "pterm: unable to load bold font \"%s\"\n", - inst->cfg.boldfont); + inst->cfg.boldfont.name); exit(1); } set_font_info(inst, 1); } else inst->fonts[1] = NULL; - if (inst->cfg.widefont[0]) { - inst->fonts[2] = gdk_font_load(inst->cfg.widefont); + if (inst->cfg.widefont.name[0]) { + inst->fonts[2] = gdk_font_load(inst->cfg.widefont.name); if (!inst->fonts[2]) { fprintf(stderr, "pterm: unable to load wide font \"%s\"\n", - inst->cfg.boldfont); + inst->cfg.widefont.name); exit(1); } set_font_info(inst, 2); } else inst->fonts[2] = NULL; - if (inst->cfg.wideboldfont[0]) { - inst->fonts[3] = gdk_font_load(inst->cfg.wideboldfont); + if (inst->cfg.wideboldfont.name[0]) { + inst->fonts[3] = gdk_font_load(inst->cfg.wideboldfont.name); if (!inst->fonts[3]) { fprintf(stderr, "pterm: unable to load wide/bold font \"%s\"\n", - inst->cfg.boldfont); + inst->cfg.wideboldfont.name); exit(1); } set_font_info(inst, 3); diff --git a/unix/unix.h b/unix/unix.h index abe8cfd3..e821cd49 100644 --- a/unix/unix.h +++ b/unix/unix.h @@ -1,8 +1,18 @@ #ifndef PUTTY_UNIX_H #define PUTTY_UNIX_H +#include /* for FILENAME_MAX */ #include "charset.h" +struct Filename { + char path[FILENAME_MAX]; +}; +#define f_open(filename, mode) ( fopen((filename).path, (mode)) ) + +struct FontSpec { + char name[256]; +}; + typedef void *Context; /* FIXME: probably needs changing */ extern Backend pty_backend; diff --git a/unix/uxcons.c b/unix/uxcons.c index c172b0a3..2375a63e 100644 --- a/unix/uxcons.c +++ b/unix/uxcons.c @@ -184,7 +184,7 @@ void askcipher(void *frontend, char *ciphername, int cs) * 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, char *filename) +int askappend(void *frontend, Filename filename) { static const char msgtemplate[] = "The session log file \"%.*s\" already exists.\n" @@ -202,11 +202,11 @@ int askappend(void *frontend, char *filename) char line[32]; if (console_batch_mode) { - fprintf(stderr, msgtemplate_batch, FILENAME_MAX, filename); + fprintf(stderr, msgtemplate_batch, FILENAME_MAX, filename.path); fflush(stderr); return 0; } - fprintf(stderr, msgtemplate, FILENAME_MAX, filename); + fprintf(stderr, msgtemplate, FILENAME_MAX, filename.path); fflush(stderr); { diff --git a/unix/uxmisc.c b/unix/uxmisc.c index 76401ea1..39ef7edd 100644 --- a/unix/uxmisc.c +++ b/unix/uxmisc.c @@ -5,6 +5,8 @@ #include #include +#include "putty.h" + unsigned long getticks(void) { struct timeval tv; @@ -15,3 +17,26 @@ unsigned long getticks(void) */ return tv.tv_sec * 1000000 + tv.tv_usec; } + +Filename filename_from_str(char *str) +{ + Filename ret; + strncpy(ret.path, str, sizeof(ret.path)); + ret.path[sizeof(ret.path)-1] = '\0'; + return ret; +} + +char *filename_to_str(Filename fn) +{ + return fn.path; +} + +int filename_equal(Filename f1, Filename f2) +{ + return !strcmp(f1.path, f2.path); +} + +int filename_is_null(Filename fn) +{ + return !*fn.path; +} diff --git a/unix/uxplink.c b/unix/uxplink.c index 2778bc5a..7448f26d 100644 --- a/unix/uxplink.c +++ b/unix/uxplink.c @@ -136,6 +136,23 @@ int platform_default_i(const char *name, int def) return def; } +FontSpec platform_default_fontspec(const char *name) +{ + FontSpec ret; + *ret.name = '\0'; + return ret; +} + +Filename platform_default_filename(const char *name) +{ + Filename ret; + if (!strcmp(name, "LogFileName")) + strcpy(ret.path, "putty.log"); + else + *ret.path = '\0'; + return ret; +} + char *x_get_default(const char *key) { return NULL; /* this is a stub */ diff --git a/unix/uxstore.c b/unix/uxstore.c index 10e33c08..6035113b 100644 --- a/unix/uxstore.c +++ b/unix/uxstore.c @@ -134,6 +134,24 @@ int read_setting_i(void *handle, const char *key, int defvalue) return atoi(val); } +int read_setting_fontspec(void *handle, const char *name, FontSpec *result) +{ + return !!read_setting_s(handle, name, result->name, sizeof(result->name)); +} +int read_setting_filename(void *handle, const char *name, Filename *result) +{ + return !!read_setting_s(handle, name, result->path, sizeof(result->path)); +} + +void write_setting_fontspec(void *handle, const char *name, FontSpec result) +{ + write_setting_s(handle, name, result.name); +} +void write_setting_filename(void *handle, const char *name, Filename result) +{ + write_setting_s(handle, name, result.path); +} + void close_settings_r(void *handle) { } diff --git a/windefs.c b/windefs.c index 80e186d1..6c65c205 100644 --- a/windefs.c +++ b/windefs.c @@ -10,16 +10,36 @@ #include "putty.h" +FontSpec platform_default_fontspec(const char *name) +{ + FontSpec ret; + if (!strcmp(name, "Font")) { + strcpy(ret.name, "Courier New"); + ret.isbold = 0; + ret.charset = ANSI_CHARSET; + ret.height = 10; + } else { + ret.name[0] = '\0'; + } + return ret; +} + +Filename platform_default_filename(const char *name) +{ + Filename ret; + if (!strcmp(name, "LogFileName")) + strcpy(ret.path, "putty.log"); + else + *ret.path = '\0'; + return ret; +} + char *platform_default_s(const char *name) { - if (!strcmp(name, "Font")) - return "Courier New"; return NULL; } int platform_default_i(const char *name, int def) { - if (!strcmp(name, "FontCharSet")) - return ANSI_CHARSET; return def; } diff --git a/windlg.c b/windlg.c index fd722886..944cfda9 100644 --- a/windlg.c +++ b/windlg.c @@ -660,14 +660,14 @@ static const char *const colours[] = { static void fmtfont(char *buf) { - sprintf(buf, "Font: %s, ", cfg.font); - if (cfg.fontisbold) + sprintf(buf, "Font: %s, ", cfg.font.name); + if (cfg.font.isbold) strcat(buf, "bold, "); - if (cfg.fontheight == 0) + if (cfg.font.height == 0) strcat(buf, "default height"); else sprintf(buf + strlen(buf), "%d-point", - (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight)); + (cfg.font.height < 0 ? -cfg.font.height : cfg.font.height)); } char *help_context_cmd(int id) @@ -1161,7 +1161,7 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess) B_IND_DISABLED ? IDC_B_IND_DISABLED : cfg.beep_ind == B_IND_FLASH ? IDC_B_IND_FLASH : cfg.beep_ind == B_IND_STEADY ? IDC_B_IND_STEADY : IDC_B_IND_DISABLED); - SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT, cfg.bell_wavefile); + SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT, cfg.bell_wavefile.path); CheckDlgButton(hwnd, IDC_BELLOVL, cfg.bellovl); SetDlgItemInt(hwnd, IDC_BELLOVLN, cfg.bellovl_n, FALSE); MySetDlgItemFlt(hwnd, IDC_BELLOVLT, cfg.bellovl_t / 1000.0); @@ -1197,7 +1197,7 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess) SetDlgItemText(hwnd, IDC_R_TSEDIT, cfg.termspeed); SetDlgItemText(hwnd, IDC_RLLUSEREDIT, cfg.localusername); SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username); - SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename); + SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename.path); CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATPACKET, cfg.logtype == LGTYP_NONE ? IDC_LSTATOFF : cfg.logtype == LGTYP_ASCII ? IDC_LSTATASCII : @@ -1240,7 +1240,7 @@ static void init_dlg_ctrls(HWND hwnd, int keepsess) cfg.sshprot == 3 ? IDC_SSHPROT2ONLY : IDC_SSHPROT1ONLY); CheckDlgButton(hwnd, IDC_AUTHTIS, cfg.try_tis_auth); CheckDlgButton(hwnd, IDC_AUTHKI, cfg.try_ki_auth); - SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile); + SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile.path); SetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd); { @@ -2116,7 +2116,7 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, struct treeview_faff tvfaff; HTREEITEM hsession; OPENFILENAME of; - char filename[sizeof(cfg.keyfile)]; + char filename[sizeof(cfg.keyfile.path)]; CHOOSEFONT cf; LOGFONT lf; char fontstatic[256]; @@ -2777,20 +2777,20 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, case IDC_CHOOSEFONT: { HDC hdc = GetDC(0); - lf.lfHeight = -MulDiv(cfg.fontheight, + lf.lfHeight = -MulDiv(cfg.font.height, GetDeviceCaps(hdc, LOGPIXELSY), 72); ReleaseDC(0, hdc); } lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0; lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0; - lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0); - lf.lfCharSet = cfg.fontcharset; + lf.lfWeight = (cfg.font.isbold ? FW_BOLD : 0); + lf.lfCharSet = cfg.font.charset; lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = DEFAULT_QUALITY; lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE; - strncpy(lf.lfFaceName, cfg.font, + strncpy(lf.lfFaceName, cfg.font.name, sizeof(lf.lfFaceName) - 1); lf.lfFaceName[sizeof(lf.lfFaceName) - 1] = '\0'; @@ -2801,11 +2801,12 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS; if (ChooseFont(&cf)) { - strncpy(cfg.font, lf.lfFaceName, sizeof(cfg.font) - 1); - cfg.font[sizeof(cfg.font) - 1] = '\0'; - cfg.fontisbold = (lf.lfWeight == FW_BOLD); - cfg.fontcharset = lf.lfCharSet; - cfg.fontheight = cf.iPointSize / 10; + strncpy(cfg.font.name, lf.lfFaceName, + sizeof(cfg.font.name) - 1); + cfg.font.name[sizeof(cfg.font.name) - 1] = '\0'; + cfg.font.isbold = (lf.lfWeight == FW_BOLD); + cfg.font.charset = lf.lfCharSet; + cfg.font.height = cf.iPointSize / 10; fmtfont(fontstatic); SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic); } @@ -2852,23 +2853,23 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, of.lpstrCustomFilter = NULL; of.nFilterIndex = 1; of.lpstrFile = filename; - strcpy(filename, cfg.bell_wavefile); + strcpy(filename, cfg.bell_wavefile.path); of.nMaxFile = sizeof(filename); of.lpstrFileTitle = NULL; of.lpstrInitialDir = NULL; of.lpstrTitle = "Select Bell Sound File"; of.Flags = 0; if (GetOpenFileName(&of)) { - strcpy(cfg.bell_wavefile, filename); + strcpy(cfg.bell_wavefile.path, filename); SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT, - cfg.bell_wavefile); + cfg.bell_wavefile.path); } break; case IDC_BELL_WAVEEDIT: if (HIWORD(wParam) == EN_CHANGE) GetDlgItemText(hwnd, IDC_BELL_WAVEEDIT, - cfg.bell_wavefile, - sizeof(cfg.bell_wavefile) - 1); + cfg.bell_wavefile.path, + sizeof(cfg.bell_wavefile.path) - 1); break; case IDC_BELLOVL: if (HIWORD(wParam) == BN_CLICKED || @@ -3090,8 +3091,8 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, case IDC_LGFEDIT: if (HIWORD(wParam) == EN_CHANGE) - GetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename, - sizeof(cfg.logfilename) - 1); + GetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename.path, + sizeof(cfg.logfilename.path) - 1); break; case IDC_LGFBUTTON: memset(&of, 0, sizeof(of)); @@ -3105,15 +3106,15 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, of.lpstrCustomFilter = NULL; of.nFilterIndex = 1; of.lpstrFile = filename; - strcpy(filename, cfg.logfilename); + strcpy(filename, cfg.logfilename.path); of.nMaxFile = sizeof(filename); of.lpstrFileTitle = NULL; of.lpstrInitialDir = NULL; of.lpstrTitle = "Select session log file"; of.Flags = 0; if (GetSaveFileName(&of)) { - strcpy(cfg.logfilename, filename); - SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename); + strcpy(cfg.logfilename.path, filename); + SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename.path); } break; case IDC_LSTATOFF: @@ -3313,8 +3314,8 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, break; case IDC_PKEDIT: if (HIWORD(wParam) == EN_CHANGE) - GetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile, - sizeof(cfg.keyfile) - 1); + GetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile.path, + sizeof(cfg.keyfile.path) - 1); break; case IDC_CMDEDIT: if (HIWORD(wParam) == EN_CHANGE) @@ -3334,15 +3335,15 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg, of.lpstrCustomFilter = NULL; of.nFilterIndex = 1; of.lpstrFile = filename; - strcpy(filename, cfg.keyfile); + strcpy(filename, cfg.keyfile.path); of.nMaxFile = sizeof(filename); of.lpstrFileTitle = NULL; of.lpstrInitialDir = NULL; of.lpstrTitle = "Select Private Key File"; of.Flags = 0; if (GetOpenFileName(&of)) { - strcpy(cfg.keyfile, filename); - SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile); + strcpy(cfg.keyfile.path, filename); + SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile.path); } break; case IDC_RAWCNP: @@ -3941,7 +3942,7 @@ void askcipher(void *frontend, char *ciphername, int cs) * 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, char *filename) +int askappend(void *frontend, Filename filename) { static const char mbtitle[] = "PuTTY Log to File"; static const char msgtemplate[] = @@ -3954,7 +3955,7 @@ int askappend(void *frontend, char *filename) char message[sizeof(msgtemplate) + FILENAME_MAX]; int mbret; - sprintf(message, msgtemplate, FILENAME_MAX, filename); + sprintf(message, msgtemplate, FILENAME_MAX, filename.path); mbret = MessageBox(NULL, message, mbtitle, MB_ICONQUESTION | MB_YESNOCANCEL); diff --git a/window.c b/window.c index b1fb5fee..effa2deb 100644 --- a/window.c +++ b/window.c @@ -1062,7 +1062,7 @@ static void init_fonts(int pick_width, int pick_height) bold_mode = cfg.bold_colour ? BOLD_COLOURS : BOLD_FONT; und_mode = UND_FONT; - if (cfg.fontisbold) { + if (cfg.font.isbold) { fw_dontcare = FW_BOLD; fw_bold = FW_HEAVY; } else { @@ -1075,7 +1075,7 @@ static void init_fonts(int pick_width, int pick_height) if (pick_height) font_height = pick_height; else { - font_height = cfg.fontheight; + font_height = cfg.font.height; if (font_height > 0) { font_height = -MulDiv(font_height, GetDeviceCaps(hdc, LOGPIXELSY), 72); @@ -1087,9 +1087,9 @@ static void init_fonts(int pick_width, int pick_height) fonts[i] = CreateFont (font_height, font_width, 0, 0, w, FALSE, u, FALSE, \ c, OUT_DEFAULT_PRECIS, \ CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, \ - FIXED_PITCH | FF_DONTCARE, cfg.font) + FIXED_PITCH | FF_DONTCARE, cfg.font.name) - f(FONT_NORMAL, cfg.fontcharset, fw_dontcare, FALSE); + f(FONT_NORMAL, cfg.font.charset, fw_dontcare, FALSE); lfont.lfHeight = font_height; lfont.lfWidth = font_width; @@ -1099,12 +1099,12 @@ static void init_fonts(int pick_width, int pick_height) lfont.lfItalic = FALSE; lfont.lfUnderline = FALSE; lfont.lfStrikeOut = FALSE; - lfont.lfCharSet = cfg.fontcharset; + lfont.lfCharSet = cfg.font.charset; lfont.lfOutPrecision = OUT_DEFAULT_PRECIS; lfont.lfClipPrecision = CLIP_DEFAULT_PRECIS; lfont.lfQuality = DEFAULT_QUALITY; lfont.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE; - strncpy(lfont.lfFaceName, cfg.font, LF_FACESIZE); + strncpy(lfont.lfFaceName, cfg.font.name, LF_FACESIZE); SelectObject(hdc, fonts[FONT_NORMAL]); GetTextMetrics(hdc, &tm); @@ -1138,7 +1138,7 @@ static void init_fonts(int pick_width, int pick_height) ucsdata.dbcs_screenfont = (cpinfo.MaxCharSize > 1); } - f(FONT_UNDERLINE, cfg.fontcharset, fw_dontcare, TRUE); + f(FONT_UNDERLINE, cfg.font.charset, fw_dontcare, TRUE); /* * Some fonts, e.g. 9-pt Courier, draw their underlines @@ -1189,7 +1189,7 @@ static void init_fonts(int pick_width, int pick_height) } if (bold_mode == BOLD_FONT) { - f(FONT_BOLD, cfg.fontcharset, fw_bold, FALSE); + f(FONT_BOLD, cfg.font.charset, fw_bold, FALSE); } #undef f @@ -1240,7 +1240,7 @@ static void another_font(int fontno) if (basefont != fontno && !fontflag[basefont]) another_font(basefont); - if (cfg.fontisbold) { + if (cfg.font.isbold) { fw_dontcare = FW_BOLD; fw_bold = FW_HEAVY; } else { @@ -1248,10 +1248,10 @@ static void another_font(int fontno) fw_bold = FW_BOLD; } - c = cfg.fontcharset; + c = cfg.font.charset; w = fw_dontcare; u = FALSE; - s = cfg.font; + s = cfg.font.name; x = font_width; if (fontno & FONT_WIDE) @@ -1878,11 +1878,11 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, icon_name); } - if (strcmp(cfg.font, prev_cfg.font) != 0 || + if (strcmp(cfg.font.name, prev_cfg.font.name) != 0 || strcmp(cfg.line_codepage, prev_cfg.line_codepage) != 0 || - cfg.fontisbold != prev_cfg.fontisbold || - cfg.fontheight != prev_cfg.fontheight || - cfg.fontcharset != prev_cfg.fontcharset || + cfg.font.isbold != prev_cfg.font.isbold || + cfg.font.height != prev_cfg.font.height || + cfg.font.charset != prev_cfg.font.charset || cfg.vtmode != prev_cfg.vtmode || cfg.bold_colour != prev_cfg.bold_colour || cfg.resize_action == RESIZE_DISABLED || @@ -4099,10 +4099,10 @@ void write_clip(void *frontend, wchar_t * data, int len, int must_deselect) get_unitab(CP_ACP, unitab, 0); - rtfsize = 100 + strlen(cfg.font); + rtfsize = 100 + strlen(cfg.font.name); rtf = smalloc(rtfsize); sprintf(rtf, "{\\rtf1\\ansi%d{\\fonttbl\\f0\\fmodern %s;}\\f0", - GetACP(), cfg.font); + GetACP(), cfg.font.name); rtflen = strlen(rtf); /* @@ -4378,7 +4378,8 @@ void beep(void *frontend, int mode) */ lastbeep = GetTickCount(); } else if (mode == BELL_WAVEFILE) { - if (!PlaySound(cfg.bell_wavefile, NULL, SND_ASYNC | SND_FILENAME)) { + if (!PlaySound(cfg.bell_wavefile.path, NULL, + SND_ASYNC | SND_FILENAME)) { char buf[sizeof(cfg.bell_wavefile) + 80]; sprintf(buf, "Unable to play sound file\n%s\n" "Using default sound instead", cfg.bell_wavefile); diff --git a/winmisc.c b/winmisc.c index a4f666eb..92609186 100644 --- a/winmisc.c +++ b/winmisc.c @@ -12,3 +12,26 @@ void platform_get_x11_auth(char *display, int *proto, { /* We don't support this at all under Windows. */ } + +Filename filename_from_str(char *str) +{ + Filename ret; + strncpy(ret.path, str, sizeof(ret.path)); + ret.path[sizeof(ret.path)-1] = '\0'; + return ret; +} + +char *filename_to_str(Filename fn) +{ + return fn.path; +} + +int filename_equal(Filename f1, Filename f2) +{ + return !strcmp(f1.path, f2.path); +} + +int filename_is_null(Filename fn) +{ + return !*fn.path; +} diff --git a/winstore.c b/winstore.c index 3199c1cd..a69d58d0 100644 --- a/winstore.c +++ b/winstore.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "putty.h" #include "storage.h" @@ -150,6 +151,67 @@ int read_setting_i(void *handle, const char *key, int defvalue) return val; } +int read_setting_fontspec(void *handle, const char *name, FontSpec *result) +{ + char *settingname; + FontSpec ret; + + if (!read_setting_s(handle, name, ret.name, sizeof(ret.name))) + return 0; + settingname = dupcat(name, "IsBold", NULL); + ret.isbold = read_setting_i(handle, settingname, -1); + sfree(settingname); + if (ret.isbold == -1) return 0; + settingname = dupcat(name, "CharSet", NULL); + ret.charset = read_setting_i(handle, settingname, -1); + sfree(settingname); + if (ret.charset == -1) return 0; + settingname = dupcat(name, "Height", NULL); + ret.height = read_setting_i(handle, settingname, INT_MIN); + sfree(settingname); + if (ret.height == INT_MIN) return 0; + if (ret.height < 0) { + int oldh, newh; + HDC hdc = GetDC(NULL); + int logpix = GetDeviceCaps(hdc, LOGPIXELSY); + ReleaseDC(NULL, hdc); + + oldh = -ret.height; + newh = MulDiv(oldh, 72, logpix) + 1; + if (MulDiv(newh, logpix, 72) > oldh) + newh--; + ret.height = newh; + } + *result = ret; + return 1; +} + +void write_setting_fontspec(void *handle, const char *name, FontSpec font) +{ + char *settingname; + + write_setting_s(handle, name, font.name); + settingname = dupcat(name, "IsBold", NULL); + write_setting_i(handle, settingname, font.isbold); + sfree(settingname); + settingname = dupcat(name, "CharSet", NULL); + write_setting_i(handle, settingname, font.charset); + sfree(settingname); + settingname = dupcat(name, "Height", NULL); + write_setting_i(handle, settingname, font.height); + sfree(settingname); +} + +int read_setting_filename(void *handle, const char *name, Filename *result) +{ + return !!read_setting_s(handle, name, result->path, sizeof(result->path)); +} + +void write_setting_filename(void *handle, const char *name, Filename result) +{ + write_setting_s(handle, name, result.path); +} + void close_settings_r(void *handle) { RegCloseKey((HKEY) handle); diff --git a/winstuff.h b/winstuff.h index 1aa68bb7..1cbe5b78 100644 --- a/winstuff.h +++ b/winstuff.h @@ -5,6 +5,20 @@ #ifndef PUTTY_WINSTUFF_H #define PUTTY_WINSTUFF_H +#include /* for FILENAME_MAX */ + +struct Filename { + char path[FILENAME_MAX]; +}; +#define f_open(filename, mode) ( fopen((filename).path, (mode)) ) + +struct FontSpec { + char name[64]; + int isbold; + int height; + int charset; +}; + /* * Global variables. Most modules declare these `extern', but * window.c will do `#define PUTTY_DO_GLOBALS' before including this