From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kay Sievers Date: Sat, 17 Jan 2004 11:49:22 +0000 Subject: Re: [PATCH] udev - reverse user query options Message-Id: <20040117114922.GA20301@vrfy.org> MIME-Version: 1 Content-Type: multipart/mixed; boundary="u3/rZRmxL6MmkK24" List-Id: References: <20040116095433.GA17756@vrfy.org> In-Reply-To: <20040116095433.GA17756@vrfy.org> To: linux-hotplug@vger.kernel.org --u3/rZRmxL6MmkK24 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Fri, Jan 16, 2004 at 02:02:41PM -0800, Greg KH wrote: > On Fri, Jan 16, 2004 at 10:54:33AM +0100, Kay Sievers wrote: > > 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 > > Nice, but I think it still needs some tweaking: > > $ ./udev -q path -n foo > /block/fd0 So here we go to compare more than the first char :) The man page update is also included. thanks, Kay --u3/rZRmxL6MmkK24 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline; filename="00-reverse-query.patch" diff -Nru a/udev.8 b/udev.8 --- a/udev.8 Sat Jan 17 12:45:06 2004 +++ b/udev.8 Sat Jan 17 12:45:06 2004 @@ -50,10 +50,13 @@ .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 -Nru a/udev.c b/udev.c --- a/udev.c Sat Jan 17 12:45:06 2004 +++ b/udev.c Sat Jan 17 12:45:06 2004 @@ -83,7 +83,8 @@ 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 @@ 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 @@ 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; @@ -120,6 +123,11 @@ dbg("option '%c'", option); switch (option) { + case 'n': + dbg("udev name: %s\n", optarg); + strfieldcpy(dev.name, optarg); + break; + case 'p': dbg("udev path: %s\n", optarg); strfieldcpy(path, optarg); @@ -148,6 +156,11 @@ break; } + if (strcmp(optarg, "path") == 0) { + query = PATH; + break; + } + printf("unknown query type\n"); return -EINVAL; @@ -161,7 +174,7 @@ 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 +192,63 @@ /* 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) - strfieldcpy(result, udev_root); - strncat(result, dev.name, sizeof(result)); - break; - case SYMLINK: - strfieldcpy(result, dev.symlink); - break; + if (path[0] != '\0') { + retval = udevdb_get_dev(path, &dev); + if (retval != 0) { + printf("device not found in database\n"); + goto exit; + } + goto print; + } - case GROUP: - strfieldcpy(result, dev.group); - break; + if (dev.name[0] != '\0') { + retval = udevdb_get_dev_byname(dev.name, path, &dev); + if (retval != 0) { + printf("device not found in database\n"); + goto exit; + } + goto print; + } - case OWNER: - strfieldcpy(result, dev.owner); - break; + printf("query needs device path(-p) or node name(-n) specified\n"); + goto exit; - default: - break; - } - printf("%s\n", result); - } else { - printf("device not found in udev database\n"); +print: + switch(query) { + case NAME: + if (root) + strfieldcpy(result, udev_root); + strncat(result, dev.name, sizeof(result)); + break; + + case SYMLINK: + strfieldcpy(result, dev.symlink); + break; + + case GROUP: + strfieldcpy(result, dev.group); + break; + + case OWNER: + strfieldcpy(result, dev.owner); + break; + + case PATH: + strfieldcpy(result, path); + break; + + default: + goto exit; } + printf("%s\n", result); + +exit: udevdb_exit(); return retval; } @@ -227,13 +259,16 @@ } 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" diff -Nru a/udevdb.c b/udevdb.c --- a/udevdb.c Sat Jan 17 12:45:06 2004 +++ b/udevdb.c Sat Jan 17 12:45:06 2004 @@ -143,25 +143,55 @@ 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_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); + /* 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_path = path; + find_dev = dev; + find_name = name; + return udevdb_call_foreach(find_device_by_name); } diff -Nru a/udevdb.h b/udevdb.h --- a/udevdb.h Sat Jan 17 12:45:06 2004 +++ b/udevdb.h Sat Jan 17 12:45:06 2004 @@ -12,10 +12,11 @@ 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_ */ --u3/rZRmxL6MmkK24-- ------------------------------------------------------- The SF.Net email is sponsored by EclipseCon 2004 Premiere Conference on Open Tools Development and Integration See the breadth of Eclipse activity. February 3-5 in Anaheim, CA. http://www.eclipsecon.org/osdn _______________________________________________ Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net Linux-hotplug-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel