xref: /aosp_15_r20/external/flashrom/cli_output.c (revision 0d6140be3aa665ecc836e8907834fcd3e3b018fc)
1 /*
2  * This file is part of the flashrom project.
3  *
4  * Copyright (C) 2009 Sean Nelson <[email protected]>
5  * Copyright (C) 2011 Carl-Daniel Hailfinger
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  */
17 
18 #include <stdio.h>
19 #include <stdarg.h>
20 #include <string.h>
21 #include <errno.h>
22 #include "flash.h"
23 
24 enum flashrom_log_level verbose_screen = FLASHROM_MSG_INFO;
25 enum flashrom_log_level verbose_logfile = FLASHROM_MSG_DEBUG2;
26 
27 static FILE *logfile = NULL;
28 
close_logfile(void)29 int close_logfile(void)
30 {
31 	if (!logfile)
32 		return 0;
33 	/* No need to call fflush() explicitly, fclose() already does that. */
34 	if (fclose(logfile)) {
35 		/* fclose returned an error. Stop writing to be safe. */
36 		logfile = NULL;
37 		msg_gerr("Closing the log file returned error %s\n", strerror(errno));
38 		return 1;
39 	}
40 	logfile = NULL;
41 	return 0;
42 }
43 
open_logfile(const char * const filename)44 int open_logfile(const char * const filename)
45 {
46 	if (!filename) {
47 		msg_gerr("No logfile name specified.\n");
48 		return 1;
49 	}
50 	if ((logfile = fopen(filename, "w")) == NULL) {
51 		msg_gerr("Error: opening log file \"%s\" failed: %s\n", filename, strerror(errno));
52 		return 1;
53 	}
54 	return 0;
55 }
56 
start_logging(void)57 void start_logging(void)
58 {
59 	enum flashrom_log_level oldverbose_screen = verbose_screen;
60 
61 	/* Shut up the console. */
62 	verbose_screen = FLASHROM_MSG_ERROR;
63 	print_version();
64 	verbose_screen = oldverbose_screen;
65 }
66 
flashrom_progress_stage_to_string(enum flashrom_progress_stage stage)67 static const char *flashrom_progress_stage_to_string(enum flashrom_progress_stage stage)
68 {
69 	if (stage == FLASHROM_PROGRESS_READ)
70 		return "READ";
71 	if (stage == FLASHROM_PROGRESS_WRITE)
72 		return "WRITE";
73 	if (stage == FLASHROM_PROGRESS_ERASE)
74 		return "ERASE";
75 	return "UNKNOWN";
76 }
77 
flashrom_progress_cb(struct flashrom_flashctx * flashctx)78 void flashrom_progress_cb(struct flashrom_flashctx *flashctx)
79 {
80 	struct flashrom_progress *progress_state = flashctx->progress_state;
81 	unsigned int pc = 0;
82 	unsigned int *percentages = progress_state->user_data;
83 	if (progress_state->current > 0 && progress_state->total > 0)
84 		pc = ((unsigned long long) progress_state->current * 10000llu) /
85 		     ((unsigned long long) progress_state->total * 100llu);
86 	if (percentages[progress_state->stage] != pc) {
87 		percentages[progress_state->stage] = pc;
88 		msg_ginfo("[%s] %u%% complete... ", flashrom_progress_stage_to_string(progress_state->stage), pc);
89 	}
90 }
91 
92 /* Please note that level is the verbosity, not the importance of the message. */
flashrom_print_cb(enum flashrom_log_level level,const char * fmt,va_list ap)93 int flashrom_print_cb(enum flashrom_log_level level, const char *fmt, va_list ap)
94 {
95 	int ret = 0;
96 	FILE *output_type = stdout;
97 
98 	va_list logfile_args;
99 	va_copy(logfile_args, ap);
100 
101 	if (level < FLASHROM_MSG_INFO)
102 		output_type = stderr;
103 
104 	if (level <= verbose_screen) {
105 		ret = vfprintf(output_type, fmt, ap);
106 		/* msg_*spew often happens inside chip accessors in possibly
107 		 * time-critical operations. Don't slow them down by flushing. */
108 		if (level != FLASHROM_MSG_SPEW)
109 			fflush(output_type);
110 	}
111 
112 	if ((level <= verbose_logfile) && logfile) {
113 		ret = vfprintf(logfile, fmt, logfile_args);
114 		if (level != FLASHROM_MSG_SPEW)
115 			fflush(logfile);
116 	}
117 
118 	va_end(logfile_args);
119 	return ret;
120 }
121