chiark / gitweb /
[PATCH] handle whole hotplug event with udevd/udev
[elogind.git] / udev_lib.c
index 84daf9fd19fba4bac7c5d3356c73ab6e27ca542e..86a526f7e816ecca46aedf4dc622a355d92b7b74 100644 (file)
@@ -28,6 +28,7 @@
 #include <dirent.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
+#include <sys/utsname.h>
 
 #include "udev.h"
 #include "logging.h"
 #include "list.h"
 
 
-#define BLOCK_PATH             "/block/"
-#define CLASS_PATH             "/class/"
-#define NET_PATH               "/class/net/"
-
-char get_device_type(const char *path, const char *subsystem)
+void udev_set_values(struct udevice *udev, const char* devpath,
+                    const char *subsystem, const char* action)
 {
-       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';
+       memset(udev, 0x00, sizeof(struct udevice));
 
-       return '\0';
+       if (devpath)
+               strfieldcpy(udev->devpath, devpath);
+       if (subsystem)
+               strfieldcpy(udev->subsystem, subsystem);
+       if (action)
+               strfieldcpy(udev->action, action);
+
+       if (strcmp(udev->subsystem, "block") == 0)
+               udev->type = 'b';
+       else if (strcmp(udev->subsystem, "net") == 0)
+               udev->type = 'n';
+       else if (strncmp(udev->devpath, "/block/", 7) == 0)
+               udev->type = 'b';
+       else if (strncmp(udev->devpath, "/class/net/", 11) == 0)
+               udev->type = 'n';
+       else if (strncmp(udev->devpath, "/class/", 7) == 0)
+               udev->type = 'c';
 }
 
-void udev_set_values(struct udevice *udev, const char* devpath,
-                    const char *subsystem, const char* action)
+int kernel_release_satisfactory(int version, int patchlevel, int sublevel)
 {
-       memset(udev, 0x00, sizeof(struct udevice));
-       strfieldcpy(udev->devpath, devpath);
-       strfieldcpy(udev->subsystem, subsystem);
-       strfieldcpy(udev->action, action);
-       udev->type = get_device_type(devpath, subsystem);
+       static int kversion = 0;
+       static int kpatchlevel;
+       static int ksublevel;
+
+       if (kversion == 0) {
+               struct utsname uts;
+               if (uname(&uts) != 0)
+                       return -1;
+
+               if (sscanf (uts.release, "%u.%u.%u", &kversion, &kpatchlevel, &ksublevel) != 3) {
+                       kversion = 0;
+                       return -1;
+               }
+       }
+
+       if (kversion >= version && kpatchlevel >= patchlevel && ksublevel >= sublevel)
+               return 1;
+       else
+               return 0;
 }
 
 int create_path(const char *path)
@@ -178,12 +189,12 @@ static int file_list_insert(char *filename, struct list_head *file_list)
 }
 
 /* calls function for every file found in specified directory */
-int call_foreach_file(int fnct(char *f) , char *dirname, char *suffix)
+int call_foreach_file(file_fnct_t fnct, const char *dirname,
+                     const char *suffix, void *data)
 {
        struct dirent *ent;
        DIR *dir;
        char *ext;
-       char file[NAME_SIZE];
        struct files *loop_file;
        struct files *tmp_file;
        LIST_HEAD(file_list);
@@ -217,10 +228,12 @@ int call_foreach_file(int fnct(char *f) , char *dirname, char *suffix)
 
        /* call function for every file in the list */
        list_for_each_entry_safe(loop_file, tmp_file, &file_list, list) {
-               snprintf(file, NAME_SIZE-1, "%s/%s", dirname, loop_file->name);
-               file[NAME_SIZE-1] = '\0';
+               char filename[NAME_SIZE];
+
+               snprintf(filename, NAME_SIZE, "%s/%s", dirname, loop_file->name);
+               filename[NAME_SIZE-1] = '\0';
 
-               fnct(file);
+               fnct(filename, data);
 
                list_del(&loop_file->list);
                free(loop_file);