#include "libsysfs/sysfs/libsysfs.h"
#include "libsysfs/dlist.h"
#include "udev.h"
+#include "udev_utils.h"
#include "udev_version.h"
+#include "udev_db.h"
#include "logging.h"
-#include "udevdb.h"
-# define SYSFS_VALUE_MAX 200
-
-char **main_argv;
-int main_argc;
+#define SYSFS_VALUE_SIZE 256
#ifdef LOG
-unsigned char logname[42];
void log_message (int level, const char *format, ...)
{
va_list args;
struct dlist *attributes;
struct sysfs_attribute *attr;
struct sysfs_directory *sysfs_dir;
- char value[SYSFS_VALUE_MAX];
+ char value[SYSFS_VALUE_SIZE];
int len;
int retval = 0;
return retval;
}
-/* callback for database dump */
-static int print_record(char *path, struct udevice *dev)
+static int print_record(struct udevice *udev)
{
- 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("P: %s\n", udev->devpath);
+ printf("N: %s\n", udev->name);
+ printf("S: %s\n", udev->symlink);
printf("\n");
return 0;
}
NAME,
PATH,
SYMLINK,
- MODE,
- OWNER,
- GROUP
+ ALL
};
static int print_device_chain(const char *path)
return -1;
}
- /* read the 'dev' file for major/minor*/
+ printf("\nudevinfo starts with the device the node belongs to and then walks up the\n"
+ "device chain, to print for every device found, all possibly useful attributes\n"
+ "in the udev key format.\n"
+ "Only attributes within one device section may be used together in one rule,\n"
+ "to match the device for which the node will be created.\n"
+ "\n");
+
+ /* look for the 'dev' file */
attr = sysfs_get_classdev_attr(class_dev, "dev");
- if (attr == NULL) {
- printf("couldn't get the \"dev\" file\n");
- retval = -1;
- goto exit;
- }
- printf("\ndevice '%s' has major:minor %s", class_dev->path, attr->value);
- sysfs_close_attribute(attr);
+ if (attr != NULL)
+ printf("device '%s' has major:minor %s", class_dev->path, attr->value);
/* open sysfs class device directory and print all attributes */
printf(" looking at class device '%s':\n", class_dev->path);
/* get the device link (if parent exists look here) */
class_dev_parent = sysfs_get_classdev_parent(class_dev);
- if (class_dev_parent != NULL) {
- //sysfs_close_class_device(class_dev);
- class_dev = class_dev_parent;
- }
- sysfs_dev = sysfs_get_classdev_device(class_dev);
+ if (class_dev_parent != NULL)
+ sysfs_dev = sysfs_get_classdev_device(class_dev_parent);
+ else
+ sysfs_dev = sysfs_get_classdev_device(class_dev);
+
if (sysfs_dev != NULL)
printf("follow the class device's \"device\"\n");
if (sysfs_dev_parent == NULL)
break;
- //sysfs_close_device(sysfs_dev);
sysfs_dev = sysfs_dev_parent;
}
- sysfs_close_device(sysfs_dev);
exit:
- //sysfs_close_class_device(class_dev);
+ sysfs_close_class_device(class_dev);
return retval;
}
-static int process_options(void)
+/* print all class/main block devices with major/minor, physical device, driver and bus */
+static int print_sysfs_devices(void)
{
- static const char short_options[] = "adn:p:q:rVh";
+ struct dlist *subsyslist;
+ char *class;
+
+ subsyslist = sysfs_open_subsystem_list("class");
+ if (!subsyslist)
+ return -1;
+
+ dlist_for_each_data(subsyslist, class, char) {
+ struct sysfs_class *cls;
+ struct dlist *class_devices;
+ struct sysfs_class_device *class_dev;
+ struct sysfs_device *phys_dev;
+ unsigned int major, minor;
+
+ cls = sysfs_open_class(class);
+ if (!cls)
+ continue;
+
+ class_devices = sysfs_get_class_devices(cls);
+ if (!class_devices)
+ continue;
+
+ dlist_for_each_data(class_devices, class_dev, struct sysfs_class_device) {
+ struct sysfs_attribute *attr;
+
+ printf("\n");
+ printf("DEVPATH '%s'\n", class_dev->path);
+ printf("SUBSYSTEM '%s'\n", class_dev->classname);
+
+ attr = sysfs_get_classdev_attr(class_dev, "dev");
+ if (attr) {
+ sscanf(attr->value, "%u:%u", &major, &minor);
+ printf("MAJOR %u\n", major);
+ printf("MINOR %u\n", minor);
+ }
+
+ phys_dev = sysfs_get_classdev_device(class_dev);
+ if (phys_dev) {
+ printf("PHYSDEVPATH '%s'\n", phys_dev->path);
+ if (phys_dev->bus[0] != '\0')
+ printf("PHYSDEVBUS '%s'\n", phys_dev->bus);
+
+ if (phys_dev->driver_name[0] != '\0')
+ printf("PHYSDEVDRIVER '%s'\n", phys_dev->driver_name);
+ }
+ }
+ sysfs_close_class(cls);
+ }
+ sysfs_close_list(subsyslist);
+
+ return 0;
+}
+
+static int process_options(int argc, char *argv[])
+{
+ static const char short_options[] = "an:p:q:rsVh";
int option;
int retval = 1;
- struct udevice dev;
+ struct udevice udev;
int root = 0;
int attributes = 0;
enum query_type query = NONE;
- char result[NAME_SIZE] = "";
+ char result[1024] = "";
char path[NAME_SIZE] = "";
char name[NAME_SIZE] = "";
char temp[NAME_SIZE];
/* get command line options */
while (1) {
- option = getopt(main_argc, main_argv, short_options);
+ option = getopt(argc, argv, short_options);
if (option == -1)
break;
break;
}
- if (strcmp(optarg, "mode") == 0) {
- query = MODE;
- break;
- }
-
- if (strcmp(optarg, "owner") == 0) {
- query = OWNER;
- break;
- }
-
- if (strcmp(optarg, "group") == 0) {
- query = GROUP;
+ if (strcmp(optarg, "path") == 0) {
+ query = PATH;
break;
}
- if (strcmp(optarg, "path") == 0) {
- query = PATH;
+ if (strcmp(optarg, "all") == 0) {
+ query = ALL;
break;
}
root = 1;
break;
+ case 's':
+ print_sysfs_devices();
+ exit(0);
+
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("udevinfo, version %s\n", UDEV_VERSION);
exit(0);
/* 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;
}
}
- retval = udevdb_get_dev(pos, &dev);
+ memset(&udev, 0x00, sizeof(struct udevice));
+ strfieldcpy(udev.devpath, pos);
+ retval = udev_db_get_device(&udev);
if (retval != 0) {
printf("device not found in database\n");
goto exit;
if (name[0] != '\0') {
/* remove udev_root if given */
- if (strncmp(name, udev_root, strlen(udev_root)) == 0) {
- pos = name + strlen(udev_root);
+ int len = strlen(udev_root);
+
+ if (strncmp(name, udev_root, len) == 0) {
+ pos = &name[len+1];
} else
pos = name;
- retval = udevdb_get_dev_byname(pos, path, &dev);
+
+ memset(&udev, 0x00, sizeof(struct udevice));
+ strfieldcpy(udev.name, pos);
+ retval = udev_db_get_device_byname(&udev, pos);
if (retval != 0) {
printf("device not found in database\n");
goto exit;
}
+
goto print;
}
print:
switch(query) {
case NAME:
- if (root)
- strfieldcpy(result, udev_root);
- strfieldcat(result, dev.name);
+ if (root) {
+ snprintf(result, NAME_SIZE-1, "%s/%s", udev_root, udev.name);
+ result[NAME_SIZE-1] = '\0';
+ } else {
+ strfieldcpy(result, udev.name);
+ }
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);
+ if (root) {
+ int slen;
+ char *spos;
+ char slink[NAME_SIZE];
+
+ pos = result;
+ foreach_strpart(udev.symlink, " \n\r", spos, slen) {
+ strncpy(slink, spos, slen);
+ slink[slen] = '\0';
+ pos += sprintf(pos, "%s/%s ", udev_root, slink);
+ }
+ } else {
+ strfieldcpy(result, udev.symlink);
+ }
break;
case PATH:
- strfieldcpy(result, path);
+ strfieldcpy(result, udev.devpath);
break;
+ case ALL:
+ print_record(&udev);
+ goto exit;
+
default:
goto exit;
}
printf("%s\n", result);
exit:
- udevdb_exit();
return retval;
}
}
help:
- printf("Usage: [-anpqrdVh]\n"
+ printf("Usage: udevinfo [-anpqrVh]\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"
+ " 'all' all values\n"
+ "\n"
" -p PATH sysfs device path used for query or chain\n"
- " -n NAME node name used for query\n"
+ " -n NAME node/symlink name used for query\n"
"\n"
" -r print udev root\n"
" -a print all SYSFS_attributes along the device chain\n"
- " -d dump whole database\n"
+ " -s print all sysfs devices with major/minor, physical device and bus\n"
" -V print udev version\n"
" -h print this help text\n"
"\n");
int main(int argc, char *argv[], char *envp[])
{
- int retval;
-
- main_argv = argv;
- main_argc = argc;
+ int rc = 0;
- init_logging("udevinfo");
+ logging_init("udevinfo");
/* initialize our configuration */
udev_init_config();
- retval = process_options();
- if (retval != 0)
- exit(1);
- exit(0);
+ rc = process_options(argc, argv);
+
+ logging_close();
+ exit(rc);
}