X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=udevdb.c;h=fc579a94512155a514186347d20fed76d5a80e63;hb=c6478ec1e128f0a92c2123ed110a651b88d43569;hp=f2469367109870009786cd6f5241c246ada8fafb;hpb=bbbe503ec1a5623a5a8abd003f46fdd8c3581054;p=elogind.git diff --git a/udevdb.c b/udevdb.c index f24693671..fc579a945 100644 --- a/udevdb.c +++ b/udevdb.c @@ -1,10 +1,10 @@ /* - * udevdb.c - udev database library + * udevdb.c * * Userspace devfs * * Copyright (C) 2003 Greg Kroah-Hartman - * Copyright (C) 2003 IBM Corp. + * Copyright (C) 2004 Kay Sievers * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -21,202 +21,194 @@ * */ -#define _KLIBC_HAS_ARCH_SIG_ATOMIC_T + #include #include #include #include #include #include -#include #include -#include +#include #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" - -static TDB_CONTEXT *udevdb; +#define PATH_TO_NAME_CHAR '@' -int udevdb_add_dev(const char *path, const struct udevice *dev) +static int get_db_filename(struct udevice *udev, char *filename, int len) { - TDB_DATA key, data; - char keystr[SYSFS_PATH_MAX]; - - if ((path == NULL) || (dev == NULL)) - return -ENODEV; - - memset(keystr, 0, NAME_SIZE); - strfieldcpy(keystr, path); - key.dptr = keystr; - key.dsize = strlen(keystr) + 1; + char devpath[SYSFS_PATH_MAX]; + char *pos; - data.dptr = (void *)dev; - data.dsize = UDEVICE_LEN; - dbg("store key '%s' for device '%s'", path, dev->name); + /* replace '/' to transform path into a filename */ + strfieldcpy(devpath, udev->devpath); + pos = strchr(&devpath[1], '/'); + while (pos) { + pos[0] = PATH_TO_NAME_CHAR; + pos = strchr(&pos[1], '/'); + } + snprintf(filename, len-1, "%s%s", udev_db_path, devpath); + filename[len-1] = '\0'; - return tdb_store(udevdb, key, data, TDB_REPLACE); + return 0; } -int udevdb_get_dev(const char *path, struct udevice *dev) +int udevdb_add_dev(struct udevice *udev) { - TDB_DATA key, data; + char filename[SYSFS_PATH_MAX]; + FILE *f; - if (path == NULL) - return -ENODEV; - - key.dptr = (void *)path; - key.dsize = strlen(path) + 1; + if (udev->test_run) + return 0; - data = tdb_fetch(udevdb, key); - if (data.dptr == NULL || data.dsize == 0) - return -ENODEV; + get_db_filename(udev, filename, SYSFS_PATH_MAX); - memset(dev, 0, sizeof(struct udevice)); - memcpy(dev, data.dptr, UDEVICE_LEN); - return 0; -} + create_path(filename); -int udevdb_delete_dev(const char *path) -{ - TDB_DATA key; - char keystr[SYSFS_PATH_MAX]; - - if (path == NULL) - return -EINVAL; + f = fopen(filename, "w"); + if (f == NULL) { + dbg("unable to create db file '%s'", filename); + return -1; + } + dbg("storing data for device '%s' in '%s'", udev->devpath, filename); - memset(keystr, 0, sizeof(keystr)); - strfieldcpy(keystr, path); + fprintf(f, "P:%s\n", udev->devpath); + fprintf(f, "N:%s\n", udev->name); + fprintf(f, "S:%s\n", udev->symlink); + fprintf(f, "A:%d\n", udev->partitions); - key.dptr = keystr; - key.dsize = strlen(keystr) + 1; + fclose(f); - return tdb_delete(udevdb, key); + return 0; } -/** - * udevdb_exit: closes database - */ -void udevdb_exit(void) +static int parse_db_file(struct udevice *udev, const char *filename) { - if (udevdb != NULL) { - tdb_close(udevdb); - udevdb = NULL; + char line[NAME_SIZE]; + char *bufline; + char *buf; + size_t bufsize; + size_t cur; + size_t count; + + if (file_map(filename, &buf, &bufsize) != 0) { + dbg("unable to read db file '%s'", filename); + return -1; } -} -/** - * udevdb_init: initializes database - * @init_flag: UDEVDB_INTERNAL - database stays in memory - * UDEVDB_DEFAULT - database is written to a file - */ -int udevdb_init(int init_flag) -{ - if (init_flag != UDEVDB_DEFAULT && init_flag != UDEVDB_INTERNAL) - return -EINVAL; - - udevdb = tdb_open(udev_db_filename, 0, init_flag, O_RDWR | O_CREAT, 0644); - if (udevdb == NULL) { - if (init_flag == UDEVDB_INTERNAL) - dbg("unable to initialize in-memory database"); - else - dbg("unable to initialize database at '%s'", udev_db_filename); - return -EACCES; + cur = 0; + while (cur < bufsize) { + count = buf_get_line(buf, bufsize, cur); + bufline = &buf[cur]; + cur += count+1; + + switch(bufline[0]) { + case 'P': + if (count > DEVPATH_SIZE) + count = DEVPATH_SIZE-1; + strncpy(udev->devpath, &bufline[2], count-2); + break; + case 'N': + if (count > NAME_SIZE) + count = NAME_SIZE-1; + strncpy(udev->name, &bufline[2], count-2); + break; + case 'S': + if (count > NAME_SIZE) + count = NAME_SIZE-1; + strncpy(udev->symlink, &bufline[2], count-2); + break; + case 'A': + strfieldcpy(line, &bufline[2]); + udev->partitions = atoi(line); + break; + } } + + if (udev->name[0] == '\0') + return -1; + return 0; } -/** - * udevdb_open_ro: open database for reading - */ -int udevdb_open_ro(void) +int udevdb_get_dev(struct udevice *udev) { - udevdb = tdb_open(udev_db_filename, 0, 0, O_RDONLY, 0); - if (udevdb == NULL) { - dbg("unable to open database at '%s'", udev_db_filename); - return -EACCES; - } - return 0; -} + char filename[SYSFS_PATH_MAX]; -static int (*user_record_callback) (char *path, struct udevice *dev); + get_db_filename(udev, filename, SYSFS_PATH_MAX); -static int traverse_callback(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - return user_record_callback((char*) key.dptr, (struct udevice*) dbuf.dptr); + return parse_db_file(udev, filename); } -/** - * 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_delete_dev(struct udevice *udev) { - int retval = 0; + char filename[SYSFS_PATH_MAX]; - if (user_record_handler == NULL) { - dbg("invalid user record handling function"); - return -EINVAL; - } - user_record_callback = user_record_handler; - retval = tdb_traverse(udevdb, traverse_callback, NULL); - if (retval < 0) - return -ENODEV; - else - return 0; -} + get_db_filename(udev, filename, SYSFS_PATH_MAX); + unlink(filename); -static struct udevice *find_dev; -static char *find_path; -static const char *find_name; -static int find_found; + return 0; +} -static int find_device_by_name(char *path, struct udevice *dev) +int udevdb_get_dev_byname(struct udevice *udev, const char *name) { - char *pos; - int len; - - if (strncmp(dev->name, find_name, sizeof(dev->name)) == 0) { - memcpy(find_dev, dev, sizeof(struct udevice)); - strfieldcpymax(find_path, path, NAME_SIZE); - find_found = 1; - /* stop search */ - return 1; + struct dirent *ent; + DIR *dir; + char filename[NAME_SIZE]; + struct udevice db_udev; + + dir = opendir(udev_db_path); + if (dir == NULL) { + dbg("unable to udev db '%s'", udev_db_path); + return -1; } - /* look for matching symlink*/ - foreach_strpart(dev->symlink, " ", pos, len) { - if (strncmp(pos, find_name, len) != 0) - continue; - if (len != strlen(find_name)) + while (1) { + ent = readdir(dir); + if (ent == NULL || ent->d_name[0] == '\0') + break; + + if (ent->d_name[0] == '.') continue; - memcpy(find_dev, dev, sizeof(struct udevice)); - strfieldcpymax(find_path, path, NAME_SIZE); - find_found = 1; - return 1; + snprintf(filename, NAME_SIZE-1, "%s/%s", udev_db_path, ent->d_name); + filename[NAME_SIZE-1] = '\0'; + + memset(&db_udev, 0x00, sizeof(struct udevice)); + if (parse_db_file(&db_udev, filename) == 0) { + char *pos; + int len; + + if (strncmp(name, db_udev.name, NAME_SIZE) == 0) { + goto found; + } + + foreach_strpart(db_udev.symlink, " ", pos, len) { + if (strncmp(name, pos, len) != 0) + continue; + + if (len == strlen(name)) + goto found; + } + + } } - return 0; -} -/** - * udevdb_get_dev_byname: search device with given name by traversing the whole database - */ -int udevdb_get_dev_byname(const char *name, char *path, struct udevice *dev) -{ - find_found = 0; - find_path = path; - find_dev = dev; - find_name = name; - udevdb_call_foreach(find_device_by_name); - if (find_found == 1) - return 0; - else - return -1; + closedir(dir); + + return -1; + +found: + closedir(dir); + + strfieldcpy(udev->devpath, db_udev.devpath); + strfieldcpy(udev->name, db_udev.name); + strfieldcpy(udev->symlink, db_udev.symlink); + udev->partitions = db_udev.partitions; + + return 0; }