mirror of
https://github.com/AuxXxilium/eudev.git
synced 2024-12-17 03:55:45 +07: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
|
||||
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)
|
||||
|
||||
$(PROG): $(PROG).o
|
||||
$(LD) $(LDFLAGS) -o $(PROG) $(PROG).o $(OBJS) -lc
|
||||
|
||||
clean:
|
||||
rm -f $(PROG) $(OBJS)
|
||||
|
||||
$(PROG): $(OBJS)
|
||||
$(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) $(SYSFS)
|
||||
rm -f $(PROG) $(OBJS) $(PROG).o
|
||||
|
||||
me:
|
||||
cd ../..; make EXTRAS=extras/udevinfo
|
||||
|
@ -23,21 +23,29 @@
|
||||
#include <string.h>
|
||||
#include <stdio.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;
|
||||
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 @@ static int print_all_attributes(char *path)
|
||||
|
||||
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 @@ exit:
|
||||
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) {
|
||||
@ -157,3 +179,246 @@ 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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user