iPXE
linux_args.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
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 St, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 FILE_LICENCE(GPL2_OR_LATER);
20 
21 #include <hci/linux_args.h>
22 #include <getopt.h>
23 #include <string.h>
24 #include <stdio.h>
25 #include <ipxe/settings.h>
26 #include <ipxe/linux.h>
27 #include <ipxe/malloc.h>
28 #include <ipxe/init.h>
29 
30 /** Saved argc */
31 static int saved_argc = 0;
32 /** Saved argv */
33 static char ** saved_argv;
34 
35 /**
36  * Save argc and argv for later access.
37  *
38  * To be called by linuxprefix
39  */
40 __asmcall void save_args(int argc, char **argv)
41 {
42  saved_argc = argc;
43  saved_argv = argv;
44 }
45 
46 /** Supported command-line options */
47 static struct option options[] = {
48  {"net", 1, NULL, 'n'},
49  {"settings", 1, NULL, 's'},
50  {NULL, 0, NULL, 0}
51 };
52 
53 /**
54  * Parse k1=v1[,k2=v2]* into linux_settings
55  */
56 static int parse_kv(char *kv, struct list_head *list)
57 {
58  char *token;
59  char *name;
60  char *value;
61  struct linux_setting *setting;
62 
63  while ((token = strsep(&kv, ",")) != NULL) {
64  name = strsep(&token, "=");
65  if (name == NULL)
66  continue;
67  value = token;
68  if (value == NULL) {
69  DBG("Bad parameter: '%s'\n", name);
70  continue;
71  }
72 
73  setting = malloc(sizeof(*setting));
74 
75  if (! setting)
76  return -1;
77 
78  setting->name = name;
79  setting->value = value;
80  setting->applied = 0;
81  list_add(&setting->list, list);
82  }
83 
84  return 0;
85 }
86 
87 /**
88  * Parse --net arguments
89  *
90  * Format is --net driver_name[,name=value]*
91  */
92 static int parse_net_args(char *args)
93 {
94  char *driver;
95  struct linux_device_request *dev_request;
96  int rc;
97 
98  driver = strsep(&args, ",");
99 
100  if (strlen(driver) == 0) {
101  printf("Missing driver name");
102  return -1;
103  }
104 
105  dev_request = malloc(sizeof(*dev_request));
106 
107  dev_request->driver = driver;
108  INIT_LIST_HEAD(&dev_request->settings);
109  list_add_tail(&dev_request->list, &linux_device_requests);
110 
111  /* Parse rest of the settings */
112  rc = parse_kv(args, &dev_request->settings);
113 
114  if (rc)
115  printf("Parsing net settings failed");
116 
117  return rc;
118 }
119 
120 /**
121  * Parse --settings arguments
122  *
123  * Format is --settings name=value[,name=value]*
124  */
125 static int parse_settings_args(char *args)
126 {
127  return parse_kv(args, &linux_global_settings);
128 }
129 
130 
131 /** Parse passed command-line arguments */
133 {
134  int c;
135  int rc;
136 
137  reset_getopt();
138  while (1) {
139  int option_index = 0;
140 
141  c = getopt_long(saved_argc, saved_argv, "", options, &option_index);
142  if (c == -1)
143  break;
144 
145  switch (c) {
146  case 'n':
147  if ((rc = parse_net_args(optarg)) != 0)
148  return;
149  break;
150  case 's':
151  if ((rc = parse_settings_args(optarg)) != 0)
152  return;
153  break;
154  default:
155  return;
156  }
157  }
158 
159  return;
160 }
161 
162 /** Clean up requests and settings */
164 {
166  struct linux_device_request *rtmp;
167  struct linux_setting *setting;
168  struct linux_setting *stmp;
169 
170  /* Clean up requests and their settings */
172  list_for_each_entry_safe(setting, stmp, &request->settings, list) {
173  list_del(&setting->list);
174  free(setting);
175  }
176  list_del(&request->list);
177  free(request);
178  }
179 
180  /* Clean up global settings */
182  list_del(&setting->list);
183  free(setting);
184  }
185 }
186 
187 struct startup_fn startup_linux_args __startup_fn(STARTUP_EARLY) = {
188  .name = "linux_args",
189  .startup = linux_args_parse,
190  .shutdown = linux_args_cleanup,
191 };
uint32_t c
Definition: md4.c:30
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1984
struct list_head list
List node.
Definition: linux.h:116
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition: vsprintf.c:464
static int parse_settings_args(char *args)
Parse –settings arguments.
Definition: linux_args.c:125
static int saved_argc
Saved argc.
Definition: linux_args.c:31
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:69
#define STARTUP_EARLY
Early startup.
Definition: init.h:62
Linux devices, drivers and device requests.
A device request.
Definition: linux.h:98
void linux_args_parse()
Parse passed command-line arguments.
Definition: linux_args.c:132
const char * name
Definition: init.h:42
A doubly-linked list entry (or list head)
Definition: list.h:18
Dynamic memory allocation.
const char * name
Name.
Definition: settings.h:28
A startup/shutdown function.
Definition: init.h:41
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
#define __asmcall
Declare a function with standard calling conventions.
Definition: compiler.h:12
FILE_LICENCE(GPL2_OR_LATER)
Parse command-line options.
A long option, as used for getopt_long()
Definition: getopt.h:24
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
A device request setting.
Definition: linux.h:108
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition: list.h:447
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
Configuration settings.
__asmcall void save_args(int argc, char **argv)
Save argc and argv for later access.
Definition: linux_args.c:40
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
static int parse_kv(char *kv, struct list_head *list)
Parse k1=v1[,k2=v2]* into linux_settings.
Definition: linux_args.c:56
size_t strlen(const char *src)
Get length of string.
Definition: string.c:228
static char ** saved_argv
Saved argv.
Definition: linux_args.c:33
char * driver
Driver name.
Definition: linux.h:100
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
static void reset_getopt(void)
Reset getopt() internal state.
Definition: getopt.h:89
u8 token
Definition: CIB_PRM.h:42
A setting.
Definition: settings.h:23
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
Parse command-line options.
Definition: getopt.c:229
struct startup_fn startup_linux_args __startup_fn(STARTUP_EARLY)
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
char * strsep(char **s, const char *ct)
strsep - Split a string into tokens @s: The string to be searched @ct: The characters to search for
Definition: stringextra.c:73
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
struct list_head linux_global_settings
List of global settings to apply.
struct list_head list
List node.
Definition: linux.h:102
u8 request[0]
List of IEs requested.
Definition: ieee80211.h:16
static struct option options[]
Supported command-line options.
Definition: linux_args.c:47
static int parse_net_args(char *args)
Parse –net arguments.
Definition: linux_args.c:92
char * optarg
Option argument.
Definition: getopt.c:43
struct list_head settings
List of settings.
Definition: linux.h:104
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
void linux_args_cleanup(int flags __unused)
Clean up requests and settings.
Definition: linux_args.c:163
String functions.
struct list_head linux_device_requests
List of requested devices.
uint8_t flags
Flags.
Definition: ena.h:18