3 * The DragonFly Project. All rights reserved.
5 * This code is derived from software contributed to The DragonFly Project
6 * by Nolan Lum <nol888@gmail.com>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
18 * 3. Neither the name of The DragonFly Project nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific, prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #include <sys/queue.h>
48 static SLIST_HEAD(, sl_entry) props = SLIST_HEAD_INITIALIZER(props);
51 SLIST_ENTRY(sl_entry) entries;
55 usage(const char *name)
58 "usage: %s [-Ah] [-p property] [-d device] [-m key:value] [-r key:value]\n"
59 "Valid options are:\n"
61 " Don't display aliases.\n"
63 " Print this help message.\n\n"
64 "Valid options with their arguments are:\n"
66 " Only display property; can be specified multiple times and\n"
67 " combined with all other options.\n"
69 " Only display devices with name `device'. When used with\n"
70 " -p, only properties `-p' of device `-d' are listed. Can be\n"
71 " specified multiple times. Allows wildcards.\n"
73 " Only display devices whose property `key' matches with wildcards\n"
74 " value `value' unless the key-value pair starts with ~, in which\n"
75 " case the match is inverted. Stacks with -p, -d, and -m.\n"
76 " Can be specified multiple times.\n"
78 " Behaves similarly to `-m', but matches with regex.\n",
84 parse_args(int argc, char *argv[], struct udev_enumerate *enumerate)
92 /* p = properties to list (defaults to all) */
93 /* d = devices to list (defaults to all) */
94 /* m = display only devices in d that match these prop values */
95 /* r = display only devices in d that match these prop values (regex) */
96 while ((ch = getopt(argc, argv, "Ap:d:m:r:h")) != -1) {
101 udev_enumerate_add_match_property(enumerate, "alias",
105 ent = malloc(sizeof(struct sl_entry));
107 SLIST_INSERT_HEAD(&props, ent, entries);
110 udev_enumerate_add_match_expr(enumerate, "name",
115 /* Check for exclusion. */
116 invert = *optarg == '~';
118 /* Split into key/value. */
119 colon = strchr(optarg, ':');
122 "Invalid property key/value pair `%s'.\n",
130 udev_enumerate_add_nomatch_regex(enumerate,
131 optarg + 1, colon + 1);
133 udev_enumerate_add_nomatch_expr(enumerate,
134 optarg + 1, colon + 1);
137 udev_enumerate_add_match_regex(enumerate,
140 udev_enumerate_add_match_expr(enumerate,
153 print_prop(const char* key, prop_object_t value)
157 printf("\t%s = ", key);
159 prop_type_t val_type = prop_object_type(value);
162 printf("%s\n", prop_bool_true((prop_bool_t)value) ?
165 case PROP_TYPE_NUMBER:
166 if (prop_number_unsigned((prop_number_t)value))
167 printf("%1$"PRIu64" (0x%1$"PRIx64")\n",
168 prop_number_unsigned_integer_value((prop_number_t)value));
170 printf("%"PRId64"\n",
171 prop_number_integer_value((prop_number_t)value));
173 case PROP_TYPE_STRING:
174 val_str = prop_string_cstring(value);
175 printf("%s\n", val_str);
184 main(int argc, char* argv[])
187 struct udev_enumerate *enumerate;
188 struct udev_list_entry *current;
189 struct udev_device *dev;
190 prop_object_t key_val;
191 prop_dictionary_t dict;
192 prop_dictionary_keysym_t cur_key;
193 prop_object_iterator_t iter;
200 err(EX_UNAVAILABLE, "udev_new");
202 enumerate = udev_enumerate_new(ctx);
203 if (enumerate == NULL)
204 err(EX_UNAVAILABLE, "udev_enumerate_new");
206 parse_args(argc, argv, enumerate);
208 ret = udev_enumerate_scan_devices(enumerate);
210 err(EX_UNAVAILABLE, "udev_enumerate_scan_devices ret = %d",
213 current = udev_enumerate_get_list_entry(enumerate);
214 if (current == NULL) {
215 printf("No devices found.\n");
217 udev_list_entry_foreach(current, current) {
218 dev = udev_list_entry_get_device(current);
221 dict = udev_device_get_dictionary(dev);
224 iter = prop_dictionary_iterator(dict);
227 dev_name = prop_string_cstring(prop_dictionary_get(dict, "name"));
228 printf("Device %s:\n", dev_name);
231 if (!SLIST_EMPTY(&props)) {
232 SLIST_FOREACH(ent, &props, entries) {
233 key_val = prop_dictionary_get(dict,
236 print_prop(ent->val, key_val);
239 while ((cur_key = (prop_dictionary_keysym_t)prop_object_iterator_next(iter)) != NULL) {
240 key_str = prop_dictionary_keysym_cstring_nocopy(cur_key);
241 key_val = prop_dictionary_get_keysym(dict,
243 print_prop(key_str, key_val);
251 udev_enumerate_unref(enumerate);