// Test l'existance du répertoire, sinon le crée void test_dir( Filename *filename ) { int i ; char * name ; if( filename == NULL ) return ; if( strlen( filename_to_str(filename) ) == 0 ) return ; if( ( name = (char*) malloc( strlen( filename_to_str(filename) ) + 1 ) ) != NULL ) { strcpy( name, filename_to_str(filename) ) ; for( i=strlen(name)-1; i>=0 ; i-- ) { if( (name[i] == '\\') || (name[i]=='/' ) ) break ; } if( i > 0 ) { name[i] = '\0'; mkdir( name, 777 ) ; } free( name ) ; } }
/* * translate format codes into time/date strings * and insert them into log file name * * "&Y":YYYY "&m":MM "&d":DD "&T":hhmmss "&h":<hostname> "&&":& */ static Filename *xlatlognam(Filename *src, char *hostname, int port, struct tm *tm) { char buf[32], *bufp; int size; char *buffer; int buflen, bufsize; const char *s; Filename *ret; bufsize = FILENAME_MAX; buffer = snewn(bufsize, char); buflen = 0; s = filename_to_str(src); while (*s) { /* Let (bufp, len) be the string to append. */ bufp = buf; /* don't usually override this */ if (*s == '&') { char c; s++; size = 0; if (*s) switch (c = *s++, tolower((unsigned char)c)) { 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; case 'p': size = sprintf(buf, "%d", port); break; default: buf[0] = '&'; size = 1; if (c != '&') buf[size++] = c; } } else { buf[0] = *s++; size = 1; } if (bufsize <= buflen + size) { bufsize = (buflen + size) * 5 / 4 + 512; buffer = sresize(buffer, bufsize, char); } memcpy(buffer + buflen, bufp, size); buflen += size; }
/* open log file append/overwrite mode */ void logfopen(void *handle) { struct LogContext *ctx = (struct LogContext *)handle; char buf[256]; time_t t; struct tm tm; char writemod[4]; /* Prevent repeat calls */ if (ctx->lgfp) return; if (!ctx->cfg.logtype) return; sprintf(writemod, "wb"); /* default to rewrite */ time(&t); tm = *localtime(&t); /* substitute special codes in file name */ xlatlognam(&ctx->currlogfilename, ctx->cfg.logfilename,ctx->cfg.host, &tm); ctx->lgfp = f_open(ctx->currlogfilename, "r"); /* file already present? */ if (ctx->lgfp) { int i; fclose(ctx->lgfp); if (ctx->cfg.logxfovr != LGXF_ASK) { i = ((ctx->cfg.logxfovr == LGXF_OVR) ? 2 : 1); } else i = askappend(ctx->frontend, ctx->currlogfilename); if (i == 1) writemod[0] = 'a'; /* set append mode */ else if (i == 0) { /* cancelled */ ctx->lgfp = NULL; ctx->cfg.logtype = 0; /* disable logging */ return; } } 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); strftime(buf, 24, "%Y.%m.%d %H:%M:%S", &tm); fputs(buf, ctx->lgfp); fputs(" =~=~=~=~=~=~=~=~=~=~=~=\r\n", ctx->lgfp); sprintf(buf, "%s session log (%s mode) to file: ", (writemod[0] == 'a') ? "Appending" : "Writing new", (ctx->cfg.logtype == LGTYP_ASCII ? "ASCII" : 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, filename_to_str(&ctx->currlogfilename), 128); buf[strlen(buf)] = '\0'; logevent(ctx->frontend, buf); } }
/* * translate format codes into time/date strings * and insert them into log file name * * "&Y":YYYY "&m":MM "&d":DD "&T":hhmmss "&h":<hostname> "&&":& */ static void xlatlognam(Filename *dest, Filename src, char *hostname, struct tm *tm) { char buf[10], *bufp; int size; char buffer[FILENAME_MAX]; int len = sizeof(buffer)-1; char *d; const char *s; d = buffer; s = filename_to_str(&src); while (*s) { /* Let (bufp, len) be the string to append. */ bufp = buf; /* don't usually override this */ if (*s == '&') { char c; s++; size = 0; if (*s) switch (c = *s++, tolower((unsigned char)c)) { 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; } if (size > len) size = len; memcpy(d, bufp, size); d += size; len -= size; } *d = '\0'; *dest = filename_from_str(buffer); }
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) { ctx->state = L_ERROR; /* disable logging */ } else { fmode = (mode == 1 ? "ab" : "wb"); ctx->lgfp = f_open(&ctx->currlogfilename, fmode, FALSE); if (ctx->lgfp) ctx->state = L_OPEN; else ctx->state = L_ERROR; } if (ctx->state == L_OPEN) { /* 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", ctx->state == L_ERROR ? (mode == 0 ? "Disabled writing" : "Error writing") : (mode == 1 ? "Appending" : "Writing new"), (ctx->cfg.logtype == LGTYP_ASCII ? "ASCII" : ctx->cfg.logtype == LGTYP_DEBUG ? "raw" : ctx->cfg.logtype == LGTYP_PACKETS ? "SSH packets" : ctx->cfg.logtype == LGTYP_SSHRAW ? "SSH raw data" : "unknown"), filename_to_str(&ctx->currlogfilename)); logevent(ctx->frontend, event); sfree(event); /* * Having either succeeded or failed in opening the log file, * we should write any queued data out. */ assert(ctx->state != L_OPENING); /* make _sure_ it won't be requeued */ while (bufchain_size(&ctx->queue)) { void *data; int len; bufchain_prefix(&ctx->queue, &data, &len); logwrite(ctx, data, len); bufchain_consume(&ctx->queue, len); } }
static void logfopen_callback(void *handle, int mode) { struct LogContext *ctx = (struct LogContext *)handle; char buf[256], *event; struct tm tm; const char *fmode; int shout = FALSE; if (mode == 0) { ctx->state = L_ERROR; /* disable logging */ } else { fmode = (mode == 1 ? "ab" : "wb"); ctx->lgfp = f_open(ctx->currlogfilename, fmode, FALSE); if (ctx->lgfp) { ctx->state = L_OPEN; } else { ctx->state = L_ERROR; shout = TRUE; } } if (ctx->state == L_OPEN) { /* 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(MPEXT_BOM "%s session log (%s mode) to file: %s", ctx->state == L_ERROR ? (mode == 0 ? "Disabled writing" : "Error writing") : (mode == 1 ? "Appending" : "Writing new"), (ctx->logtype == LGTYP_ASCII ? "ASCII" : ctx->logtype == LGTYP_DEBUG ? "raw" : ctx->logtype == LGTYP_PACKETS ? "SSH packets" : ctx->logtype == LGTYP_SSHRAW ? "SSH raw data" : "unknown"), filename_to_str(ctx->currlogfilename)); logevent(ctx->frontend, event); if (shout) { /* * If we failed to open the log file due to filesystem error * (as opposed to user action such as clicking Cancel in the * askappend box), we should log it more prominently. We do * this by sending it to the same place that stderr output * from the main session goes (so, either a console tool's * actual stderr, or a terminal window). * * Of course this is one case in which that policy won't cause * it to turn up embarrassingly in a log file of real server * output, because the whole point is that we haven't managed * to open any such log file :-) */ from_backend(ctx->frontend, 1, event, strlen(event)); from_backend(ctx->frontend, 1, "\r\n", 2); } sfree(event); /* * Having either succeeded or failed in opening the log file, * we should write any queued data out. */ assert(ctx->state != L_OPENING); /* make _sure_ it won't be requeued */ while (bufchain_size(&ctx->queue)) { void *data; int len; bufchain_prefix(&ctx->queue, &data, &len); logwrite(ctx, data, len); bufchain_consume(&ctx->queue, len); } }
/* * translate format codes into time/date strings * and insert them into log file name * * "&Y":YYYY "&m":MM "&d":DD "&T":hhmmss "&h":<hostname> "&&":& */ static Filename *xlatlognam(Filename *src, char *hostname, int port, struct tm *tm) { char buf[32], *bufp; int size; char *buffer; int buflen, bufsize; const char *s; Filename *ret; bufsize = FILENAME_MAX; buffer = snewn(bufsize, char); buflen = 0; s = filename_to_str(src); while (*s) { int sanitise = FALSE; /* Let (bufp, len) be the string to append. */ bufp = buf; /* don't usually override this */ if (*s == '&') { char c; s++; size = 0; if (*s) switch (c = *s++, tolower((unsigned char)c)) { 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; case 'p': size = sprintf(buf, "%d", port); break; default: buf[0] = '&'; size = 1; if (c != '&') buf[size++] = c; } /* Never allow path separators - or any other illegal * filename character - to come out of any of these * auto-format directives. E.g. 'hostname' can contain * colons, if it's an IPv6 address, and colons aren't * legal in filenames on Windows. */ sanitise = TRUE; } else { buf[0] = *s++; size = 1; } if (bufsize <= buflen + size) { bufsize = (buflen + size) * 5 / 4 + 512; buffer = sresize(buffer, bufsize, char); } while (size-- > 0) { char c = *bufp++; if (sanitise) c = filename_char_sanitise(c); buffer[buflen++] = c; } }