Add option to log output to a file

Corresponds to r1540 from upstream.

Allows the user to specify a logfile with the
-o <filename> or --o <filename> option. The logfile
by default has a higher verbosity level than the output
to the screen, so it will contain more information.

BUG=chromium:478356
BRANCH=none
TEST=works correctly on Linux

Change-Id: Ieaf5c16a11467f0bfcdc524a90c96f8649ca50b0
Signed-off-by: Souvik Ghosh <souvikghosh@google.com>
Reviewed-on: https://chromium-review.googlesource.com/361822
Reviewed-by: David Hendricks <dhendrix@chromium.org>
diff --git a/cli_output.c b/cli_output.c
index 2a67bea..424721c 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 <audiohacked@gmail.com>
+ * 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 <stdio.h>
 #include <stdarg.h>
+#include <string.h>
+#include <errno.h>
 #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)
+{
+	int oldverbose_screen = verbose_screen;
+
+	/* make the console quieter. */
+	verbose_screen = MSG_ERROR;
+	print_version();
+	verbose_screen = oldverbose_screen;
+}
+#endif /* !STANDALONE */
+
 int print(int type, const char *fmt, ...)
 {
 	va_list ap;
@@ -33,13 +78,13 @@
 		output_type = stderr;
 		break;
 	case MSG_BARF:
-		if (verbose < 3)
+		if (verbose_screen < 3)
 			return 0;
 	case MSG_DEBUG2:
-		if (verbose < 2)
+		if (verbose_screen < 2)
 			return 0;
 	case MSG_DEBUG:
-		if (verbose < 1)
+		if (verbose_screen < 1)
 			return 0;
 	case MSG_INFO:
 	default:
@@ -51,5 +96,16 @@
 	ret = vfprintf(output_type, fmt, ap);
 	va_end(ap);
 	fflush(output_type);
+
+#ifndef STANDALONE
+	if ((type <= verbose_logfile) && logfile) {
+		va_start(ap, fmt);
+		ret = vfprintf(logfile, fmt, ap);
+		va_end(ap);
+		if (type != MSG_BARF)
+			fflush(logfile);
+	}
+#endif /* !STANDALONE */
+
 	return ret;
 }