# 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.
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
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 */
* 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;
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);
#include <assert.h>
#include <ctype.h>
+#include "putty.h"
#include "ssh.h"
#include "misc.h"
((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.
/*
* 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) {
/*
* 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;
}
/*
* 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);
/*
* 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;
}
/*
* 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)
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;
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;
return NULL;
}
-int openssh_encrypted(char *filename)
+int openssh_encrypted(const Filename *filename)
{
struct openssh_key *key = load_openssh_key(filename);
int ret;
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;
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;
* 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);
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;
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;
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;
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;
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;
* 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);
/* 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.
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);
}
}
- 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);
ctx->cfg.logtype == LGTYP_DEBUG ? "raw" :
ctx->cfg.logtype == LGTYP_PACKETS ? "SSH packets" : "<ukwn>"));
/* 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);
}
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
*
* "&Y":YYYY "&m":MM "&d":DD "&T":hhmm "&h":<hostname> "&&":&
*/
-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. */
len -= size;
}
*d = '\0';
+
+ *dest = filename_from_str(s);
}
-/* $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.
}
-char *platform_default_s(char const *name)
+FontSpec platform_default_font(char const *name)
{
+ FontSpec ret;
long smfs;
Str255 pname;
static char cname[256];
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;
}
{
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
/* 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"
#include <Palettes.h>
#include <UnicodeConverter.h>
+#include <stdio.h> /* 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')
-/* $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
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;
-/* $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
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;
&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');
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);
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;
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;
* 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. */
#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, ...);
#include <assert.h>
#include <tchar.h>
+#include "putty.h"
#include "ssh.h"
#include "misc.h"
#include "tree234.h"
/*
* 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;
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));
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;
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);
}
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));
} 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)
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
memcpy(filename + dirlen, filewalker, n);
filewalker += n;
- add_keyfile(filename);
+ add_keyfile(filename_from_str(filename));
}
}
command = "";
break;
} else {
- add_keyfile(argv[i]);
+ add_keyfile(filename_from_str(argv[i]));
added_keys = TRUE;
}
}
#ifndef PUTTY_PUTTY_H
#define PUTTY_PUTTY_H
-#include <stdio.h> /* for FILENAME_MAX */
#include <stddef.h> /* for wchar_t */
/*
#include "puttyps.h"
#include "network.h"
+#include "misc.h"
/* Three attribute types:
* The ATTRs (normal attributes) are stored with the characters in
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;
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;
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;
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;
};
* (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.
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
};
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
}
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;
struct RSAKey newkey1;
struct ssh2_userkey *newkey2 = NULL;
- type = realtype = key_type(filename);
+ type = realtype = key_type(&filename);
if (type != SSH_KEYTYPE_SSH1 &&
type != SSH_KEYTYPE_SSH2 &&
!import_possible(type)) {
comment = NULL;
if (realtype == SSH_KEYTYPE_SSH1)
- needs_pass = rsakey_encrypted(filename, &comment);
+ needs_pass = rsakey_encrypted(&filename, &comment);
else if (realtype == SSH_KEYTYPE_SSH2)
needs_pass =
- ssh2_userkey_encrypted(filename, &comment);
+ 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;
*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;
* 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:
}
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) {
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;
}
}
+/*
+ * 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);
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);
}
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);
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);
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);
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);
}
} 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);
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);
/* 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);
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);
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);
}
}
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
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 &&
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));
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;
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 */
}
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;
* 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) {
* 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);
*/
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");
#include "puttymem.h"
#include "network.h"
#include "int64.h"
+#include "misc.h"
struct ssh_channel;
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);
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 {
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);
#include <stdlib.h>
#include <assert.h>
+#include "putty.h"
#include "ssh.h"
#include "misc.h"
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 */
* 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 */
* 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];
*bloblen = 0;
ret = 0;
- fp = fopen(filename, "rb");
+ fp = f_open(*filename, "rb");
if (!fp)
return 0; /* doesn't even exist */
/*
* 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];
/*
* 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);
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;
comment = mac = NULL;
public_blob = private_blob = NULL;
- fp = fopen(filename, "rb");
+ fp = f_open(*filename, "rb");
if (!fp)
goto error;
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;
public_blob = NULL;
- fp = fopen(filename, "rb");
+ fp = f_open(*filename, "rb");
if (!fp)
goto error;
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;
if (commentptr)
*commentptr = NULL;
- fp = fopen(filename, "rb");
+ fp = f_open(*filename, "rb");
if (!fp)
return 0;
if (!read_header(fp, header)
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;
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);
* 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];
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);
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);
/*
* 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);
/*
/*
* Default settings that are specific to pterm.
*/
-char *platform_default_s(const char *name)
+FontSpec platform_default_fontspec(const char *name)
{
+ FontSpec ret;
if (!strcmp(name, "Font"))
- return "fixed";
+ 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)
+{
return NULL;
}
*/
}
-int askappend(void *frontend, char *filename)
+int askappend(void *frontend, Filename filename)
{
/*
* Logging in an xterm-alike is liable to be something you only
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;
} 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")) {
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);
#ifndef PUTTY_UNIX_H
#define PUTTY_UNIX_H
+#include <stdio.h> /* 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;
* 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"
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);
{
#include <stdio.h>
#include <sys/time.h>
+#include "putty.h"
+
unsigned long getticks(void)
{
struct timeval tv;
*/
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;
+}
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 */
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)
{
}
#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;
}
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)
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);
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 :
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);
{
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];
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';
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);
}
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 ||
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));
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:
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)
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:
* 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[] =
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);
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 {
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);
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;
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);
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
}
if (bold_mode == BOLD_FONT) {
- f(FONT_BOLD, cfg.fontcharset, fw_bold, FALSE);
+ f(FONT_BOLD, cfg.font.charset, fw_bold, FALSE);
}
#undef f
if (basefont != fontno && !fontflag[basefont])
another_font(basefont);
- if (cfg.fontisbold) {
+ if (cfg.font.isbold) {
fw_dontcare = FW_BOLD;
fw_bold = FW_HEAVY;
} else {
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)
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 ||
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);
/*
*/
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);
{
/* 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;
+}
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
+#include <limits.h>
#include "putty.h"
#include "storage.h"
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);
#ifndef PUTTY_WINSTUFF_H
#define PUTTY_WINSTUFF_H
+#include <stdio.h> /* 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