mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-10-30 23:21:08 +03:00
[PATCH] udevinfo - now a real program :)
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
This commit is contained in:
parent
a695feaeff
commit
87171e46cd
@ -1,14 +1,28 @@
|
|||||||
PROG=udevinfo
|
PROG=udevinfo
|
||||||
LD=$(CC)
|
OBJS= ../../udev_config.o \
|
||||||
OBJS=udevinfo.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)
|
||||||
|
|
||||||
|
$(PROG): $(PROG).o
|
||||||
|
$(LD) $(LDFLAGS) -o $(PROG) $(PROG).o $(OBJS) -lc
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(PROG) $(OBJS)
|
rm -f $(PROG) $(OBJS) $(PROG).o
|
||||||
|
|
||||||
$(PROG): $(OBJS)
|
|
||||||
$(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) $(SYSFS)
|
|
||||||
|
|
||||||
me:
|
me:
|
||||||
cd ../..; make EXTRAS=extras/udevinfo
|
cd ../..; make EXTRAS=extras/udevinfo
|
||||||
|
@ -23,21 +23,29 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include "libsysfs.h"
|
#include "../../udev.h"
|
||||||
|
#include "../../udev_version.h"
|
||||||
|
#include "../../logging.h"
|
||||||
|
#include "../../udevdb.h"
|
||||||
|
#include "../../libsysfs/libsysfs.h"
|
||||||
|
|
||||||
|
|
||||||
# define VALUE_SIZE 200
|
# define SYSFS_VALUE_MAX 200
|
||||||
|
|
||||||
char **main_argv;
|
char **main_argv;
|
||||||
|
int main_argc;
|
||||||
char **main_envp;
|
char **main_envp;
|
||||||
|
|
||||||
static int print_all_attributes(char *path)
|
static int print_all_attributes(const char *path)
|
||||||
{
|
{
|
||||||
struct dlist *attributes;
|
struct dlist *attributes;
|
||||||
struct sysfs_attribute *attr;
|
struct sysfs_attribute *attr;
|
||||||
struct sysfs_directory *sysfs_dir;
|
struct sysfs_directory *sysfs_dir;
|
||||||
char value[VALUE_SIZE];
|
char value[SYSFS_VALUE_MAX];
|
||||||
int len;
|
int len;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
@ -53,7 +61,7 @@ static int print_all_attributes(char *path)
|
|||||||
|
|
||||||
dlist_for_each_data(attributes, attr, struct sysfs_attribute) {
|
dlist_for_each_data(attributes, attr, struct sysfs_attribute) {
|
||||||
if (attr->value != NULL) {
|
if (attr->value != NULL) {
|
||||||
strncpy(value, attr->value, VALUE_SIZE);
|
strncpy(value, attr->value, SYSFS_VALUE_MAX);
|
||||||
len = strlen(value);
|
len = strlen(value);
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
continue;
|
continue;
|
||||||
@ -82,24 +90,38 @@ exit:
|
|||||||
return retval;
|
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;
|
||||||
struct sysfs_class_device *class_dev_parent;
|
struct sysfs_class_device *class_dev_parent;
|
||||||
struct sysfs_attribute *attr;
|
struct sysfs_attribute *attr;
|
||||||
struct sysfs_device *sysfs_dev;
|
struct sysfs_device *sysfs_dev;
|
||||||
struct sysfs_device *sysfs_dev_parent;
|
struct sysfs_device *sysfs_dev_parent;
|
||||||
char *path;
|
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
printf("Usage: udevinfo <sysfs_device_path>\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
path = argv[1];
|
|
||||||
|
|
||||||
/* get the class dev */
|
/* get the class dev */
|
||||||
class_dev = sysfs_open_class_device_path(path);
|
class_dev = sysfs_open_class_device_path(path);
|
||||||
if (class_dev == NULL) {
|
if (class_dev == NULL) {
|
||||||
@ -157,3 +179,246 @@ exit:
|
|||||||
//sysfs_close_class_device(class_dev);
|
//sysfs_close_class_device(class_dev);
|
||||||
return retval;
|
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);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user