iPXE
dynui_cmd.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 FILE_SECBOOT ( PERMITTED );
26 
27 /** @file
28  *
29  * Dynamic user interface commands
30  *
31  */
32 
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <errno.h>
37 #include <getopt.h>
38 #include <ipxe/dynui.h>
39 #include <ipxe/command.h>
40 #include <ipxe/parseopt.h>
41 #include <ipxe/settings.h>
42 #include <ipxe/features.h>
43 
45 
46 /** "dynui" options */
47 struct dynui_options {
48  /** Name */
49  char *name;
50  /** Delete */
51  int delete;
52 };
53 
54 /** "dynui" option list */
55 static struct option_descriptor dynui_opts[] = {
56  OPTION_DESC ( "name", 'n', required_argument,
57  struct dynui_options, name, parse_string ),
58  OPTION_DESC ( "delete", 'd', no_argument,
59  struct dynui_options, delete, parse_flag ),
60 };
61 
62 /** "dynui" command descriptor */
65  "[<title>]" );
66 
67 /**
68  * The "dynui" command
69  *
70  * @v argc Argument count
71  * @v argv Argument list
72  * @ret rc Return status code
73  */
74 static int dynui_exec ( int argc, char **argv ) {
75  struct dynui_options opts;
76  struct dynamic_ui *dynui;
77  char *title;
78  int rc;
79 
80  /* Parse options */
81  if ( ( rc = parse_options ( argc, argv, &dynui_cmd, &opts ) ) != 0 )
82  goto err_parse_options;
83 
84  /* Parse title */
85  title = concat_args ( &argv[optind] );
86  if ( ! title ) {
87  rc = -ENOMEM;
88  goto err_parse_title;
89  }
90 
91  /* Create dynamic user interface */
92  dynui = create_dynui ( opts.name, title );
93  if ( ! dynui ) {
94  rc = -ENOMEM;
95  goto err_create_dynui;
96  }
97 
98  /* Destroy dynamic user interface, if applicable */
99  if ( opts.delete )
100  destroy_dynui ( dynui );
101 
102  /* Success */
103  rc = 0;
104 
105  err_create_dynui:
106  free ( title );
107  err_parse_title:
108  err_parse_options:
109  return rc;
110 }
111 
112 /** "item" options */
113 struct item_options {
114  /** Dynamic user interface name */
115  char *dynui;
116  /** Shortcut key */
117  unsigned int key;
118  /** Use as default */
120  /** Value is a secret */
122  /** Use as a separator */
123  int is_gap;
124 };
125 
126 /** "item" option list */
127 static struct option_descriptor item_opts[] = {
128  OPTION_DESC ( "menu", 'm', required_argument,
129  struct item_options, dynui, parse_string ),
130  OPTION_DESC ( "form", 'f', required_argument,
131  struct item_options, dynui, parse_string ),
132  OPTION_DESC ( "key", 'k', required_argument,
133  struct item_options, key, parse_key ),
134  OPTION_DESC ( "default", 'd', no_argument,
135  struct item_options, is_default, parse_flag ),
136  OPTION_DESC ( "secret", 's', no_argument,
137  struct item_options, is_secret, parse_flag ),
138  OPTION_DESC ( "gap", 'g', no_argument,
139  struct item_options, is_gap, parse_flag ),
140 };
141 
142 /** "item" command descriptor */
145  "[<name> [<text>]]" );
146 
147 /**
148  * The "item" command
149  *
150  * @v argc Argument count
151  * @v argv Argument list
152  * @ret rc Return status code
153  */
154 static int item_exec ( int argc, char **argv ) {
155  struct item_options opts;
156  struct dynamic_ui *dynui;
157  struct dynamic_item *item;
158  unsigned int flags = 0;
159  char *name = NULL;
160  char *text = NULL;
161  int rc;
162 
163  /* Parse options */
164  if ( ( rc = parse_options ( argc, argv, &item_cmd, &opts ) ) != 0 )
165  goto err_parse_options;
166 
167  /* Parse name, if present */
168  if ( ! opts.is_gap )
169  name = argv[optind++]; /* May be NULL */
170 
171  /* Parse text, if present */
172  if ( optind < argc ) {
173  text = concat_args ( &argv[optind] );
174  if ( ! text ) {
175  rc = -ENOMEM;
176  goto err_parse_text;
177  }
178  }
179 
180  /* Identify dynamic user interface */
181  if ( ( rc = parse_dynui ( opts.dynui, &dynui ) ) != 0 )
182  goto err_parse_dynui;
183 
184  /* Add dynamic user interface item */
185  if ( opts.is_default )
186  flags |= DYNUI_DEFAULT;
187  if ( opts.is_secret )
188  flags |= DYNUI_SECRET;
189  item = add_dynui_item ( dynui, name, ( text ? text : "" ), flags,
190  opts.key );
191  if ( ! item ) {
192  rc = -ENOMEM;
193  goto err_add_dynui_item;
194  }
195 
196  /* Success */
197  rc = 0;
198 
199  err_add_dynui_item:
200  err_parse_dynui:
201  free ( text );
202  err_parse_text:
203  err_parse_options:
204  return rc;
205 }
206 
207 /** "choose" options */
209  /** Dynamic user interface name */
210  char *dynui;
211  /** Initial timeout */
212  unsigned long timeout;
213  /** Post-activity timeout */
214  unsigned long retimeout;
215  /** Default selection */
216  char *select;
217  /** Keep dynamic user interface */
218  int keep;
219 };
220 
221 /** "choose" option list */
222 static struct option_descriptor choose_opts[] = {
223  OPTION_DESC ( "menu", 'm', required_argument,
224  struct choose_options, dynui, parse_string ),
225  OPTION_DESC ( "default", 'd', required_argument,
227  OPTION_DESC ( "timeout", 't', required_argument,
229  OPTION_DESC ( "retimeout", 'r', required_argument,
230  struct choose_options, retimeout, parse_timeout ),
231  OPTION_DESC ( "keep", 'k', no_argument,
232  struct choose_options, keep, parse_flag ),
233 };
234 
235 /** "choose" command descriptor */
237  COMMAND_DESC ( struct choose_options, choose_opts, 1, 1, "<setting>" );
238 
239 /**
240  * The "choose" command
241  *
242  * @v argc Argument count
243  * @v argv Argument list
244  * @ret rc Return status code
245  */
246 static int choose_exec ( int argc, char **argv ) {
247  struct choose_options opts;
248  struct named_setting setting;
249  struct dynamic_ui *dynui;
250  struct dynamic_item *item;
251  int rc;
252 
253  /* Parse options */
254  if ( ( rc = parse_options ( argc, argv, &choose_cmd, &opts ) ) != 0 )
255  goto err_parse_options;
256 
257  /* Parse setting name */
258  if ( ( rc = parse_autovivified_setting ( argv[optind],
259  &setting ) ) != 0 )
260  goto err_parse_setting;
261 
262  /* Identify dynamic user interface */
263  if ( ( rc = parse_dynui ( opts.dynui, &dynui ) ) != 0 )
264  goto err_parse_dynui;
265 
266  /* Show as menu */
267  if ( ( rc = show_menu ( dynui, opts.timeout, opts.retimeout,
268  opts.select, &item ) ) != 0 )
269  goto err_show_menu;
270 
271  /* Apply default type if necessary */
272  if ( ! setting.setting.type )
273  setting.setting.type = &setting_type_string;
274 
275  /* Store setting */
276  if ( ( rc = storef_setting ( setting.settings, &setting.setting,
277  item->name ) ) != 0 ) {
278  printf ( "Could not store \"%s\": %s\n",
279  setting.setting.name, strerror ( rc ) );
280  goto err_store;
281  }
282 
283  /* Success */
284  rc = 0;
285 
286  err_store:
287  err_show_menu:
288  /* Destroy dynamic user interface, if applicable */
289  if ( ! opts.keep )
290  destroy_dynui ( dynui );
291  err_parse_dynui:
292  err_parse_setting:
293  err_parse_options:
294  return rc;
295 }
296 
297 /** "present" options */
299  /** Dynamic user interface name */
300  char *dynui;
301  /** Keep dynamic user interface */
302  int keep;
303 };
304 
305 /** "present" option list */
306 static struct option_descriptor present_opts[] = {
307  OPTION_DESC ( "form", 'f', required_argument,
308  struct present_options, dynui, parse_string ),
309  OPTION_DESC ( "keep", 'k', no_argument,
310  struct present_options, keep, parse_flag ),
311 };
312 
313 /** "present" command descriptor */
315  COMMAND_DESC ( struct present_options, present_opts, 0, 0, NULL );
316 
317 /**
318  * The "present" command
319  *
320  * @v argc Argument count
321  * @v argv Argument list
322  * @ret rc Return status code
323  */
324 static int present_exec ( int argc, char **argv ) {
325  struct present_options opts;
326  struct dynamic_ui *dynui;
327  int rc;
328 
329  /* Parse options */
330  if ( ( rc = parse_options ( argc, argv, &present_cmd, &opts ) ) != 0 )
331  goto err_parse_options;
332 
333  /* Identify dynamic user interface */
334  if ( ( rc = parse_dynui ( opts.dynui, &dynui ) ) != 0 )
335  goto err_parse_dynui;
336 
337  /* Show as form */
338  if ( ( rc = show_form ( dynui ) ) != 0 )
339  goto err_show_form;
340 
341  /* Success */
342  rc = 0;
343 
344  err_show_form:
345  /* Destroy dynamic user interface, if applicable */
346  if ( ! opts.keep )
347  destroy_dynui ( dynui );
348  err_parse_dynui:
349  err_parse_options:
350  return rc;
351 }
352 
353 /** Dynamic user interface commands */
354 COMMAND ( menu, dynui_exec );
355 COMMAND ( form, dynui_exec );
356 COMMAND ( item, item_exec );
357 COMMAND ( choose, choose_exec );
358 COMMAND ( present, present_exec );
char * dynui
Dynamic user interface name.
Definition: dynui_cmd.c:210
const char * title
Title.
Definition: dynui.h:22
static struct command_descriptor dynui_cmd
"dynui" command descriptor
Definition: dynui_cmd.c:63
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1986
A dynamic user interface item.
Definition: dynui.h:30
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition: vsprintf.c:465
A parsed named setting.
Definition: parseopt.h:123
int parse_key(char *text, unsigned int *key)
Parse key.
Definition: parseopt.c:242
int optind
Current option index.
Definition: getopt.c:52
static int item_exec(int argc, char **argv)
The "item" command.
Definition: dynui_cmd.c:154
int parse_dynui(char *text, struct dynamic_ui **dynui)
Parse dynamic user interface name.
Definition: parseopt.c:204
static int present_exec(int argc, char **argv)
The "present" command.
Definition: dynui_cmd.c:324
Error codes.
#define DHCP_EB_FEATURE_MENU
Menu support.
Definition: features.h:56
int parse_timeout(char *text, unsigned long *value)
Parse timeout value (in ms)
Definition: parseopt.c:115
int parse_autovivified_setting(char *text, struct named_setting *setting)
Parse and autovivify setting name.
Definition: parseopt.c:337
int keep
Keep dynamic user interface.
Definition: dynui_cmd.c:302
int parse_options(int argc, char **argv, struct command_descriptor *cmd, void *opts)
Parse command-line options.
Definition: parseopt.c:485
A command descriptor.
Definition: parseopt.h:78
FEATURE(FEATURE_MISC, "Menu", DHCP_EB_FEATURE_MENU, 1)
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
"item" options
Definition: dynui_cmd.c:113
unsigned long retimeout
Post-activity timeout.
Definition: dynui_cmd.c:214
const char * name
Name.
Definition: settings.h:29
"dynui" options
Definition: dynui_cmd.c:47
static struct option_descriptor present_opts[]
"present" option list
Definition: dynui_cmd.c:306
static struct command_descriptor present_cmd
"present" command descriptor
Definition: dynui_cmd.c:314
static struct command_descriptor item_cmd
"item" command descriptor
Definition: dynui_cmd.c:143
#define ENOMEM
Not enough space.
Definition: errno.h:535
char * select
Default selection.
Definition: dynui_cmd.c:216
"present" options
Definition: dynui_cmd.c:298
A form.
Definition: form_ui.c:65
int keep
Keep dynamic user interface.
Definition: dynui_cmd.c:218
Parse command-line options.
static int dynui_exec(int argc, char **argv)
The "dynui" command.
Definition: dynui_cmd.c:74
const char * name
Name.
Definition: dynui.h:34
int parse_string(char *text, char **value)
Parse string value.
Definition: parseopt.c:74
char * name
Name.
Definition: dynui_cmd.c:49
FILE_SECBOOT(PERMITTED)
#define MAX_ARGUMENTS
No maximum number of arguments.
Definition: parseopt.h:98
Feature list.
char * concat_args(char **args)
Concatenate arguments.
Definition: exec.c:359
const struct setting_type * type
Setting type.
Definition: settings.h:37
"choose" options
Definition: dynui_cmd.c:208
int is_default
Use as default.
Definition: dynui_cmd.c:119
static int choose_exec(int argc, char **argv)
The "choose" command.
Definition: dynui_cmd.c:246
static struct option_descriptor item_opts[]
"item" option list
Definition: dynui_cmd.c:127
struct dynamic_ui * create_dynui(const char *name, const char *title)
Create dynamic user interface.
Definition: dynui.c:49
static struct option_descriptor choose_opts[]
"choose" option list
Definition: dynui_cmd.c:222
Configuration settings.
#define FEATURE_MISC
Miscellaneous.
Definition: features.h:24
int storef_setting(struct settings *settings, const struct setting *setting, const char *value)
Store formatted value of setting.
Definition: settings.c:1320
int parse_flag(char *text __unused, int *flag)
Parse flag.
Definition: parseopt.c:227
struct dynamic_item * add_dynui_item(struct dynamic_ui *dynui, const char *name, const char *text, unsigned int flags, int shortcut)
Add dynamic user interface item.
Definition: dynui.c:104
uint8_t flags
Flags.
Definition: ena.h:18
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
static struct command_descriptor choose_cmd
"choose" command descriptor
Definition: dynui_cmd.c:236
Command line option parsing.
int select(fd_set *readfds, int wait)
Check file descriptors for readiness.
Definition: posix_io.c:229
Option does not take an argument.
Definition: getopt.h:17
A setting.
Definition: settings.h:24
int show_form(struct dynamic_ui *dynui)
Show form.
Definition: form_ui.c:508
A dynamic user interface.
Definition: dynui.h:16
COMMAND(menu, dynui_exec)
Dynamic user interface commands.
char * dynui
Dynamic user interface name.
Definition: dynui_cmd.c:115
int is_secret
Value is a secret.
Definition: dynui_cmd.c:121
int is_gap
Use as a separator.
Definition: dynui_cmd.c:123
static struct option_descriptor dynui_opts[]
"dynui" option list
Definition: dynui_cmd.c:55
const char * text
Text.
Definition: dynui.h:36
#define DYNUI_DEFAULT
Dynamic user interface item is default selection.
Definition: dynui.h:46
#define OPTION_DESC(_longopt, _shortopt, _has_arg, _struct, _field, _parse)
Construct option descriptor.
Definition: parseopt.h:68
Option requires an argument.
Definition: getopt.h:19
A command-line option descriptor.
Definition: parseopt.h:24
static union @447 opts
"cert<xxx>" option list
#define COMMAND_DESC(_struct, _options, _min_args, _max_args, _usage)
Construct command descriptor.
Definition: parseopt.h:109
void timeout(int)
char * dynui
Dynamic user interface name.
Definition: dynui_cmd.c:300
Dynamic user interfaces.
unsigned long timeout
Initial timeout.
Definition: dynui_cmd.c:212
void destroy_dynui(struct dynamic_ui *dynui)
Destroy dynamic user interface.
Definition: dynui.c:150
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
#define DYNUI_SECRET
Dynamic user interface item represents a secret.
Definition: dynui.h:49
String functions.
unsigned int key
Shortcut key.
Definition: dynui_cmd.c:117
union @391 key
Sense key.
Definition: scsi.h:18