chiark / gitweb /
vol_id: export encoded strings
[elogind.git] / udevinfo.c
index dca4616958b4eeeb5e662e034af6f58346971c91..cda229244d9b59aadaea86d55fca32d098271016 100644 (file)
@@ -26,6 +26,8 @@
 #include <dirent.h>
 #include <errno.h>
 #include <getopt.h>
 #include <dirent.h>
 #include <errno.h>
 #include <getopt.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 
 #include "udev.h"
 
 
 #include "udev.h"
 
@@ -56,10 +58,23 @@ static void print_all_attributes(const char *devpath, const char *key)
        dir = opendir(path);
        if (dir != NULL) {
                for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
        dir = opendir(path);
        if (dir != NULL) {
                for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
+                       struct stat statbuf;
+                       char filename[PATH_SIZE];
                        char *attr_value;
                        char value[NAME_SIZE];
                        size_t len;
 
                        char *attr_value;
                        char value[NAME_SIZE];
                        size_t len;
 
+                       if (dent->d_name[0] == '.')
+                               continue;
+
+                       strlcpy(filename, path, sizeof(filename));
+                       strlcat(filename, "/", sizeof(filename));
+                       strlcat(filename, dent->d_name, sizeof(filename));
+                       if (lstat(filename, &statbuf) != 0)
+                               continue;
+                       if (S_ISLNK(statbuf.st_mode))
+                               continue;
+
                        attr_value = sysfs_attr_get_value(devpath, dent->d_name);
                        if (attr_value == NULL)
                                continue;
                        attr_value = sysfs_attr_get_value(devpath, dent->d_name);
                        if (attr_value == NULL)
                                continue;
@@ -78,7 +93,7 @@ static void print_all_attributes(const char *devpath, const char *key)
                                continue;
                        }
 
                                continue;
                        }
 
-                       replace_untrusted_chars(value);
+                       replace_chars(value, ALLOWED_CHARS_INPUT);
                        printf("    %s{%s}==\"%s\"\n", key, dent->d_name, value);
                }
        }
                        printf("    %s{%s}==\"%s\"\n", key, dent->d_name, value);
                }
        }
@@ -89,6 +104,10 @@ static int print_device_chain(const char *devpath)
 {
        struct sysfs_device *dev;
 
 {
        struct sysfs_device *dev;
 
+       dev = sysfs_device_get(devpath);
+       if (dev == NULL)
+               return -1;
+
        printf("\n"
               "Udevinfo starts with the device specified by the devpath and then\n"
               "walks up the chain of parent devices. It prints for every device\n"
        printf("\n"
               "Udevinfo starts with the device specified by the devpath and then\n"
               "walks up the chain of parent devices. It prints for every device\n"
@@ -97,10 +116,6 @@ static int print_device_chain(const char *devpath)
               "and the attributes from one single parent device.\n"
               "\n");
 
               "and the attributes from one single parent device.\n"
               "\n");
 
-       dev = sysfs_device_get(devpath);
-       if (dev == NULL)
-               return -1;
-
        printf("  looking at device '%s':\n", dev->devpath);
        printf("    KERNEL==\"%s\"\n", dev->kernel);
        printf("    SUBSYSTEM==\"%s\"\n", dev->subsystem);
        printf("  looking at device '%s':\n", dev->devpath);
        printf("    KERNEL==\"%s\"\n", dev->kernel);
        printf("    SUBSYSTEM==\"%s\"\n", dev->subsystem);
@@ -114,7 +129,7 @@ static int print_device_chain(const char *devpath)
                        break;
                printf("  looking at parent device '%s':\n", dev->devpath);
                printf("    KERNELS==\"%s\"\n", dev->kernel);
                        break;
                printf("  looking at parent device '%s':\n", dev->devpath);
                printf("    KERNELS==\"%s\"\n", dev->kernel);
-               printf("    SUBSYTEMS==\"%s\"\n", dev->subsystem);
+               printf("    SUBSYSTEMS==\"%s\"\n", dev->subsystem);
                printf("    DRIVERS==\"%s\"\n", dev->driver);
 
                print_all_attributes(dev->devpath, "ATTRS");
                printf("    DRIVERS==\"%s\"\n", dev->driver);
 
                print_all_attributes(dev->devpath, "ATTRS");
@@ -131,20 +146,17 @@ static void print_record(struct udevice *udev)
        printf("N: %s\n", udev->name);
        list_for_each_entry(name_loop, &udev->symlink_list, node)
                printf("S: %s\n", name_loop->name);
        printf("N: %s\n", udev->name);
        list_for_each_entry(name_loop, &udev->symlink_list, node)
                printf("S: %s\n", name_loop->name);
+       if (udev->link_priority != 0)
+               printf("L: %i\n", udev->link_priority);
+       if (udev->partitions != 0)
+               printf("A:%u\n", udev->partitions);
+       if (udev->ignore_remove)
+               printf("R:%u\n", udev->ignore_remove);
        list_for_each_entry(name_loop, &udev->env_list, node)
                printf("E: %s\n", name_loop->name);
 }
 
        list_for_each_entry(name_loop, &udev->env_list, node)
                printf("E: %s\n", name_loop->name);
 }
 
-static void export_name_devpath(struct udevice *udev) {
-       printf("%s=%s/%s\n", udev->dev->devpath, udev_root, udev->name);
-}
-
-static void export_record(struct udevice *udev) {
-       print_record(udev);
-       printf("\n");
-}
-
-static void export_db(void fnct(struct udevice *udev)) {
+static void export_db(void) {
        LIST_HEAD(name_list);
        struct name_entry *name_loop;
 
        LIST_HEAD(name_list);
        struct name_entry *name_loop;
 
@@ -152,16 +164,58 @@ static void export_db(void fnct(struct udevice *udev)) {
        list_for_each_entry(name_loop, &name_list, node) {
                struct udevice *udev_db;
 
        list_for_each_entry(name_loop, &name_list, node) {
                struct udevice *udev_db;
 
-               udev_db = udev_device_init();
+               udev_db = udev_device_init(NULL);
                if (udev_db == NULL)
                        continue;
                if (udev_db_get_device(udev_db, name_loop->name) == 0)
                if (udev_db == NULL)
                        continue;
                if (udev_db_get_device(udev_db, name_loop->name) == 0)
-                       fnct(udev_db);
+                       print_record(udev_db);
+                       printf("\n");
                udev_device_cleanup(udev_db);
        }
        name_list_cleanup(&name_list);
 }
 
                udev_device_cleanup(udev_db);
        }
        name_list_cleanup(&name_list);
 }
 
+static int lookup_device_by_name(struct udevice *udev, const char *name)
+{
+       LIST_HEAD(name_list);
+       int count;
+       struct name_entry *device;
+       int rc  = -1;
+
+       count = udev_db_get_devices_by_name(name, &name_list);
+       if (count <= 0)
+               goto out;
+
+       info("found %i devices for '%s'", count, name);
+
+       /* select the device that seems to match */
+       list_for_each_entry(device, &name_list, node) {
+               char filename[PATH_SIZE];
+               struct stat statbuf;
+
+               udev_device_init(udev);
+               if (udev_db_get_device(udev, device->name) != 0)
+                       continue;
+               info("found db entry '%s'", device->name);
+
+               /* make sure, we don't get a link of a differnt device */
+               strlcpy(filename, udev_root, sizeof(filename));
+               strlcat(filename, "/", sizeof(filename));
+               strlcat(filename, name, sizeof(filename));
+               if (stat(filename, &statbuf) != 0)
+                       continue;
+               if (major(udev->devt) > 0 && udev->devt != statbuf.st_rdev) {
+                       info("skip '%s', dev_t doesn't match", udev->name);
+                       continue;
+               }
+               rc = 0;
+               break;
+       }
+out:
+       name_list_cleanup(&name_list);
+       return rc;
+}
+
 int main(int argc, char *argv[], char *envp[])
 {
        int option;
 int main(int argc, char *argv[], char *envp[])
 {
        int option;
@@ -175,7 +229,7 @@ int main(int argc, char *argv[], char *envp[])
                { "attribute-walk", 0, NULL, 'a' },
                { "export-db", 0, NULL, 'e' },
                { "root", 0, NULL, 'r' },
                { "attribute-walk", 0, NULL, 'a' },
                { "export-db", 0, NULL, 'e' },
                { "root", 0, NULL, 'r' },
-               { "version", 0, NULL, 'V' },
+               { "version", 0, NULL, 1 }, /* -V outputs braindead format */
                { "help", 0, NULL, 'h' },
                {}
        };
                { "help", 0, NULL, 'h' },
                {}
        };
@@ -205,7 +259,7 @@ int main(int argc, char *argv[], char *envp[])
        udev_config_init();
        sysfs_init();
 
        udev_config_init();
        sysfs_init();
 
-       udev = udev_device_init();
+       udev = udev_device_init(NULL);
        if (udev == NULL) {
                rc = 1;
                goto exit;
        if (udev == NULL) {
                rc = 1;
                goto exit;
@@ -213,7 +267,7 @@ int main(int argc, char *argv[], char *envp[])
 
        /* get command line options */
        while (1) {
 
        /* get command line options */
        while (1) {
-               option = getopt_long(argc, argv, "aden:p:q:rVh", options, NULL);
+               option = getopt_long(argc, argv, "aen:p:q:rVh", options, NULL);
                if (option == -1)
                        break;
 
                if (option == -1)
                        break;
 
@@ -269,11 +323,11 @@ int main(int argc, char *argv[], char *envp[])
                case 'a':
                        action = ACTION_ATTRIBUTE_WALK;
                        break;
                case 'a':
                        action = ACTION_ATTRIBUTE_WALK;
                        break;
-               case 'd':
-                       export_db(export_name_devpath);
-                       goto exit;
                case 'e':
                case 'e':
-                       export_db(export_record);
+                       export_db();
+                       goto exit;
+               case 1:
+                       printf("%s\n", UDEV_VERSION);
                        goto exit;
                case 'V':
                        printf("udevinfo, version %s\n", UDEV_VERSION);
                        goto exit;
                case 'V':
                        printf("udevinfo, version %s\n", UDEV_VERSION);
@@ -293,7 +347,6 @@ int main(int argc, char *argv[], char *envp[])
                               "  --root            prepend to query result or print udev_root\n"
                               "  --attribute-walk  print all SYSFS_attributes along the device chain\n"
                               "  --export-db       export the content of the udev database\n"
                               "  --root            prepend to query result or print udev_root\n"
                               "  --attribute-walk  print all SYSFS_attributes along the device chain\n"
                               "  --export-db       export the content of the udev database\n"
-                              "  --verision        print udev version\n"
                               "  --help            print this text\n"
                               "\n");
                        goto exit;
                               "  --help            print this text\n"
                               "\n");
                        goto exit;
@@ -313,14 +366,11 @@ int main(int argc, char *argv[], char *envp[])
                                goto exit;
                        }
                } else if (name[0] != '\0') {
                                goto exit;
                        }
                } else if (name[0] != '\0') {
-                       char devpath[PATH_SIZE];
-
-                       if (udev_db_lookup_name(name, devpath, sizeof(devpath)) != 0) {
+                       if (lookup_device_by_name(udev, name) != 0) {
                                fprintf(stderr, "node name not found\n");
                                rc = 4;
                                goto exit;
                        }
                                fprintf(stderr, "node name not found\n");
                                rc = 4;
                                goto exit;
                        }
-                       udev_db_get_device(udev, devpath);
                } else {
                        fprintf(stderr, "query needs --path or node --name specified\n");
                        rc = 4;
                } else {
                        fprintf(stderr, "query needs --path or node --name specified\n");
                        rc = 4;
@@ -362,16 +412,22 @@ int main(int argc, char *argv[], char *envp[])
                break;
        case ACTION_ATTRIBUTE_WALK:
                if (path[0] != '\0') {
                break;
        case ACTION_ATTRIBUTE_WALK:
                if (path[0] != '\0') {
-                       print_device_chain(path);
+                       if (print_device_chain(path) != 0) {
+                               fprintf(stderr, "device not found\n");
+                               rc = 4;
+                               goto exit;
+                       }
                } else if (name[0] != '\0') {
                } else if (name[0] != '\0') {
-                       char devpath[PATH_SIZE];
-
-                       if (udev_db_lookup_name(name, devpath, sizeof(devpath)) != 0) {
+                       if (lookup_device_by_name(udev, name) != 0) {
                                fprintf(stderr, "node name not found\n");
                                rc = 4;
                                goto exit;
                        }
                                fprintf(stderr, "node name not found\n");
                                rc = 4;
                                goto exit;
                        }
-                       print_device_chain(devpath);
+                       if (print_device_chain(udev->dev->devpath) != 0) {
+                               fprintf(stderr, "device not found\n");
+                               rc = 4;
+                               goto exit;
+                       }
                } else {
                        fprintf(stderr, "attribute walk needs --path or node --name specified\n");
                        rc = 5;
                } else {
                        fprintf(stderr, "attribute walk needs --path or node --name specified\n");
                        rc = 5;