X-Git-Url: https://git.archive.openwrt.org/?p=project%2Fprocd.git;a=blobdiff_plain;f=udevtrigger.c;h=08ddb06707bc59b1a9daeb4f03119bb10843a5d2;hp=efea6b287c897bbbb817b569eee67fcbf49249b7;hb=0a5f43565309fc6cad3d47fd6ad12dc368677d10;hpb=ee92d6fa240e28d8031d7204939ffec61090d7e2 diff --git a/udevtrigger.c b/udevtrigger.c index efea6b2..08ddb06 100644 --- a/udevtrigger.c +++ b/udevtrigger.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -135,21 +136,34 @@ static int sysfs_resolve_link(char *devpath, size_t size) return 0; } +static bool device_has_attribute(const char *path, const char *attr, + mode_t mode) +{ + char filename[PATH_SIZE]; + struct stat statbuf; + + strlcpy(filename, path, sizeof(filename)); + strlcat(filename, attr, sizeof(filename)); + + if (stat(filename, &statbuf) < 0) + return false; + + if (!(statbuf.st_mode & mode)) + return false; + + return true; +} static int device_list_insert(const char *path) { - char filename[PATH_SIZE]; char devpath[PATH_SIZE]; struct stat statbuf; dbg("add '%s'" , path); - /* we only have a device, if we have an uevent file */ - strlcpy(filename, path, sizeof(filename)); - strlcat(filename, "/uevent", sizeof(filename)); - if (stat(filename, &statbuf) < 0) - return -1; - if (!(statbuf.st_mode & S_IWUSR)) + /* we only have a device, if we have a dev and an uevent file */ + if (!device_has_attribute(path, "/dev", S_IRUSR) || + !device_has_attribute(path, "/uevent", S_IWUSR)) return -1; strlcpy(devpath, &path[4], sizeof(devpath)); @@ -165,50 +179,52 @@ static int device_list_insert(const char *path) return 0; } - -static void scan_subsystem(const char *subsys) +static void scan_subdir(const char *base, const char *subdir, + bool insert, int depth) { - char base[PATH_SIZE]; DIR *dir; struct dirent *dent; - strlcpy(base, "/sys/", sizeof(base)); - strlcat(base, subsys, sizeof(base)); - dir = opendir(base); - if (dir != NULL) { - for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { - char dirname[PATH_SIZE]; - DIR *dir2; - struct dirent *dent2; + if (dir == NULL) + return; - if (dent->d_name[0] == '.') - continue; + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + char dirname[PATH_SIZE]; + + if (dent->d_name[0] == '.') + continue; + + strlcpy(dirname, base, sizeof(dirname)); + strlcat(dirname, "/", sizeof(dirname)); + strlcat(dirname, dent->d_name, sizeof(dirname)); + + if (insert) { + int err; - strlcpy(dirname, base, sizeof(dirname)); - strlcat(dirname, "/", sizeof(dirname)); - strlcat(dirname, dent->d_name, sizeof(dirname)); - strlcat(dirname, "/devices", sizeof(dirname)); - - /* look for devices */ - dir2 = opendir(dirname); - if (dir2 != NULL) { - for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { - char dirname2[PATH_SIZE]; - - if (dent2->d_name[0] == '.') - continue; - - strlcpy(dirname2, dirname, sizeof(dirname2)); - strlcat(dirname2, "/", sizeof(dirname2)); - strlcat(dirname2, dent2->d_name, sizeof(dirname2)); - device_list_insert(dirname2); - } - closedir(dir2); - } + err = device_list_insert(dirname); + if (err) + continue; } - closedir(dir); + + if (subdir) + strlcat(dirname, subdir, sizeof(base)); + + if (depth) + scan_subdir(dirname, NULL, true, depth - 1); } + + closedir(dir); +} + +static void scan_subsystem(const char *subsys) +{ + char base[PATH_SIZE]; + + strlcpy(base, "/sys/", sizeof(base)); + strlcat(base, subsys, sizeof(base)); + + scan_subdir(base, "/devices", false, 1); } static void scan_block(void) @@ -220,43 +236,26 @@ static void scan_block(void) strlcpy(base, "/sys/block", sizeof(base)); dir = opendir(base); - if (dir != NULL) { - for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { - char dirname[PATH_SIZE]; - DIR *dir2; - struct dirent *dent2; + if (dir == NULL) + return; - if (dent->d_name[0] == '.') - continue; + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + char dirname[PATH_SIZE]; - strlcpy(dirname, base, sizeof(dirname)); - strlcat(dirname, "/", sizeof(dirname)); - strlcat(dirname, dent->d_name, sizeof(dirname)); - if (device_list_insert(dirname) != 0) - continue; + if (dent->d_name[0] == '.') + continue; - /* look for partitions */ - dir2 = opendir(dirname); - if (dir2 != NULL) { - for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { - char dirname2[PATH_SIZE]; - - if (dent2->d_name[0] == '.') - continue; - - if (!strcmp(dent2->d_name,"device")) - continue; - - strlcpy(dirname2, dirname, sizeof(dirname2)); - strlcat(dirname2, "/", sizeof(dirname2)); - strlcat(dirname2, dent2->d_name, sizeof(dirname2)); - device_list_insert(dirname2); - } - closedir(dir2); - } - } - closedir(dir); + strlcpy(dirname, base, sizeof(dirname)); + strlcat(dirname, "/", sizeof(dirname)); + strlcat(dirname, dent->d_name, sizeof(dirname)); + if (device_list_insert(dirname) != 0) + continue; + + /* look for partitions */ + scan_subdir(dirname, NULL, true, 0); } + + closedir(dir); } static void scan_class(void) @@ -268,44 +267,27 @@ static void scan_class(void) strlcpy(base, "/sys/class", sizeof(base)); dir = opendir(base); - if (dir != NULL) { - for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { - char dirname[PATH_SIZE]; - DIR *dir2; - struct dirent *dent2; + if (dir == NULL) + return; - if (dent->d_name[0] == '.') - continue; + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + char dirname[PATH_SIZE]; - strlcpy(dirname, base, sizeof(dirname)); - strlcat(dirname, "/", sizeof(dirname)); - strlcat(dirname, dent->d_name, sizeof(dirname)); - dir2 = opendir(dirname); - if (dir2 != NULL) { - for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { - char dirname2[PATH_SIZE]; - - if (dent2->d_name[0] == '.') - continue; - - if (!strcmp(dent2->d_name, "device")) - continue; - - strlcpy(dirname2, dirname, sizeof(dirname2)); - strlcat(dirname2, "/", sizeof(dirname2)); - strlcat(dirname2, dent2->d_name, sizeof(dirname2)); - device_list_insert(dirname2); - } - closedir(dir2); - } - } - closedir(dir); + if (dent->d_name[0] == '.') + continue; + + strlcpy(dirname, base, sizeof(dirname)); + strlcat(dirname, "/", sizeof(dirname)); + strlcat(dirname, dent->d_name, sizeof(dirname)); + + scan_subdir(dirname, NULL, true, 0); } + + closedir(dir); } int main(int argc, char *argv[], char *envp[]) { - char base[PATH_SIZE]; struct stat statbuf; int option; @@ -341,8 +323,7 @@ int main(int argc, char *argv[], char *envp[]) scan_class(); /* scan "block" if it isn't a "class" */ - strlcpy(base, "/sys/class/block", sizeof(base)); - if (stat(base, &statbuf) != 0) + if (stat("/sys/class/block", &statbuf) != 0) scan_block(); exit: