xref: /aosp_15_r20/external/coreboot/util/nvramtool/cli/opts.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include "common.h"
4 #include "opts.h"
5 
6 nvramtool_op_info_t nvramtool_op;
7 
8 nvramtool_op_modifier_info_t nvramtool_op_modifiers[NVRAMTOOL_NUM_OP_MODIFIERS];
9 
10 static char *handle_optional_arg(int argc, char *argv[]);
11 static void register_op(int *op_found, nvramtool_op_t op, char op_param[]);
12 static void register_op_modifier(nvramtool_op_modifier_t mod, char mod_param[]);
13 static void resolve_op_modifiers(void);
14 static void sanity_check_args(void);
15 
16 static const char getopt_string[] = "-ab:B:c::C:dD:e:hH:iL:l::np:r:tvw:xX:y:Y";
17 
18 /****************************************************************************
19  * parse_nvramtool_args
20  *
21  * Parse command line arguments.
22  ****************************************************************************/
parse_nvramtool_args(int argc,char * argv[])23 void parse_nvramtool_args(int argc, char *argv[])
24 {
25 	nvramtool_op_modifier_info_t *mod_info;
26 	int i, op_found, c;
27 
28 	for (i = 0, mod_info = nvramtool_op_modifiers;
29 	     i < NVRAMTOOL_NUM_OP_MODIFIERS; i++, mod_info++) {
30 		mod_info->found = FALSE;
31 		mod_info->found_seq = 0;
32 		mod_info->param = NULL;
33 	}
34 
35 	op_found = FALSE;
36 	opterr = 0;
37 
38 	do {
39 		switch (c = getopt(argc, argv, getopt_string)) {
40 		case 'a':
41 			register_op(&op_found,
42 				    NVRAMTOOL_OP_CMOS_SHOW_ALL_PARAMS, NULL);
43 			break;
44 		case 'b':
45 			register_op(&op_found, NVRAMTOOL_OP_WRITE_CMOS_DUMP,
46 				    optarg);
47 			break;
48 		case 'B':
49 			register_op(&op_found, NVRAMTOOL_OP_READ_CMOS_DUMP,
50 				    optarg);
51 			break;
52 		case 'c':
53 			register_op(&op_found, NVRAMTOOL_OP_CMOS_CHECKSUM,
54 				    handle_optional_arg(argc, argv));
55 			break;
56 		case 'C':
57 			register_op_modifier(NVRAMTOOL_MOD_USE_CBFS_FILE,
58 					     optarg);
59 			break;
60 		case 'd':
61 			register_op(&op_found, NVRAMTOOL_OP_LBTABLE_DUMP, NULL);
62 			break;
63 		case 'D':
64 			register_op_modifier(NVRAMTOOL_MOD_USE_CMOS_FILE,
65 					     optarg);
66 			break;
67 		case 'e':
68 			register_op(&op_found, NVRAMTOOL_OP_SHOW_PARAM_VALUES,
69 				    optarg);
70 			break;
71 		case 'h':
72 			register_op(&op_found, NVRAMTOOL_OP_SHOW_USAGE, NULL);
73 			break;
74 		case 'H':
75 			register_op(&op_found, NVRAMTOOL_OP_WRITE_HEADER_FILE, optarg);
76 			break;
77 		case 'i':
78 			register_op(&op_found,
79 				    NVRAMTOOL_OP_CMOS_SET_PARAMS_STDIN, NULL);
80 			break;
81 		case 'l':
82 			register_op(&op_found, NVRAMTOOL_OP_LBTABLE_SHOW_INFO,
83 				    handle_optional_arg(argc, argv));
84 			break;
85 		case 'L':
86 			register_op(&op_found, NVRAMTOOL_OP_WRITE_BINARY_FILE,
87 					     optarg);
88 			break;
89 		case 'n':
90 			register_op_modifier(NVRAMTOOL_MOD_SHOW_VALUE_ONLY,
91 					     NULL);
92 			break;
93 		case 'p':
94 			register_op(&op_found,
95 				    NVRAMTOOL_OP_CMOS_SET_PARAMS_FILE, optarg);
96 			break;
97 		case 'r':
98 			register_op(&op_found, NVRAMTOOL_OP_CMOS_SHOW_ONE_PARAM,
99 				    optarg);
100 			break;
101 		case 't':
102 			register_op_modifier(NVRAMTOOL_MOD_USE_CMOS_OPT_TABLE,
103 					     NULL);
104 			break;
105 		case 'v':
106 			register_op(&op_found, NVRAMTOOL_OP_SHOW_VERSION, NULL);
107 			break;
108 		case 'w':
109 			register_op(&op_found, NVRAMTOOL_OP_CMOS_SET_ONE_PARAM,
110 				    optarg);
111 			break;
112 		case 'x':
113 			register_op(&op_found, NVRAMTOOL_OP_SHOW_CMOS_HEX_DUMP,
114 				    NULL);
115 			break;
116 		case 'X':
117 			register_op(&op_found, NVRAMTOOL_OP_SHOW_CMOS_DUMPFILE,
118 				    optarg);
119 			break;
120 		case 'y':
121 			register_op_modifier(NVRAMTOOL_MOD_USE_CMOS_LAYOUT_FILE,
122 					     optarg);
123 			break;
124 		case 'Y':
125 			register_op(&op_found, NVRAMTOOL_OP_SHOW_LAYOUT, NULL);
126 			break;
127 		case -1:	/* no more command line args */
128 			break;
129 		case '?':	/* unknown option found */
130 		case 1:	/* nonoption command line arg found */
131 		default:
132 			usage(stderr);
133 			break;
134 		}
135 	} while (c != -1);
136 
137 	if (!op_found)
138 		usage(stderr);
139 
140 	resolve_op_modifiers();
141 	sanity_check_args();
142 }
143 
144 /****************************************************************************
145  * handle_optional_arg
146  *
147  * Handle a command line option with an optional argument.
148  ****************************************************************************/
handle_optional_arg(int argc,char * argv[])149 static char *handle_optional_arg(int argc, char *argv[])
150 {
151 	char *arg;
152 
153 	if (optarg != NULL) {
154 		/* optional arg is present and arg was specified as
155 		 * "-zarg" (with no whitespace between "z" and "arg"),
156 		 * where -z is the option and "arg" is the value of the
157 		 * optional arg
158 		 */
159 		return optarg;
160 	}
161 
162 	if ((argv[optind] == NULL) || (argv[optind][0] == '-'))
163 		return NULL;
164 
165 	arg = argv[optind];	/* optional arg is present */
166 
167 	/* This call to getopt yields the optional arg we just found,
168 	 * which we want to skip.
169 	 */
170 	getopt(argc, argv, getopt_string);
171 
172 	return arg;
173 }
174 
175 /****************************************************************************
176  * register_op
177  *
178  * Store the user's selection of which operation this program should perform.
179  ****************************************************************************/
register_op(int * op_found,nvramtool_op_t op,char op_param[])180 static void register_op(int *op_found, nvramtool_op_t op, char op_param[])
181 {
182 	if (*op_found && (op != nvramtool_op.op))
183 		usage(stderr);
184 
185 	*op_found = TRUE;
186 	nvramtool_op.op = op;
187 	nvramtool_op.param = op_param;
188 }
189 
190 /****************************************************************************
191  * register_op_modifier
192  *
193  * Store information regarding an optional argument specified in addition to
194  * the user's selection of which operation this program should perform.
195  ****************************************************************************/
register_op_modifier(nvramtool_op_modifier_t mod,char mod_param[])196 static void register_op_modifier(nvramtool_op_modifier_t mod, char mod_param[])
197 {
198 	static int found_seq = 0;
199 	nvramtool_op_modifier_info_t *mod_info;
200 
201 	mod_info = &nvramtool_op_modifiers[mod];
202 	mod_info->found = TRUE;
203 	mod_info->found_seq = ++found_seq;
204 	mod_info->param = mod_param;
205 }
206 
207 /****************************************************************************
208  * resolve_op_modifiers
209  *
210  * If the user specifies multiple arguments that conflict with each other,
211  * the last specified argument overrides previous conflicting arguments.
212  ****************************************************************************/
resolve_op_modifiers(void)213 static void resolve_op_modifiers(void)
214 {
215 	if (nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_LAYOUT_FILE].found &&
216 	    nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_OPT_TABLE].found) {
217 		if (nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_LAYOUT_FILE].found_seq >
218 		    nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_OPT_TABLE].found_seq)
219 			nvramtool_op_modifiers
220 			    [NVRAMTOOL_MOD_USE_CMOS_OPT_TABLE].found = FALSE;
221 		else
222 			nvramtool_op_modifiers
223 			    [NVRAMTOOL_MOD_USE_CMOS_LAYOUT_FILE].found = FALSE;
224 	}
225 }
226 
227 /****************************************************************************
228  * sanity_check_args
229  *
230  * Perform sanity checking on command line arguments.
231  ****************************************************************************/
sanity_check_args(void)232 static void sanity_check_args(void)
233 {
234 	if ((nvramtool_op_modifiers[NVRAMTOOL_MOD_SHOW_VALUE_ONLY].found) &&
235 	    (nvramtool_op.op != NVRAMTOOL_OP_CMOS_SHOW_ONE_PARAM))
236 		usage(stderr);
237 }
238