2 * udevinfo - fetches attributes for a device
4 * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation version 2 of the License.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 #include "libsysfs/sysfs/libsysfs.h"
30 #include "libsysfs/dlist.h"
32 #include "udev_utils.h"
33 #include "udev_version.h"
38 #define SYSFS_VALUE_SIZE 256
41 void log_message (int level, const char *format, ...)
45 va_start(args, format);
46 vsyslog(level, format, args);
51 static void print_all_attributes(struct dlist *attr_list)
53 struct sysfs_attribute *attr;
54 char value[SYSFS_VALUE_SIZE];
57 dlist_for_each_data(attr_list, attr, struct sysfs_attribute) {
58 if (attr->value != NULL) {
59 strfieldcpy(value, attr->value);
64 /* remove trailing newline */
65 if (value[len-1] == '\n') {
70 /* skip nonprintable values */
72 if (isprint(value[len-1]) == 0)
77 printf(" SYSFS{%s}=\"%s\"\n", attr->name, value);
83 static int print_record(struct udevice *udev)
85 struct name_entry *name_loop;
87 printf("P: %s\n", udev->devpath);
88 printf("N: %s\n", udev->name);
89 list_for_each_entry(name_loop, &udev->symlink_list, node)
90 printf("S: %s\n", name_loop->name);
103 static int print_device_chain(const char *path)
105 struct sysfs_class_device *class_dev;
106 struct sysfs_class_device *class_dev_parent;
107 struct sysfs_attribute *attr;
108 struct sysfs_device *sysfs_dev;
109 struct sysfs_device *sysfs_dev_parent;
110 struct dlist *attr_list;
113 /* get the class dev */
114 class_dev = sysfs_open_class_device_path(path);
115 if (class_dev == NULL) {
116 printf("couldn't get the class device\n");
120 printf("\nudevinfo starts with the device the node belongs to and then walks up the\n"
121 "device chain, to print for every device found, all possibly useful attributes\n"
122 "in the udev key format.\n"
123 "Only attributes within one device section may be used together in one rule,\n"
124 "to match the device for which the node will be created.\n"
127 /* look for the 'dev' file */
128 attr = sysfs_get_classdev_attr(class_dev, "dev");
130 printf("device '%s' has major:minor %s", class_dev->path, attr->value);
132 /* open sysfs class device directory and print all attributes */
133 printf(" looking at class device '%s':\n", class_dev->path);
134 printf(" SUBSYSTEM=\"%s\"\n", class_dev->classname);
136 attr_list = sysfs_get_classdev_attributes(class_dev);
137 if (attr_list == NULL) {
138 printf("couldn't open class device directory\n");
142 print_all_attributes(attr_list);
144 /* get the device link (if parent exists look here) */
145 class_dev_parent = sysfs_get_classdev_parent(class_dev);
146 if (class_dev_parent != NULL)
147 sysfs_dev = sysfs_get_classdev_device(class_dev_parent);
149 sysfs_dev = sysfs_get_classdev_device(class_dev);
151 if (sysfs_dev != NULL)
152 printf("follow the class device's \"device\"\n");
154 /* look the device chain upwards */
155 while (sysfs_dev != NULL) {
156 attr_list = sysfs_get_device_attributes(sysfs_dev);
157 if (attr_list == NULL) {
158 printf("couldn't open device directory\n");
163 printf(" looking at the device chain at '%s':\n", sysfs_dev->path);
164 printf(" BUS=\"%s\"\n", sysfs_dev->bus);
165 printf(" ID=\"%s\"\n", sysfs_dev->bus_id);
166 printf(" DRIVER=\"%s\"\n", sysfs_dev->driver_name);
168 /* open sysfs device directory and print all attributes */
169 print_all_attributes(attr_list);
171 sysfs_dev_parent = sysfs_get_device_parent(sysfs_dev);
172 if (sysfs_dev_parent == NULL)
175 sysfs_dev = sysfs_dev_parent;
179 sysfs_close_class_device(class_dev);
183 static int print_dump(const char *devpath, const char *name) {
184 printf("%s:%s/%s\n", devpath, udev_root, name);
188 int main(int argc, char *argv[], char *envp[])
190 static const char short_options[] = "adn:p:q:rVh";
195 enum query_type query = NONE;
196 char path[NAME_SIZE] = "";
197 char name[NAME_SIZE] = "";
198 char temp[NAME_SIZE];
199 struct name_entry *name_loop;
203 logging_init("udevinfo");
206 udev_init_device(&udev, NULL, NULL);
208 /* get command line options */
210 option = getopt(argc, argv, short_options);
214 dbg("option '%c'", option);
217 dbg("udev name: %s\n", optarg);
218 strfieldcpy(name, optarg);
222 dbg("udev path: %s\n", optarg);
223 strfieldcpy(path, optarg);
227 dbg("udev query: %s\n", optarg);
229 if (strcmp(optarg, "name") == 0) {
234 if (strcmp(optarg, "symlink") == 0) {
239 if (strcmp(optarg, "path") == 0) {
244 if (strcmp(optarg, "all") == 0) {
249 printf("unknown query type\n");
262 udev_db_dump_names(print_dump);
266 printf("udevinfo, version %s\n", UDEV_VERSION);
277 /* process options */
279 if (path[0] != '\0') {
280 /* remove sysfs_path if given */
281 if (strncmp(path, sysfs_path, strlen(sysfs_path)) == 0) {
282 pos = path + strlen(sysfs_path);
284 if (path[0] != '/') {
285 /* prepend '/' if missing */
287 strfieldcat(temp, path);
293 retval = udev_db_get_device(&udev, pos);
295 printf("device not found in database\n");
301 if (name[0] != '\0') {
302 char devpath[NAME_SIZE];
305 /* remove udev_root if given */
306 len = strlen(udev_root);
307 if (strncmp(name, udev_root, len) == 0) {
312 retval = udev_db_search_name(devpath, DEVPATH_SIZE, pos);
314 printf("device not found in database\n");
317 udev_db_get_device(&udev, devpath);
321 printf("query needs device path(-p) or node name(-n) specified\n");
329 printf("%s/%s\n", udev_root, udev.name);
331 printf("%s\n", udev.name);
334 if (list_empty(&udev.symlink_list))
337 list_for_each_entry(name_loop, &udev.symlink_list, node)
338 printf("%s/%s ", udev_root, name_loop->name);
340 list_for_each_entry(name_loop, &udev.symlink_list, node)
341 printf("%s ", name_loop->name);
345 printf("%s\n", udev.devpath);
356 if (path[0] == '\0') {
357 printf("attribute walk on device chain needs path(-p) specified\n");
361 if (strncmp(path, sysfs_path, strlen(sysfs_path)) != 0) {
362 /* prepend sysfs mountpoint if not given */
363 strfieldcpy(temp, path);
364 strfieldcpy(path, sysfs_path);
365 strfieldcat(path, temp);
367 print_device_chain(path);
373 printf("%s\n", udev_root);
378 printf("Usage: udevinfo [-anpqrVh]\n"
379 " -q TYPE query database for the specified value:\n"
380 " 'name' name of device node\n"
381 " 'symlink' pointing to node\n"
382 " 'path' sysfs device path\n"
383 " 'all' all values\n"
385 " -p PATH sysfs device path used for query or chain\n"
386 " -n NAME node/symlink name used for query\n"
388 " -r print udev root\n"
389 " -a print all SYSFS_attributes along the device chain\n"
390 " -d print the relationship of devpath and the node name for all\n"
391 " devices available in the database\n"
392 " -V print udev version\n"
393 " -h print this help text\n"
397 udev_cleanup_device(&udev);