X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=udev_lib.c;h=db1096ebf7b7254847c98f521d44e462cd373961;hb=e5a2989efbae81f40b60885a8f92ea1f87df7ea9;hp=50598a4a318592d315fc942d6fead6b89ced4b41;hpb=c81b35c08bbd7789883993ea280e0d3772cce440;p=elogind.git diff --git a/udev_lib.c b/udev_lib.c index 50598a4a3..db1096ebf 100644 --- a/udev_lib.c +++ b/udev_lib.c @@ -21,14 +21,19 @@ #include #include +#include #include #include +#include +#include #include #include #include "libsysfs/sysfs/libsysfs.h" #include "udev.h" +#include "logging.h" #include "udev_lib.h" +#include "list.h" char *get_action(void) @@ -53,6 +58,17 @@ char *get_devpath(void) return devpath; } +char *get_devnode(void) +{ + char *devnode; + + devnode = getenv("DEVNODE"); + if (devnode != NULL && strlen(devnode) > NAME_SIZE) + devnode[NAME_SIZE-1] = '\0'; + + return devnode; +} + char *get_seqnum(void) { char *seqnum; @@ -70,6 +86,33 @@ char *get_subsystem(char *subsystem) return subsystem; } +#define BLOCK_PATH "/block/" +#define CLASS_PATH "/class/" +#define NET_PATH "/class/net/" + +char get_device_type(const char *path, const char *subsystem) +{ + if (strcmp(subsystem, "block") == 0) + return 'b'; + + if (strcmp(subsystem, "net") == 0) + return 'n'; + + if (strncmp(path, BLOCK_PATH, strlen(BLOCK_PATH)) == 0 && + strlen(path) > strlen(BLOCK_PATH)) + return 'b'; + + if (strncmp(path, NET_PATH, strlen(NET_PATH)) == 0 && + strlen(path) > strlen(NET_PATH)) + return 'n'; + + if (strncmp(path, CLASS_PATH, strlen(CLASS_PATH)) == 0 && + strlen(path) > strlen(CLASS_PATH)) + return 'c'; + + return '\0'; +} + int file_map(const char *filename, char **buf, size_t *bufsize) { struct stat stats; @@ -109,3 +152,84 @@ size_t buf_get_line(char *buf, size_t buflen, size_t cur) return count - cur; } +struct files { + struct list_head list; + char name[NAME_SIZE]; +}; + +/* sort files in lexical order */ +static int file_list_insert(char *filename, struct list_head *file_list) +{ + struct files *loop_file; + struct files *new_file; + + list_for_each_entry(loop_file, file_list, list) { + if (strcmp(loop_file->name, filename) > 0) { + break; + } + } + + new_file = malloc(sizeof(struct files)); + if (new_file == NULL) { + dbg("error malloc"); + return -ENOMEM; + } + + strfieldcpy(new_file->name, filename); + list_add_tail(&new_file->list, &loop_file->list); + return 0; +} + +/* calls function for file or every file found in directory */ +int call_foreach_file(int fnct(char *f) , char *dirname, char *suffix) +{ + struct dirent *ent; + DIR *dir; + char *ext; + char file[NAME_SIZE]; + struct files *loop_file; + struct files *tmp_file; + LIST_HEAD(file_list); + + dbg("open directory '%s'", dirname); + dir = opendir(dirname); + if (dir == NULL) { + dbg("unable to open '%s'", dirname); + return -1; + } + + while (1) { + ent = readdir(dir); + if (ent == NULL || ent->d_name[0] == '\0') + break; + + if ((ent->d_name[0] == '.') || (ent->d_name[0] == COMMENT_CHARACTER)) + continue; + + /* look for file with specified suffix */ + ext = strrchr(ent->d_name, '.'); + if (ext == NULL) + continue; + + if (strcmp(ext, suffix) != 0) + continue; + + dbg("put file '%s/%s' in list", dirname, ent->d_name); + file_list_insert(ent->d_name, &file_list); + } + + /* call function for every file in the list */ + list_for_each_entry_safe(loop_file, tmp_file, &file_list, list) { + strfieldcpy(file, dirname); + strfieldcat(file, "/"); + strfieldcat(file, loop_file->name); + + fnct(file); + + list_del(&loop_file->list); + free(loop_file); + } + + closedir(dir); + return 0; +}