X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=udev%2Fudevadm-info.c;h=87c1c32314b2d0784c9d9cf2e0745ad72dc166e4;hp=4510f4aa907dc56a22544564ec1e10045046bf61;hb=c7c32e9c9835a0bdaee931f33ac0fc86a1e4c415;hpb=24d1076696ebe6696a8b8df414ab265aa6fc89c2 diff --git a/udev/udevadm-info.c b/udev/udevadm-info.c index 4510f4aa9..87c1c3231 100644 --- a/udev/udevadm-info.c +++ b/udev/udevadm-info.c @@ -31,49 +31,54 @@ #include "udev.h" -static void print_all_attributes(struct udev_device *device, const char *key) +static bool skip_attribute(const char *name) { - struct udev *udev = udev_device_get_udev(device); - DIR *dir; - struct dirent *dent; + static const char const *skip[] = { + "uevent", + "dev", + "modalias", + "resource", + "driver", + "subsystem", + "module", + }; + unsigned int i; - dir = opendir(udev_device_get_syspath(device)); - if (dir != NULL) { - for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { - struct stat statbuf; - const char *value; - size_t len; - - if (dent->d_name[0] == '.') - continue; - - if (strcmp(dent->d_name, "uevent") == 0) - continue; - if (strcmp(dent->d_name, "dev") == 0) - continue; - - if (fstatat(dirfd(dir), dent->d_name, &statbuf, AT_SYMLINK_NOFOLLOW) != 0) - continue; - if (S_ISLNK(statbuf.st_mode)) - continue; - - value = udev_device_get_sysattr_value(device, dent->d_name); - if (value == NULL) - continue; - dbg(udev, "attr '%s'='%s'\n", dent->d_name, value); - - /* skip nonprintable attributes */ - len = strlen(value); - while (len > 0 && isprint(value[len-1])) - len--; - if (len > 0) { - dbg(udev, "attribute value of '%s' non-printable, skip\n", dent->d_name); - continue; - } + for (i = 0; i < ARRAY_SIZE(skip); i++) + if (strcmp(name, skip[i]) == 0) + return true; + return false; +} - printf(" %s{%s}==\"%s\"\n", key, dent->d_name, value); +static void print_all_attributes(struct udev_device *device, const char *key) +{ + struct udev_list_entry *sysattr; + + udev_list_entry_foreach(sysattr, udev_device_get_sysattr_list_entry(device)) { + struct udev *udev = udev_device_get_udev(device); + const char *name; + const char *value; + size_t len; + + name = udev_list_entry_get_name(sysattr); + if (skip_attribute(name)) + continue; + + value = udev_device_get_sysattr_value(device, name); + if (value == NULL) + continue; + dbg(udev, "attr '%s'='%s'\n", name, value); + + /* skip nonprintable attributes */ + len = strlen(value); + while (len > 0 && isprint(value[len-1])) + len--; + if (len > 0) { + dbg(udev, "attribute value of '%s' non-printable, skip\n", name); + continue; } - closedir(dir); + + printf(" %s{%s}==\"%s\"\n", key, name, value); } printf("\n"); } @@ -195,64 +200,79 @@ static int export_devices(struct udev *udev) return 0; } -static int convert_db(struct udev *udev) +static void cleanup_dir(DIR *dir, mode_t mask, int depth) { - struct udev_enumerate *udev_enumerate; - struct udev_list_entry *list_entry; - - udev_enumerate = udev_enumerate_new(udev); - if (udev_enumerate == NULL) - return -1; - udev_enumerate_scan_devices(udev_enumerate); - udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(udev_enumerate)) { - struct udev_device *device; + struct dirent *dent; - device = udev_device_new_from_syspath(udev, udev_list_entry_get_name(list_entry)); - if (device != NULL) { - const char *id; - struct stat stats; - char to[UTIL_PATH_SIZE]; - char devpath[UTIL_PATH_SIZE]; - char from[UTIL_PATH_SIZE]; - - id = udev_device_get_id_filename(device); - if (id == NULL) { - udev_device_unref(device); - continue; - } - util_strscpyl(to, sizeof(to), udev_get_dev_path(udev), "/.udev/db/", id, NULL); - - /* find old database with $subsys:$sysname */ - util_strscpyl(from, sizeof(from), udev_get_dev_path(udev), - "/.udev/db/", udev_device_get_subsystem(device), ":", - udev_device_get_sysname(device), NULL); - if (lstat(from, &stats) == 0) { - if (lstat(to, &stats) == 0) - unlink(from); - else - rename(from, to); + if (depth <= 0) + return; + + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + struct stat stats; + + if (dent->d_name[0] == '.') + continue; + if (fstatat(dirfd(dir), dent->d_name, &stats, AT_SYMLINK_NOFOLLOW) != 0) + continue; + if ((stats.st_mode & mask) != 0) + continue; + if (S_ISDIR(stats.st_mode)) { + DIR *dir2; + + dir2 = fdopendir(openat(dirfd(dir), dent->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC)); + if (dir2 != NULL) { + cleanup_dir(dir2, mask, depth-1); + closedir(dir2); } + unlinkat(dirfd(dir), dent->d_name, AT_REMOVEDIR); + } else { + unlinkat(dirfd(dir), dent->d_name, 0); + } + } +} - /* find old database with the encoded devpath */ - util_path_encode(udev_device_get_devpath(device), devpath, sizeof(devpath)); - util_strscpyl(from, sizeof(from), udev_get_dev_path(udev), - "/.udev/db/", devpath, NULL); - if (lstat(from, &stats) == 0) { - if (lstat(to, &stats) == 0) - unlink(from); - else - rename(from, to); - } +static void cleanup_db(struct udev *udev) +{ + char filename[UTIL_PATH_SIZE]; + DIR *dir; - /* read the old database, and write out a new one */ - udev_device_read_db(device); - udev_device_update_db(device); + util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/queue.bin", NULL); + unlink(filename); - udev_device_unref(device); - } + util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/data", NULL); + dir = opendir(filename); + if (dir != NULL) { + cleanup_dir(dir, S_ISVTX, 1); + closedir(dir); + } + + util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/links", NULL); + dir = opendir(filename); + if (dir != NULL) { + cleanup_dir(dir, 0, 2); + closedir(dir); + } + + util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/tags", NULL); + dir = opendir(filename); + if (dir != NULL) { + cleanup_dir(dir, 0, 2); + closedir(dir); + } + + util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/watch", NULL); + dir = opendir(filename); + if (dir != NULL) { + cleanup_dir(dir, 0, 1); + closedir(dir); + } + + util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/firmware-missing", NULL); + dir = opendir(filename); + if (dir != NULL) { + cleanup_dir(dir, 0, 1); + closedir(dir); } - udev_enumerate_unref(udev_enumerate); - return 0; } int udevadm_info(struct udev *udev, int argc, char *argv[]) @@ -271,9 +291,10 @@ int udevadm_info(struct udev *udev, int argc, char *argv[]) { "path", required_argument, NULL, 'p' }, { "query", required_argument, NULL, 'q' }, { "attribute-walk", no_argument, NULL, 'a' }, + { "cleanup-db", no_argument, NULL, 'c' }, { "export-db", no_argument, NULL, 'e' }, - { "convert-db", no_argument, NULL, 'C' }, { "root", no_argument, NULL, 'r' }, + { "run", no_argument, NULL, 'R' }, { "device-id-of-file", required_argument, NULL, 'd' }, { "export", no_argument, NULL, 'x' }, { "export-prefix", required_argument, NULL, 'P' }, @@ -303,7 +324,7 @@ int udevadm_info(struct udev *udev, int argc, char *argv[]) int option; struct stat statbuf; - option = getopt_long(argc, argv, "aed:n:p:q:rxP:Vh", options, NULL); + option = getopt_long(argc, argv, "aced:n:p:q:rxP:RVh", options, NULL); if (option == -1) break; @@ -387,6 +408,9 @@ int udevadm_info(struct udev *udev, int argc, char *argv[]) action = ACTION_ROOT; root = true; break; + case 'R': + printf("%s\n", udev_get_run_path(udev)); + goto exit; case 'd': action = ACTION_DEVICE_ID_FILE; util_strscpy(name, sizeof(name), optarg); @@ -397,8 +421,8 @@ int udevadm_info(struct udev *udev, int argc, char *argv[]) case 'e': export_devices(udev); goto exit; - case 'C': - convert_db(udev); + case 'c': + cleanup_db(udev); goto exit; case 'x': export = true; @@ -426,7 +450,7 @@ int udevadm_info(struct udev *udev, int argc, char *argv[]) " --export export key/value pairs\n" " --export-prefix export the key name with a prefix\n" " --export-db export the content of the udev database\n" - " --convert-db convert older version of database without a reboot\n" + " --cleanup-db cleanup the udev database\n" " --help\n\n"); goto exit; default: