chiark / gitweb /
[PATCH] udevinfo: print SUBSYSTEM and DRIVER
[elogind.git] / udevinfo.c
index dc3f94fffe364deb241f8738f8d914d789c8f7cd..a6daf46be69f03cd5d37827c6950a07e86cfda5b 100644 (file)
 #include "libsysfs/sysfs/libsysfs.h"
 #include "libsysfs/dlist.h"
 #include "udev.h"
-#include "udev_lib.h"
+#include "udev_utils.h"
 #include "udev_version.h"
+#include "udev_db.h"
 #include "logging.h"
-#include "udevdb.h"
 
 
-# define SYSFS_VALUE_MAX 200
-
-char **main_argv;
-int main_argc;
+#define SYSFS_VALUE_SIZE               256
 
 #ifdef LOG
-unsigned char logname[LOGNAME_SIZE];
 void log_message (int level, const char *format, ...)
 {
        va_list args;
@@ -58,7 +54,7 @@ static int print_all_attributes(const char *path)
        struct dlist *attributes;
        struct sysfs_attribute *attr;
        struct sysfs_directory *sysfs_dir;
-       char value[SYSFS_VALUE_MAX];
+       char value[SYSFS_VALUE_SIZE];
        int len;
        int retval = 0;
 
@@ -103,18 +99,11 @@ exit:
        return retval;
 }
 
-/* callback for database dump */
-static int print_record(char *path, struct udevice *dev)
+static int print_record(struct udevice *udev)
 {
-       printf("P: %s\n", path);
-       printf("N: %s\n", dev->name);
-       printf("M: %#o\n", dev->mode);
-       printf("S: %s\n", dev->symlink);
-       printf("O: %s\n", dev->owner);
-       printf("G: %s\n", dev->group);
-       printf("F: %s\n", dev->config_file);
-       printf("L: %i\n", dev->config_line);
-       printf("T: %li\n", dev->config_time);
+       printf("P: %s\n", udev->devpath);
+       printf("N: %s\n", udev->name);
+       printf("S: %s\n", udev->symlink);
        printf("\n");
        return 0;
 }
@@ -124,9 +113,6 @@ enum query_type {
        NAME,
        PATH,
        SYMLINK,
-       MODE,
-       OWNER,
-       GROUP,
        ALL
 };
 
@@ -146,25 +132,21 @@ static int print_device_chain(const char *path)
                return -1;
        }
 
-       /* read the 'dev' file for major/minor*/
-       attr = sysfs_get_classdev_attr(class_dev, "dev");
-       if (attr == NULL) {
-               printf("couldn't get the \"dev\" file\n");
-               retval = -1;
-               goto exit;
-       }
-
        printf("\nudevinfo starts with the device the node belongs to and then walks up the\n"
               "device chain, to print for every device found, all possibly useful attributes\n"
               "in the udev key format.\n"
               "Only attributes within one device section may be used together in one rule,\n"
               "to match the device for which the node will be created.\n"
               "\n");
-       printf("device '%s' has major:minor %s", class_dev->path, attr->value);
-       sysfs_close_attribute(attr);
+
+       /* look for the 'dev' file */
+       attr = sysfs_get_classdev_attr(class_dev, "dev");
+       if (attr != NULL)
+               printf("device '%s' has major:minor %s", class_dev->path, attr->value);
 
        /* open sysfs class device directory and print all attributes */
        printf("  looking at class device '%s':\n", class_dev->path);
+       printf("    SUBSYSTEM=\"%s\"\n", class_dev->classname);
        if (print_all_attributes(class_dev->path) != 0) {
                printf("couldn't open class device directory\n");
                retval = -1;
@@ -173,11 +155,11 @@ static int print_device_chain(const char *path)
 
        /* get the device link (if parent exists look here) */
        class_dev_parent = sysfs_get_classdev_parent(class_dev);
-       if (class_dev_parent != NULL) {
-               //sysfs_close_class_device(class_dev);
-               class_dev = class_dev_parent;
-       }
-       sysfs_dev = sysfs_get_classdev_device(class_dev);
+       if (class_dev_parent != NULL) 
+               sysfs_dev = sysfs_get_classdev_device(class_dev_parent);
+       else 
+               sysfs_dev = sysfs_get_classdev_device(class_dev);
+       
        if (sysfs_dev != NULL)
                printf("follow the class device's \"device\"\n");
 
@@ -186,6 +168,7 @@ static int print_device_chain(const char *path)
                printf("  looking at the device chain at '%s':\n", sysfs_dev->path);
                printf("    BUS=\"%s\"\n", sysfs_dev->bus);
                printf("    ID=\"%s\"\n", sysfs_dev->bus_id);
+               printf("    DRIVER=\"%s\"\n", sysfs_dev->driver_name);
 
                /* open sysfs device directory and print all attributes */
                print_all_attributes(sysfs_dev->path);
@@ -194,26 +177,80 @@ static int print_device_chain(const char *path)
                if (sysfs_dev_parent == NULL)
                        break;
 
-               //sysfs_close_device(sysfs_dev);
                sysfs_dev = sysfs_dev_parent;
        }
-       sysfs_close_device(sysfs_dev);
 
 exit:
-       //sysfs_close_class_device(class_dev);
+       sysfs_close_class_device(class_dev);
        return retval;
 }
 
-static int process_options(void)
+/* print all class/main block devices with major/minor, physical device, driver and bus */
+static int print_sysfs_devices(void)
+{
+       struct dlist *subsyslist;
+       char *class;
+
+       subsyslist = sysfs_open_subsystem_list("class");
+       if (!subsyslist)
+               return -1;
+
+       dlist_for_each_data(subsyslist, class, char) {
+               struct sysfs_class *cls;
+               struct dlist *class_devices;
+               struct sysfs_class_device *class_dev;
+               struct sysfs_device *phys_dev;
+               unsigned int major, minor;
+
+               cls = sysfs_open_class(class);
+               if (!cls)
+                       continue;
+
+               class_devices = sysfs_get_class_devices(cls);
+               if (!class_devices)
+                       continue;
+
+               dlist_for_each_data(class_devices, class_dev, struct sysfs_class_device) {
+                       struct sysfs_attribute *attr;
+
+                       printf("\n");
+                       printf("DEVPATH        '%s'\n", class_dev->path);
+                       printf("SUBSYSTEM      '%s'\n", class_dev->classname);
+
+                       attr = sysfs_get_classdev_attr(class_dev, "dev");
+                       if (attr) {
+                               sscanf(attr->value, "%u:%u", &major, &minor);
+                               printf("MAJOR          %u\n", major);
+                               printf("MINOR          %u\n", minor);
+                       }
+
+                       phys_dev = sysfs_get_classdev_device(class_dev);
+                       if (phys_dev) {
+                               printf("PHYSDEVPATH    '%s'\n", phys_dev->path);
+                               if (phys_dev->bus[0] != '\0')
+                                       printf("PHYSDEVBUS     '%s'\n", phys_dev->bus);
+
+                               if (phys_dev->driver_name[0] != '\0')
+                                       printf("PHYSDEVDRIVER  '%s'\n", phys_dev->driver_name);
+                       }
+               }
+               sysfs_close_class(cls);
+       }
+       sysfs_close_list(subsyslist);
+
+       return 0;
+}
+
+static int process_options(int argc, char *argv[])
 {
-       static const char short_options[] = "adn:p:q:rVh";
+       static const char short_options[] = "an:p:q:rsVh";
        int option;
        int retval = 1;
-       struct udevice dev;
+       struct udevice udev;
        int root = 0;
        int attributes = 0;
        enum query_type query = NONE;
-       char result[NAME_SIZE] = "";
+       char result[1024] = "";
        char path[NAME_SIZE] = "";
        char name[NAME_SIZE] = "";
        char temp[NAME_SIZE];
@@ -221,7 +258,7 @@ static int process_options(void)
 
        /* get command line options */
        while (1) {
-               option = getopt(main_argc, main_argv, short_options);
+               option = getopt(argc, argv, short_options);
                if (option == -1)
                        break;
 
@@ -250,21 +287,6 @@ static int process_options(void)
                                break;
                        }
 
-                       if (strcmp(optarg, "mode") == 0) {
-                               query = MODE;
-                               break;
-                       }
-
-                       if (strcmp(optarg, "owner") == 0) {
-                               query = OWNER;
-                               break;
-                       }
-
-                       if (strcmp(optarg, "group") == 0) {
-                               query = GROUP;
-                               break;
-                       }
-
                        if (strcmp(optarg, "path") == 0) {
                                query = PATH;
                                break;
@@ -282,20 +304,14 @@ static int process_options(void)
                        root = 1;
                        break;
 
+               case 's':
+                       print_sysfs_devices();
+                       exit(0);
+
                case 'a':
                        attributes = 1;
                        break;
 
-               case 'd':
-                       retval = udevdb_open_ro();
-                       if (retval != 0) {
-                               printf("unable to open udev database\n");
-                               exit(2);
-                       }
-                       udevdb_call_foreach(print_record);
-                       udevdb_exit();
-                       exit(0);
-
                case 'V':
                        printf("udevinfo, version %s\n", UDEV_VERSION);
                        exit(0);
@@ -310,12 +326,6 @@ static int process_options(void)
 
        /* process options */
        if (query != NONE) {
-               retval = udevdb_open_ro();
-               if (retval != 0) {
-                       printf("unable to open udev database\n");
-                       return -EACCES;
-               }
-
                if (path[0] != '\0') {
                        /* remove sysfs_path if given */
                        if (strncmp(path, sysfs_path, strlen(sysfs_path)) == 0) {
@@ -330,7 +340,9 @@ static int process_options(void)
                                        pos = path;
                                }
                        }
-                       retval = udevdb_get_dev(pos, &dev);
+                       memset(&udev, 0x00, sizeof(struct udevice));
+                       strfieldcpy(udev.devpath, pos);
+                       retval = udev_db_get_device(&udev);
                        if (retval != 0) {
                                printf("device not found in database\n");
                                goto exit;
@@ -340,15 +352,21 @@ static int process_options(void)
 
                if (name[0] != '\0') {
                        /* remove udev_root if given */
-                       if (strncmp(name, udev_root, strlen(udev_root)) == 0) {
-                               pos = name + strlen(udev_root);
+                       int len = strlen(udev_root);
+
+                       if (strncmp(name, udev_root, len) == 0) {
+                               pos = &name[len+1];
                        } else
                                pos = name;
-                       retval = udevdb_get_dev_byname(pos, path, &dev);
+
+                       memset(&udev, 0x00, sizeof(struct udevice));
+                       strfieldcpy(udev.name, pos);
+                       retval = udev_db_get_device_byname(&udev, pos);
                        if (retval != 0) {
                                printf("device not found in database\n");
                                goto exit;
                        }
+
                        goto print;
                }
 
@@ -358,33 +376,37 @@ static int process_options(void)
 print:
                switch(query) {
                case NAME:
-                       if (root)
-                               strfieldcpy(result, udev_root);
-                       strfieldcat(result, dev.name);
+                       if (root) {
+                               snprintf(result, NAME_SIZE-1, "%s/%s", udev_root, udev.name);
+                               result[NAME_SIZE-1] = '\0';
+                       } else {
+                               strfieldcpy(result, udev.name);
+                       }
                        break;
 
                case SYMLINK:
-                       strfieldcpy(result, dev.symlink);
-                       break;
-
-               case MODE:
-                       sprintf(result, "%#o", dev.mode);
-                       break;
-
-               case GROUP:
-                       strfieldcpy(result, dev.group);
-                       break;
-
-               case OWNER:
-                       strfieldcpy(result, dev.owner);
+                       if (root) {
+                               int slen;
+                               char *spos;
+                               char slink[NAME_SIZE];
+
+                               pos = result;
+                               foreach_strpart(udev.symlink, " \n\r", spos, slen) {
+                                       strncpy(slink, spos, slen);
+                                       slink[slen] = '\0';
+                                       pos += sprintf(pos, "%s/%s ", udev_root, slink);
+                               }
+                       } else {
+                               strfieldcpy(result, udev.symlink);
+                       }
                        break;
 
                case PATH:
-                       strfieldcpy(result, path);
+                       strfieldcpy(result, udev.devpath);
                        break;
 
                case ALL:
-                       print_record(path, &dev);
+                       print_record(&udev);
                        goto exit;
 
                default:
@@ -393,7 +415,6 @@ print:
                printf("%s\n", result);
 
 exit:
-               udevdb_exit();
                return retval;
        }
 
@@ -419,13 +440,10 @@ exit:
        }
 
 help:
-       printf("Usage: [-anpqrdVh]\n"
+       printf("Usage: udevinfo [-anpqrVh]\n"
               "  -q TYPE  query database for the specified value:\n"
               "             'name'    name of device node\n"
               "             'symlink' pointing to node\n"
-              "             'mode'    permissions of node\n"
-              "             'owner'   of node\n"
-              "             'group'   of node\n"
               "             'path'    sysfs device path\n"
               "             'all'     all values\n"
               "\n"
@@ -434,7 +452,7 @@ help:
               "\n"
               "  -r       print udev root\n"
               "  -a       print all SYSFS_attributes along the device chain\n"
-              "  -d       dump whole database\n"
+              "  -s       print all sysfs devices with major/minor, physical device and bus\n"
               "  -V       print udev version\n"
               "  -h       print this help text\n"
               "\n");
@@ -443,18 +461,15 @@ help:
 
 int main(int argc, char *argv[], char *envp[])
 {
-       int retval;
-
-       main_argv = argv;
-       main_argc = argc;
+       int rc = 0;
 
-       init_logging("udevinfo");
+       logging_init("udevinfo");
 
        /* initialize our configuration */
        udev_init_config();
 
-       retval = process_options();
-       if (retval != 0)
-               exit(1);
-       exit(0);
+       rc = process_options(argc, argv);
+
+       logging_close();
+       exit(rc);
 }