1 /* $NetBSD: main.c,v 1.12 2009/06/10 03:30:32 jnemeth Exp $ */
4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
29 #include <sys/cdefs.h>
31 __RCSID("$NetBSD: main.c,v 1.12 2009/06/10 03:30:32 jnemeth Exp $");
34 #include <sys/module.h>
35 #include <sys/queue.h>
45 #include <prop/proplib.h>
47 int main(int, char **);
48 static void parse_bool_param(prop_dictionary_t
, const char *,
50 static void parse_int_param(prop_dictionary_t
, const char *,
52 static void parse_param(prop_dictionary_t
, const char *,
53 void (*)(prop_dictionary_t
, const char *,
55 static void parse_string_param(prop_dictionary_t
, const char *,
57 static void usage(void) __dead
;
58 static void merge_dicts(prop_dictionary_t
, const prop_dictionary_t
);
61 main(int argc
, char **argv
)
63 SIMPLEQ_HEAD(del_head
, del_item
) del_head
;
64 modctl_load_t cmdargs
;
65 prop_dictionary_t ext_props
, props
;
66 bool del_props
, merge_props
, output_props
;
73 SIMPLEQ_ENTRY(del_item
) del_items
;
77 SIMPLEQ_INIT(&del_head
);
80 props
= prop_dictionary_create();
81 del_props
= merge_props
= output_props
= false;
84 while ((ch
= getopt(argc
, argv
, "Pb:d:fi:m:ps:")) != -1) {
87 flags
|= MODCTL_NO_PROP
;
90 parse_param(props
, optarg
, parse_bool_param
);
95 delp
= malloc(sizeof(struct del_item
));
97 errx(EXIT_FAILURE
, "Out of memory");
98 delp
->del_key
= optarg
;
99 SIMPLEQ_INSERT_TAIL(&del_head
, delp
, del_items
);
103 flags
|= MODCTL_LOAD_FORCE
;
107 parse_param(props
, optarg
, parse_int_param
);
120 parse_param(props
, optarg
, parse_string_param
);
132 propsstr
= prop_dictionary_externalize(props
);
133 if (propsstr
== NULL
)
134 errx(EXIT_FAILURE
, "Failed to process properties");
139 prop_dictionary_internalize_from_file(ext_file
);
140 if (ext_props
== NULL
) {
141 errx(EXIT_FAILURE
, "Failed to read existing "
146 merge_dicts(ext_props
, props
);
149 SIMPLEQ_FOREACH(delp
, &del_head
, del_items
)
150 prop_dictionary_remove(ext_props
,
153 propsstr
= prop_dictionary_externalize(ext_props
);
154 if (propsstr
== NULL
)
155 errx(EXIT_FAILURE
, "Failed to process "
159 fputs(propsstr
, stdout
);
163 cmdargs
.ml_filename
= argv
[0];
164 cmdargs
.ml_flags
= flags
;
165 cmdargs
.ml_props
= propsstr
;
166 cmdargs
.ml_propslen
= strlen(propsstr
);
168 if (modctl(MODCTL_LOAD
, &cmdargs
)) {
169 err(EXIT_FAILURE
, NULL
);
174 prop_object_release(props
);
180 parse_bool_param(prop_dictionary_t props
, const char *name
,
185 assert(name
!= NULL
);
186 assert(value
!= NULL
);
188 if (strcasecmp(value
, "1") == 0 ||
189 strcasecmp(value
, "true") == 0 ||
190 strcasecmp(value
, "yes") == 0)
192 else if (strcasecmp(value
, "0") == 0 ||
193 strcasecmp(value
, "false") == 0 ||
194 strcasecmp(value
, "no") == 0)
197 errx(EXIT_FAILURE
, "Invalid boolean value `%s'", value
);
199 prop_dictionary_set(props
, name
, prop_bool_create(boolvalue
));
203 parse_int_param(prop_dictionary_t props
, const char *name
,
208 assert(name
!= NULL
);
209 assert(value
!= NULL
);
211 if (dehumanize_number(value
, &intvalue
) != 0)
212 err(EXIT_FAILURE
, "Invalid integer value `%s'", value
);
214 prop_dictionary_set(props
, name
,
215 prop_number_create_integer(intvalue
));
219 parse_param(prop_dictionary_t props
, const char *origstr
,
220 void (*fmt_handler
)(prop_dictionary_t
, const char *, const char *))
224 name
= strdup(origstr
);
226 value
= strchr(name
, '=');
229 errx(EXIT_FAILURE
, "Invalid parameter `%s'", origstr
);
233 fmt_handler(props
, name
, value
);
239 parse_string_param(prop_dictionary_t props
, const char *name
,
243 assert(name
!= NULL
);
244 assert(value
!= NULL
);
246 prop_dictionary_set(props
, name
, prop_string_create_cstring(value
));
253 (void)fprintf(stderr
,
254 "Usage: %s [-fP] [-b var=boolean] [-i var=integer] "
255 "[-s var=string] module\n"
256 " %s -p [-b var=boolean] [-d var] [-i var=integer] "
257 "[-m plist]\n [-s var=string]\n",
258 getprogname(), getprogname());
263 merge_dicts(prop_dictionary_t existing_dict
, const prop_dictionary_t new_dict
)
265 prop_dictionary_keysym_t props_keysym
;
266 prop_object_iterator_t props_iter
;
267 prop_object_t props_obj
;
268 const char *props_key
;
270 props_iter
= prop_dictionary_iterator(new_dict
);
271 if (props_iter
== NULL
) {
272 errx(EXIT_FAILURE
, "Failed to iterate new property list");
275 while ((props_obj
= prop_object_iterator_next(props_iter
)) != NULL
) {
276 props_keysym
= (prop_dictionary_keysym_t
)props_obj
;
277 props_key
= prop_dictionary_keysym_cstring_nocopy(props_keysym
);
278 props_obj
= prop_dictionary_get_keysym(new_dict
, props_keysym
);
279 if ((props_obj
== NULL
) || !prop_dictionary_set(existing_dict
,
280 props_key
, props_obj
)) {
281 errx(EXIT_FAILURE
, "Failed to copy "
282 "existing property list");
285 prop_object_iterator_release(props_iter
);