chiark / gitweb /
[PATCH] udev - reverse user query options
authorkay.sievers@vrfy.org <kay.sievers@vrfy.org>
Tue, 20 Jan 2004 03:40:32 +0000 (19:40 -0800)
committerGreg KH <gregkh@suse.de>
Wed, 27 Apr 2005 04:13:17 +0000 (21:13 -0700)
Here we get the ability to query with the name of the node instead of
the device path. It uses a linear search over the whole database.

  kay@pim:~/src/udev.kay$ ./udev -q path -n video/webcam0
  /class/video4linux/video0

New version, with better function return codes for error handling.

udev.8
udev.c
udevdb.c
udevdb.h

diff --git a/udev.8 b/udev.8
index 0421fee4e66f9ad72e2f4e51284e54a74b540385..ff89e435ffa31866d362168fc6fc125e206af235 100644 (file)
--- a/udev.8
+++ b/udev.8
@@ -50,10 +50,13 @@ will be prepended.
 .BI -q " query_type"
 Query the database for specified value of a created device node.
 Valid types are:
-.BR name ", " symlink ", " owner " or " group .
+.BR name ", " symlink ", " owner " , " group " or " path.
 .TP
 .BI -p " sysfs_path"
-Specify the sysfs path needed for the query.
+Specify the sysfs path of the device to query.
+.TP
+.BI -n " name"
+Specify the name of the node for the device to query.
 .TP
 .B -d
 Dump the whole database.
diff --git a/udev.c b/udev.c
index b872f42494e68070e34452e6221dca619fb5e650..3b701ac26fc913e1ef6b8676bca5baa50ef47179 100644 (file)
--- a/udev.c
+++ b/udev.c
@@ -83,7 +83,8 @@ static inline char *get_seqnum(void)
        return seqnum;
 }
 
-static void print_record(char *path, struct udevice *dev)
+/* callback for database dump */
+static int print_record(char *path, struct udevice *dev)
 {
        printf("P: %s\n", path);
        printf("N: %s\n", dev->name);
@@ -91,11 +92,13 @@ static void print_record(char *path, struct udevice *dev)
        printf("O: %s\n", dev->owner);
        printf("G: %s\n", dev->group);
        printf("\n");
+       return 0;
 }
 
 enum query_type {
        NONE,
        NAME,
+       PATH,
        SYMLINK,
        OWNER,
        GROUP
@@ -103,7 +106,7 @@ enum query_type {
 
 static inline int udev_user(int argc, char **argv)
 {
-       static const char short_options[] = "dp:q:rVh";
+       static const char short_options[] = "dn:p:q:rVh";
        int option;
        int retval = -EINVAL;
        struct udevice dev;
@@ -111,6 +114,7 @@ static inline int udev_user(int argc, char **argv)
        enum query_type query = NONE;
        char result[NAME_SIZE] = "";
        char path[NAME_SIZE] = "";
+       char name[NAME_SIZE] = "";
 
        /* get command line options */
        while (1) {
@@ -120,6 +124,11 @@ static inline int udev_user(int argc, char **argv)
 
                dbg("option '%c'", option);
                switch (option) {
+               case 'n':
+                       dbg("udev name: %s\n", optarg);
+                       strfieldcpy(name, optarg);
+                       break;
+
                case 'p':
                        dbg("udev path: %s\n", optarg);
                        strfieldcpy(path, optarg);
@@ -148,6 +157,11 @@ static inline int udev_user(int argc, char **argv)
                                break;
                        }
 
+                       if (strcmp(optarg, "path") == 0) {
+                               query = PATH;
+                               break;
+                       }
+
                        printf("unknown query type\n");
                        return -EINVAL;
 
@@ -161,7 +175,7 @@ static inline int udev_user(int argc, char **argv)
                                printf("unable to open udev database\n");
                                return -EACCES;
                        }
-                       retval = udevdb_dump(print_record);
+                       retval = udevdb_call_foreach(print_record);
                        udevdb_exit();
                        return retval;
 
@@ -179,44 +193,63 @@ static inline int udev_user(int argc, char **argv)
 
        /* process options */
        if (query != NONE) {
-               if (path[0] == '\0') {
-                       printf("query needs device path specified\n");
-                       return -EINVAL;
-               }
-
                retval = udevdb_open_ro();
                if (retval != 0) {
                        printf("unable to open udev database\n");
                        return -EACCES;
                }
-               retval = udevdb_get_dev(path, &dev);
-               if (retval == 0) {
-                       switch(query) {
-                       case NAME:
-                               if (root)
+
+               if (path[0] != '\0') {
+                       retval = udevdb_get_dev(path, &dev);
+                       if (retval != 0) {
+                               printf("device not found in database\n");
+                               goto exit;
+                       }
+                       goto print;
+               }
+
+               if (name[0] != '\0') {
+                       retval = udevdb_get_dev_byname(name, path, &dev);
+                       if (retval != 0) {
+                               printf("device not found in database\n");
+                               goto exit;
+                       }
+                       goto print;
+               }
+
+               printf("query needs device path(-p) or node name(-n) specified\n");
+               goto exit;
+
+print:
+               switch(query) {
+               case NAME:
+                       if (root)
                                strfieldcpy(result, udev_root);
-                               strncat(result, dev.name, sizeof(result));
-                               break;
+                       strncat(result, dev.name, sizeof(result));
+                       break;
 
-                       case SYMLINK:
-                               strfieldcpy(result, dev.symlink);
-                               break;
+               case SYMLINK:
+                       strfieldcpy(result, dev.symlink);
+                       break;
 
-                       case GROUP:
-                               strfieldcpy(result, dev.group);
-                               break;
+               case GROUP:
+                       strfieldcpy(result, dev.group);
+                       break;
 
-                       case OWNER:
-                               strfieldcpy(result, dev.owner);
-                               break;
+               case OWNER:
+                       strfieldcpy(result, dev.owner);
+                       break;
 
-                       default:
-                               break;
-                       }
-                       printf("%s\n", result);
-               } else {
-                       printf("device not found in udev database\n");
+               case PATH:
+                       strfieldcpy(result, path);
+                       break;
+
+               default:
+                       goto exit;
                }
+               printf("%s\n", result);
+
+exit:
                udevdb_exit();
                return retval;
        }
@@ -227,13 +260,16 @@ static inline int udev_user(int argc, char **argv)
        }
 
 help:
-       printf("Usage: [-pqrdVh]\n"
+       printf("Usage: [-npqrdVh]\n"
               "  -q TYPE  query database for the specified value:\n"
               "             'name'    name of device node\n"
               "             'symlink' pointing to node\n"
               "             'owner'   of node\n"
               "             'group'   of node\n"
+              "             'path'    sysfs device path\n"
               "  -p PATH  sysfs device path used for query\n"
+              "  -n NAME  node name used for query\n"
+              "\n"
               "  -r       print udev root\n"
               "  -d       dump whole database\n"
               "  -V       print udev version\n"
index 2d99f51d0e4ef819efc0b1638a3910db7b23c092..c4e064fc115d4414ef21cbbbc44403ed4570e7bc 100644 (file)
--- a/udevdb.c
+++ b/udevdb.c
@@ -143,25 +143,62 @@ int udevdb_open_ro(void)
        return 0;
 }
 
-void (*user_record_callback) (char *path, struct udevice *dev);
+static int (*user_record_callback) (char *path, struct udevice *dev);
 
 static int traverse_callback(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
 {
-       user_record_callback((char*) key.dptr, (struct udevice*) dbuf.dptr);
-       return 0;
+       return user_record_callback((char*) key.dptr, (struct udevice*) dbuf.dptr);
 }
 
 /**
- * udevdb_dump: dumps whole database by passing record data to user function
+ * udevdb_call_foreach: dumps whole database by passing record data to user function
  * @user_record_handler: user function called for every record in the database
  */
-int udevdb_dump(void (*user_record_handler) (char *path, struct udevice *dev))
+int udevdb_call_foreach(int (*user_record_handler) (char *path, struct udevice *dev))
 {
+       int retval = 0;
+
        if (user_record_handler == NULL) {
                dbg("invalid user record handling function");
                return -EINVAL;
        }
        user_record_callback = user_record_handler;
-       tdb_traverse(udevdb, traverse_callback, NULL);
+       retval = tdb_traverse(udevdb, traverse_callback, NULL);
+       if (retval < 0)
+               return -ENODEV;
+       else
+               return 0;
+}
+
+static struct udevice *find_dev;
+static char *find_path;
+static const char *find_name;
+static int find_found;
+
+static int find_device_by_name(char *path, struct udevice *dev)
+{
+       if (strncmp(dev->name, find_name, sizeof(dev->name)) == 0) {
+               memcpy(find_dev, dev, sizeof(*find_dev));
+               strncpy(find_path, path, NAME_SIZE);
+               find_found = 1;
+               /* stop search */
+               return 1;
+       }
        return 0;
 }
+
+/**
+ * udevdb_get_dev_byname: search device with given name by traversing the whole database
+ */
+int udevdb_get_dev_byname(const char *name, char *path, struct udevice *dev)
+{
+       find_found = 0;
+       find_path = path;
+       find_dev = dev;
+       find_name = name;
+       udevdb_call_foreach(find_device_by_name);
+       if (find_found == 1)
+               return 0;
+       else
+               return -1;
+}
index a0e53382655a855e33598beb8b1a009ed2348e94..6eaeb25668f6a17a92e57ba6c234e3a8fb39a4db 100644 (file)
--- a/udevdb.h
+++ b/udevdb.h
 extern void udevdb_exit(void);
 extern int udevdb_init(int init_flag);
 extern int udevdb_open_ro(void);
-extern int udevdb_dump(void (*user_record_handler) (char *path, struct udevice *dev));
+extern int udevdb_call_foreach(int (*user_record_handler) (char *path, struct udevice *dev));
 
 extern int udevdb_add_dev(const char *path, const struct udevice *dev);
 extern int udevdb_get_dev(const char *path, struct udevice *dev);
 extern int udevdb_delete_dev(const char *path);
+extern int udevdb_get_dev_byname(const char *name, char *path, struct udevice *dev);
 
 #endif /* _UDEVDB_H_ */