All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kay Sievers <kay.sievers@vrfy.org>
To: linux-hotplug@vger.kernel.org
Subject: [patch] udevinfo - now a real program :)
Date: Mon, 26 Jan 2004 01:49:01 +0000	[thread overview]
Message-ID: <20040126014901.GA9078@vrfy.org> (raw)

[-- Attachment #1: Type: text/plain, Size: 1145 bytes --]

I want to make udevinfo the standard query interface, so all the user
features of the main udev are copied in here. It is now capable to:

  o query the database for a given value
  o dump the whole database
  o extract all possible device attributes for a sysfs_device


In addition to the known options of udev it supports the query for the
mode of the device node, and it includes the mode in the database dump:

  udevinfo -d
  P: /class/video4linux/video0
  N: video/webcam0
  M: 0666
  S: camera0 kamera0
  O: 500
  G: 500


It is also a bit more friendly with the pathnames specified for devices or nodes.
We remove the absolute path or add it if neccessary:

  udevinfo -q mode -n video/webcam0
  udevinfo -q mode -n /udev/video/webcam0
  0666

  udevinfo -q mode -p /sys/class/video4linux/video0
  udevinfo -q mode -p /class/video4linux/video0
  udevinfo -q mode -p class/video4linux/video0
  0666


Greg, I want to move the program out of extras/udevinfo to the root
folder and include it in the install target. Then we may remove the
user mode code from the main udev program and update the man page.
What do you think?

thanks,
Kay


[-- Attachment #2: 02-udevinfo.patch --]
[-- Type: text/plain, Size: 8304 bytes --]

diff -Nru a/extras/udevinfo/Makefile b/extras/udevinfo/Makefile
--- a/extras/udevinfo/Makefile	Mon Jan 26 02:22:35 2004
+++ b/extras/udevinfo/Makefile	Mon Jan 26 02:22:35 2004
@@ -1,14 +1,28 @@
 PROG=udevinfo
-LD=$(CC)
-OBJS=udevinfo.o
+OBJS=	../../udev_config.o \
+	../../udev-add.o \
+	../../udev-remove.o \
+	../../udevdb.o \
+	../../logging.o \
+	../../namedev.o  \
+	../../namedev_parse.o \
+	../../libsysfs/sysfs_bus.o \
+	../../libsysfs/sysfs_class.o \
+	../../libsysfs/sysfs_device.o \
+	../../libsysfs/sysfs_dir.o \
+	../../libsysfs/sysfs_driver.o \
+	../../libsysfs/sysfs_utils.o \
+	../../libsysfs/dlist.o \
+	../../tdb/tdb.o \
+	../../tdb/spinlock.o \
 
-all:	$(PROG)
+all: $(PROG)
 
-clean:
-	rm -f $(PROG) $(OBJS)
+$(PROG): $(PROG).o
+	$(LD) $(LDFLAGS) -o $(PROG) $(PROG).o $(OBJS) -lc
 
-$(PROG):	$(OBJS)
-	$(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) $(SYSFS)
+clean:
+	rm -f $(PROG) $(OBJS) $(PROG).o
 
 me:
 	cd ../..; make EXTRAS=extras/udevinfo
diff -Nru a/extras/udevinfo/udevinfo.c b/extras/udevinfo/udevinfo.c
--- a/extras/udevinfo/udevinfo.c	Mon Jan 26 02:22:35 2004
+++ b/extras/udevinfo/udevinfo.c	Mon Jan 26 02:22:35 2004
@@ -23,21 +23,29 @@
 #include <string.h>
 #include <stdio.h>
 #include <ctype.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "../../udev.h"
+#include "../../udev_version.h"
+#include "../../logging.h"
+#include "../../udevdb.h"
+#include "../../libsysfs/libsysfs.h"
 
-#include "libsysfs.h"
 
-
-# define VALUE_SIZE 200
+# define SYSFS_VALUE_MAX 200
 
 char **main_argv;
+int main_argc;
 char **main_envp;
 
-static int print_all_attributes(char *path)
+static int print_all_attributes(const char *path)
 {
 	struct dlist *attributes;
 	struct sysfs_attribute *attr;
 	struct sysfs_directory *sysfs_dir;
-	char value[VALUE_SIZE];
+	char value[SYSFS_VALUE_MAX];
 	int len;
 	int retval = 0;
 
@@ -53,7 +61,7 @@
 
 	dlist_for_each_data(attributes, attr, struct sysfs_attribute) {
 		if (attr->value != NULL) {
-			strncpy(value, attr->value, VALUE_SIZE);
+			strncpy(value, attr->value, SYSFS_VALUE_MAX);
 			len = strlen(value);
 			if (len == 0)
 				continue;
@@ -82,24 +90,38 @@
 	return retval;
 }
 
-int main(int argc, char **argv, char **envp)
+/* callback for database dump */
+static int print_record(char *path, struct udevice *dev)
+{
+	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("\n");
+	return 0;
+}
+
+enum query_type {
+	NONE,
+	NAME,
+	PATH,
+	SYMLINK,
+	MODE,
+	OWNER,
+	GROUP
+};
+
+static int print_device_chain(const char *path)
 {
-	main_argv = argv;
-	main_envp = envp;
 	struct sysfs_class_device *class_dev;
 	struct sysfs_class_device *class_dev_parent;
 	struct sysfs_attribute *attr;
 	struct sysfs_device *sysfs_dev;
 	struct sysfs_device *sysfs_dev_parent;
-	char *path;
 	int retval = 0;
 
-	if (argc != 2) {
-		printf("Usage: udevinfo <sysfs_device_path>\n");
-		return -1;
-	}
-	path = argv[1];
-
 	/*  get the class dev */
 	class_dev = sysfs_open_class_device_path(path);
 	if (class_dev == NULL) {
@@ -156,4 +178,247 @@
 exit:
 	//sysfs_close_class_device(class_dev);
 	return retval;
+}
+
+static int process_options(void)
+{
+	static const char short_options[] = "adn:p:q:rVh";
+	int option;
+	int retval = 1;
+	struct udevice dev;
+	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];
+	char *pos;
+
+	/* get command line options */
+	while (1) {
+		option = getopt(main_argc, main_argv, short_options);
+		if (option == -1)
+			break;
+
+		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);
+			break;
+
+		case 'q':
+			dbg("udev query: %s\n", optarg);
+
+			if (strcmp(optarg, "name") == 0) {
+				query = NAME;
+				break;
+			}
+
+			if (strcmp(optarg, "symlink") == 0) {
+				query = SYMLINK;
+				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;
+			}
+
+			printf("unknown query type\n");
+			exit(1);
+
+		case 'r':
+			root = 1;
+			break;
+
+		case 'a':
+			attributes = 1;
+			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);
+
+		case 'V':
+			printf("udev, version %s\n", UDEV_VERSION);
+			exit(0);
+
+		case 'h':
+			retval = 0;
+		case '?':
+		default:
+			goto help;
+		}
+	}
+
+	/* 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) {
+				pos = path + strlen(sysfs_path);
+			} else {
+				if (path[0] != '/') {
+					/* prepend '/' if missing */
+					strcat(temp, "/");
+					strncat(temp, path, sizeof(path));
+					pos = temp;
+				} else {
+					pos = path;
+				}
+			}
+			retval = udevdb_get_dev(pos, &dev);
+			if (retval != 0) {
+				printf("device not found in database\n");
+				goto exit;
+			}
+			goto print;
+		}
+
+		if (name[0] != '\0') {
+			/* remove udev_root if given */
+			if (strncmp(name, udev_root, strlen(udev_root)) == 0) {
+				pos = name + strlen(udev_root);
+			} else
+				pos = name;
+			retval = udevdb_get_dev_byname(pos, 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;
+
+		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;
+
+		case PATH:
+			strfieldcpy(result, path);
+			break;
+
+		default:
+			goto exit;
+		}
+		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;
+		} else {
+			if (strncmp(path, sysfs_path, strlen(sysfs_path)) != 0) {
+				/* prepend sysfs mountpoint if not given */
+				strfieldcpy(temp, path);
+				strfieldcpy(path, sysfs_path);
+				strncat(path, temp, sizeof(path));
+			}
+			print_device_chain(path);
+			return 0;
+		}
+	}
+
+	if (root) {
+		printf("%s\n", udev_root);
+		return 0;
+	}
+
+help:
+	printf("Usage: [-anpqrdVh]\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"
+	       "  -p PATH  sysfs device path used for query or chain\n"
+	       "  -n NAME  node name used for query\n"
+	       "\n"
+	       "  -r       print udev root\n"
+	       "  -a       print all attributes along the chain of the device\n"
+	       "  -d       dump whole 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;
+	main_envp = envp;
+
+	/* initialize our configuration */
+	udev_init_config();
+
+	retval = process_options();
+	if (retval != 0)
+		exit(1);
+	exit(0);
 }

             reply	other threads:[~2004-01-26  1:49 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-01-26  1:49 Kay Sievers [this message]
2004-01-26 19:23 ` [patch] udevinfo - now a real program :) Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20040126014901.GA9078@vrfy.org \
    --to=kay.sievers@vrfy.org \
    --cc=linux-hotplug@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.