From 1c1554888875840f3d64231978aa891154b05f53 Mon Sep 17 00:00:00 2001 From: Carl-Daniel Hailfinger Date: Wed, 6 Jun 2012 09:17:06 +0000 Subject: Add logfile support Usage: flashrom --output logfile.txt Logfile output has at least dbg2 verbosity or screen verbosity, whichever is greater. Corresponding to flashrom svn r1540. Signed-off-by: Carl-Daniel Hailfinger Tested on Linux, Windows and FreeBSD. Acked-by: Idwer Vollering --- cli_classic.c | 38 +++++++++++++++++++++++++++++++++++--- cli_output.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- flash.h | 9 ++++++++- flashrom.c | 34 ++++++++++++++++++++-------------- 4 files changed, 118 insertions(+), 19 deletions(-) diff --git a/cli_classic.c b/cli_classic.c index edcef8e..b415076 100644 --- a/cli_classic.c +++ b/cli_classic.c @@ -106,7 +106,7 @@ static void cli_classic_usage(const char *name) "-z|" #endif "-E|-r |-w |-v ]\n" - " [-c ] [-l ]\n" + " [-c ] [-l ] [-o ]\n" " [-i ] [-p [:]]\n\n"); printf("Please note that the command line interface for flashrom has " @@ -135,6 +135,7 @@ static void cli_classic_usage(const char *name) "\n" " -i | --image only flash image " "from flash layout\n" + " -o | --output log to file \n" " -L | --list-supported print supported devices\n" #if CONFIG_PRINT_WIKI == 1 " -z | --list-supported-wiki print supported devices " @@ -189,7 +190,7 @@ int main(int argc, char *argv[]) enum programmer prog = PROGRAMMER_INVALID; int ret = 0; - static const char optstring[] = "r:Rw:v:nVEfc:l:i:p:Lzh"; + static const char optstring[] = "r:Rw:v:nVEfc:l:i:p:Lzho:"; static const struct option long_options[] = { {"read", 1, NULL, 'r'}, {"write", 1, NULL, 'w'}, @@ -206,11 +207,13 @@ int main(int argc, char *argv[]) {"programmer", 1, NULL, 'p'}, {"help", 0, NULL, 'h'}, {"version", 0, NULL, 'R'}, + {"output", 1, NULL, 'o'}, {NULL, 0, NULL, 0}, }; char *filename = NULL; char *layoutfile = NULL; + char *logfile = NULL; char *tempstr = NULL; char *pparam = NULL; @@ -272,7 +275,9 @@ int main(int argc, char *argv[]) chip_to_probe = strdup(optarg); break; case 'V': - verbose++; + verbose_screen++; + if (verbose_screen > MSG_DEBUG2) + verbose_logfile = verbose_screen; break; case 'E': if (++operation_specified > 1) { @@ -378,6 +383,18 @@ int main(int argc, char *argv[]) cli_classic_usage(argv[0]); exit(0); break; + case 'o': +#ifdef STANDALONE + fprintf(stderr, "Log file not supported in standalone mode. Aborting.\n"); + cli_classic_abort_usage(); +#else /* STANDALONE */ + logfile = strdup(optarg); + if (logfile[0] == '\0') { + fprintf(stderr, "No log filename specified.\n"); + cli_classic_abort_usage(); + } +#endif /* STANDALONE */ + break; default: cli_classic_abort_usage(); break; @@ -396,6 +413,13 @@ int main(int argc, char *argv[]) cli_classic_abort_usage(); } +#ifndef STANDALONE + if (logfile && check_filename(logfile, "log")) + cli_classic_abort_usage(); + if (logfile && open_logfile(logfile)) + return 1; +#endif /* !STANDALONE */ + #if CONFIG_PRINT_WIKI == 1 if (list_supported_wiki) { print_supported_wiki(); @@ -410,6 +434,11 @@ int main(int argc, char *argv[]) goto out; } +#ifndef STANDALONE + start_logging(); +#endif /* !STANDALONE */ + + print_buildinfo(); msg_gdbg("Command line (%i args):", argc - 1); for (i = 0; i < argc; i++) { msg_gdbg(" %s", argv[i]); @@ -552,5 +581,8 @@ int main(int argc, char *argv[]) out_shutdown: programmer_shutdown(); out: +#ifndef STANDALONE + ret |= close_logfile(); +#endif /* !STANDALONE */ return ret; } diff --git a/cli_output.c b/cli_output.c index 231f2a8..57a0a05 100644 --- a/cli_output.c +++ b/cli_output.c @@ -2,6 +2,7 @@ * This file is part of the flashrom project. * * Copyright (C) 2009 Sean Nelson + * Copyright (C) 2011 Carl-Daniel Hailfinger * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,8 +21,52 @@ #include #include +#include +#include #include "flash.h" +#ifndef STANDALONE +static FILE *logfile = NULL; + +int close_logfile(void) +{ + if (!logfile) + return 0; + /* No need to call fflush() explicitly, fclose() already does that. */ + if (fclose(logfile)) { + /* fclose returned an error. Stop writing to be safe. */ + logfile = NULL; + msg_perr("Closing the log file returned error %s\n", strerror(errno)); + return 1; + } + logfile = NULL; + return 0; +} + +int open_logfile(const char * const filename) +{ + if (!filename) { + msg_gerr("No filename specified.\n"); + return 1; + } + if ((logfile = fopen(filename, "w")) == NULL) { + perror(filename); + return 1; + } + return 0; +} + +void start_logging(void) +{ + enum msglevel oldverbose_screen = verbose_screen; + + /* Shut up the console. */ + verbose_screen = MSG_ERROR; + print_version(); + verbose_screen = oldverbose_screen; +} +#endif /* !STANDALONE */ + /* Please note that level is the verbosity, not the importance of the message. */ int print(enum msglevel level, const char *fmt, ...) { @@ -32,7 +77,7 @@ int print(enum msglevel level, const char *fmt, ...) if (level == MSG_ERROR) output_type = stderr; - if (level <= verbose) { + if (level <= verbose_screen) { va_start(ap, fmt); ret = vfprintf(output_type, fmt, ap); va_end(ap); @@ -42,5 +87,14 @@ int print(enum msglevel level, const char *fmt, ...) if (level != MSG_SPEW) fflush(output_type); } +#ifndef STANDALONE + if ((level <= verbose_logfile) && logfile) { + va_start(ap, fmt); + ret = vfprintf(logfile, fmt, ap); + va_end(ap); + if (level != MSG_SPEW) + fflush(logfile); + } +#endif /* !STANDALONE */ return ret; } diff --git a/flash.h b/flash.h index 0c14ce1..cae1ea9 100644 --- a/flash.h +++ b/flash.h @@ -228,7 +228,8 @@ enum write_granularity { write_gran_1byte, write_gran_256bytes, }; -extern int verbose; +extern int verbose_screen; +extern int verbose_logfile; extern const char flashrom_version[]; extern char *chip_to_probe; void map_flash_registers(struct flashctx *flash); @@ -244,6 +245,7 @@ int verify_range(struct flashctx *flash, uint8_t *cmpbuf, unsigned int start, un int need_erase(uint8_t *have, uint8_t *want, unsigned int len, enum write_granularity gran); char *strcat_realloc(char *dest, const char *src); void print_version(void); +void print_buildinfo(void); void print_banner(void); void list_programmers_linebreak(int startcol, int cols, int paren); int selfcheck(void); @@ -268,6 +270,11 @@ int write_buf_to_file(unsigned char *buf, unsigned long size, const char *filena #define ERROR_FLASHROM_LIMIT -201 /* cli_output.c */ +#ifndef STANDALONE +int open_logfile(const char * const filename); +int close_logfile(void); +void start_logging(void); +#endif enum msglevel { MSG_ERROR = 0, MSG_INFO = 1, diff --git a/flashrom.c b/flashrom.c index ec8137b..518e3d4 100644 --- a/flashrom.c +++ b/flashrom.c @@ -40,7 +40,8 @@ const char flashrom_version[] = FLASHROM_VERSION; char *chip_to_probe = NULL; -int verbose = MSG_INFO; +int verbose_screen = MSG_INFO; +int verbose_logfile = MSG_DEBUG2; static enum programmer programmer = PROGRAMMER_INVALID; @@ -1493,43 +1494,48 @@ void print_sysinfo(void) #else msg_ginfo(" on unknown machine"); #endif - msg_ginfo(", built with"); +} + +void print_buildinfo(void) +{ + msg_gdbg("flashrom was built with"); #if NEED_PCI == 1 #ifdef PCILIB_VERSION - msg_ginfo(" libpci %s,", PCILIB_VERSION); + msg_gdbg(" libpci %s,", PCILIB_VERSION); #else - msg_ginfo(" unknown PCI library,"); + msg_gdbg(" unknown PCI library,"); #endif #endif #ifdef __clang__ - msg_ginfo(" LLVM Clang"); + msg_gdbg(" LLVM Clang"); #ifdef __clang_version__ - msg_ginfo(" %s,", __clang_version__); + msg_gdbg(" %s,", __clang_version__); #else - msg_ginfo(" unknown version (before r102686),"); + msg_gdbg(" unknown version (before r102686),"); #endif #elif defined(__GNUC__) - msg_ginfo(" GCC"); + msg_gdbg(" GCC"); #ifdef __VERSION__ - msg_ginfo(" %s,", __VERSION__); + msg_gdbg(" %s,", __VERSION__); #else - msg_ginfo(" unknown version,"); + msg_gdbg(" unknown version,"); #endif #else - msg_ginfo(" unknown compiler,"); + msg_gdbg(" unknown compiler,"); #endif #if defined (__FLASHROM_LITTLE_ENDIAN__) - msg_ginfo(" little endian"); + msg_gdbg(" little endian"); #else - msg_ginfo(" big endian"); + msg_gdbg(" big endian"); #endif - msg_ginfo("\n"); + msg_gdbg("\n"); } void print_version(void) { msg_ginfo("flashrom v%s", flashrom_version); print_sysinfo(); + msg_ginfo("\n"); } void print_banner(void) -- cgit v1.1