X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=udevdb.c;h=23de22751d47802714d479df05ac5d997675580b;hp=c4e064fc115d4414ef21cbbbc44403ed4570e7bc;hb=ab51035617d5725305b8ef98eff6b7c64f3ccec6;hpb=b2a21a35476b4780ef1fc68c60216117ab66fa2b diff --git a/udevdb.c b/udevdb.c index c4e064fc1..23de22751 100644 --- a/udevdb.c +++ b/udevdb.c @@ -1,5 +1,5 @@ /* - * udevdb.c + * udevdb.c - udev database library * * Userspace devfs * @@ -21,52 +21,59 @@ * */ -/* - * udev database library - */ #define _KLIBC_HAS_ARCH_SIG_ATOMIC_T #include #include +#include +#include #include #include #include #include #include -#include "udev_version.h" +#include "libsysfs/sysfs/libsysfs.h" #include "udev.h" +#include "udev_lib.h" +#include "udev_version.h" #include "logging.h" #include "namedev.h" #include "udevdb.h" #include "tdb/tdb.h" -#include "libsysfs/libsysfs.h" static TDB_CONTEXT *udevdb; +sig_atomic_t gotalarm; - -int udevdb_add_dev(const char *path, const struct udevice *dev) +int udevdb_add_dev(struct udevice *udev) { TDB_DATA key, data; char keystr[SYSFS_PATH_MAX]; - if ((path == NULL) || (dev == NULL)) - return -ENODEV; + if (udev->test_run) + return 0; + + if (udevdb == NULL) + return -1; - memset(keystr, 0, NAME_SIZE); - strcpy(keystr, path); + memset(keystr, 0x00, SYSFS_PATH_MAX); + strfieldcpy(keystr, udev->devpath); key.dptr = keystr; key.dsize = strlen(keystr) + 1; - data.dptr = (void *)dev; - data.dsize = sizeof(*dev); - + data.dptr = (void *) udev; + data.dsize = UDEVICE_DB_LEN; + dbg("store key '%s' for device '%s'", keystr, udev->name); + return tdb_store(udevdb, key, data, TDB_REPLACE); } -int udevdb_get_dev(const char *path, struct udevice *dev) +int udevdb_get_dev(const char *path, struct udevice *udev) { TDB_DATA key, data; + if (udevdb == NULL) + return -1; + if (path == NULL) return -ENODEV; @@ -77,7 +84,9 @@ int udevdb_get_dev(const char *path, struct udevice *dev) if (data.dptr == NULL || data.dsize == 0) return -ENODEV; - memcpy(dev, data.dptr, sizeof(*dev)); + memset(udev, 0x00, sizeof(struct udevice)); + memcpy(udev, data.dptr, UDEVICE_DB_LEN); + return 0; } @@ -86,11 +95,14 @@ int udevdb_delete_dev(const char *path) TDB_DATA key; char keystr[SYSFS_PATH_MAX]; + if (udevdb == NULL) + return -1; + if (path == NULL) return -EINVAL; memset(keystr, 0, sizeof(keystr)); - strcpy(keystr, path); + strfieldcpy(keystr, path); key.dptr = keystr; key.dsize = strlen(keystr) + 1; @@ -119,6 +131,8 @@ int udevdb_init(int init_flag) if (init_flag != UDEVDB_DEFAULT && init_flag != UDEVDB_INTERNAL) return -EINVAL; + tdb_set_lock_alarm(&gotalarm); + udevdb = tdb_open(udev_db_filename, 0, init_flag, O_RDWR | O_CREAT, 0644); if (udevdb == NULL) { if (init_flag == UDEVDB_INTERNAL) @@ -143,7 +157,7 @@ int udevdb_open_ro(void) return 0; } -static int (*user_record_callback) (char *path, struct udevice *dev); +static int (*user_record_callback) (const char *path, struct udevice *dev); static int traverse_callback(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) { @@ -154,10 +168,13 @@ static int traverse_callback(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void * udevdb_call_foreach: dumps whole database by passing record data to user function * @user_record_handler: user function called for every record in the database */ -int udevdb_call_foreach(int (*user_record_handler) (char *path, struct udevice *dev)) +int udevdb_call_foreach(int (*user_record_handler) (const char *path, struct udevice *dev)) { int retval = 0; + if (udevdb == NULL) + return -1; + if (user_record_handler == NULL) { dbg("invalid user record handling function"); return -EINVAL; @@ -175,15 +192,31 @@ static char *find_path; static const char *find_name; static int find_found; -static int find_device_by_name(char *path, struct udevice *dev) +static int find_device_by_name(const char *path, struct udevice *udev) { - if (strncmp(dev->name, find_name, sizeof(dev->name)) == 0) { - memcpy(find_dev, dev, sizeof(*find_dev)); - strncpy(find_path, path, NAME_SIZE); + char *pos; + int len; + + if (strncmp(udev->name, find_name, sizeof(udev->name)) == 0) { + memcpy(find_dev, udev, sizeof(struct udevice)); + strfieldcpymax(find_path, path, NAME_SIZE); find_found = 1; /* stop search */ return 1; } + /* look for matching symlink*/ + foreach_strpart(udev->symlink, " ", pos, len) { + if (strncmp(pos, find_name, len) != 0) + continue; + + if (len != strlen(find_name)) + continue; + + memcpy(find_dev, udev, sizeof(struct udevice)); + strfieldcpymax(find_path, path, NAME_SIZE); + find_found = 1; + return 1; + } return 0; }