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 <getopt.h>
22 #include <string.h>
23 #include <stdio.h>
24 #include <ipxe/settings.h>
25 #include <ipxe/linux.h>
26 #include <ipxe/malloc.h>
27 #include <ipxe/init.h>
28 
30 char **linux_argv;
31 
32 /** Supported command-line options */
33 static struct option options[] = {
34  {"net", 1, NULL, 'n'},
35  {"settings", 1, NULL, 's'},
36  {NULL, 0, NULL, 0}
37 };
38 
39 /**
40  * Parse k1=v1[,k2=v2]* into linux_settings
41  */
42 static int parse_kv(char *kv, struct list_head *list)
43 {
44  char *token;
45  char *name;
46  char *value;
47  struct linux_setting *setting;
48 
49  while ((token = strsep(&kv, ",")) != NULL) {
50  name = strsep(&token, "=");
51  if (name == NULL)
52  continue;
53  value = token;
54  if (value == NULL) {
55  DBG("Bad parameter: '%s'\n", name);
56  continue;
57  }
58 
59  setting = malloc(sizeof(*setting));
60 
61  if (! setting)
62  return -1;
63 
64  setting->name = name;
65  setting->value = value;
66  setting->applied = 0;
67  list_add(&setting->list, list);
68  }
69 
70  return 0;
71 }
72 
73 /**
74  * Parse --net arguments
75  *
76  * Format is --net driver_name[,name=value]*
77  */
78 static int parse_net_args(char *args)
79 {
80  char *driver;
81  struct linux_device_request *dev_request;
82  int rc;
83 
84  driver = strsep(&args, ",");
85 
86  if (strlen(driver) == 0) {
87  printf("Missing driver name");
88  return -1;
89  }
90 
91  dev_request = malloc(sizeof(*dev_request));
92 
93  dev_request->driver = driver;
94  INIT_LIST_HEAD(&dev_request->settings);
95  list_add_tail(&dev_request->list, &linux_device_requests);
96 
97  /* Parse rest of the settings */
98  rc = parse_kv(args, &dev_request->settings);
99 
100  if (rc)
101  printf("Parsing net settings failed");
102 
103  return rc;
104 }
105 
106 /**
107  * Parse --settings arguments
108  *
109  * Format is --settings name=value[,name=value]*
110  */
111 static int parse_settings_args(char *args)
112 {
113  return parse_kv(args, &linux_global_settings);
114 }
115 
116 
117 /** Parse passed command-line arguments */
119 {
120  int c;
121  int rc;
122 
123  reset_getopt();
124  while (1) {
125  int option_index = 0;
126 
127  c = getopt_long(linux_argc, linux_argv, "", options, &option_index);
128  if (c == -1)
129  break;
130 
131  switch (c) {
132  case 'n':
133  if ((rc = parse_net_args(optarg)) != 0)
134  return;
135  break;
136  case 's':
137  if ((rc = parse_settings_args(optarg)) != 0)
138  return;
139  break;
140  default:
141  return;
142  }
143  }
144 
145  return;
146 }
147 
148 /** Clean up requests and settings */
150 {
152  struct linux_device_request *rtmp;
153  struct linux_setting *setting;
154  struct linux_setting *stmp;
155 
156  /* Clean up requests and their settings */
158  list_for_each_entry_safe(setting, stmp, &request->settings, list) {
159  list_del(&setting->list);
160  free(setting);
161  }
162  list_del(&request->list);
163  free(request);
164  }
165 
166  /* Clean up global settings */
168  list_del(&setting->list);
169  free(setting);
170  }
171 }
172 
173 struct startup_fn startup_linux_args __startup_fn(STARTUP_EARLY) = {
174  .name = "linux_args",
175  .startup = linux_args_parse,
176  .shutdown = linux_args_cleanup,
177 };
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:111
#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:118
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
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.
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:42
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
char * driver
Driver name.
Definition: linux.h:100
char ** linux_argv
Definition: linux_args.c:30
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
int linux_argc
Definition: linux_args.c:29
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:33
static int parse_net_args(char *args)
Parse –net arguments.
Definition: linux_args.c:78
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:149
String functions.
struct list_head linux_device_requests
List of requested devices.
uint8_t flags
Flags.
Definition: ena.h:18