nvramtool:
[coreboot.git] / util / nvramtool / opts.c
1 /*****************************************************************************\
2  * opts.c
3  *****************************************************************************
4  *  Copyright (C) 2002-2005 The Regents of the University of California.
5  *  Produced at the Lawrence Livermore National Laboratory.
6  *  Written by Dave Peterson <dsp@llnl.gov> <dave_peterson@pobox.com>.
7  *  UCRL-CODE-2003-012
8  *  All rights reserved.
9  *
10  *  This file is part of nvramtool, a utility for reading/writing coreboot
11  *  parameters and displaying information from the coreboot table.
12  *  For details, see http://coreboot.org/nvramtool.
13  *
14  *  Please also read the file DISCLAIMER which is included in this software
15  *  distribution.
16  *
17  *  This program is free software; you can redistribute it and/or modify it
18  *  under the terms of the GNU General Public License (as published by the
19  *  Free Software Foundation) version 2, dated June 1991.
20  *
21  *  This program is distributed in the hope that it will be useful, but
22  *  WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
23  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the terms and
24  *  conditions of the GNU General Public License for more details.
25  *
26  *  You should have received a copy of the GNU General Public License along
27  *  with this program; if not, write to the Free Software Foundation, Inc.,
28  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
29 \*****************************************************************************/
30
31 #include "common.h"
32 #include "opts.h"
33
34 nvramtool_op_info_t nvramtool_op;
35
36 nvramtool_op_modifier_info_t nvramtool_op_modifiers[NVRAMTOOL_NUM_OP_MODIFIERS];
37
38 static char * handle_optional_arg (int argc, char *argv[]);
39 static void register_op (int *op_found, nvramtool_op_t op, char op_param[]);
40 static void register_op_modifier (nvramtool_op_modifier_t mod, char mod_param[]);
41 static void resolve_op_modifiers (void);
42 static void sanity_check_args (void);
43
44 static const char getopt_string[] = "-ab:B:c::de:hil::np:r:tvw:xX:y:Y";
45
46 /****************************************************************************
47  * parse_nvramtool_args
48  *
49  * Parse command line arguments.
50  ****************************************************************************/
51 void parse_nvramtool_args (int argc, char *argv[])
52  { nvramtool_op_modifier_info_t *mod_info;
53    int i, op_found;
54    char c;
55
56    for (i = 0, mod_info = nvramtool_op_modifiers;
57         i < NVRAMTOOL_NUM_OP_MODIFIERS;
58         i++, mod_info++)
59     { mod_info->found = FALSE;
60       mod_info->found_seq = 0;
61       mod_info->param = NULL;
62     }
63
64    op_found = FALSE;
65    opterr = 0;
66
67    do
68     { switch (c = getopt(argc, argv, getopt_string))
69        { case 'a':
70             register_op(&op_found, NVRAMTOOL_OP_CMOS_SHOW_ALL_PARAMS, NULL);
71             break;
72          case 'b':
73             register_op(&op_found, NVRAMTOOL_OP_WRITE_CMOS_DUMP, optarg);
74             break;
75          case 'B':
76             register_op(&op_found, NVRAMTOOL_OP_READ_CMOS_DUMP, optarg);
77             break;
78          case 'c':
79             register_op(&op_found, NVRAMTOOL_OP_CMOS_CHECKSUM,
80                         handle_optional_arg(argc, argv));
81             break;
82          case 'd':
83             register_op(&op_found, NVRAMTOOL_OP_LBTABLE_DUMP, NULL);
84             break;
85          case 'e':
86             register_op(&op_found, NVRAMTOOL_OP_SHOW_PARAM_VALUES, optarg);
87             break;
88          case 'h':
89             register_op(&op_found, NVRAMTOOL_OP_SHOW_USAGE, NULL);
90             break;
91          case 'i':
92             register_op(&op_found, NVRAMTOOL_OP_CMOS_SET_PARAMS_STDIN, NULL);
93             break;
94          case 'l':
95             register_op(&op_found, NVRAMTOOL_OP_LBTABLE_SHOW_INFO,
96                         handle_optional_arg(argc, argv));
97             break;
98          case 'n':
99             register_op_modifier(NVRAMTOOL_MOD_SHOW_VALUE_ONLY, NULL);
100             break;
101          case 'p':
102             register_op(&op_found, NVRAMTOOL_OP_CMOS_SET_PARAMS_FILE, optarg);
103             break;
104          case 'r':
105             register_op(&op_found, NVRAMTOOL_OP_CMOS_SHOW_ONE_PARAM, optarg);
106             break;
107          case 't':
108             register_op_modifier(NVRAMTOOL_MOD_USE_CMOS_OPT_TABLE, NULL);
109             break;
110          case 'v':
111             register_op(&op_found, NVRAMTOOL_OP_SHOW_VERSION, NULL);
112             break;
113          case 'w':
114             register_op(&op_found, NVRAMTOOL_OP_CMOS_SET_ONE_PARAM, optarg);
115             break;
116          case 'x':
117             register_op(&op_found, NVRAMTOOL_OP_SHOW_CMOS_HEX_DUMP, NULL);
118             break;
119          case 'X':
120             register_op(&op_found, NVRAMTOOL_OP_SHOW_CMOS_DUMPFILE, optarg);
121             break;
122          case 'y':
123             register_op_modifier(NVRAMTOOL_MOD_USE_CMOS_LAYOUT_FILE, optarg);
124             break;
125          case 'Y':
126             register_op(&op_found, NVRAMTOOL_OP_SHOW_LAYOUT, NULL);
127             break;
128          case -1:  /* no more command line args */
129             break;
130          case '?':  /* unknown option found */
131          case 1:  /* nonoption command line arg found */
132          default:
133             usage(stderr);
134             break;
135        }
136     }
137    while (c != -1);
138
139    if (!op_found)
140       usage(stderr);
141
142    resolve_op_modifiers();
143    sanity_check_args();
144  }
145
146 /****************************************************************************
147  * handle_optional_arg
148  *
149  * Handle a command line option with an optional argument.
150  ****************************************************************************/
151 static char * handle_optional_arg (int argc, char *argv[])
152  { char *arg;
153
154    if (optarg != NULL)
155     { /* optional arg is present and arg was specified as "-zarg" (with no
156        * whitespace between "z" and "arg"), where -z is the option and "arg"
157        * is the value of the 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, which we want
168     * 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  ****************************************************************************/
180 static void register_op (int *op_found, nvramtool_op_t op, char op_param[])
181  { if (*op_found && (op != nvramtool_op.op))
182       usage(stderr);
183
184    *op_found = TRUE;
185    nvramtool_op.op = op;
186    nvramtool_op.param = op_param;
187  }
188
189 /****************************************************************************
190  * register_op_modifier
191  *
192  * Store information regarding an optional argument specified in addition to
193  * the user's selection of which operation this program should perform.
194  ****************************************************************************/
195 static void register_op_modifier (nvramtool_op_modifier_t mod, char mod_param[])
196  { static int found_seq = 0;
197    nvramtool_op_modifier_info_t *mod_info;
198
199    mod_info = &nvramtool_op_modifiers[mod];
200    mod_info->found = TRUE;
201    mod_info->found_seq = ++found_seq;
202    mod_info->param = mod_param;
203  }
204
205 /****************************************************************************
206  * resolve_op_modifiers
207  *
208  * If the user specifies multiple arguments that conflict with each other,
209  * the last specified argument overrides previous conflicting arguments.
210  ****************************************************************************/
211 static void resolve_op_modifiers (void)
212  { if (nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_LAYOUT_FILE].found &&
213        nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_OPT_TABLE].found)
214     { if (nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_LAYOUT_FILE].found_seq >
215           nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_OPT_TABLE].found_seq)
216          nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_OPT_TABLE].found = FALSE;
217       else
218          nvramtool_op_modifiers[NVRAMTOOL_MOD_USE_CMOS_LAYOUT_FILE].found = FALSE;
219     }
220  }
221
222 /****************************************************************************
223  * sanity_check_args
224  *
225  * Perform sanity checking on command line arguments.
226  ****************************************************************************/
227 static void sanity_check_args (void)
228  { if ((nvramtool_op_modifiers[NVRAMTOOL_MOD_SHOW_VALUE_ONLY].found) &&
229        (nvramtool_op.op != NVRAMTOOL_OP_CMOS_SHOW_ONE_PARAM))
230       usage(stderr);
231  }