[cloud] Allow aws-import script to run on Python 3.6
[ipxe.git] / src / hci / linux_args.c
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
29 int linux_argc;
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 */
118 void linux_args_parse()
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 */
149 void linux_args_cleanup(int flags __unused)
150 {
151 struct linux_device_request *request;
152 struct linux_device_request *rtmp;
153 struct linux_setting *setting;
154 struct linux_setting *stmp;
155
156 /* Clean up requests and their settings */
157 list_for_each_entry_safe(request, rtmp, &linux_device_requests, list) {
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 */
167 list_for_each_entry_safe(setting, stmp, &linux_global_settings, list) {
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 };