2006-04-23 22:26:03 +04:00
|
|
|
/*
|
|
|
|
* Session logging.
|
|
|
|
*/
|
|
|
|
|
2001-12-14 17:57:50 +03:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
|
|
|
|
#include <time.h>
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
#include "putty.h"
|
|
|
|
|
|
|
|
/* log session to file stuff ... */
|
2002-10-26 16:58:13 +04:00
|
|
|
struct LogContext {
|
|
|
|
FILE *lgfp;
|
2005-02-19 01:03:15 +03:00
|
|
|
enum { L_CLOSED, L_OPENING, L_OPEN, L_ERROR } state;
|
2005-02-18 21:33:31 +03:00
|
|
|
bufchain queue;
|
2011-10-02 15:01:57 +04:00
|
|
|
Filename *currlogfilename;
|
2002-10-26 16:58:13 +04:00
|
|
|
void *frontend;
|
Post-release destabilisation! Completely remove the struct type
'Config' in putty.h, which stores all PuTTY's settings and includes an
arbitrary length limit on every single one of those settings which is
stored in string form. In place of it is 'Conf', an opaque data type
everywhere outside the new file conf.c, which stores a list of (key,
value) pairs in which every key contains an integer identifying a
configuration setting, and for some of those integers the key also
contains extra parts (so that, for instance, CONF_environmt is a
string-to-string mapping). Everywhere that a Config was previously
used, a Conf is now; everywhere there was a Config structure copy,
conf_copy() is called; every lookup, adjustment, load and save
operation on a Config has been rewritten; and there's a mechanism for
serialising a Conf into a binary blob and back for use with Duplicate
Session.
User-visible effects of this change _should_ be minimal, though I
don't doubt I've introduced one or two bugs here and there which will
eventually be found. The _intended_ visible effects of this change are
that all arbitrary limits on configuration strings and lists (e.g.
limit on number of port forwardings) should now disappear; that list
boxes in the configuration will now be displayed in a sorted order
rather than the arbitrary order in which they were added to the list
(since the underlying data structure is now a sorted tree234 rather
than an ad-hoc comma-separated string); and one more specific change,
which is that local and dynamic port forwardings on the same port
number are now mutually exclusive in the configuration (putting 'D' in
the key rather than the value was a mistake in the first place).
One other reorganisation as a result of this is that I've moved all
the dialog.c standard handlers (dlg_stdeditbox_handler and friends)
out into config.c, because I can't really justify calling them generic
any more. When they took a pointer to an arbitrary structure type and
the offset of a field within that structure, they were independent of
whether that structure was a Config or something completely different,
but now they really do expect to talk to a Conf, which can _only_ be
used for PuTTY configuration, so I've renamed them all things like
conf_editbox_handler and moved them out of the nominally independent
dialog-box management module into the PuTTY-specific config.c.
[originally from svn r9214]
2011-07-14 22:52:21 +04:00
|
|
|
Conf *conf;
|
|
|
|
int logtype; /* cached out of conf */
|
2002-10-26 16:58:13 +04:00
|
|
|
};
|
2001-12-14 17:57:50 +03:00
|
|
|
|
2011-10-02 15:01:57 +04:00
|
|
|
static Filename *xlatlognam(Filename *s, char *hostname, struct tm *tm);
|
2001-12-14 17:57:50 +03:00
|
|
|
|
|
|
|
/*
|
2005-02-18 21:33:31 +03:00
|
|
|
* Internal wrapper function which must be called for _all_ output
|
|
|
|
* to the log file. It takes care of opening the log file if it
|
|
|
|
* isn't open, buffering data if it's in the process of being
|
|
|
|
* opened asynchronously, etc.
|
2001-12-14 17:57:50 +03:00
|
|
|
*/
|
2005-02-18 21:33:31 +03:00
|
|
|
static void logwrite(struct LogContext *ctx, void *data, int len)
|
2001-12-14 17:57:50 +03:00
|
|
|
{
|
2005-02-18 21:33:31 +03:00
|
|
|
/*
|
2005-02-19 01:03:15 +03:00
|
|
|
* In state L_CLOSED, we call logfopen, which will set the state
|
|
|
|
* to one of L_OPENING, L_OPEN or L_ERROR. Hence we process all of
|
|
|
|
* those three _after_ processing L_CLOSED.
|
2005-02-18 21:33:31 +03:00
|
|
|
*/
|
2005-02-19 01:03:15 +03:00
|
|
|
if (ctx->state == L_CLOSED)
|
2005-02-18 21:33:31 +03:00
|
|
|
logfopen(ctx);
|
|
|
|
|
2005-02-19 01:03:15 +03:00
|
|
|
if (ctx->state == L_OPENING) {
|
2005-02-18 21:33:31 +03:00
|
|
|
bufchain_add(&ctx->queue, data, len);
|
2005-02-19 01:03:15 +03:00
|
|
|
} else if (ctx->state == L_OPEN) {
|
2005-02-18 21:33:31 +03:00
|
|
|
assert(ctx->lgfp);
|
2011-07-12 22:13:33 +04:00
|
|
|
if (fwrite(data, 1, len, ctx->lgfp) < (size_t)len) {
|
2009-08-07 04:19:04 +04:00
|
|
|
logfclose(ctx);
|
|
|
|
ctx->state = L_ERROR;
|
2009-08-30 15:09:22 +04:00
|
|
|
/* Log state is L_ERROR so this won't cause a loop */
|
|
|
|
logevent(ctx->frontend,
|
|
|
|
"Disabled writing session log due to error while writing");
|
2009-08-07 04:19:04 +04:00
|
|
|
}
|
2005-02-19 01:03:15 +03:00
|
|
|
} /* else L_ERROR, so ignore the write */
|
2005-02-18 21:33:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Convenience wrapper on logwrite() which printf-formats the
|
|
|
|
* string.
|
|
|
|
*/
|
|
|
|
static void logprintf(struct LogContext *ctx, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
char *data;
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
data = dupvprintf(fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
logwrite(ctx, data, strlen(data));
|
|
|
|
sfree(data);
|
2001-12-14 17:57:50 +03:00
|
|
|
}
|
|
|
|
|
2004-08-12 05:02:01 +04:00
|
|
|
/*
|
|
|
|
* Flush any open log file.
|
|
|
|
*/
|
|
|
|
void logflush(void *handle) {
|
|
|
|
struct LogContext *ctx = (struct LogContext *)handle;
|
Post-release destabilisation! Completely remove the struct type
'Config' in putty.h, which stores all PuTTY's settings and includes an
arbitrary length limit on every single one of those settings which is
stored in string form. In place of it is 'Conf', an opaque data type
everywhere outside the new file conf.c, which stores a list of (key,
value) pairs in which every key contains an integer identifying a
configuration setting, and for some of those integers the key also
contains extra parts (so that, for instance, CONF_environmt is a
string-to-string mapping). Everywhere that a Config was previously
used, a Conf is now; everywhere there was a Config structure copy,
conf_copy() is called; every lookup, adjustment, load and save
operation on a Config has been rewritten; and there's a mechanism for
serialising a Conf into a binary blob and back for use with Duplicate
Session.
User-visible effects of this change _should_ be minimal, though I
don't doubt I've introduced one or two bugs here and there which will
eventually be found. The _intended_ visible effects of this change are
that all arbitrary limits on configuration strings and lists (e.g.
limit on number of port forwardings) should now disappear; that list
boxes in the configuration will now be displayed in a sorted order
rather than the arbitrary order in which they were added to the list
(since the underlying data structure is now a sorted tree234 rather
than an ad-hoc comma-separated string); and one more specific change,
which is that local and dynamic port forwardings on the same port
number are now mutually exclusive in the configuration (putting 'D' in
the key rather than the value was a mistake in the first place).
One other reorganisation as a result of this is that I've moved all
the dialog.c standard handlers (dlg_stdeditbox_handler and friends)
out into config.c, because I can't really justify calling them generic
any more. When they took a pointer to an arbitrary structure type and
the offset of a field within that structure, they were independent of
whether that structure was a Config or something completely different,
but now they really do expect to talk to a Conf, which can _only_ be
used for PuTTY configuration, so I've renamed them all things like
conf_editbox_handler and moved them out of the nominally independent
dialog-box management module into the PuTTY-specific config.c.
[originally from svn r9214]
2011-07-14 22:52:21 +04:00
|
|
|
if (ctx->logtype > 0)
|
2005-02-19 01:03:15 +03:00
|
|
|
if (ctx->state == L_OPEN)
|
2004-08-12 05:02:01 +04:00
|
|
|
fflush(ctx->lgfp);
|
|
|
|
}
|
|
|
|
|
2005-02-18 21:33:31 +03:00
|
|
|
static void logfopen_callback(void *handle, int mode)
|
|
|
|
{
|
|
|
|
struct LogContext *ctx = (struct LogContext *)handle;
|
|
|
|
char buf[256], *event;
|
|
|
|
struct tm tm;
|
|
|
|
const char *fmode;
|
|
|
|
|
|
|
|
if (mode == 0) {
|
2005-02-19 01:03:15 +03:00
|
|
|
ctx->state = L_ERROR; /* disable logging */
|
2005-02-18 21:33:31 +03:00
|
|
|
} else {
|
2005-02-19 04:20:16 +03:00
|
|
|
fmode = (mode == 1 ? "ab" : "wb");
|
2009-02-24 01:40:09 +03:00
|
|
|
ctx->lgfp = f_open(ctx->currlogfilename, fmode, FALSE);
|
2005-02-18 21:33:31 +03:00
|
|
|
if (ctx->lgfp)
|
2005-02-19 01:03:15 +03:00
|
|
|
ctx->state = L_OPEN;
|
2005-02-18 21:33:31 +03:00
|
|
|
else
|
2005-02-19 01:03:15 +03:00
|
|
|
ctx->state = L_ERROR;
|
2005-02-18 21:33:31 +03:00
|
|
|
}
|
|
|
|
|
2005-02-19 01:03:15 +03:00
|
|
|
if (ctx->state == L_OPEN) {
|
2005-02-18 21:33:31 +03:00
|
|
|
/* Write header line into log file. */
|
|
|
|
tm = ltime();
|
|
|
|
strftime(buf, 24, "%Y.%m.%d %H:%M:%S", &tm);
|
|
|
|
logprintf(ctx, "=~=~=~=~=~=~=~=~=~=~=~= PuTTY log %s"
|
|
|
|
" =~=~=~=~=~=~=~=~=~=~=~=\r\n", buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
event = dupprintf("%s session log (%s mode) to file: %s",
|
2009-08-30 15:09:22 +04:00
|
|
|
ctx->state == L_ERROR ?
|
|
|
|
(mode == 0 ? "Disabled writing" : "Error writing") :
|
|
|
|
(mode == 1 ? "Appending" : "Writing new"),
|
Post-release destabilisation! Completely remove the struct type
'Config' in putty.h, which stores all PuTTY's settings and includes an
arbitrary length limit on every single one of those settings which is
stored in string form. In place of it is 'Conf', an opaque data type
everywhere outside the new file conf.c, which stores a list of (key,
value) pairs in which every key contains an integer identifying a
configuration setting, and for some of those integers the key also
contains extra parts (so that, for instance, CONF_environmt is a
string-to-string mapping). Everywhere that a Config was previously
used, a Conf is now; everywhere there was a Config structure copy,
conf_copy() is called; every lookup, adjustment, load and save
operation on a Config has been rewritten; and there's a mechanism for
serialising a Conf into a binary blob and back for use with Duplicate
Session.
User-visible effects of this change _should_ be minimal, though I
don't doubt I've introduced one or two bugs here and there which will
eventually be found. The _intended_ visible effects of this change are
that all arbitrary limits on configuration strings and lists (e.g.
limit on number of port forwardings) should now disappear; that list
boxes in the configuration will now be displayed in a sorted order
rather than the arbitrary order in which they were added to the list
(since the underlying data structure is now a sorted tree234 rather
than an ad-hoc comma-separated string); and one more specific change,
which is that local and dynamic port forwardings on the same port
number are now mutually exclusive in the configuration (putting 'D' in
the key rather than the value was a mistake in the first place).
One other reorganisation as a result of this is that I've moved all
the dialog.c standard handlers (dlg_stdeditbox_handler and friends)
out into config.c, because I can't really justify calling them generic
any more. When they took a pointer to an arbitrary structure type and
the offset of a field within that structure, they were independent of
whether that structure was a Config or something completely different,
but now they really do expect to talk to a Conf, which can _only_ be
used for PuTTY configuration, so I've renamed them all things like
conf_editbox_handler and moved them out of the nominally independent
dialog-box management module into the PuTTY-specific config.c.
[originally from svn r9214]
2011-07-14 22:52:21 +04:00
|
|
|
(ctx->logtype == LGTYP_ASCII ? "ASCII" :
|
|
|
|
ctx->logtype == LGTYP_DEBUG ? "raw" :
|
|
|
|
ctx->logtype == LGTYP_PACKETS ? "SSH packets" :
|
|
|
|
ctx->logtype == LGTYP_SSHRAW ? "SSH raw data" :
|
2005-02-18 21:33:31 +03:00
|
|
|
"unknown"),
|
2011-10-02 15:01:57 +04:00
|
|
|
filename_to_str(ctx->currlogfilename));
|
2005-02-18 21:33:31 +03:00
|
|
|
logevent(ctx->frontend, event);
|
|
|
|
sfree(event);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Having either succeeded or failed in opening the log file,
|
|
|
|
* we should write any queued data out.
|
|
|
|
*/
|
2005-02-19 01:03:15 +03:00
|
|
|
assert(ctx->state != L_OPENING); /* make _sure_ it won't be requeued */
|
2005-02-18 21:33:31 +03:00
|
|
|
while (bufchain_size(&ctx->queue)) {
|
|
|
|
void *data;
|
|
|
|
int len;
|
|
|
|
bufchain_prefix(&ctx->queue, &data, &len);
|
|
|
|
logwrite(ctx, data, len);
|
|
|
|
bufchain_consume(&ctx->queue, len);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Open the log file. Takes care of detecting an already-existing
|
|
|
|
* file and asking the user whether they want to append, overwrite
|
|
|
|
* or cancel logging.
|
|
|
|
*/
|
|
|
|
void logfopen(void *handle)
|
|
|
|
{
|
|
|
|
struct LogContext *ctx = (struct LogContext *)handle;
|
|
|
|
struct tm tm;
|
|
|
|
int mode;
|
|
|
|
|
|
|
|
/* Prevent repeat calls */
|
2005-02-19 01:03:15 +03:00
|
|
|
if (ctx->state != L_CLOSED)
|
2005-02-18 21:33:31 +03:00
|
|
|
return;
|
|
|
|
|
Post-release destabilisation! Completely remove the struct type
'Config' in putty.h, which stores all PuTTY's settings and includes an
arbitrary length limit on every single one of those settings which is
stored in string form. In place of it is 'Conf', an opaque data type
everywhere outside the new file conf.c, which stores a list of (key,
value) pairs in which every key contains an integer identifying a
configuration setting, and for some of those integers the key also
contains extra parts (so that, for instance, CONF_environmt is a
string-to-string mapping). Everywhere that a Config was previously
used, a Conf is now; everywhere there was a Config structure copy,
conf_copy() is called; every lookup, adjustment, load and save
operation on a Config has been rewritten; and there's a mechanism for
serialising a Conf into a binary blob and back for use with Duplicate
Session.
User-visible effects of this change _should_ be minimal, though I
don't doubt I've introduced one or two bugs here and there which will
eventually be found. The _intended_ visible effects of this change are
that all arbitrary limits on configuration strings and lists (e.g.
limit on number of port forwardings) should now disappear; that list
boxes in the configuration will now be displayed in a sorted order
rather than the arbitrary order in which they were added to the list
(since the underlying data structure is now a sorted tree234 rather
than an ad-hoc comma-separated string); and one more specific change,
which is that local and dynamic port forwardings on the same port
number are now mutually exclusive in the configuration (putting 'D' in
the key rather than the value was a mistake in the first place).
One other reorganisation as a result of this is that I've moved all
the dialog.c standard handlers (dlg_stdeditbox_handler and friends)
out into config.c, because I can't really justify calling them generic
any more. When they took a pointer to an arbitrary structure type and
the offset of a field within that structure, they were independent of
whether that structure was a Config or something completely different,
but now they really do expect to talk to a Conf, which can _only_ be
used for PuTTY configuration, so I've renamed them all things like
conf_editbox_handler and moved them out of the nominally independent
dialog-box management module into the PuTTY-specific config.c.
[originally from svn r9214]
2011-07-14 22:52:21 +04:00
|
|
|
if (!ctx->logtype)
|
2005-02-18 21:33:31 +03:00
|
|
|
return;
|
|
|
|
|
|
|
|
tm = ltime();
|
|
|
|
|
|
|
|
/* substitute special codes in file name */
|
2011-10-02 15:01:57 +04:00
|
|
|
if (ctx->currlogfilename)
|
|
|
|
filename_free(ctx->currlogfilename);
|
|
|
|
ctx->currlogfilename =
|
|
|
|
xlatlognam(conf_get_filename(ctx->conf, CONF_logfilename),
|
|
|
|
conf_get_str(ctx->conf, CONF_host), &tm);
|
2005-02-18 21:33:31 +03:00
|
|
|
|
2007-01-09 21:14:30 +03:00
|
|
|
ctx->lgfp = f_open(ctx->currlogfilename, "r", FALSE); /* file already present? */
|
2005-02-18 21:33:31 +03:00
|
|
|
if (ctx->lgfp) {
|
Post-release destabilisation! Completely remove the struct type
'Config' in putty.h, which stores all PuTTY's settings and includes an
arbitrary length limit on every single one of those settings which is
stored in string form. In place of it is 'Conf', an opaque data type
everywhere outside the new file conf.c, which stores a list of (key,
value) pairs in which every key contains an integer identifying a
configuration setting, and for some of those integers the key also
contains extra parts (so that, for instance, CONF_environmt is a
string-to-string mapping). Everywhere that a Config was previously
used, a Conf is now; everywhere there was a Config structure copy,
conf_copy() is called; every lookup, adjustment, load and save
operation on a Config has been rewritten; and there's a mechanism for
serialising a Conf into a binary blob and back for use with Duplicate
Session.
User-visible effects of this change _should_ be minimal, though I
don't doubt I've introduced one or two bugs here and there which will
eventually be found. The _intended_ visible effects of this change are
that all arbitrary limits on configuration strings and lists (e.g.
limit on number of port forwardings) should now disappear; that list
boxes in the configuration will now be displayed in a sorted order
rather than the arbitrary order in which they were added to the list
(since the underlying data structure is now a sorted tree234 rather
than an ad-hoc comma-separated string); and one more specific change,
which is that local and dynamic port forwardings on the same port
number are now mutually exclusive in the configuration (putting 'D' in
the key rather than the value was a mistake in the first place).
One other reorganisation as a result of this is that I've moved all
the dialog.c standard handlers (dlg_stdeditbox_handler and friends)
out into config.c, because I can't really justify calling them generic
any more. When they took a pointer to an arbitrary structure type and
the offset of a field within that structure, they were independent of
whether that structure was a Config or something completely different,
but now they really do expect to talk to a Conf, which can _only_ be
used for PuTTY configuration, so I've renamed them all things like
conf_editbox_handler and moved them out of the nominally independent
dialog-box management module into the PuTTY-specific config.c.
[originally from svn r9214]
2011-07-14 22:52:21 +04:00
|
|
|
int logxfovr = conf_get_int(ctx->conf, CONF_logxfovr);
|
2005-02-18 21:33:31 +03:00
|
|
|
fclose(ctx->lgfp);
|
Post-release destabilisation! Completely remove the struct type
'Config' in putty.h, which stores all PuTTY's settings and includes an
arbitrary length limit on every single one of those settings which is
stored in string form. In place of it is 'Conf', an opaque data type
everywhere outside the new file conf.c, which stores a list of (key,
value) pairs in which every key contains an integer identifying a
configuration setting, and for some of those integers the key also
contains extra parts (so that, for instance, CONF_environmt is a
string-to-string mapping). Everywhere that a Config was previously
used, a Conf is now; everywhere there was a Config structure copy,
conf_copy() is called; every lookup, adjustment, load and save
operation on a Config has been rewritten; and there's a mechanism for
serialising a Conf into a binary blob and back for use with Duplicate
Session.
User-visible effects of this change _should_ be minimal, though I
don't doubt I've introduced one or two bugs here and there which will
eventually be found. The _intended_ visible effects of this change are
that all arbitrary limits on configuration strings and lists (e.g.
limit on number of port forwardings) should now disappear; that list
boxes in the configuration will now be displayed in a sorted order
rather than the arbitrary order in which they were added to the list
(since the underlying data structure is now a sorted tree234 rather
than an ad-hoc comma-separated string); and one more specific change,
which is that local and dynamic port forwardings on the same port
number are now mutually exclusive in the configuration (putting 'D' in
the key rather than the value was a mistake in the first place).
One other reorganisation as a result of this is that I've moved all
the dialog.c standard handlers (dlg_stdeditbox_handler and friends)
out into config.c, because I can't really justify calling them generic
any more. When they took a pointer to an arbitrary structure type and
the offset of a field within that structure, they were independent of
whether that structure was a Config or something completely different,
but now they really do expect to talk to a Conf, which can _only_ be
used for PuTTY configuration, so I've renamed them all things like
conf_editbox_handler and moved them out of the nominally independent
dialog-box management module into the PuTTY-specific config.c.
[originally from svn r9214]
2011-07-14 22:52:21 +04:00
|
|
|
if (logxfovr != LGXF_ASK) {
|
|
|
|
mode = ((logxfovr == LGXF_OVR) ? 2 : 1);
|
2005-02-18 21:33:31 +03:00
|
|
|
} else
|
|
|
|
mode = askappend(ctx->frontend, ctx->currlogfilename,
|
|
|
|
logfopen_callback, ctx);
|
|
|
|
} else
|
|
|
|
mode = 2; /* create == overwrite */
|
|
|
|
|
|
|
|
if (mode < 0)
|
2005-02-19 01:03:15 +03:00
|
|
|
ctx->state = L_OPENING;
|
2005-02-18 21:33:31 +03:00
|
|
|
else
|
|
|
|
logfopen_callback(ctx, mode); /* open the file */
|
|
|
|
}
|
|
|
|
|
|
|
|
void logfclose(void *handle)
|
|
|
|
{
|
|
|
|
struct LogContext *ctx = (struct LogContext *)handle;
|
|
|
|
if (ctx->lgfp) {
|
|
|
|
fclose(ctx->lgfp);
|
|
|
|
ctx->lgfp = NULL;
|
|
|
|
}
|
2005-02-19 01:03:15 +03:00
|
|
|
ctx->state = L_CLOSED;
|
2005-02-18 21:33:31 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Log session traffic.
|
|
|
|
*/
|
|
|
|
void logtraffic(void *handle, unsigned char c, int logmode)
|
|
|
|
{
|
|
|
|
struct LogContext *ctx = (struct LogContext *)handle;
|
Post-release destabilisation! Completely remove the struct type
'Config' in putty.h, which stores all PuTTY's settings and includes an
arbitrary length limit on every single one of those settings which is
stored in string form. In place of it is 'Conf', an opaque data type
everywhere outside the new file conf.c, which stores a list of (key,
value) pairs in which every key contains an integer identifying a
configuration setting, and for some of those integers the key also
contains extra parts (so that, for instance, CONF_environmt is a
string-to-string mapping). Everywhere that a Config was previously
used, a Conf is now; everywhere there was a Config structure copy,
conf_copy() is called; every lookup, adjustment, load and save
operation on a Config has been rewritten; and there's a mechanism for
serialising a Conf into a binary blob and back for use with Duplicate
Session.
User-visible effects of this change _should_ be minimal, though I
don't doubt I've introduced one or two bugs here and there which will
eventually be found. The _intended_ visible effects of this change are
that all arbitrary limits on configuration strings and lists (e.g.
limit on number of port forwardings) should now disappear; that list
boxes in the configuration will now be displayed in a sorted order
rather than the arbitrary order in which they were added to the list
(since the underlying data structure is now a sorted tree234 rather
than an ad-hoc comma-separated string); and one more specific change,
which is that local and dynamic port forwardings on the same port
number are now mutually exclusive in the configuration (putting 'D' in
the key rather than the value was a mistake in the first place).
One other reorganisation as a result of this is that I've moved all
the dialog.c standard handlers (dlg_stdeditbox_handler and friends)
out into config.c, because I can't really justify calling them generic
any more. When they took a pointer to an arbitrary structure type and
the offset of a field within that structure, they were independent of
whether that structure was a Config or something completely different,
but now they really do expect to talk to a Conf, which can _only_ be
used for PuTTY configuration, so I've renamed them all things like
conf_editbox_handler and moved them out of the nominally independent
dialog-box management module into the PuTTY-specific config.c.
[originally from svn r9214]
2011-07-14 22:52:21 +04:00
|
|
|
if (ctx->logtype > 0) {
|
|
|
|
if (ctx->logtype == logmode)
|
2005-02-18 21:33:31 +03:00
|
|
|
logwrite(ctx, &c, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-09-15 17:21:32 +04:00
|
|
|
/*
|
2002-12-19 17:24:28 +03:00
|
|
|
* Log an Event Log entry. Used in SSH packet logging mode; this is
|
|
|
|
* also as convenient a place as any to put the output of Event Log
|
|
|
|
* entries to stderr when a command-line tool is in verbose mode.
|
|
|
|
* (In particular, this is a better place to put it than in the
|
|
|
|
* front ends, because it only has to be done once for all
|
|
|
|
* platforms. Platforms which don't have a meaningful stderr can
|
|
|
|
* just avoid defining FLAG_STDERR.
|
2002-09-15 17:21:32 +04:00
|
|
|
*/
|
2003-05-04 18:18:18 +04:00
|
|
|
void log_eventlog(void *handle, const char *event)
|
2002-09-15 17:21:32 +04:00
|
|
|
{
|
2002-10-26 16:58:13 +04:00
|
|
|
struct LogContext *ctx = (struct LogContext *)handle;
|
2002-12-19 17:24:28 +03:00
|
|
|
if ((flags & FLAG_STDERR) && (flags & FLAG_VERBOSE)) {
|
|
|
|
fprintf(stderr, "%s\n", event);
|
|
|
|
fflush(stderr);
|
|
|
|
}
|
2006-12-23 12:04:27 +03:00
|
|
|
/* If we don't have a context yet (eg winnet.c init) then skip entirely */
|
|
|
|
if (!ctx)
|
|
|
|
return;
|
Post-release destabilisation! Completely remove the struct type
'Config' in putty.h, which stores all PuTTY's settings and includes an
arbitrary length limit on every single one of those settings which is
stored in string form. In place of it is 'Conf', an opaque data type
everywhere outside the new file conf.c, which stores a list of (key,
value) pairs in which every key contains an integer identifying a
configuration setting, and for some of those integers the key also
contains extra parts (so that, for instance, CONF_environmt is a
string-to-string mapping). Everywhere that a Config was previously
used, a Conf is now; everywhere there was a Config structure copy,
conf_copy() is called; every lookup, adjustment, load and save
operation on a Config has been rewritten; and there's a mechanism for
serialising a Conf into a binary blob and back for use with Duplicate
Session.
User-visible effects of this change _should_ be minimal, though I
don't doubt I've introduced one or two bugs here and there which will
eventually be found. The _intended_ visible effects of this change are
that all arbitrary limits on configuration strings and lists (e.g.
limit on number of port forwardings) should now disappear; that list
boxes in the configuration will now be displayed in a sorted order
rather than the arbitrary order in which they were added to the list
(since the underlying data structure is now a sorted tree234 rather
than an ad-hoc comma-separated string); and one more specific change,
which is that local and dynamic port forwardings on the same port
number are now mutually exclusive in the configuration (putting 'D' in
the key rather than the value was a mistake in the first place).
One other reorganisation as a result of this is that I've moved all
the dialog.c standard handlers (dlg_stdeditbox_handler and friends)
out into config.c, because I can't really justify calling them generic
any more. When they took a pointer to an arbitrary structure type and
the offset of a field within that structure, they were independent of
whether that structure was a Config or something completely different,
but now they really do expect to talk to a Conf, which can _only_ be
used for PuTTY configuration, so I've renamed them all things like
conf_editbox_handler and moved them out of the nominally independent
dialog-box management module into the PuTTY-specific config.c.
[originally from svn r9214]
2011-07-14 22:52:21 +04:00
|
|
|
if (ctx->logtype != LGTYP_PACKETS &&
|
|
|
|
ctx->logtype != LGTYP_SSHRAW)
|
2002-09-15 17:21:32 +04:00
|
|
|
return;
|
2005-02-18 21:33:31 +03:00
|
|
|
logprintf(ctx, "Event Log: %s\r\n", event);
|
New logging mode, which records the exact bytes sent over the wire
in an SSH connection _in addition_ to the decrypted packets. This
will hopefully come in useful for debugging wire data corruption
issues: you can strace the server, enable this mode in the client,
and compare the sent and received data.
I'd _like_ to have this mode also log Diffie-Hellman private
exponents, session IDs, encryption and MAC keys, so that the
resulting log file could be used to independently verify the
correctness of all cryptographic operations performed by PuTTY.
However, I haven't been able to convince myself that the security
implications are acceptable. (It doesn't matter that this
information would permit an attacker to decrypt the session, because
the _already_ decrypted session is stored alongside it in the log
file. And I'm not planning, under any circumstances, to log users'
private keys. But gaining access to the log file while the session
was still running would permit an attacker to _hijack_ the session,
and that's the iffy bit.)
[originally from svn r6835]
2006-08-29 23:07:11 +04:00
|
|
|
logflush(ctx);
|
2002-09-15 17:21:32 +04:00
|
|
|
}
|
|
|
|
|
2001-12-14 17:57:50 +03:00
|
|
|
/*
|
|
|
|
* Log an SSH packet.
|
2004-10-02 04:33:27 +04:00
|
|
|
* If n_blanks != 0, blank or omit some parts.
|
|
|
|
* Set of blanking areas must be in increasing order.
|
2001-12-14 17:57:50 +03:00
|
|
|
*/
|
2002-10-26 16:58:13 +04:00
|
|
|
void log_packet(void *handle, int direction, int type,
|
2008-11-11 10:47:27 +03:00
|
|
|
char *texttype, const void *data, int len,
|
|
|
|
int n_blanks, const struct logblank_t *blanks,
|
2013-11-17 18:05:41 +04:00
|
|
|
const unsigned long *seq,
|
|
|
|
unsigned downstream_id, const char *additional_log_text)
|
2001-12-14 17:57:50 +03:00
|
|
|
{
|
2002-10-26 16:58:13 +04:00
|
|
|
struct LogContext *ctx = (struct LogContext *)handle;
|
2001-12-14 17:57:50 +03:00
|
|
|
char dumpdata[80], smalldata[5];
|
2005-02-18 21:33:31 +03:00
|
|
|
int p = 0, b = 0, omitted = 0;
|
|
|
|
int output_pos = 0; /* NZ if pending output in dumpdata */
|
2001-12-14 17:57:50 +03:00
|
|
|
|
Post-release destabilisation! Completely remove the struct type
'Config' in putty.h, which stores all PuTTY's settings and includes an
arbitrary length limit on every single one of those settings which is
stored in string form. In place of it is 'Conf', an opaque data type
everywhere outside the new file conf.c, which stores a list of (key,
value) pairs in which every key contains an integer identifying a
configuration setting, and for some of those integers the key also
contains extra parts (so that, for instance, CONF_environmt is a
string-to-string mapping). Everywhere that a Config was previously
used, a Conf is now; everywhere there was a Config structure copy,
conf_copy() is called; every lookup, adjustment, load and save
operation on a Config has been rewritten; and there's a mechanism for
serialising a Conf into a binary blob and back for use with Duplicate
Session.
User-visible effects of this change _should_ be minimal, though I
don't doubt I've introduced one or two bugs here and there which will
eventually be found. The _intended_ visible effects of this change are
that all arbitrary limits on configuration strings and lists (e.g.
limit on number of port forwardings) should now disappear; that list
boxes in the configuration will now be displayed in a sorted order
rather than the arbitrary order in which they were added to the list
(since the underlying data structure is now a sorted tree234 rather
than an ad-hoc comma-separated string); and one more specific change,
which is that local and dynamic port forwardings on the same port
number are now mutually exclusive in the configuration (putting 'D' in
the key rather than the value was a mistake in the first place).
One other reorganisation as a result of this is that I've moved all
the dialog.c standard handlers (dlg_stdeditbox_handler and friends)
out into config.c, because I can't really justify calling them generic
any more. When they took a pointer to an arbitrary structure type and
the offset of a field within that structure, they were independent of
whether that structure was a Config or something completely different,
but now they really do expect to talk to a Conf, which can _only_ be
used for PuTTY configuration, so I've renamed them all things like
conf_editbox_handler and moved them out of the nominally independent
dialog-box management module into the PuTTY-specific config.c.
[originally from svn r9214]
2011-07-14 22:52:21 +04:00
|
|
|
if (!(ctx->logtype == LGTYP_SSHRAW ||
|
|
|
|
(ctx->logtype == LGTYP_PACKETS && texttype)))
|
2001-12-14 17:57:50 +03:00
|
|
|
return;
|
2004-10-02 04:33:27 +04:00
|
|
|
|
2005-02-18 21:33:31 +03:00
|
|
|
/* Packet header. */
|
2008-11-11 10:47:27 +03:00
|
|
|
if (texttype) {
|
2013-11-17 18:05:41 +04:00
|
|
|
logprintf(ctx, "%s packet ",
|
|
|
|
direction == PKT_INCOMING ? "Incoming" : "Outgoing");
|
|
|
|
|
|
|
|
if (seq)
|
|
|
|
logprintf(ctx, "#0x%lx, ", *seq);
|
|
|
|
|
|
|
|
logprintf(ctx, "type %d / 0x%02x (%s)", type, type, texttype);
|
|
|
|
|
|
|
|
if (downstream_id) {
|
|
|
|
logprintf(ctx, " on behalf of downstream #%u", downstream_id);
|
|
|
|
if (additional_log_text)
|
|
|
|
logprintf(ctx, " (%s)", additional_log_text);
|
|
|
|
}
|
|
|
|
|
|
|
|
logprintf(ctx, "\r\n");
|
2008-11-11 10:47:27 +03:00
|
|
|
} else {
|
2012-10-10 22:32:23 +04:00
|
|
|
/*
|
|
|
|
* Raw data is logged with a timestamp, so that it's possible
|
|
|
|
* to determine whether a mysterious delay occurred at the
|
|
|
|
* client or server end. (Timestamping the raw data avoids
|
|
|
|
* cluttering the normal case of only logging decrypted SSH
|
|
|
|
* messages, and also adds conceptual rigour in the case where
|
|
|
|
* an SSH message arrives in several pieces.)
|
|
|
|
*/
|
|
|
|
char buf[256];
|
|
|
|
struct tm tm;
|
|
|
|
tm = ltime();
|
|
|
|
strftime(buf, 24, "%Y-%m-%d %H:%M:%S", &tm);
|
|
|
|
logprintf(ctx, "%s raw data at %s\r\n",
|
|
|
|
direction == PKT_INCOMING ? "Incoming" : "Outgoing",
|
|
|
|
buf);
|
2008-11-11 10:47:27 +03:00
|
|
|
}
|
2005-02-18 21:33:31 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Output a hex/ASCII dump of the packet body, blanking/omitting
|
|
|
|
* parts as specified.
|
|
|
|
*/
|
|
|
|
while (p < len) {
|
|
|
|
int blktype;
|
|
|
|
|
|
|
|
/* Move to a current entry in the blanking array. */
|
|
|
|
while ((b < n_blanks) &&
|
|
|
|
(p >= blanks[b].offset + blanks[b].len))
|
|
|
|
b++;
|
|
|
|
/* Work out what type of blanking to apply to
|
|
|
|
* this byte. */
|
|
|
|
blktype = PKTLOG_EMIT; /* default */
|
|
|
|
if ((b < n_blanks) &&
|
|
|
|
(p >= blanks[b].offset) &&
|
|
|
|
(p < blanks[b].offset + blanks[b].len))
|
|
|
|
blktype = blanks[b].type;
|
|
|
|
|
|
|
|
/* If we're about to stop omitting, it's time to say how
|
|
|
|
* much we omitted. */
|
|
|
|
if ((blktype != PKTLOG_OMIT) && omitted) {
|
|
|
|
logprintf(ctx, " (%d byte%s omitted)\r\n",
|
|
|
|
omitted, (omitted==1?"":"s"));
|
|
|
|
omitted = 0;
|
|
|
|
}
|
2004-10-02 04:33:27 +04:00
|
|
|
|
2005-02-18 21:33:31 +03:00
|
|
|
/* (Re-)initialise dumpdata as necessary
|
|
|
|
* (start of row, or if we've just stopped omitting) */
|
|
|
|
if (!output_pos && !omitted)
|
|
|
|
sprintf(dumpdata, " %08x%*s\r\n", p-(p%16), 1+3*16+2+16, "");
|
|
|
|
|
|
|
|
/* Deal with the current byte. */
|
|
|
|
if (blktype == PKTLOG_OMIT) {
|
|
|
|
omitted++;
|
|
|
|
} else {
|
|
|
|
int c;
|
|
|
|
if (blktype == PKTLOG_BLANK) {
|
|
|
|
c = 'X';
|
|
|
|
sprintf(smalldata, "XX");
|
|
|
|
} else { /* PKTLOG_EMIT */
|
|
|
|
c = ((unsigned char *)data)[p];
|
|
|
|
sprintf(smalldata, "%02x", c);
|
2001-12-14 17:57:50 +03:00
|
|
|
}
|
2005-02-18 21:33:31 +03:00
|
|
|
dumpdata[10+2+3*(p%16)] = smalldata[0];
|
|
|
|
dumpdata[10+2+3*(p%16)+1] = smalldata[1];
|
|
|
|
dumpdata[10+1+3*16+2+(p%16)] = (isprint(c) ? c : '.');
|
|
|
|
output_pos = (p%16) + 1;
|
2001-12-14 17:57:50 +03:00
|
|
|
}
|
2004-10-02 04:33:27 +04:00
|
|
|
|
2005-02-18 21:33:31 +03:00
|
|
|
p++;
|
2001-12-14 17:57:50 +03:00
|
|
|
|
2005-02-18 21:33:31 +03:00
|
|
|
/* Flush row if necessary */
|
|
|
|
if (((p % 16) == 0) || (p == len) || omitted) {
|
|
|
|
if (output_pos) {
|
|
|
|
strcpy(dumpdata + 10+1+3*16+2+output_pos, "\r\n");
|
|
|
|
logwrite(ctx, dumpdata, strlen(dumpdata));
|
|
|
|
output_pos = 0;
|
|
|
|
}
|
2001-12-14 17:57:50 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2005-02-18 21:33:31 +03:00
|
|
|
/* Tidy up */
|
|
|
|
if (omitted)
|
|
|
|
logprintf(ctx, " (%d byte%s omitted)\r\n",
|
|
|
|
omitted, (omitted==1?"":"s"));
|
|
|
|
logflush(ctx);
|
2001-12-14 17:57:50 +03:00
|
|
|
}
|
|
|
|
|
Post-release destabilisation! Completely remove the struct type
'Config' in putty.h, which stores all PuTTY's settings and includes an
arbitrary length limit on every single one of those settings which is
stored in string form. In place of it is 'Conf', an opaque data type
everywhere outside the new file conf.c, which stores a list of (key,
value) pairs in which every key contains an integer identifying a
configuration setting, and for some of those integers the key also
contains extra parts (so that, for instance, CONF_environmt is a
string-to-string mapping). Everywhere that a Config was previously
used, a Conf is now; everywhere there was a Config structure copy,
conf_copy() is called; every lookup, adjustment, load and save
operation on a Config has been rewritten; and there's a mechanism for
serialising a Conf into a binary blob and back for use with Duplicate
Session.
User-visible effects of this change _should_ be minimal, though I
don't doubt I've introduced one or two bugs here and there which will
eventually be found. The _intended_ visible effects of this change are
that all arbitrary limits on configuration strings and lists (e.g.
limit on number of port forwardings) should now disappear; that list
boxes in the configuration will now be displayed in a sorted order
rather than the arbitrary order in which they were added to the list
(since the underlying data structure is now a sorted tree234 rather
than an ad-hoc comma-separated string); and one more specific change,
which is that local and dynamic port forwardings on the same port
number are now mutually exclusive in the configuration (putting 'D' in
the key rather than the value was a mistake in the first place).
One other reorganisation as a result of this is that I've moved all
the dialog.c standard handlers (dlg_stdeditbox_handler and friends)
out into config.c, because I can't really justify calling them generic
any more. When they took a pointer to an arbitrary structure type and
the offset of a field within that structure, they were independent of
whether that structure was a Config or something completely different,
but now they really do expect to talk to a Conf, which can _only_ be
used for PuTTY configuration, so I've renamed them all things like
conf_editbox_handler and moved them out of the nominally independent
dialog-box management module into the PuTTY-specific config.c.
[originally from svn r9214]
2011-07-14 22:52:21 +04:00
|
|
|
void *log_init(void *frontend, Conf *conf)
|
2002-10-26 16:58:13 +04:00
|
|
|
{
|
2003-03-29 19:14:26 +03:00
|
|
|
struct LogContext *ctx = snew(struct LogContext);
|
2002-10-26 16:58:13 +04:00
|
|
|
ctx->lgfp = NULL;
|
2005-02-19 01:03:15 +03:00
|
|
|
ctx->state = L_CLOSED;
|
2002-10-26 16:58:13 +04:00
|
|
|
ctx->frontend = frontend;
|
Post-release destabilisation! Completely remove the struct type
'Config' in putty.h, which stores all PuTTY's settings and includes an
arbitrary length limit on every single one of those settings which is
stored in string form. In place of it is 'Conf', an opaque data type
everywhere outside the new file conf.c, which stores a list of (key,
value) pairs in which every key contains an integer identifying a
configuration setting, and for some of those integers the key also
contains extra parts (so that, for instance, CONF_environmt is a
string-to-string mapping). Everywhere that a Config was previously
used, a Conf is now; everywhere there was a Config structure copy,
conf_copy() is called; every lookup, adjustment, load and save
operation on a Config has been rewritten; and there's a mechanism for
serialising a Conf into a binary blob and back for use with Duplicate
Session.
User-visible effects of this change _should_ be minimal, though I
don't doubt I've introduced one or two bugs here and there which will
eventually be found. The _intended_ visible effects of this change are
that all arbitrary limits on configuration strings and lists (e.g.
limit on number of port forwardings) should now disappear; that list
boxes in the configuration will now be displayed in a sorted order
rather than the arbitrary order in which they were added to the list
(since the underlying data structure is now a sorted tree234 rather
than an ad-hoc comma-separated string); and one more specific change,
which is that local and dynamic port forwardings on the same port
number are now mutually exclusive in the configuration (putting 'D' in
the key rather than the value was a mistake in the first place).
One other reorganisation as a result of this is that I've moved all
the dialog.c standard handlers (dlg_stdeditbox_handler and friends)
out into config.c, because I can't really justify calling them generic
any more. When they took a pointer to an arbitrary structure type and
the offset of a field within that structure, they were independent of
whether that structure was a Config or something completely different,
but now they really do expect to talk to a Conf, which can _only_ be
used for PuTTY configuration, so I've renamed them all things like
conf_editbox_handler and moved them out of the nominally independent
dialog-box management module into the PuTTY-specific config.c.
[originally from svn r9214]
2011-07-14 22:52:21 +04:00
|
|
|
ctx->conf = conf_copy(conf);
|
|
|
|
ctx->logtype = conf_get_int(ctx->conf, CONF_logtype);
|
2011-10-02 15:01:57 +04:00
|
|
|
ctx->currlogfilename = NULL;
|
2005-02-18 21:33:31 +03:00
|
|
|
bufchain_init(&ctx->queue);
|
2002-10-26 16:58:13 +04:00
|
|
|
return ctx;
|
|
|
|
}
|
|
|
|
|
2003-01-16 02:30:21 +03:00
|
|
|
void log_free(void *handle)
|
|
|
|
{
|
|
|
|
struct LogContext *ctx = (struct LogContext *)handle;
|
|
|
|
|
|
|
|
logfclose(ctx);
|
2005-02-18 21:33:31 +03:00
|
|
|
bufchain_clear(&ctx->queue);
|
2011-10-02 15:01:57 +04:00
|
|
|
if (ctx->currlogfilename)
|
|
|
|
filename_free(ctx->currlogfilename);
|
2003-01-16 02:30:21 +03:00
|
|
|
sfree(ctx);
|
|
|
|
}
|
|
|
|
|
Post-release destabilisation! Completely remove the struct type
'Config' in putty.h, which stores all PuTTY's settings and includes an
arbitrary length limit on every single one of those settings which is
stored in string form. In place of it is 'Conf', an opaque data type
everywhere outside the new file conf.c, which stores a list of (key,
value) pairs in which every key contains an integer identifying a
configuration setting, and for some of those integers the key also
contains extra parts (so that, for instance, CONF_environmt is a
string-to-string mapping). Everywhere that a Config was previously
used, a Conf is now; everywhere there was a Config structure copy,
conf_copy() is called; every lookup, adjustment, load and save
operation on a Config has been rewritten; and there's a mechanism for
serialising a Conf into a binary blob and back for use with Duplicate
Session.
User-visible effects of this change _should_ be minimal, though I
don't doubt I've introduced one or two bugs here and there which will
eventually be found. The _intended_ visible effects of this change are
that all arbitrary limits on configuration strings and lists (e.g.
limit on number of port forwardings) should now disappear; that list
boxes in the configuration will now be displayed in a sorted order
rather than the arbitrary order in which they were added to the list
(since the underlying data structure is now a sorted tree234 rather
than an ad-hoc comma-separated string); and one more specific change,
which is that local and dynamic port forwardings on the same port
number are now mutually exclusive in the configuration (putting 'D' in
the key rather than the value was a mistake in the first place).
One other reorganisation as a result of this is that I've moved all
the dialog.c standard handlers (dlg_stdeditbox_handler and friends)
out into config.c, because I can't really justify calling them generic
any more. When they took a pointer to an arbitrary structure type and
the offset of a field within that structure, they were independent of
whether that structure was a Config or something completely different,
but now they really do expect to talk to a Conf, which can _only_ be
used for PuTTY configuration, so I've renamed them all things like
conf_editbox_handler and moved them out of the nominally independent
dialog-box management module into the PuTTY-specific config.c.
[originally from svn r9214]
2011-07-14 22:52:21 +04:00
|
|
|
void log_reconfig(void *handle, Conf *conf)
|
2003-01-12 18:10:27 +03:00
|
|
|
{
|
|
|
|
struct LogContext *ctx = (struct LogContext *)handle;
|
|
|
|
int reset_logging;
|
|
|
|
|
2011-10-02 15:01:57 +04:00
|
|
|
if (!filename_equal(conf_get_filename(ctx->conf, CONF_logfilename),
|
|
|
|
conf_get_filename(conf, CONF_logfilename)) ||
|
Post-release destabilisation! Completely remove the struct type
'Config' in putty.h, which stores all PuTTY's settings and includes an
arbitrary length limit on every single one of those settings which is
stored in string form. In place of it is 'Conf', an opaque data type
everywhere outside the new file conf.c, which stores a list of (key,
value) pairs in which every key contains an integer identifying a
configuration setting, and for some of those integers the key also
contains extra parts (so that, for instance, CONF_environmt is a
string-to-string mapping). Everywhere that a Config was previously
used, a Conf is now; everywhere there was a Config structure copy,
conf_copy() is called; every lookup, adjustment, load and save
operation on a Config has been rewritten; and there's a mechanism for
serialising a Conf into a binary blob and back for use with Duplicate
Session.
User-visible effects of this change _should_ be minimal, though I
don't doubt I've introduced one or two bugs here and there which will
eventually be found. The _intended_ visible effects of this change are
that all arbitrary limits on configuration strings and lists (e.g.
limit on number of port forwardings) should now disappear; that list
boxes in the configuration will now be displayed in a sorted order
rather than the arbitrary order in which they were added to the list
(since the underlying data structure is now a sorted tree234 rather
than an ad-hoc comma-separated string); and one more specific change,
which is that local and dynamic port forwardings on the same port
number are now mutually exclusive in the configuration (putting 'D' in
the key rather than the value was a mistake in the first place).
One other reorganisation as a result of this is that I've moved all
the dialog.c standard handlers (dlg_stdeditbox_handler and friends)
out into config.c, because I can't really justify calling them generic
any more. When they took a pointer to an arbitrary structure type and
the offset of a field within that structure, they were independent of
whether that structure was a Config or something completely different,
but now they really do expect to talk to a Conf, which can _only_ be
used for PuTTY configuration, so I've renamed them all things like
conf_editbox_handler and moved them out of the nominally independent
dialog-box management module into the PuTTY-specific config.c.
[originally from svn r9214]
2011-07-14 22:52:21 +04:00
|
|
|
conf_get_int(ctx->conf, CONF_logtype) !=
|
|
|
|
conf_get_int(conf, CONF_logtype))
|
2003-01-12 18:10:27 +03:00
|
|
|
reset_logging = TRUE;
|
|
|
|
else
|
|
|
|
reset_logging = FALSE;
|
|
|
|
|
|
|
|
if (reset_logging)
|
2003-01-12 18:42:24 +03:00
|
|
|
logfclose(ctx);
|
2003-01-12 18:10:27 +03:00
|
|
|
|
Post-release destabilisation! Completely remove the struct type
'Config' in putty.h, which stores all PuTTY's settings and includes an
arbitrary length limit on every single one of those settings which is
stored in string form. In place of it is 'Conf', an opaque data type
everywhere outside the new file conf.c, which stores a list of (key,
value) pairs in which every key contains an integer identifying a
configuration setting, and for some of those integers the key also
contains extra parts (so that, for instance, CONF_environmt is a
string-to-string mapping). Everywhere that a Config was previously
used, a Conf is now; everywhere there was a Config structure copy,
conf_copy() is called; every lookup, adjustment, load and save
operation on a Config has been rewritten; and there's a mechanism for
serialising a Conf into a binary blob and back for use with Duplicate
Session.
User-visible effects of this change _should_ be minimal, though I
don't doubt I've introduced one or two bugs here and there which will
eventually be found. The _intended_ visible effects of this change are
that all arbitrary limits on configuration strings and lists (e.g.
limit on number of port forwardings) should now disappear; that list
boxes in the configuration will now be displayed in a sorted order
rather than the arbitrary order in which they were added to the list
(since the underlying data structure is now a sorted tree234 rather
than an ad-hoc comma-separated string); and one more specific change,
which is that local and dynamic port forwardings on the same port
number are now mutually exclusive in the configuration (putting 'D' in
the key rather than the value was a mistake in the first place).
One other reorganisation as a result of this is that I've moved all
the dialog.c standard handlers (dlg_stdeditbox_handler and friends)
out into config.c, because I can't really justify calling them generic
any more. When they took a pointer to an arbitrary structure type and
the offset of a field within that structure, they were independent of
whether that structure was a Config or something completely different,
but now they really do expect to talk to a Conf, which can _only_ be
used for PuTTY configuration, so I've renamed them all things like
conf_editbox_handler and moved them out of the nominally independent
dialog-box management module into the PuTTY-specific config.c.
[originally from svn r9214]
2011-07-14 22:52:21 +04:00
|
|
|
conf_free(ctx->conf);
|
|
|
|
ctx->conf = conf_copy(conf);
|
|
|
|
|
|
|
|
ctx->logtype = conf_get_int(ctx->conf, CONF_logtype);
|
2003-01-12 18:10:27 +03:00
|
|
|
|
|
|
|
if (reset_logging)
|
2003-01-12 18:42:24 +03:00
|
|
|
logfopen(ctx);
|
2003-01-12 18:10:27 +03:00
|
|
|
}
|
|
|
|
|
2001-12-14 17:57:50 +03:00
|
|
|
/*
|
|
|
|
* translate format codes into time/date strings
|
|
|
|
* and insert them into log file name
|
|
|
|
*
|
2006-10-31 19:59:56 +03:00
|
|
|
* "&Y":YYYY "&m":MM "&d":DD "&T":hhmmss "&h":<hostname> "&&":&
|
2001-12-14 17:57:50 +03:00
|
|
|
*/
|
2011-10-02 15:01:57 +04:00
|
|
|
static Filename *xlatlognam(Filename *src, char *hostname, struct tm *tm)
|
|
|
|
{
|
2001-12-14 17:57:50 +03:00
|
|
|
char buf[10], *bufp;
|
|
|
|
int size;
|
2011-10-02 15:01:57 +04:00
|
|
|
char *buffer;
|
|
|
|
int buflen, bufsize;
|
2003-02-01 20:24:27 +03:00
|
|
|
const char *s;
|
2011-10-02 15:01:57 +04:00
|
|
|
Filename *ret;
|
2003-02-01 15:54:40 +03:00
|
|
|
|
2011-10-02 15:01:57 +04:00
|
|
|
bufsize = FILENAME_MAX;
|
|
|
|
buffer = snewn(bufsize, char);
|
|
|
|
buflen = 0;
|
|
|
|
s = filename_to_str(src);
|
2001-12-14 17:57:50 +03:00
|
|
|
|
|
|
|
while (*s) {
|
|
|
|
/* Let (bufp, len) be the string to append. */
|
|
|
|
bufp = buf; /* don't usually override this */
|
|
|
|
if (*s == '&') {
|
|
|
|
char c;
|
|
|
|
s++;
|
2002-10-09 22:09:42 +04:00
|
|
|
size = 0;
|
2009-01-11 17:26:27 +03:00
|
|
|
if (*s) switch (c = *s++, tolower((unsigned char)c)) {
|
2001-12-14 17:57:50 +03:00
|
|
|
case 'y':
|
|
|
|
size = strftime(buf, sizeof(buf), "%Y", tm);
|
|
|
|
break;
|
|
|
|
case 'm':
|
|
|
|
size = strftime(buf, sizeof(buf), "%m", tm);
|
|
|
|
break;
|
|
|
|
case 'd':
|
|
|
|
size = strftime(buf, sizeof(buf), "%d", tm);
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
size = strftime(buf, sizeof(buf), "%H%M%S", tm);
|
|
|
|
break;
|
|
|
|
case 'h':
|
|
|
|
bufp = hostname;
|
|
|
|
size = strlen(bufp);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
buf[0] = '&';
|
|
|
|
size = 1;
|
|
|
|
if (c != '&')
|
|
|
|
buf[size++] = c;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
buf[0] = *s++;
|
|
|
|
size = 1;
|
|
|
|
}
|
2011-10-02 15:01:57 +04:00
|
|
|
if (bufsize <= buflen + size) {
|
|
|
|
bufsize = (buflen + size) * 5 / 4 + 512;
|
|
|
|
buffer = sresize(buffer, bufsize, char);
|
|
|
|
}
|
|
|
|
memcpy(buffer + buflen, bufp, size);
|
|
|
|
buflen += size;
|
2001-12-14 17:57:50 +03:00
|
|
|
}
|
2011-10-02 15:01:57 +04:00
|
|
|
buffer[buflen] = '\0';
|
2003-02-01 15:54:40 +03:00
|
|
|
|
2011-10-02 15:01:57 +04:00
|
|
|
ret = filename_from_str(buffer);
|
|
|
|
sfree(buffer);
|
|
|
|
return ret;
|
2001-12-14 17:57:50 +03:00
|
|
|
}
|