1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Improved session logging courtesy of Roman Pompejus

[originally from svn r846]
This commit is contained in:
Simon Tatham 2001-01-07 18:24:59 +00:00
parent 947c03869e
commit 3a2a06b1fc
5 changed files with 194 additions and 12 deletions

View File

@ -78,6 +78,9 @@ GLOBAL int seen_disp_event;
GLOBAL int session_closed;
#define LGTYP_NONE 0 /* logmode: no logging */
#define LGTYP_ASCII 1 /* logmode: pure ascii */
#define LGTYP_DEBUG 2 /* logmode: all chars of taffic */
GLOBAL char *logfile;
/*
@ -188,6 +191,8 @@ typedef struct {
int fontisbold;
int fontheight;
int fontcharset;
char logfilename[FILENAME_MAX];
int logtype;
/* Colour options */
int try_palette;
int bold_colour;
@ -283,6 +288,7 @@ void showeventlog (HWND);
void showabout (HWND);
void verify_ssh_host_key(char *host, int port, char *keytype,
char *keystr, char *fingerprint);
int askappend(char *filename);
void registry_cleanup(void);
void force_normal(HWND hwnd);
@ -315,6 +321,8 @@ void term_blink(int set_cursor);
void term_paste(void);
void term_nopaste(void);
void from_backend(int is_stderr, char *data, int len);
void logfopen (void);
void logfclose (void);
void term_copyall(void);
/*

View File

@ -32,6 +32,8 @@ void save_settings (char *section, int do_host, Config *cfg) {
if (do_host) {
write_setting_s (sesskey, "HostName", cfg->host);
write_setting_i (sesskey, "PortNumber", cfg->port);
write_setting_s (sesskey, "LogFileName", cfg->logfilename);
write_setting_i (sesskey, "LogType", cfg->logtype);
p = "raw";
for (i = 0; backends[i].name != NULL; i++)
if (backends[i].protocol == cfg->protocol) {
@ -150,6 +152,9 @@ void load_settings (char *section, int do_host, Config *cfg) {
gpps (sesskey, "HostName", "", cfg->host, sizeof(cfg->host));
gppi (sesskey, "PortNumber", default_port, &cfg->port);
gpps (sesskey, "LogFileName", "putty.log",
cfg->logfilename, sizeof(cfg->logfilename));
gppi (sesskey, "LogType", 0, &cfg->logtype);
gpps (sesskey, "Protocol", "default", prot, 10);
cfg->protocol = default_protocol;

View File

@ -4,6 +4,7 @@
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#include "putty.h"
#define CL_ANSIMIN 0x0001 /* Codes in all ANSI like terminals. */
@ -155,6 +156,9 @@ static void erase_lots (int, int, int);
static void swap_screen (int);
static void update_sbar (void);
static void deselect (void);
/* log session to file stuff ... */
static FILE *lgfp = NULL;
static void logtraffic(unsigned char c, int logmode);
/*
* Set up power-on settings for the terminal.
@ -780,11 +784,8 @@ static int beep_overload = 0;
* Optionally log the session traffic to a file. Useful for
* debugging and possibly also useful for actual logging.
*/
if (logfile) {
static FILE *fp = NULL;
if (!fp) fp = fopen(logfile, "wb");
if (fp) fputc (c, fp);
}
logtraffic((unsigned char)c, LGTYP_DEBUG);
/* Note only VT220+ are 8-bit VT102 is seven bit, it shouldn't even
* be able to display 8-bit characters, but I'll let that go 'cause
* of i18n.
@ -856,6 +857,7 @@ static int beep_overload = 0;
fix_cpos;
seen_disp_event = TRUE;
paste_hold = 0;
logtraffic((unsigned char)c,LGTYP_ASCII);
break;
case '\013':
case '\014':
@ -871,6 +873,7 @@ static int beep_overload = 0;
wrapnext = FALSE;
seen_disp_event = 1;
paste_hold = 0;
logtraffic((unsigned char)c,LGTYP_ASCII);
break;
case '\t':
{
@ -946,8 +949,10 @@ static int beep_overload = 0;
}
/*FALLTHROUGH*/
default:
*cpos++ = xlat_tty2scr((unsigned char)c) | curr_attr |
*cpos = xlat_tty2scr((unsigned char)c) | curr_attr |
(c <= 0x7F ? cset_attr[cset] : ATTR_ASCII);
logtraffic((unsigned char)c, LGTYP_ASCII);
cpos++;
break;
}
curs_x++;
@ -2230,3 +2235,64 @@ void from_backend(int is_stderr, char *data, int len) {
inbuf[inbuf_head++] = *data++;
}
}
/*
* Log session traffic.
*/
void logtraffic(unsigned char c, int logmode) {
if (cfg.logtype > 0) {
if (cfg.logtype == logmode) {
/* deferred open file from pgm start? */
if (!lgfp) logfopen();
if (lgfp) fputc (c, lgfp);
}
}
}
/* open log file append/overwrite mode */
void logfopen(void) {
char buf[256];
time_t t;
struct tm *tm;
char writemod[4];
if (!cfg.logtype)
return;
sprintf (writemod, "wb"); /* default to rewrite */
lgfp = fopen(cfg.logfilename, "r"); /* file already present? */
if (lgfp) {
int i;
fclose(lgfp);
i = askappend(cfg.logfilename);
if (i == 1)
writemod[0] = 'a'; /* set append mode */
else if (i == 0) { /* cancelled */
lgfp = NULL;
return;
}
}
lgfp = fopen(cfg.logfilename, writemod);
if (lgfp) { /* enter into event log */
sprintf(buf, "%s session log (%s mode) to file : ",
(writemod[0] == 'a') ? "Appending" : "Writing new",
(cfg.logtype == LGTYP_ASCII ? "ASCII" :
cfg.logtype == LGTYP_DEBUG ? "raw" : "<ukwn>") );
/* Make sure we do not exceed the output buffer size */
strncat (buf, cfg.logfilename, 128);
buf[strlen(buf)] = '\0';
logevent(buf);
/* --- write header line iinto log file */
fputs ("=~=~=~=~=~=~=~=~=~=~=~= PuTTY log ", lgfp);
time(&t);
tm = localtime(&t);
strftime(buf, 24, "%Y.%m.%d %H:%M:%S", tm);
fputs (buf, lgfp);
fputs (" =~=~=~=~=~=~=~=~=~=~=~=\r\n", lgfp);
}
}
void logfclose (void) {
if (lgfp) { fclose(lgfp); lgfp = NULL; }
}

View File

@ -230,6 +230,7 @@ enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
terminalpanelstart,
IDC_TITLE_TERMINAL,
IDC_BOX_TERMINAL1, IDC_BOXT_TERMINAL1,
IDC_BOX_TERMINAL2, IDC_BOXT_TERMINAL2,
IDC_WRAPMODE,
IDC_DECOM,
IDC_LFHASCR,
@ -237,6 +238,13 @@ enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
IDC_BCE,
IDC_BLINKTEXT,
IDC_LDISCTERM,
IDC_LSTATSTATIC,
IDC_LSTATOFF,
IDC_LSTATASCII,
IDC_LSTATRAW,
IDC_LGFSTATIC,
IDC_LGFEDIT,
IDC_LGFBUTTON,
terminalpanelend,
windowpanelstart,
@ -473,6 +481,11 @@ static void init_dlg_ctrls(HWND hwnd) {
SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
SetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed);
SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename);
CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
cfg.logtype == 0 ? IDC_LSTATOFF :
cfg.logtype == 1 ? IDC_LSTATASCII :
IDC_LSTATRAW);
{
char *p = cfg.environmt;
while (*p) {
@ -704,7 +717,7 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg,
hsession = treeview_insert(&tvfaff, 0, "Session");
}
/* The Terminal panel. Accelerators used: [acgo] &dlbenu */
/* The Terminal panel. Accelerators used: [acgo] &dflbenuw */
{
struct ctlpos cp;
ctlposinit(&cp, hwnd, 80, 3, 13);
@ -721,6 +734,18 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg,
checkbox(&cp, "&Use local terminal line discipline", IDC_LDISCTERM);
endbox(&cp);
beginbox(&cp, "Control session logging",
IDC_BOX_TERMINAL2, IDC_BOXT_TERMINAL2);
radiobig(&cp,
"Session logging:", IDC_LSTATSTATIC,
"Logging turned &off completely", IDC_LSTATOFF,
"Log printable output only", IDC_LSTATASCII,
"Log all session output", IDC_LSTATRAW, NULL);
editbutton(&cp, "Log &file name:",
IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
IDC_LGFBUTTON);
endbox(&cp);
treeview_insert(&tvfaff, 0, "Terminal");
}
@ -1428,6 +1453,43 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg,
GetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype,
sizeof(cfg.termtype)-1);
break;
case IDC_LGFEDIT:
if (HIWORD(wParam) == EN_CHANGE)
GetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename,
sizeof(cfg.logfilename)-1);
break;
case IDC_LGFBUTTON:
memset(&of, 0, sizeof(of));
#ifdef OPENFILENAME_SIZE_VERSION_400
of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
#else
of.lStructSize = sizeof(of);
#endif
of.hwndOwner = hwnd;
of.lpstrFilter = "All Files\0*\0\0\0";
of.lpstrCustomFilter = NULL;
of.nFilterIndex = 1;
of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
of.nMaxFile = sizeof(filename);
of.lpstrFileTitle = NULL;
of.lpstrInitialDir = NULL;
of.lpstrTitle = "Select session log file";
of.Flags = 0;
if (GetSaveFileName(&of)) {
strcpy(cfg.keyfile, filename);
SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.keyfile);
}
break;
case IDC_LSTATOFF:
case IDC_LSTATASCII:
case IDC_LSTATRAW:
if (HIWORD(wParam) == BN_CLICKED ||
HIWORD(wParam) == BN_DOUBLECLICKED) {
if (IsDlgButtonChecked (hwnd, IDC_LSTATOFF)) cfg.logtype = 0;
if (IsDlgButtonChecked (hwnd, IDC_LSTATASCII)) cfg.logtype = 1;
if (IsDlgButtonChecked (hwnd, IDC_LSTATRAW)) cfg.logtype = 2;
}
break;
case IDC_TSEDIT:
if (HIWORD(wParam) == EN_CHANGE)
GetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed,
@ -1891,3 +1953,30 @@ void verify_ssh_host_key(char *host, int port, char *keytype,
store_host_key(host, port, keytype, keystr);
}
}
/*
* 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(char *filename) {
static const char mbtitle[] = "PuTTY Log to File";
static const char msgtemplate[] =
"The session log file \"%.*s\" already exists.\n"
"You can overwrite it with a new session log,\n"
"append your session log to the end of it,\n"
"or disable session logging for this session.\n"
"Hit Yes to wipe the file, No to append to it,\n"
"or Cancel to disable logging.";
char message[sizeof(msgtemplate) + FILENAME_MAX];
int mbret;
sprintf(message, msgtemplate, FILENAME_MAX, filename);
mbret = MessageBox(NULL, message, mbtitle,
MB_ICONQUESTION | MB_YESNOCANCEL);
if (mbret == IDYES)
return 2;
else if (mbret == IDNO)
return 1;
else
return 0;
}

View File

@ -149,6 +149,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
default_protocol = DEFAULT_PROTOCOL;
default_port = DEFAULT_PORT;
cfg.logtype = LGTYP_NONE;
do_defaults(NULL, &cfg);
@ -169,11 +170,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
tolower(p[2]) == 'h') {
default_protocol = cfg.protocol = PROT_SSH;
default_port = cfg.port = 22;
} else if (q == p + 3 &&
tolower(p[0]) == 'l' &&
tolower(p[1]) == 'o' &&
tolower(p[2]) == 'g') {
logfile = "putty.log";
} else if (q == p + 7 &&
tolower(p[0]) == 'c' &&
tolower(p[1]) == 'l' &&
@ -536,6 +532,11 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
*/
ShowWindow (hwnd, show);
/*
* Open the initial log file if there is one.
*/
logfopen();
/*
* Set the palette up.
*/
@ -1171,14 +1172,27 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message,
case IDM_RECONF:
{
int prev_alwaysontop = cfg.alwaysontop;
char oldlogfile[FILENAME_MAX];
int oldlogtype;
int need_setwpos = FALSE;
int old_fwidth, old_fheight;
strcpy(oldlogfile, cfg.logfilename);
oldlogtype = cfg.logtype;
cfg.width = cols;
cfg.height = rows;
old_fwidth = font_width;
old_fheight = font_height;
if (!do_reconfig(hwnd))
break;
if (strcmp(oldlogfile, cfg.logfilename) ||
oldlogtype != cfg.logtype) {
logfclose(); /* reset logging */
logfopen();
}
just_reconfigged = TRUE;
{
int i;