chiark / gitweb /
rules_generator: remove policy from write_cd_rules
[elogind.git] / udevinfo.c
index dca4616958b4eeeb5e662e034af6f58346971c91..d0b1c447f4d65f2692b026996333dbf58f8f0328 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,15 +259,14 @@ 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;
        }
 
-       /* get command line options */
        while (1) {
        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;
 
@@ -225,7 +278,7 @@ int main(int argc, char *argv[], char *envp[])
                                strlcpy(name, &optarg[strlen(udev_root)+1], sizeof(name));
                        else
                                strlcpy(name, optarg, sizeof(name));
                                strlcpy(name, &optarg[strlen(udev_root)+1], sizeof(name));
                        else
                                strlcpy(name, optarg, sizeof(name));
-                       dbg("name: %s\n", name);
+                       dbg("name: %s", name);
                        break;
                case 'p':
                        /* remove /sys if given */
                        break;
                case 'p':
                        /* remove /sys if given */
@@ -233,10 +286,9 @@ int main(int argc, char *argv[], char *envp[])
                                strlcpy(path, &optarg[strlen(sysfs_path)], sizeof(path));
                        else
                                strlcpy(path, optarg, sizeof(path));
                                strlcpy(path, &optarg[strlen(sysfs_path)], sizeof(path));
                        else
                                strlcpy(path, optarg, sizeof(path));
-                       dbg("path: %s\n", path);
+                       dbg("path: %s", path);
                        break;
                case 'q':
                        break;
                case 'q':
-                       dbg("udev query: %s\n", optarg);
                        action = ACTION_QUERY;
                        if (strcmp(optarg, "name") == 0) {
                                query = QUERY_NAME;
                        action = ACTION_QUERY;
                        if (strcmp(optarg, "name") == 0) {
                                query = QUERY_NAME;
@@ -269,11 +321,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 +345,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 +364,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 +410,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, "no valid sysfs device 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, "no valid sysfs device 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;