chiark / gitweb /
[PATCH] use numeric owner/group as default values to avoid parsing userdb
[elogind.git] / udevinfo.c
index dc3f94fffe364deb241f8738f8d914d789c8f7cd..b2d22e984e44caa3a5d5e0d0bcdf5f22479de02a 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;
@@ -53,26 +49,13 @@ void log_message (int level, const char *format, ...)
 }
 #endif
 
-static int print_all_attributes(const char *path)
+static void print_all_attributes(struct dlist *attr_list)
 {
-       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;
-
-       sysfs_dir = sysfs_open_directory(path);
-       if (sysfs_dir == NULL)
-               return -1;
-
-       attributes = sysfs_get_dir_attributes(sysfs_dir);
-       if (attributes == NULL) {
-               retval = -1;
-               goto exit;
-       }
 
-       dlist_for_each_data(attributes, attr, struct sysfs_attribute) {
+       dlist_for_each_data(attr_list, attr, struct sysfs_attribute) {
                if (attr->value != NULL) {
                        strfieldcpy(value, attr->value);
                        len = strlen(value);
@@ -96,26 +79,17 @@ static int print_all_attributes(const char *path)
                }
        }
        printf("\n");
-
-exit:
-       sysfs_close_directory(sysfs_dir);
-
-       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("\n");
+       struct name_entry *name_loop;
+
+       printf("P: %s\n", udev->devpath);
+       printf("N: %s\n", udev->name);
+       list_for_each_entry(name_loop, &udev->symlink_list, node)
+               printf("S: %s\n", name_loop->name);
+
        return 0;
 }
 
@@ -124,10 +98,7 @@ enum query_type {
        NAME,
        PATH,
        SYMLINK,
-       MODE,
-       OWNER,
-       GROUP,
-       ALL
+       ALL,
 };
 
 static int print_device_chain(const char *path)
@@ -137,6 +108,7 @@ static int print_device_chain(const char *path)
        struct sysfs_attribute *attr;
        struct sysfs_device *sysfs_dev;
        struct sysfs_device *sysfs_dev_parent;
+       struct dlist *attr_list;
        int retval = 0;
 
        /*  get the class dev */
@@ -146,82 +118,97 @@ 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);
-       if (print_all_attributes(class_dev->path) != 0) {
+       printf("    SUBSYSTEM=\"%s\"\n", class_dev->classname);
+
+       attr_list = sysfs_get_classdev_attributes(class_dev);
+       if (attr_list == NULL) {
                printf("couldn't open class device directory\n");
                retval = -1;
                goto exit;
        }
+       print_all_attributes(attr_list);
 
        /* 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");
 
        /* look the device chain upwards */
        while (sysfs_dev != NULL) {
+               attr_list = sysfs_get_device_attributes(sysfs_dev);
+               if (attr_list == NULL) {
+                       printf("couldn't open device directory\n");
+                       retval = -1;
+                       goto exit;
+               }
+
                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);
+               print_all_attributes(attr_list);
 
                sysfs_dev_parent = sysfs_get_device_parent(sysfs_dev);
                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)
+static int print_dump(const char *devpath, const char *name) {
+       printf("%s:%s/%s\n", devpath, udev_root, name);
+       return 0;
+}
+
+int main(int argc, char *argv[], char *envp[])
 {
        static const char short_options[] = "adn:p:q:rVh";
        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 path[NAME_SIZE] = "";
        char name[NAME_SIZE] = "";
        char temp[NAME_SIZE];
+       struct name_entry *name_loop;
        char *pos;
+       int retval = 0;
+
+       logging_init("udevinfo");
+
+       udev_init_config();
+       udev_init_device(&udev, NULL, NULL);
 
        /* 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 +237,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;
@@ -276,7 +248,8 @@ static int process_options(void)
                        }
 
                        printf("unknown query type\n");
-                       exit(1);
+                       retval = 1;
+                       goto exit;
 
                case 'r':
                        root = 1;
@@ -287,21 +260,15 @@ static int process_options(void)
                        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);
+                       udev_db_dump_names(print_dump);
+                       goto exit;
 
                case 'V':
                        printf("udevinfo, version %s\n", UDEV_VERSION);
-                       exit(0);
+                       goto exit;
 
                case 'h':
-                       retval = 0;
+                       retval = 2;
                case '?':
                default:
                        goto help;
@@ -310,12 +277,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) {
@@ -323,14 +284,14 @@ static int process_options(void)
                        } else {
                                if (path[0] != '/') {
                                        /* prepend '/' if missing */
-                                       strfieldcat(temp, "/");
+                                       strcpy(temp, "/");
                                        strfieldcat(temp, path);
                                        pos = temp;
                                } else {
                                        pos = path;
                                }
                        }
-                       retval = udevdb_get_dev(pos, &dev);
+                       retval = udev_db_get_device(&udev, pos);
                        if (retval != 0) {
                                printf("device not found in database\n");
                                goto exit;
@@ -339,68 +300,64 @@ static int process_options(void)
                }
 
                if (name[0] != '\0') {
+                       char devpath[NAME_SIZE];
+                       int len;
+
                        /* remove udev_root if given */
-                       if (strncmp(name, udev_root, strlen(udev_root)) == 0) {
-                               pos = name + strlen(udev_root);
+                       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);
+
+                       retval = udev_db_search_name(devpath, DEVPATH_SIZE, pos);
                        if (retval != 0) {
                                printf("device not found in database\n");
                                goto exit;
                        }
+                       udev_db_get_device(&udev, devpath);
                        goto print;
                }
 
                printf("query needs device path(-p) or node name(-n) specified\n");
+               retval = 3;
                goto exit;
 
 print:
                switch(query) {
                case NAME:
                        if (root)
-                               strfieldcpy(result, udev_root);
-                       strfieldcat(result, dev.name);
-                       break;
-
+                               printf("%s/%s\n", udev_root, udev.name);
+                       else
+                               printf("%s\n", udev.name);
+                       goto exit;
                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);
-                       break;
-
+                       if (list_empty(&udev.symlink_list))
+                               break;
+                       if (root)
+                               list_for_each_entry(name_loop, &udev.symlink_list, node)
+                                       printf("%s/%s ", udev_root, name_loop->name);
+                       else
+                               list_for_each_entry(name_loop, &udev.symlink_list, node)
+                                       printf("%s ", name_loop->name);
+                       printf("\n");
+                       goto exit;
                case PATH:
-                       strfieldcpy(result, path);
-                       break;
-
+                       printf("%s\n", udev.devpath);
+                       goto exit;
                case ALL:
-                       print_record(path, &dev);
+                       print_record(&udev);
                        goto exit;
-
                default:
-                       goto exit;
+                       goto help;
                }
-               printf("%s\n", result);
-
-exit:
-               udevdb_exit();
-               return retval;
        }
 
        if (attributes) {
                if (path[0] == '\0') {
                        printf("attribute walk on device chain needs path(-p) specified\n");
-                       return -EINVAL;
+                       retval = 4;
+                       goto exit;
                } else {
                        if (strncmp(path, sysfs_path, strlen(sysfs_path)) != 0) {
                                /* prepend sysfs mountpoint if not given */
@@ -409,23 +366,20 @@ exit:
                                strfieldcat(path, temp);
                        }
                        print_device_chain(path);
-                       return 0;
+                       goto exit;
                }
        }
 
        if (root) {
                printf("%s\n", udev_root);
-               return 0;
+               goto 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,27 +388,14 @@ help:
               "\n"
               "  -r       print udev root\n"
               "  -a       print all SYSFS_attributes along the device chain\n"
-              "  -d       dump whole database\n"
+              "  -d       print the relationship of devpath and the node name for all\n"
+              "           devices available in the database\n"
               "  -V       print udev version\n"
               "  -h       print this help text\n"
               "\n");
-       return retval;
-}
-
-int main(int argc, char *argv[], char *envp[])
-{
-       int retval;
-
-       main_argv = argv;
-       main_argc = argc;
 
-       init_logging("udevinfo");
-
-       /* initialize our configuration */
-       udev_init_config();
-
-       retval = process_options();
-       if (retval != 0)
-               exit(1);
-       exit(0);
+exit:
+       udev_cleanup_device(&udev);
+       logging_close();
+       return retval;
 }