chiark / gitweb /
[PATCH] Libsysfs updates
authorananth@in.ibm.com <ananth@in.ibm.com>
Fri, 12 Mar 2004 08:57:30 +0000 (00:57 -0800)
committerGreg KH <gregkh@suse.de>
Wed, 27 Apr 2005 04:35:09 +0000 (21:35 -0700)
Please find attached a _BIG_ patch to update udev's libsysfs. Patch applies
on udev-021 and contains:

1. Updates to get udev's libsysfs to the latest (to be released) level.
2. Changes for C++ compatibility (use "char" and not "unsigned char"
unless absolutely necessary).
3. More importantly, take care of buffer overflows. Libsysfs now uses a
        scaled down version of Kay's "safe" macros.

Tested using a usb-storage device.

I will send you a doc update shortly.

libsysfs/dlist.c
libsysfs/dlist.h
libsysfs/sysfs/libsysfs.h
libsysfs/sysfs_bus.c
libsysfs/sysfs_class.c
libsysfs/sysfs_device.c
libsysfs/sysfs_dir.c
libsysfs/sysfs_driver.c
libsysfs/sysfs_utils.c

index a94ab1f..942eccb 100644 (file)
@@ -260,6 +260,16 @@ void dlist_unshift(Dlist *list,void *data)
   dlist_insert(list,data,0);
 }
 
+void dlist_unshift_sorted(Dlist *list, void *data, 
+                       int (*sorter)(void *new, void *old))
+{
+       if (list->count == 0)
+               dlist_unshift(list, data);
+       else {
+               list->marker=list->head->next;
+               dlist_insert_sorted(list, data, sorter);
+       }
+}
 
 /* 
  * Remove end node from list.
index 83f67e8..7fc90e5 100644 (file)
@@ -76,13 +76,14 @@ void dlist_end(Dlist *);
 
 void *dlist_insert(Dlist *,void *,int) ;
 
-void *dlist_insert_sorted(struct dlist *list, void *new, int (*sorter)(void *, void *));
+void *dlist_insert_sorted(struct dlist *list, void *new_elem, int (*sorter)(void *, void *));
 
 void dlist_delete(Dlist *,int);
 
 void dlist_push(Dlist *,void *);
 
 void dlist_unshift(Dlist *,void *);
+void dlist_unshift_sorted(Dlist *,void *,int (*sorter)(void *, void *));
 
 void *dlist_pop(Dlist *);
 
index f3d2dd4..cbde2f5 100644 (file)
 #define _LIBSYSFS_H_
 
 #include <sys/types.h>
+#include <string.h>
+
+/* 
+ * Defines to prevent buffer overruns
+ */
+#define safestrcpy(to, from)   strncpy(to, from, sizeof(to)-1)
+#define safestrcat(to, from)   strncat(to, from, sizeof(to) - strlen(to)-1)
+
+#define safestrncpy(to, from, maxsize) \
+do { \
+       to[maxsize-1] = '\0'; \
+       strncpy(to, from, maxsize-1); \
+} while (0)
+
+#define safestrncat(to, from, maxsize) \
+do { \
+       to[maxsize-1] = '\0'; \
+       strncat(to, from, maxsize - strlen(to)-1); \
+} while (0)
 
 /*
  * Generic #defines go here..
 #define SYSFS_METHOD_SHOW      0x01    /* attr can be read by user */
 #define SYSFS_METHOD_STORE     0x02    /* attr can be changed by user */
 
-struct dlist;
+/*
+ * NOTE: We have the statically allocated "name" as the first element of all 
+ * the structures. This feature is used in the "sorter" function for dlists
+ */
 
 struct sysfs_attribute {
-       unsigned char *value;
+       char name[SYSFS_NAME_LEN];
+       char path[SYSFS_PATH_MAX];
+       char *value;
        unsigned short len;             /* value length */
        unsigned short method;          /* show and store */
-       unsigned char name[SYSFS_NAME_LEN];
-       unsigned char path[SYSFS_PATH_MAX];
 };
 
 struct sysfs_link {
-       unsigned char name[SYSFS_NAME_LEN];
-       unsigned char path[SYSFS_PATH_MAX];
-       unsigned char target[SYSFS_PATH_MAX];
+       char name[SYSFS_NAME_LEN];
+       char path[SYSFS_PATH_MAX];
+       char target[SYSFS_PATH_MAX];
 };
 
 struct sysfs_directory {
-       unsigned char name[SYSFS_NAME_LEN];
-       unsigned char path[SYSFS_PATH_MAX];
+       char name[SYSFS_NAME_LEN];
+       char path[SYSFS_PATH_MAX];
 
        /* Private: for internal use only */
        struct dlist *subdirs;  
@@ -73,8 +95,8 @@ struct sysfs_directory {
 };
 
 struct sysfs_driver {
-       unsigned char name[SYSFS_NAME_LEN];
-       unsigned char path[SYSFS_PATH_MAX];
+       char name[SYSFS_NAME_LEN];
+       char path[SYSFS_PATH_MAX];
 
        /* Private: for internal use only */
        struct dlist *devices;
@@ -82,11 +104,11 @@ struct sysfs_driver {
 };
 
 struct sysfs_device {
-       unsigned char name[SYSFS_NAME_LEN];
-       unsigned char bus_id[SYSFS_NAME_LEN];
-       unsigned char bus[SYSFS_NAME_LEN];
-       unsigned char driver_name[SYSFS_NAME_LEN];
-       unsigned char path[SYSFS_PATH_MAX];
+       char name[SYSFS_NAME_LEN];
+       char bus_id[SYSFS_NAME_LEN];
+       char bus[SYSFS_NAME_LEN];
+       char driver_name[SYSFS_NAME_LEN];
+       char path[SYSFS_PATH_MAX];
 
        /* Private: for internal use only */
        struct sysfs_device *parent;            
@@ -95,8 +117,8 @@ struct sysfs_device {
 };
 
 struct sysfs_root_device {
-       unsigned char name[SYSFS_NAME_LEN];
-       unsigned char path[SYSFS_PATH_MAX];
+       char name[SYSFS_NAME_LEN];
+       char path[SYSFS_PATH_MAX];
 
        /* Private: for internal use only */
        struct dlist *devices;
@@ -104,8 +126,8 @@ struct sysfs_root_device {
 };
 
 struct sysfs_bus {
-       unsigned char name[SYSFS_NAME_LEN];
-       unsigned char path[SYSFS_PATH_MAX];
+       char name[SYSFS_NAME_LEN];
+       char path[SYSFS_PATH_MAX];
 
        /* Private: for internal use only */
        struct dlist *drivers;
@@ -114,9 +136,9 @@ struct sysfs_bus {
 };
 
 struct sysfs_class_device {
-       unsigned char name[SYSFS_NAME_LEN];
-       unsigned char classname[SYSFS_NAME_LEN];
-       unsigned char path[SYSFS_PATH_MAX];
+       char name[SYSFS_NAME_LEN];
+       char classname[SYSFS_NAME_LEN];
+       char path[SYSFS_PATH_MAX];
 
        /* Private: for internal use only */
        struct sysfs_class_device *parent;      
@@ -126,8 +148,8 @@ struct sysfs_class_device {
 };
 
 struct sysfs_class {
-       unsigned char name[SYSFS_NAME_LEN];
-       unsigned char path[SYSFS_PATH_MAX];
+       char name[SYSFS_NAME_LEN];
+       char path[SYSFS_PATH_MAX];
 
        /* Private: for internal use only */
        struct dlist *devices;
@@ -141,49 +163,47 @@ extern "C" {
 /*
  * Function Prototypes
  */
-extern int sysfs_get_mnt_path(unsigned char *mnt_path, size_t len);
-extern int sysfs_remove_trailing_slash(unsigned char *path);
-extern int sysfs_get_name_from_path(const unsigned char *path, 
-                                       unsigned char *name, size_t len);
-extern int sysfs_path_is_dir(const unsigned char *path);
-extern int sysfs_path_is_link(const unsigned char *path);
-extern int sysfs_path_is_file(const unsigned char *path);
-extern int sysfs_get_link(const unsigned char *path, unsigned char *target, 
-                                                               size_t len);
-extern struct dlist *sysfs_open_subsystem_list(unsigned char *name);
-extern struct dlist *sysfs_open_bus_devices_list(unsigned char *name);
+extern int sysfs_get_mnt_path(char *mnt_path, size_t len);
+extern int sysfs_remove_trailing_slash(char *path);
+extern int sysfs_get_name_from_path(const char *path, char *name, size_t len);
+extern int sysfs_path_is_dir(const char *path);
+extern int sysfs_path_is_link(const char *path);
+extern int sysfs_path_is_file(const char *path);
+extern int sysfs_get_link(const char *path, char *target, size_t len);
+extern struct dlist *sysfs_open_subsystem_list(char *name);
+extern struct dlist *sysfs_open_bus_devices_list(char *name);
 extern void sysfs_close_list(struct dlist *list);
 
 /* sysfs directory and file access */
 extern void sysfs_close_attribute(struct sysfs_attribute *sysattr);
-extern struct sysfs_attribute *sysfs_open_attribute(const unsigned char *path);
+extern struct sysfs_attribute *sysfs_open_attribute(const char *path);
 extern int sysfs_read_attribute(struct sysfs_attribute *sysattr);
-extern int sysfs_read_attribute_value(const unsigned char *attrpath, 
-                               unsigned char *value, size_t vsize);
+extern int sysfs_read_attribute_value(const char *attrpath, 
+               char *value, size_t vsize);
 extern int sysfs_write_attribute(struct sysfs_attribute *sysattr,
-               const unsigned char *new_value, size_t len);
-extern unsigned char *sysfs_get_value_from_attributes(struct dlist *attr, 
-                                               const unsigned char * name);
+               const char *new_value, size_t len);
+extern char *sysfs_get_value_from_attributes(struct dlist *attr, 
+               const char *name);
 extern int sysfs_refresh_dir_attributes(struct sysfs_directory *sysdir);
 extern int sysfs_refresh_dir_links(struct sysfs_directory *sysdir);
 extern int sysfs_refresh_dir_subdirs(struct sysfs_directory *sysdir);
 extern void sysfs_close_directory(struct sysfs_directory *sysdir);
-extern struct sysfs_directory *sysfs_open_directory(const unsigned char *path);
+extern struct sysfs_directory *sysfs_open_directory(const char *path);
 extern int sysfs_read_dir_attributes(struct sysfs_directory *sysdir);
 extern int sysfs_read_dir_links(struct sysfs_directory *sysdir);
 extern int sysfs_read_dir_subdirs(struct sysfs_directory *sysdir);
 extern int sysfs_read_directory(struct sysfs_directory *sysdir);
 extern int sysfs_read_all_subdirs(struct sysfs_directory *sysdir);
 extern struct sysfs_directory *sysfs_get_subdirectory
-                       (struct sysfs_directory *dir, unsigned char *subname);
+       (struct sysfs_directory *dir, char *subname);
 extern void sysfs_close_link(struct sysfs_link *ln);
-extern struct sysfs_link *sysfs_open_link(const unsigned char *lnpath);
-extern struct sysfs_link *sysfs_get_directory_link(struct sysfs_directory *dir,
-                                               unsigned char *linkname);
+extern struct sysfs_link *sysfs_open_link(const char *lnpath);
+extern struct sysfs_link *sysfs_get_directory_link
+       (struct sysfs_directory *dir, char *linkname);
 extern struct sysfs_link *sysfs_get_subdirectory_link
-                       (struct sysfs_directory *dir, unsigned char *linkname);
+       (struct sysfs_directory *dir, char *linkname);
 extern struct sysfs_attribute *sysfs_get_directory_attribute
-                       (struct sysfs_directory *dir, unsigned char *attrname);
+       (struct sysfs_directory *dir, char *attrname);
 extern struct dlist *sysfs_get_dir_attributes(struct sysfs_directory *dir);
 extern struct dlist *sysfs_get_dir_links(struct sysfs_directory *dir);
 extern struct dlist *sysfs_get_dir_subdirs(struct sysfs_directory *dir);
@@ -191,84 +211,101 @@ extern struct dlist *sysfs_get_dir_subdirs(struct sysfs_directory *dir);
 /* sysfs driver access */
 extern void sysfs_close_driver(struct sysfs_driver *driver);
 extern struct sysfs_driver *sysfs_open_driver
-       (const unsigned char *drv_name, const unsigned char *bus_name);
-extern struct sysfs_driver *sysfs_open_driver_path(const unsigned char *path);
+       (const char *bus_name, const char *drv_name);
+extern struct sysfs_driver *sysfs_open_driver_path(const char *path);
 extern struct sysfs_attribute *sysfs_get_driver_attr
-               (struct sysfs_driver *drv, const unsigned char *name);
+       (struct sysfs_driver *drv, const char *name);
 extern struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver);
 extern struct dlist *sysfs_get_driver_devices(struct sysfs_driver *driver);
 extern struct dlist *sysfs_refresh_driver_devices(struct sysfs_driver *driver);
 extern struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver);
 extern struct sysfs_device *sysfs_get_driver_device
-       (struct sysfs_driver *driver, const unsigned char *name);
+       (struct sysfs_driver *driver, const char *name);
 extern struct dlist *sysfs_refresh_driver_attributes
-                       (struct sysfs_driver *driver);
-extern struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus, 
-               const unsigned char *drv, const unsigned char *attrib);
+       (struct sysfs_driver *driver);
+extern struct sysfs_attribute *sysfs_open_driver_attr
+       (const char *bus, const char *drv, const char *attrib);
 
 /* generic sysfs device access */
 extern void sysfs_close_root_device(struct sysfs_root_device *root);
-extern struct sysfs_root_device *sysfs_open_root_device
-                                               (const unsigned char *name);
+extern struct sysfs_root_device *sysfs_open_root_device(const char *name);
 extern struct dlist *sysfs_get_root_devices(struct sysfs_root_device *root);
+extern void sysfs_close_device_tree(struct sysfs_device *device);
+extern struct sysfs_device *sysfs_open_device_tree(const char *path);
 extern void sysfs_close_device(struct sysfs_device *dev);
 extern struct sysfs_device *sysfs_open_device
-               (const unsigned char *bus_id, const unsigned char *bus);
+       (const char *bus, const char *bus_id);
 extern struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev);
-extern struct sysfs_device *sysfs_open_device_path(const unsigned char *path);
+extern struct sysfs_device *sysfs_open_device_path(const char *path);
 extern int sysfs_get_device_bus(struct sysfs_device *dev);
 extern struct sysfs_attribute *sysfs_get_device_attr
-                       (struct sysfs_device *dev, const unsigned char *name);
+       (struct sysfs_device *dev, const char *name);
 extern struct dlist *sysfs_get_device_attributes(struct sysfs_device *device);
 extern struct dlist *sysfs_refresh_device_attributes
-                       (struct sysfs_device *device);
-extern struct sysfs_attribute *sysfs_open_device_attr(const unsigned char *bus, 
-               const unsigned char *bus_id, const unsigned char *attrib);
+       (struct sysfs_device *device);
+extern struct sysfs_attribute *sysfs_open_device_attr(const char *bus, 
+               const char *bus_id, const char *attrib);
 
 /* generic sysfs bus access */
 extern void sysfs_close_bus(struct sysfs_bus *bus);
-extern struct sysfs_bus *sysfs_open_bus(const unsigned char *name);
-extern struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus,
-                                               unsigned char *id);
+extern struct sysfs_bus *sysfs_open_bus(const char *name);
+extern struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus, 
+               char *id);
 extern struct sysfs_driver *sysfs_get_bus_driver(struct sysfs_bus *bus,
-                                               unsigned char *drvname);
+               char *drvname);
 extern struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus);
 extern struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus);
 extern struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus);
 extern struct dlist *sysfs_refresh_bus_attributes(struct sysfs_bus *bus);
-extern struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus,
-                                               unsigned char *attrname);
-extern struct sysfs_device *sysfs_open_bus_device(unsigned char *busname, 
-                                                       unsigned char *dev_id);
-extern int sysfs_find_driver_bus(const unsigned char *driver, 
-                                       unsigned char *busname, size_t bsize);
+extern struct sysfs_attribute *sysfs_get_bus_attribute
+       (struct sysfs_bus *bus, char *attrname);
+extern int sysfs_find_driver_bus(const char *driver, char *busname, 
+               size_t bsize);
 
 /* generic sysfs class access */
 extern void sysfs_close_class_device(struct sysfs_class_device *dev);
 extern struct sysfs_class_device *sysfs_open_class_device_path
-                                       (const unsigned char *path);
+       (const char *path);
 extern struct sysfs_class_device *sysfs_open_class_device
-       (const unsigned char *class, const unsigned char *name);
+       (const char *classname, const char *name);
 extern struct sysfs_device *sysfs_get_classdev_device
-                               (struct sysfs_class_device *clsdev);
+       (struct sysfs_class_device *clsdev);
 extern struct sysfs_driver *sysfs_get_classdev_driver
-                               (struct sysfs_class_device *clsdev);
+       (struct sysfs_class_device *clsdev);
 extern struct sysfs_class_device *sysfs_get_classdev_parent
-                               (struct sysfs_class_device *clsdev);
+       (struct sysfs_class_device *clsdev);
 extern void sysfs_close_class(struct sysfs_class *cls);
-extern struct sysfs_class *sysfs_open_class(const unsigned char *name);
+extern struct sysfs_class *sysfs_open_class(const char *name);
 extern struct dlist *sysfs_get_class_devices(struct sysfs_class *cls);
 extern struct sysfs_class_device *sysfs_get_class_device
-       (struct sysfs_class *class, unsigned char *name);
+       (struct sysfs_class *cls, char *name);
 extern struct dlist *sysfs_get_classdev_attributes
        (struct sysfs_class_device *cdev);
 extern struct dlist *sysfs_refresh_classdev_attributes
        (struct sysfs_class_device *cdev);
 extern struct sysfs_attribute *sysfs_get_classdev_attr
-       (struct sysfs_class_device *clsdev, const unsigned char *name);
+       (struct sysfs_class_device *clsdev, const char *name);
 extern struct sysfs_attribute *sysfs_open_classdev_attr
-       (const unsigned char *classname, const unsigned char *dev, 
-                                               const unsigned char *attrib); 
+       (const char *classname, const char *dev, 
+                                               const char *attrib); 
+
+/**
+ * sort_list: sorter function to keep list elements sorted in alphabetical 
+ *     order. Just does a strncmp as you can see :)
+ *     
+ * Returns 1 if less than 0 otherwise
+ *
+ * NOTE: We take care to have a statically allocated "name" as the first 
+ *     lement of all libsysfs structures. Hence, this function will work 
+ *     AS IS for _ALL_ the lists that have to be sorted.
+ */
+static inline int sort_list(void *new_elem, void *old_elem)
+{
+        return ((strncmp(((struct sysfs_attribute *)new_elem)->name,
+               ((struct sysfs_attribute *)old_elem)->name,
+               strlen(((struct sysfs_attribute *)new_elem)->name))) < 0 ? 1 : 0);
+}
+
 
 #ifdef __cplusplus
 }
index 87318c0..bff7f78 100644 (file)
@@ -44,7 +44,7 @@ static int bus_device_id_equal(void *a, void *b)
        if (a == NULL || b == NULL)
                return 0;
 
-       if (strcmp(((unsigned char *)a), ((struct sysfs_device *)b)->bus_id) 
+       if (strcmp(((char *)a), ((struct sysfs_device *)b)->bus_id) 
            == 0)
                return 1;
        return 0;
@@ -61,7 +61,7 @@ static int bus_driver_name_equal(void *a, void *b)
        if (a == NULL || b == NULL)
                return 0;
 
-       if (strcmp(((unsigned char *)a), ((struct sysfs_driver *)b)->name) == 0)
+       if (strcmp(((char *)a), ((struct sysfs_driver *)b)->name) == 0)
                return 1;
        return 0;
 }
@@ -102,16 +102,16 @@ struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus)
        struct sysfs_device *bdev = NULL;
        struct sysfs_directory *devdir = NULL;
        struct sysfs_link *curl = NULL;
-       unsigned char path[SYSFS_PATH_MAX];
+       char path[SYSFS_PATH_MAX];
 
        if (bus == NULL) {
                errno = EINVAL;
                return NULL;
        }
        memset(path, 0, SYSFS_PATH_MAX);
-       strcpy(path, bus->path);
-       strcat(path, "/");
-       strcat(path, SYSFS_DEVICES_NAME);
+       safestrcpy(path, bus->path);
+       safestrcat(path, "/");
+       safestrcat(path, SYSFS_DEVICES_NAME);
        devdir = sysfs_open_directory(path);
        if (devdir == NULL) 
                return NULL;
@@ -121,7 +121,7 @@ struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus)
                return NULL;
        }
 
-       if (devdir->links != 0) {
+       if (devdir->links != NULL) {
                dlist_for_each_data(devdir->links, curl, struct sysfs_link) {
                        bdev = sysfs_open_device_path(curl->target);
                        if (bdev == NULL) {
@@ -133,7 +133,7 @@ struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus)
                                bus->devices = dlist_new_with_delete
                                        (sizeof(struct sysfs_device), 
                                                        sysfs_close_dev);
-                       dlist_unshift(bus->devices, bdev);
+                       dlist_unshift_sorted(bus->devices, bdev, sort_list);
                }
        }
        sysfs_close_directory(devdir);
@@ -151,16 +151,16 @@ struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus)
        struct sysfs_driver *driver = NULL;
        struct sysfs_directory *drvdir = NULL;
        struct sysfs_directory *cursub = NULL;
-       unsigned char path[SYSFS_PATH_MAX];
+       char path[SYSFS_PATH_MAX];
 
        if (bus == NULL) {
                errno = EINVAL;
                return NULL;
        }
        memset(path, 0, SYSFS_PATH_MAX);
-       strcpy(path, bus->path);
-       strcat(path, "/");
-       strcat(path, SYSFS_DRIVERS_NAME);
+       safestrcpy(path, bus->path);
+       safestrcat(path, "/");
+       safestrcat(path, SYSFS_DRIVERS_NAME);
        drvdir = sysfs_open_directory(path);
        if (drvdir == NULL) 
                return NULL;
@@ -182,7 +182,7 @@ struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus)
                                bus->drivers = dlist_new_with_delete
                                        (sizeof(struct sysfs_driver), 
                                                        sysfs_close_drv);
-                       dlist_unshift(bus->drivers, driver);
+                       dlist_unshift_sorted(bus->drivers, driver, sort_list);
                }
        }
        sysfs_close_directory(drvdir);
@@ -193,10 +193,10 @@ struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus)
  * sysfs_open_bus: opens specific bus and all its devices on system
  * returns sysfs_bus structure with success or NULL with error.
  */
-struct sysfs_bus *sysfs_open_bus(const unsigned char *name)
+struct sysfs_bus *sysfs_open_bus(const char *name)
 {
        struct sysfs_bus *bus = NULL;
-       unsigned char buspath[SYSFS_PATH_MAX];
+       char buspath[SYSFS_PATH_MAX];
 
        if (name == NULL) {
                errno = EINVAL;
@@ -209,10 +209,10 @@ struct sysfs_bus *sysfs_open_bus(const unsigned char *name)
                return NULL;
        }
 
-       strcat(buspath, "/");
-       strcat(buspath, SYSFS_BUS_NAME);
-       strcat(buspath, "/");
-       strcat(buspath, name);
+       safestrcat(buspath, "/");
+       safestrcat(buspath, SYSFS_BUS_NAME);
+       safestrcat(buspath, "/");
+       safestrcat(buspath, name);
        if ((sysfs_path_is_dir(buspath)) != 0) {
                dprintf("Invalid path to bus: %s\n", buspath);
                return NULL;
@@ -222,8 +222,8 @@ struct sysfs_bus *sysfs_open_bus(const unsigned char *name)
                dprintf("calloc failed\n");
                return NULL;
        }
-       strcpy(bus->name, name);        
-       strcpy(bus->path, buspath);
+       safestrcpy(bus->name, name);    
+       safestrcpy(bus->path, buspath);
        if ((sysfs_remove_trailing_slash(bus->path)) != 0) {
                dprintf("Incorrect path to bus %s\n", bus->path);
                sysfs_close_bus(bus);
@@ -239,8 +239,7 @@ struct sysfs_bus *sysfs_open_bus(const unsigned char *name)
  * @id: bus_id for device
  * returns struct sysfs_device reference or NULL if not found.
  */
-struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus, 
-                                                       unsigned char *id)
+struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus, char *id)
 {
        if (bus == NULL || id == NULL) {
                errno = EINVAL;
@@ -264,7 +263,7 @@ struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus,
  * returns struct sysfs_driver reference or NULL if not found.
  */
 struct sysfs_driver *sysfs_get_bus_driver(struct sysfs_bus *bus, 
-                                                       unsigned char *drvname)
+                                                       char *drvname)
 {
        if (bus == NULL || drvname == NULL) {
                errno = EINVAL;
@@ -338,7 +337,7 @@ struct dlist *sysfs_refresh_bus_attributes(struct sysfs_bus *bus)
  * returns reference to sysfs_attribute if found or NULL if not found
  */
 struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus,
-                                               unsigned char *attrname)
+                                               char *attrname)
 {
        struct dlist *attrlist = NULL;
        
@@ -354,59 +353,15 @@ struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus,
 }
 
 /**
- * sysfs_open_bus_device: locates a device on a bus and returns it. Device
- *     must be closed using sysfs_close_device.
- * @busname: Name of bus to search
- * @dev_id: Id of device on bus.
- * returns sysfs_device if found or NULL if not.
- */
-struct sysfs_device *sysfs_open_bus_device(unsigned char *busname, 
-                                                       unsigned char *dev_id)
-{
-       struct sysfs_device *rdev = NULL;
-       char path[SYSFS_PATH_MAX];
-
-       if (busname == NULL || dev_id == NULL) {
-               errno = EINVAL;
-               return NULL;
-       }
-
-       memset(path, 0, SYSFS_PATH_MAX);
-       if (sysfs_get_mnt_path(path, SYSFS_PATH_MAX) != 0) {
-               dprintf("Error getting sysfs mount point\n");
-               return NULL;
-       }
-
-       strcat(path, "/");
-       strcat(path, SYSFS_BUS_NAME);
-       strcat(path, "/");
-       strcat(path, busname);
-       strcat(path, "/");
-       strcat(path, SYSFS_DEVICES_NAME);
-       strcat(path, "/");
-       strcat(path, dev_id);
-
-       rdev = sysfs_open_device_path(path);
-       if (rdev == NULL) {
-               dprintf("Error getting device %s on bus %s\n",
-                               dev_id, busname);
-               return NULL;
-       }
-       
-       return rdev;
-}
-
-/**
  * sysfs_find_driver_bus: locates the bus the driver is on.
  * @driver: name of the driver to locate
  * @busname: buffer to copy name to
  * @bsize: buffer size
  * returns 0 with success, -1 with error
  */
-int sysfs_find_driver_bus(const unsigned char *driver, unsigned char *busname,
-                                                       size_t bsize)
+int sysfs_find_driver_bus(const char *driver, char *busname, size_t bsize)
 {
-       unsigned char subsys[SYSFS_PATH_MAX], *bus = NULL, *curdrv = NULL;
+       char subsys[SYSFS_PATH_MAX], *bus = NULL, *curdrv = NULL;
        struct dlist *buslist = NULL, *drivers = NULL;
 
        if (driver == NULL || busname == NULL) {
@@ -415,23 +370,22 @@ int sysfs_find_driver_bus(const unsigned char *driver, unsigned char *busname,
        }
 
        memset(subsys, 0, SYSFS_PATH_MAX);
-       strcat(subsys, "/");
-       strcpy(subsys, SYSFS_BUS_NAME);
+       safestrcpy(subsys, SYSFS_BUS_NAME);
        buslist = sysfs_open_subsystem_list(subsys);
        if (buslist != NULL) {
                dlist_for_each_data(buslist, bus, char) {
                        memset(subsys, 0, SYSFS_PATH_MAX);
-                       strcat(subsys, "/");
-                       strcpy(subsys, SYSFS_BUS_NAME);
-                       strcat(subsys, "/");
-                       strcat(subsys, bus);
-                       strcat(subsys, "/");
-                       strcat(subsys, SYSFS_DRIVERS_NAME);
+                       safestrcpy(subsys, SYSFS_BUS_NAME);
+                       safestrcat(subsys, "/");
+                       safestrcat(subsys, bus);
+                       safestrcat(subsys, "/");
+                       safestrcat(subsys, SYSFS_DRIVERS_NAME);
                        drivers = sysfs_open_subsystem_list(subsys);
                        if (drivers != NULL) {
                                dlist_for_each_data(drivers, curdrv, char) {
                                        if (strcmp(driver, curdrv) == 0) {
-                                               strncpy(busname, bus, bsize);
+                                               safestrncpy(busname, 
+                                                               bus, bsize);
                                                sysfs_close_list(drivers);
                                                sysfs_close_list(buslist);
                                                return 0;
index 0530505..7a69635 100644 (file)
@@ -38,8 +38,7 @@ static int class_name_equal(void *a, void *b)
        if (a == NULL || b == NULL)
                return 0;
 
-       if (strcmp(((unsigned char *)a), ((struct sysfs_class_device *)b)->name)
-               == 0)
+       if (strcmp(((char *)a), ((struct sysfs_class_device *)b)->name) == 0)
                return 1;
 
        return 0;
@@ -66,7 +65,7 @@ void sysfs_close_class_device(struct sysfs_class_device *dev)
 
 /**
  * sysfs_close_class: close single class
- * @class: class structure
+ * @cls: class structure
  */
 void sysfs_close_class(struct sysfs_class *cls)
 {
@@ -105,7 +104,7 @@ static struct sysfs_class *alloc_class(void)
  */
 static void set_classdev_classname(struct sysfs_class_device *cdev)
 {
-       unsigned char *c = NULL, *e = NULL;
+       char *c = NULL, *e = NULL;
        int count = 0;
 
        c = strstr(cdev->path, SYSFS_CLASS_NAME);
@@ -116,7 +115,7 @@ static void set_classdev_classname(struct sysfs_class_device *cdev)
        }
 
        if (c == NULL)
-               strcpy(cdev->classname, SYSFS_UNKNOWN);
+               safestrcpy(cdev->classname, SYSFS_UNKNOWN);
        else {
                if (*c == '/')
                        c++;
@@ -134,8 +133,7 @@ static void set_classdev_classname(struct sysfs_class_device *cdev)
  * @path: path to class device.
  * returns struct sysfs_class_device with success and NULL with error.
  */
-struct sysfs_class_device *sysfs_open_class_device_path
-                                       (const unsigned char *path)
+struct sysfs_class_device *sysfs_open_class_device_path(const char *path)
 {
        struct sysfs_class_device *cdev = NULL;
 
@@ -159,7 +157,7 @@ struct sysfs_class_device *sysfs_open_class_device_path
                return NULL;
        }
 
-       strcpy(cdev->path, path);
+       safestrcpy(cdev->path, path);
        if ((sysfs_remove_trailing_slash(cdev->path)) != 0) {
                dprintf("Invalid path to class device %s\n", cdev->path);
                sysfs_close_class_device(cdev);
@@ -172,7 +170,7 @@ struct sysfs_class_device *sysfs_open_class_device_path
 
 /**
  * sysfs_get_class_devices: gets all devices for class
- * @class: class to get devices for
+ * @cls: class to get devices for
  * returns dlist of class_devices with success and NULL with error
  */
 struct dlist *sysfs_get_class_devices(struct sysfs_class *cls)
@@ -210,7 +208,7 @@ struct dlist *sysfs_get_class_devices(struct sysfs_class *cls)
                                cls->devices = dlist_new_with_delete
                                        (sizeof(struct sysfs_class_device),
                                                        sysfs_close_cls_dev);
-                       dlist_unshift(cls->devices, dev);
+                       dlist_unshift_sorted(cls->devices, dev, sort_list);
                }
        }
        return cls->devices;
@@ -220,10 +218,10 @@ struct dlist *sysfs_get_class_devices(struct sysfs_class *cls)
  * sysfs_open_class: opens specific class and all its devices on system
  * returns sysfs_class structure with success or NULL with error.
  */
-struct sysfs_class *sysfs_open_class(const unsigned char *name)
+struct sysfs_class *sysfs_open_class(const char *name)
 {
        struct sysfs_class *cls = NULL;
-       unsigned char classpath[SYSFS_PATH_MAX];
+       char classpath[SYSFS_PATH_MAX];
 
        if (name == NULL) {
                errno = EINVAL;
@@ -241,13 +239,13 @@ struct sysfs_class *sysfs_open_class(const unsigned char *name)
         * if "name" is "block" and proceed accordingly
         */
        if (strcmp(name, SYSFS_BLOCK_NAME) == 0) {
-               strcat(classpath, "/");
-               strcat(classpath, SYSFS_BLOCK_NAME);
+               safestrcat(classpath, "/");
+               safestrcat(classpath, SYSFS_BLOCK_NAME);
        } else {
-               strcat(classpath, "/");
-               strcat(classpath, SYSFS_CLASS_NAME);
-               strcat(classpath, "/");
-               strcat(classpath, name);
+               safestrcat(classpath, "/");
+               safestrcat(classpath, SYSFS_CLASS_NAME);
+               safestrcat(classpath, "/");
+               safestrcat(classpath, name);
        }
        if ((sysfs_path_is_dir(classpath)) != 0) {
                dprintf("Class %s not found on the system\n", name);
@@ -259,8 +257,8 @@ struct sysfs_class *sysfs_open_class(const unsigned char *name)
                dprintf("calloc failed\n");
                return NULL;
        }
-       strcpy(cls->name, name);        
-       strcpy(cls->path, classpath);
+       safestrcpy(cls->name, name);    
+       safestrcpy(cls->path, classpath);
        if ((sysfs_remove_trailing_slash(cls->path)) != 0) {
                dprintf("Invalid path to class device %s\n", cls->path);
                sysfs_close_class(cls);
@@ -275,20 +273,20 @@ struct sysfs_class *sysfs_open_class(const unsigned char *name)
  * @class: class to find device on
  * @name: class name of the device
  */ 
-struct sysfs_class_device *sysfs_get_class_device(struct sysfs_class *class,
-                                       unsigned char *name)
+struct sysfs_class_device *sysfs_get_class_device(struct sysfs_class *cls,
+                                       char *name)
 {
-       if (class == NULL || name == NULL) {
+       if (cls == NULL || name == NULL) {
                errno = EINVAL;
                return NULL;
        }
 
-       if (class->devices == NULL) {
-               class->devices = sysfs_get_class_devices(class);
-               if (class->devices == NULL) 
+       if (cls->devices == NULL) {
+               cls->devices = sysfs_get_class_devices(cls);
+               if (cls->devices == NULL) 
                        return NULL;
        }
-       return (struct sysfs_class_device *)dlist_find_custom(class->devices,
+       return (struct sysfs_class_device *)dlist_find_custom(cls->devices,
                        name, class_name_equal);
 }
 
@@ -303,14 +301,14 @@ struct sysfs_device *sysfs_get_classdev_device
                        (struct sysfs_class_device *clsdev)
 {
        struct sysfs_link *devlink = NULL;
-       unsigned char devpath[SYSFS_PATH_MAX];
+       char devpath[SYSFS_PATH_MAX];
        
        if (clsdev == NULL) {
                errno = EINVAL;
                return NULL;
        }
-       strcpy(devpath, clsdev->path);
-       strcat(devpath, "/device");
+       safestrcpy(devpath, clsdev->path);
+       safestrcat(devpath, "/device");
        if ((sysfs_path_is_link(devpath)) != 0) {
                if (clsdev->sysdevice != NULL) {
                        sysfs_close_device(clsdev->sysdevice);
@@ -347,8 +345,6 @@ struct sysfs_device *sysfs_get_classdev_device
        clsdev->sysdevice = sysfs_open_device_path(devlink->target);
        if (clsdev->sysdevice == NULL)
                return NULL;
-       if (clsdev->driver != NULL) 
-               strcpy(clsdev->sysdevice->driver_name, clsdev->driver->name);
 
        return (clsdev->sysdevice);
 }
@@ -364,14 +360,14 @@ struct sysfs_driver *sysfs_get_classdev_driver
                        (struct sysfs_class_device *clsdev)
 {
        struct sysfs_link *drvlink = NULL;
-       unsigned char drvpath[SYSFS_PATH_MAX];
+       char drvpath[SYSFS_PATH_MAX];
        
        if (clsdev == NULL) {
                errno = EINVAL;
                return NULL;
        }
-       strcpy(drvpath, clsdev->path);
-        strcat(drvpath, "/driver");
+       safestrcpy(drvpath, clsdev->path);
+       safestrcat(drvpath, "/driver");
        if ((sysfs_path_is_link(drvpath)) != 0) {
                if (clsdev->driver != NULL) {
                        sysfs_close_driver(clsdev->driver);
@@ -407,8 +403,6 @@ struct sysfs_driver *sysfs_get_classdev_driver
        clsdev->driver = sysfs_open_driver_path(drvlink->target);
        if (clsdev->driver == NULL)
                return NULL;
-       if (clsdev->sysdevice != NULL)
-               strcpy(clsdev->sysdevice->driver_name, clsdev->driver->name);
 
        return (clsdev->driver);
 }
@@ -421,16 +415,15 @@ struct sysfs_driver *sysfs_get_classdev_driver
  */
 static int get_blockdev_parent(struct sysfs_class_device *clsdev)
 {
-       unsigned char parent_path[SYSFS_PATH_MAX], *c = NULL;
+       char parent_path[SYSFS_PATH_MAX], *c = NULL;
 
-       strcpy(parent_path, clsdev->path);
+       safestrcpy(parent_path, clsdev->path);
        c = strstr(parent_path, SYSFS_BLOCK_NAME);
        if (c == NULL) {
                dprintf("Class device %s does not belong to BLOCK subsystem\n",
                                clsdev->name);
                return 1;
        }
-
        c += strlen(SYSFS_BLOCK_NAME);
        if (*c == '/')
                c++;
@@ -486,7 +479,8 @@ struct sysfs_class_device *sysfs_get_classdev_parent
         * structure. Hence, we now call a specialized function for block and
         * later we can add support functions for other subsystems as required.
         */ 
-       if (!(strcmp(clsdev->classname, SYSFS_BLOCK_NAME))) {
+       if (!(strncmp(clsdev->classname, SYSFS_BLOCK_NAME, 
+                                       sizeof(SYSFS_BLOCK_NAME)))) {
                if ((get_blockdev_parent(clsdev)) == 0) 
                        return (clsdev->parent);
        }
@@ -502,8 +496,8 @@ struct sysfs_class_device *sysfs_get_classdev_parent
  * @psize: size of "path"
  * Returns 0 on SUCCESS or -1 on error
  */
-static int get_classdev_path(const unsigned char *classname
-               const unsigned char *clsdev, unsigned char *path, size_t len)
+static int get_classdev_path(const char *classname, const char *clsdev
+               char *path, size_t len)
 {
        if (classname == NULL || clsdev == NULL || path == NULL) {
                errno = EINVAL;
@@ -513,17 +507,18 @@ static int get_classdev_path(const unsigned char *classname,
                 dprintf("Error getting sysfs mount path\n");
                 return -1;
        }
-       if (strcmp(classname, SYSFS_BLOCK_NAME) == 0) {
-               strcat(path, "/");
-               strcat(path, SYSFS_BLOCK_NAME);
+       if (strncmp(classname, SYSFS_BLOCK_NAME,
+                               sizeof(SYSFS_BLOCK_NAME)) == 0) {
+               safestrncat(path, "/", len);
+               safestrncat(path, SYSFS_BLOCK_NAME, len);
        } else {
-               strcat(path, "/");
-               strcat(path, SYSFS_CLASS_NAME);
-               strcat(path, "/");
-               strcat(path, classname);
+               safestrncat(path, "/", len);
+               safestrncat(path, SYSFS_CLASS_NAME, len);
+               safestrncat(path, "/", len);
+               safestrncat(path, classname, len);
        }
-       strcat(path, "/");
-       strcat(path, clsdev);
+       safestrncat(path, "/", len);
+       safestrncat(path, clsdev, len);
        return 0;
 }
 
@@ -537,9 +532,9 @@ static int get_classdev_path(const unsigned char *classname,
  *     Call sysfs_close_class_device() to close the class device
  */
 struct sysfs_class_device *sysfs_open_class_device
-               (const unsigned char *classname, const unsigned char *name)
+               (const char *classname, const char *name)
 {
-       unsigned char devpath[SYSFS_PATH_MAX];
+       char devpath[SYSFS_PATH_MAX];
        struct sysfs_class_device *cdev = NULL;
 
        if (classname == NULL || name == NULL) {
@@ -622,7 +617,7 @@ struct dlist *sysfs_refresh_classdev_attributes
  * returns sysfs_attribute reference with success or NULL with error
  */
 struct sysfs_attribute *sysfs_get_classdev_attr
-               (struct sysfs_class_device *clsdev, const unsigned char *name)
+               (struct sysfs_class_device *clsdev, const char *name)
 {
        struct sysfs_attribute *cur = NULL;
        struct sysfs_directory *sdir = NULL;
@@ -640,7 +635,7 @@ struct sysfs_attribute *sysfs_get_classdev_attr
        attrlist = sysfs_get_classdev_attributes(clsdev);
        if (attrlist != NULL) {
                cur = sysfs_get_directory_attribute(clsdev->directory,
-                                               (unsigned char *)name);
+                                               (char *)name);
                if (cur != NULL)
                        return cur;
        }
@@ -656,7 +651,7 @@ struct sysfs_attribute *sysfs_get_classdev_attr
                        if ((sysfs_path_is_dir(sdir->path)) != 0) 
                                continue;
                        cur = sysfs_get_directory_attribute(sdir,
-                                                       (unsigned char *)name);
+                                                       (char *)name);
                        if (cur == NULL)
                                continue;
                }
@@ -675,11 +670,11 @@ struct sysfs_attribute *sysfs_get_classdev_attr
  *     A call to sysfs_close_attribute() is required to close the
  *     attribute returned and to free memory
  */
-struct sysfs_attribute *sysfs_open_classdev_attr(const unsigned char *classname,
-               const unsigned char *dev, const unsigned char *attrib)
+struct sysfs_attribute *sysfs_open_classdev_attr(const char *classname,
+               const char *dev, const char *attrib)
 {
        struct sysfs_attribute *attribute = NULL;
-       unsigned char path[SYSFS_PATH_MAX];
+       char path[SYSFS_PATH_MAX];
 
        if (classname == NULL || dev == NULL || attrib == NULL) {
                errno = EINVAL;
@@ -691,8 +686,8 @@ struct sysfs_attribute *sysfs_open_classdev_attr(const unsigned char *classname,
                                                dev, classname);
                return NULL;
        }
-       strcat(path, "/");
-       strcat(path, attrib);
+       safestrcat(path, "/");
+       safestrcat(path, attrib);
        attribute = sysfs_open_attribute(path);
        if (attribute == NULL) {
                dprintf("Error opening attribute %s on class device %s\n",
index 06b8d2d..e3a8977 100644 (file)
 #include "sysfs.h"
 
 /**
+ * get_dev_driver: fills in the dev->driver_name field 
+ *
+ * Returns 0 on SUCCESS and 1 on error
+ */
+static int get_dev_driver(struct sysfs_device *dev)
+{
+       struct dlist *drvlist = NULL;
+       char path[SYSFS_PATH_MAX], devpath[SYSFS_PATH_MAX];
+       char *drv = NULL, *c = NULL;
+       
+       if (dev == NULL) {
+               errno = EINVAL;
+               return 1;
+       }
+       if (dev->bus[0] == '\0')
+               return 1;
+       memset(path, 0, SYSFS_PATH_MAX);
+       memset(devpath, 0, SYSFS_PATH_MAX);
+       safestrcpy(path, SYSFS_BUS_NAME);
+       safestrcat(path, "/");
+       safestrcat(path, dev->bus);
+       safestrcat(path, "/");
+       safestrcat(path, SYSFS_DRIVERS_NAME);
+
+       safestrcpy(devpath, dev->path);
+       c = strstr(devpath, SYSFS_DEVICES_NAME);
+       if (c == NULL)
+               return 1;
+       *c = '\0';
+       safestrncat(c, path, (sizeof(devpath) - strlen(devpath)));
+
+       drvlist = sysfs_open_subsystem_list(path);
+       if (drvlist != NULL) {
+               dlist_for_each_data(drvlist, drv, char) {
+                       safestrcpy(path, devpath);
+                       safestrcat(path, "/");
+                       safestrcat(path, drv);
+                       safestrcat(path, "/");
+                       safestrcat(path, dev->bus_id);
+                       if (sysfs_path_is_link(path) == 0) {
+                               safestrcpy(dev->driver_name, drv);
+                               sysfs_close_list(drvlist);
+                               return 0;
+                       }
+               }
+               sysfs_close_list(drvlist);
+       }
+       return 1;
+}
+       
+/**
  * sysfs_get_device_bus: retrieves the bus name the device is on, checks path 
  *     to bus' link to make sure it has correct device.
  * @dev: device to get busname.
@@ -31,8 +82,8 @@
  */
 int sysfs_get_device_bus(struct sysfs_device *dev)
 {
-       unsigned char subsys[SYSFS_NAME_LEN], path[SYSFS_PATH_MAX];
-       unsigned char target[SYSFS_PATH_MAX], *bus = NULL, *c = NULL;
+       char subsys[SYSFS_NAME_LEN], path[SYSFS_PATH_MAX];
+       char target[SYSFS_PATH_MAX], *bus = NULL, *c = NULL;
        struct dlist *buslist = NULL;
 
        if (dev == NULL) {
@@ -41,13 +92,12 @@ int sysfs_get_device_bus(struct sysfs_device *dev)
        }
 
        memset(subsys, 0, SYSFS_NAME_LEN);
-       strcat(subsys, "/");
-       strcpy(subsys, SYSFS_BUS_NAME);  /* subsys = /bus */
+       safestrcpy(subsys, SYSFS_BUS_NAME);  /* subsys = bus */
        buslist = sysfs_open_subsystem_list(subsys);
        if (buslist != NULL) {
                dlist_for_each_data(buslist, bus, char) {
                        memset(path, 0, SYSFS_PATH_MAX);
-                       strcpy(path, dev->path);
+                       safestrcpy(path, dev->path);
                        c = strstr(path, "/devices");
                        if (c == NULL) {
                                dprintf("Invalid path to device %s\n", path);
@@ -55,25 +105,25 @@ int sysfs_get_device_bus(struct sysfs_device *dev)
                                return -1;
                        }
                        *c = '\0';
-                       strcat(path, "/");
-                       strcat(path, SYSFS_BUS_NAME);
-                       strcat(path, "/");
-                       strcat(path, bus);
-                       strcat(path, "/");
-                       strcat(path, SYSFS_DEVICES_NAME);
-                       strcat(path, "/");
-                       strcat(path, dev->bus_id);
+                       safestrcat(path, "/");
+                       safestrcat(path, SYSFS_BUS_NAME);
+                       safestrcat(path, "/");
+                       safestrcat(path, bus);
+                       safestrcat(path, "/");
+                       safestrcat(path, SYSFS_DEVICES_NAME);
+                       safestrcat(path, "/");
+                       safestrcat(path, dev->bus_id);
                        if ((sysfs_path_is_link(path)) == 0) {
                                memset(target, 0, SYSFS_PATH_MAX);
                                if ((sysfs_get_link(path, target, 
-                                                       SYSFS_PATH_MAX)) != 0) {
+                                               SYSFS_PATH_MAX)) != 0) {
                                        dprintf("Error getting link target\n");
                                        sysfs_close_list(buslist);
                                        return -1;
                                }
                                if (!(strncmp(target, dev->path, 
                                                        SYSFS_PATH_MAX))) {
-                                       strcpy(dev->bus, bus);
+                                       safestrcpy(dev->bus, bus);
                                        sysfs_close_list(buslist);
                                        return 0;
                                }
@@ -89,7 +139,7 @@ int sysfs_get_device_bus(struct sysfs_device *dev)
  *     closing children only.
  * @devroot: device root of tree.
  */
-static void sysfs_close_device_tree(struct sysfs_device *devroot)
+void sysfs_close_device_tree(struct sysfs_device *devroot)
 {
        if (devroot != NULL) {
                if (devroot->children != NULL) {
@@ -143,7 +193,7 @@ static struct sysfs_device *alloc_device(void)
  * @name: name of root
  * returns struct sysfs_directory with success and NULL with error
  */
-static struct sysfs_directory *open_device_dir(const unsigned char *path)
+static struct sysfs_directory *open_device_dir(const char *path)
 {
        struct sysfs_directory *rdir = NULL;
 
@@ -172,7 +222,7 @@ static struct sysfs_directory *open_device_dir(const unsigned char *path)
  * @path: path to device, this is the /sys/devices/ path
  * returns sysfs_device structure with success or NULL with error
  */
-struct sysfs_device *sysfs_open_device_path(const unsigned char *path)
+struct sysfs_device *sysfs_open_device_path(const char *path)
 {
        struct sysfs_device *dev = NULL;
 
@@ -196,7 +246,7 @@ struct sysfs_device *sysfs_open_device_path(const unsigned char *path)
                sysfs_close_device(dev);
                return NULL;
        }
-       strcpy(dev->path, path);
+       safestrcpy(dev->path, path);
        if ((sysfs_remove_trailing_slash(dev->path)) != 0) {
                dprintf("Invalid path to device %s\n", dev->path);
                sysfs_close_device(dev);
@@ -207,10 +257,15 @@ struct sysfs_device *sysfs_open_device_path(const unsigned char *path)
         * sysfs representation instead, in the "dev->name" field, which
         * implies that the dev->name and dev->bus_id contain same data.
         */
-       strncpy(dev->name, dev->bus_id, SYSFS_NAME_LEN);
+       safestrcpy(dev->name, dev->bus_id);
        
        if (sysfs_get_device_bus(dev) != 0)
                dprintf("Could not get device bus\n");
+       
+       if (get_dev_driver(dev) != 0) {
+               dprintf("Could not get device %s's driver\n", dev->bus_id);
+               safestrcpy(dev->driver_name, SYSFS_UNKNOWN);
+       }
 
        return dev;
 }
@@ -222,7 +277,7 @@ struct sysfs_device *sysfs_open_device_path(const unsigned char *path)
  * returns struct sysfs_device and its children with success or NULL with
  *     error.
  */
-static struct sysfs_device *sysfs_open_device_tree(const unsigned char *path)
+struct sysfs_device *sysfs_open_device_tree(const char *path)
 {
        struct sysfs_device *rootdev = NULL, *new = NULL;
        struct sysfs_directory *cur = NULL;
@@ -255,7 +310,8 @@ static struct sysfs_device *sysfs_open_device_tree(const unsigned char *path)
                                rootdev->children = dlist_new_with_delete
                                        (sizeof(struct sysfs_device),
                                        sysfs_close_dev_tree);
-                       dlist_unshift(rootdev->children, new);
+                       dlist_unshift_sorted(rootdev->children, 
+                                                       new, sort_list);
                }
        }
 
@@ -311,7 +367,7 @@ struct dlist *sysfs_get_root_devices(struct sysfs_root_device *root)
                        root->devices = dlist_new_with_delete
                                (sizeof(struct sysfs_device), 
                                sysfs_close_dev_tree);
-               dlist_unshift(root->devices, dev);
+               dlist_unshift_sorted(root->devices, dev, sort_list);
        }
 
        return root->devices;
@@ -323,10 +379,10 @@ struct dlist *sysfs_get_root_devices(struct sysfs_root_device *root)
  * @name: name of /sys/devices/root to open
  * returns struct sysfs_root_device if success and NULL with error
  */
-struct sysfs_root_device *sysfs_open_root_device(const unsigned char *name)
+struct sysfs_root_device *sysfs_open_root_device(const char *name)
 {
        struct sysfs_root_device *root = NULL;
-       unsigned char rootpath[SYSFS_PATH_MAX];
+       char rootpath[SYSFS_PATH_MAX];
 
        if (name == NULL) {
                errno = EINVAL;
@@ -339,10 +395,10 @@ struct sysfs_root_device *sysfs_open_root_device(const unsigned char *name)
                return NULL;
        }
 
-       strcat(rootpath, "/");
-       strcat(rootpath, SYSFS_DEVICES_NAME);
-       strcat(rootpath, "/");
-       strcat(rootpath, name);
+       safestrcat(rootpath, "/");
+       safestrcat(rootpath, SYSFS_DEVICES_NAME);
+       safestrcat(rootpath, "/");
+       safestrcat(rootpath, name);
        if ((sysfs_path_is_dir(rootpath)) != 0) {
                errno = EINVAL;
                dprintf("Invalid root device: %s\n", name);
@@ -354,8 +410,8 @@ struct sysfs_root_device *sysfs_open_root_device(const unsigned char *name)
                dprintf("calloc failure\n");
                return NULL;
        }
-       strcpy(root->name, name);
-       strcpy(root->path, rootpath);
+       safestrcpy(root->name, name);
+       safestrcpy(root->path, rootpath);
        if ((sysfs_remove_trailing_slash(root->path)) != 0) {
                dprintf("Invalid path to root device %s\n", root->path);
                sysfs_close_root_device(root);
@@ -371,8 +427,10 @@ struct sysfs_root_device *sysfs_open_root_device(const unsigned char *name)
  */
 struct dlist *sysfs_get_device_attributes(struct sysfs_device *device)
 {
-       if (device == NULL) 
+       if (device == NULL) {
+               errno = EINVAL;
                return NULL;
+       }
 
        if (device->directory == NULL) {
                device->directory = sysfs_open_directory(device->path);
@@ -420,7 +478,7 @@ struct dlist *sysfs_refresh_device_attributes(struct sysfs_device *device)
  * returns sysfs_attribute reference with success or NULL with error.
  */
 struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev,
-                                               const unsigned char *name)
+                                               const char *name)
 {
        struct dlist *attrlist = NULL;
 
@@ -433,8 +491,7 @@ struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev,
        if (attrlist == NULL)
                return NULL;
 
-       return sysfs_get_directory_attribute(dev->directory, 
-                                       (unsigned char *)name);
+       return sysfs_get_directory_attribute(dev->directory, (char *)name);
 }
 
 /**
@@ -445,10 +502,10 @@ struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev,
  * @psize: size of "path"
  * Returns 0 on success -1 on failure
  */
-static int get_device_absolute_path(const unsigned char *device,
-               const unsigned char *bus, unsigned char *path, size_t psize)
+static int get_device_absolute_path(const char *device, const char *bus, 
+                               char *path, size_t psize)
 {
-       unsigned char bus_path[SYSFS_PATH_MAX];
+       char bus_path[SYSFS_PATH_MAX];
 
        if (device == NULL || path == NULL) {
                errno = EINVAL;
@@ -460,19 +517,19 @@ static int get_device_absolute_path(const unsigned char *device,
                dprintf ("Sysfs not supported on this system\n");
                return -1;
        }
-       strcat(bus_path, "/");
-       strcat(bus_path, SYSFS_BUS_NAME);
-       strcat(bus_path, "/");
-       strcat(bus_path, bus);
-       strcat(bus_path, "/");
-       strcat(bus_path, SYSFS_DEVICES_NAME);
-       strcat(bus_path, "/");
-       strcat(bus_path, device);
+       safestrcat(bus_path, "/");
+       safestrcat(bus_path, SYSFS_BUS_NAME);
+       safestrcat(bus_path, "/");
+       safestrcat(bus_path, bus);
+       safestrcat(bus_path, "/");
+       safestrcat(bus_path, SYSFS_DEVICES_NAME);
+       safestrcat(bus_path, "/");
+       safestrcat(bus_path, device);
        /*
         * We now are at /sys/bus/"bus_name"/devices/"device" which is a link.
         * Now read this link to reach to the device.
         */ 
-       if ((sysfs_get_link(bus_path, path, SYSFS_PATH_MAX)) != 0) {
+       if ((sysfs_get_link(bus_path, path, psize)) != 0) {
                dprintf("Error getting to device %s\n", device);
                return -1;
        }
@@ -481,17 +538,16 @@ static int get_device_absolute_path(const unsigned char *device,
 
 /**
  * sysfs_open_device: open a device by id (use the "bus" subsystem)
+ * @bus: bus the device belongs to
  * @bus_id: bus_id of the device to open - has to be the "bus_id" in 
  *             /sys/bus/xxx/devices
- * @bus: bus the device belongs to
  * returns struct sysfs_device if found, NULL otherwise
  * NOTE: 
  * 1. Use sysfs_close_device to close the device
  * 2. Bus the device is on must be supplied
  *     Use sysfs_find_device_bus to get the bus name
  */
-struct sysfs_device *sysfs_open_device(const unsigned char *bus_id, 
-                                               const unsigned char *bus)
+struct sysfs_device *sysfs_open_device(const char *bus, const char *bus_id)
 {
        char sysfs_path[SYSFS_PATH_MAX];
        struct sysfs_device *device = NULL;
@@ -524,7 +580,7 @@ struct sysfs_device *sysfs_open_device(const unsigned char *bus_id,
  */
 struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev)
 {
-       unsigned char ppath[SYSFS_PATH_MAX], *tmp = NULL;
+       char ppath[SYSFS_PATH_MAX], *tmp = NULL;
 
        if (dev == NULL) {
                errno = EINVAL;
@@ -535,13 +591,13 @@ struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev)
                return (dev->parent);
 
        memset(ppath, 0, SYSFS_PATH_MAX);
-       strcpy(ppath, dev->path);
+       safestrcpy(ppath, dev->path);
        tmp = strrchr(ppath, '/');
        if (tmp == NULL) {
                dprintf("Invalid path to device %s\n", ppath);
                return NULL;
        }
-       if (*(tmp +1) == '\0') {
+       if (*(tmp + 1) == '\0') {
                *tmp = '\0';
                tmp = strrchr(tmp, '/');
                if (tmp == NULL) {
@@ -554,7 +610,7 @@ struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev)
        /*
         * All "devices" have the "detach_state" attribute - validate here
         */
-       strcat(ppath, "/detach_state");
+       safestrcat(ppath, "/detach_state");
        if ((sysfs_path_is_file(ppath)) != 0) {
                dprintf("Device at %s does not have a parent\n", dev->path);
                return NULL;
@@ -581,11 +637,11 @@ struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev)
  *     A call to sysfs_close_attribute() is required to close
  *     the attribute returned and free memory. 
  */
-struct sysfs_attribute *sysfs_open_device_attr(const unsigned char *bus,
-               const unsigned char *bus_id, const unsigned char *attrib)
+struct sysfs_attribute *sysfs_open_device_attr(const char *bus,
+               const char *bus_id, const char *attrib)
 {
        struct sysfs_attribute *attribute = NULL;
-       unsigned char devpath[SYSFS_PATH_MAX];
+       char devpath[SYSFS_PATH_MAX];
        
        if (bus == NULL || bus_id == NULL || attrib == NULL) {
                errno = EINVAL;
@@ -598,8 +654,8 @@ struct sysfs_attribute *sysfs_open_device_attr(const unsigned char *bus,
                dprintf("Error getting to device %s\n", bus_id);
                return NULL;
        }
-       strcat(devpath, "/");
-       strcat(devpath, attrib);
+       safestrcat(devpath, "/");
+       safestrcat(devpath, attrib);
        attribute = sysfs_open_attribute(devpath);
        if (attribute == NULL) {
                dprintf("Error opening attribute %s for device %s\n",
index 050e674..be54a1c 100644 (file)
@@ -58,9 +58,9 @@ static int dir_attribute_name_equal(void *a, void *b)
        if (a == NULL || b == NULL)
                return 0;
 
-       if (strcmp(((unsigned char *)a), ((struct sysfs_attribute *)b)->name) 
-           == 0)
+       if (strcmp(((char *)a), ((struct sysfs_attribute *)b)->name) == 0)
                return 1;
+
        return 0;
 }
 
@@ -75,9 +75,9 @@ static int dir_link_name_equal(void *a, void *b)
        if (a == NULL || b == NULL)
                return 0;
 
-       if (strcmp(((unsigned char *)a), ((struct sysfs_link *)b)->name) 
-           == 0)
+       if (strcmp(((char *)a), ((struct sysfs_link *)b)->name) == 0)
                return 1;
+
        return 0;
 }
 
@@ -92,9 +92,9 @@ static int dir_subdir_name_equal(void *a, void *b)
        if (a == NULL || b == NULL)
                return 0;
 
-       if (strcmp(((unsigned char *)a), ((struct sysfs_directory *)b)->name)
-           == 0)
+       if (strcmp(((char *)a), ((struct sysfs_directory *)b)->name) == 0)
                return 1;
+
        return 0;
 }
 
@@ -126,7 +126,7 @@ static struct sysfs_attribute *alloc_attribute(void)
  * @path: path to attribute.
  * returns sysfs_attribute struct with success and NULL with error.
  */
-struct sysfs_attribute *sysfs_open_attribute(const unsigned char *path)
+struct sysfs_attribute *sysfs_open_attribute(const char *path)
 {
        struct sysfs_attribute *sysattr = NULL;
        struct stat fileinfo;
@@ -140,14 +140,13 @@ struct sysfs_attribute *sysfs_open_attribute(const unsigned char *path)
                dprintf("Error allocating attribute at %s\n", path);
                return NULL;
        }
-       if (sysfs_get_name_from_path(path, sysattr->name, SYSFS_NAME_LEN) 
-           != 0) {
-               dprintf("Error retrieving attribute name from path: %s\n", 
-                       path);
+       if (sysfs_get_name_from_path(path, sysattr->name, 
+                               SYSFS_NAME_LEN) != 0) {
+               dprintf("Error retrieving attrib name from path: %s\n", path);
                sysfs_close_attribute(sysattr);
                return NULL;
        }
-       strncpy(sysattr->path, path, SYSFS_PATH_MAX);
+       safestrcpy(sysattr->path, path);
        if ((stat(sysattr->path, &fileinfo)) != 0) {
                dprintf("Stat failed: No such attribute?\n");
                sysattr->method = 0;
@@ -171,7 +170,7 @@ struct sysfs_attribute *sysfs_open_attribute(const unsigned char *path)
  * returns 0 with success and -1 with error.
  */
 int sysfs_write_attribute(struct sysfs_attribute *sysattr,
-               const unsigned char *new_value, size_t len)
+               const char *new_value, size_t len)
 {
        int fd;
        int length;
@@ -184,6 +183,7 @@ int sysfs_write_attribute(struct sysfs_attribute *sysattr,
        if (!(sysattr->method & SYSFS_METHOD_STORE)) {
                dprintf ("Store method not supported for attribute %s\n",
                        sysattr->path);
+               errno = EACCES;
                return -1;
        }
        if (sysattr->method & SYSFS_METHOD_SHOW) {
@@ -215,7 +215,7 @@ int sysfs_write_attribute(struct sysfs_attribute *sysattr,
                        sysattr->name);
                close(fd);
                return -1;
-       } else if (length != len) {
+       } else if ((unsigned int)length != len) {
                dprintf("Could not write %d bytes to attribute %s\n", 
                                        len, sysattr->name);
                /* 
@@ -236,13 +236,13 @@ int sysfs_write_attribute(struct sysfs_attribute *sysattr,
         */ 
        if (sysattr->method & SYSFS_METHOD_SHOW) {
                if (length != sysattr->len) {
-                       sysattr->value = (char *)realloc(sysattr->value, 
-                                                               length);
+                       sysattr->value = (char *)realloc
+                               (sysattr->value, length);
                        sysattr->len = length;
-                       strncpy(sysattr->value, new_value, length);
+                       safestrncpy(sysattr->value, new_value, length);
                } else {
                        /*"length" of the new value is same as old one */ 
-                       strncpy(sysattr->value, new_value, length);
+                       safestrncpy(sysattr->value, new_value, length);
                }
        }
                        
@@ -250,7 +250,6 @@ int sysfs_write_attribute(struct sysfs_attribute *sysattr,
        return 0;
 }
 
-
 /**
  * sysfs_read_attribute: reads value from attribute
  * @sysattr: attribute to read
@@ -258,8 +257,8 @@ int sysfs_write_attribute(struct sysfs_attribute *sysattr,
  */
 int sysfs_read_attribute(struct sysfs_attribute *sysattr)
 {
-       unsigned char *fbuf = NULL;
-       unsigned char *vbuf = NULL;
+       char *fbuf = NULL;
+       char *vbuf = NULL;
        ssize_t length = 0;
        long pgsize = 0;
        int fd;
@@ -271,11 +270,11 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr)
        if (!(sysattr->method & SYSFS_METHOD_SHOW)) {
                dprintf("Show method not supported for attribute %s\n",
                        sysattr->path);
+               errno = EACCES;
                return -1;
        }
-
        pgsize = getpagesize();
-       fbuf = (unsigned char *)calloc(1, pgsize+1);
+       fbuf = (char *)calloc(1, pgsize+1);
        if (fbuf == NULL) {
                dprintf("calloc failed\n");
                return -1;
@@ -296,13 +295,14 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr)
                if ((sysattr->len == length) && 
                                (!(strncmp(sysattr->value, fbuf, length)))) {
                        close(fd);
+                       free(fbuf);
                        return 0;
                }
                free(sysattr->value);
        }
        sysattr->len = length;
        close(fd);
-       vbuf = (unsigned char *)realloc(fbuf, length+1);
+       vbuf = (char *)realloc(fbuf, length+1);
        if (vbuf == NULL) {
                dprintf("realloc failed\n");
                free(fbuf);
@@ -322,13 +322,13 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr)
  * @vsize: size of value buffer
  * returns 0 with success and -1 with error.
  */
-int sysfs_read_attribute_value(const unsigned char *attrpath, 
-                                       unsigned char *value, size_t vsize)
+int sysfs_read_attribute_value(const char *attrpath, 
+                                       char *value, size_t vsize)
 {
        struct sysfs_attribute *attr = NULL;
        size_t length = 0;
 
-       if (attrpath == NULL || value == NULL) {
+       if (attrpath == NULL || value == NULL || vsize == 0) {
                errno = EINVAL;
                return -1;
        }
@@ -348,7 +348,7 @@ int sysfs_read_attribute_value(const unsigned char *attrpath,
        if (length > vsize) 
                dprintf("Value length %d is larger than supplied buffer %d\n",
                        length, vsize);
-       strncpy(value, attr->value, vsize);
+       safestrncpy(value, attr->value, vsize);
        sysfs_close_attribute(attr);
 
        return 0;
@@ -359,10 +359,9 @@ int sysfs_read_attribute_value(const unsigned char *attrpath,
  *     attribute name, return its value
  * @attr: attribute to search
  * @name: name to look for
- * returns unsigned char * value - could be NULL
+ * returns char * value - could be NULL
  */
-unsigned char *sysfs_get_value_from_attributes(struct dlist *attr, 
-                                       const unsigned char *name)
+char *sysfs_get_value_from_attributes(struct dlist *attr, const char *name)
 {      
        struct sysfs_attribute *cur = NULL;
        
@@ -432,6 +431,7 @@ static struct sysfs_link *alloc_link(void)
 int sysfs_read_all_subdirs(struct sysfs_directory *sysdir)
 {
        struct sysfs_directory *cursub = NULL;
+       int retval = 0;
 
        if (sysdir == NULL) {
                errno = EINVAL;
@@ -443,12 +443,16 @@ int sysfs_read_all_subdirs(struct sysfs_directory *sysdir)
        if (sysdir->subdirs != NULL) {
                dlist_for_each_data(sysdir->subdirs, cursub, 
                                                struct sysfs_directory) {
-                       if ((sysfs_read_dir_subdirs(cursub)) != 0) 
+                       if ((sysfs_read_dir_subdirs(cursub)) != 0) {
                                dprintf ("Error reading subdirectory %s\n",
                                                cursub->name);
+                               retval = -1;
+                       }
                }
        }
-       return 0;
+       if (!retval)
+               errno = 0;
+       return retval;
 }
 
 /**
@@ -457,7 +461,7 @@ int sysfs_read_all_subdirs(struct sysfs_directory *sysdir)
  * @path: path of directory to open.
  * returns: struct sysfs_directory * with success and NULL on error.
  */
-struct sysfs_directory *sysfs_open_directory(const unsigned char *path)
+struct sysfs_directory *sysfs_open_directory(const char *path)
 {
        struct sysfs_directory *sdir = NULL;
 
@@ -467,7 +471,7 @@ struct sysfs_directory *sysfs_open_directory(const unsigned char *path)
        }
 
        if (sysfs_path_is_dir(path) != 0) {
-               dprintf("Invalid path directory %s\n", path);
+               dprintf("Invalid path to directory %s\n", path);
                errno = EINVAL;
                return NULL;
        }
@@ -482,7 +486,7 @@ struct sysfs_directory *sysfs_open_directory(const unsigned char *path)
                sysfs_close_directory(sdir);
                return NULL;
        }
-       strncpy(sdir->path, path, SYSFS_PATH_MAX);
+       safestrcpy(sdir->path, path);
 
        return sdir;
 }
@@ -492,7 +496,7 @@ struct sysfs_directory *sysfs_open_directory(const unsigned char *path)
  * @path: path of link to open.
  * returns: struct sysfs_link * with success and NULL on error.
  */
-struct sysfs_link *sysfs_open_link(const unsigned char *linkpath)
+struct sysfs_link *sysfs_open_link(const char *linkpath)
 {
        struct sysfs_link *ln = NULL;
 
@@ -506,7 +510,7 @@ struct sysfs_link *sysfs_open_link(const unsigned char *linkpath)
                dprintf("Error allocating link %s\n", linkpath);
                return NULL;
        }
-       strcpy(ln->path, linkpath);
+       safestrcpy(ln->path, linkpath);
        if ((sysfs_get_name_from_path(linkpath, ln->name, SYSFS_NAME_LEN)) != 0
            || (sysfs_get_link(linkpath, ln->target, SYSFS_PATH_MAX)) != 0) {
                errno = EINVAL;
@@ -523,8 +527,7 @@ struct sysfs_link *sysfs_open_link(const unsigned char *linkpath)
  * @path: path to attribute
  * returns 0 with success and -1 with error.
  */
-static int add_attribute(struct sysfs_directory *sysdir, 
-                                       const unsigned char *path)
+static int add_attribute(struct sysfs_directory *sysdir, const char *path)
 {
        struct sysfs_attribute *attr = NULL;
 
@@ -545,7 +548,7 @@ static int add_attribute(struct sysfs_directory *sysdir,
                sysdir->attributes = dlist_new_with_delete
                        (sizeof(struct sysfs_attribute), sysfs_del_attribute);
        }
-       dlist_unshift(sysdir->attributes, attr);
+       dlist_unshift_sorted(sysdir->attributes, attr, sort_list);
 
        return 0;
 }
@@ -556,8 +559,7 @@ static int add_attribute(struct sysfs_directory *sysdir,
  * @path: path to subdirectory
  * returns 0 with success and -1 with error.
  */
-static int add_subdirectory(struct sysfs_directory *sysdir, 
-                                       const unsigned char *path)
+static int add_subdirectory(struct sysfs_directory *sysdir, const char *path)
 {
        struct sysfs_directory *subdir = NULL;
 
@@ -569,7 +571,7 @@ static int add_subdirectory(struct sysfs_directory *sysdir,
        if (sysdir->subdirs == NULL)
                sysdir->subdirs = dlist_new_with_delete
                        (sizeof(struct sysfs_directory), sysfs_del_directory);
-       dlist_unshift(sysdir->subdirs, subdir);
+       dlist_unshift_sorted(sysdir->subdirs, subdir, sort_list);
        return 0;
 }
 
@@ -579,7 +581,7 @@ static int add_subdirectory(struct sysfs_directory *sysdir,
  * @path: path to link
  * returns 0 with success and -1 with error.
  */
-static int add_link(struct sysfs_directory *sysdir, const unsigned char *path)
+static int add_link(struct sysfs_directory *sysdir, const char *path)
 {
        struct sysfs_link *ln = NULL;
 
@@ -591,7 +593,7 @@ static int add_link(struct sysfs_directory *sysdir, const unsigned char *path)
        if (sysdir->links == NULL)
                sysdir->links = dlist_new_with_delete
                                (sizeof(struct sysfs_link), sysfs_del_link);
-       dlist_unshift(sysdir->links, ln);
+       dlist_unshift_sorted(sysdir->links, ln, sort_list);
        return 0;
 }
 
@@ -604,7 +606,7 @@ int sysfs_read_dir_attributes(struct sysfs_directory *sysdir)
 {
        DIR *dir = NULL;
        struct dirent *dirent = NULL;
-       unsigned char file_path[SYSFS_PATH_MAX];
+       char file_path[SYSFS_PATH_MAX];
        int retval = 0;
 
        if (sysdir == NULL) {
@@ -622,13 +624,15 @@ int sysfs_read_dir_attributes(struct sysfs_directory *sysdir)
                if (0 == strcmp(dirent->d_name, ".."))
                        continue;
                memset(file_path, 0, SYSFS_PATH_MAX);
-               strncpy(file_path, sysdir->path, SYSFS_PATH_MAX);
-               strcat(file_path, "/");
-               strcat(file_path, dirent->d_name);
+               safestrcpy(file_path, sysdir->path);
+               safestrcat(file_path, "/");
+               safestrcat(file_path, dirent->d_name);
                if ((sysfs_path_is_file(file_path)) == 0)
                        retval = add_attribute(sysdir, file_path);
        }
        closedir(dir);
+       if (!retval)
+               errno = 0;
        return(retval);
 }
 
@@ -641,7 +645,7 @@ int sysfs_read_dir_links(struct sysfs_directory *sysdir)
 {
        DIR *dir = NULL;
        struct dirent *dirent = NULL;
-       unsigned char file_path[SYSFS_PATH_MAX];
+       char file_path[SYSFS_PATH_MAX];
        int retval = 0;
 
        if (sysdir == NULL) {
@@ -659,9 +663,9 @@ int sysfs_read_dir_links(struct sysfs_directory *sysdir)
                if (0 == strcmp(dirent->d_name, ".."))
                        continue;
                memset(file_path, 0, SYSFS_PATH_MAX);
-               strncpy(file_path, sysdir->path, SYSFS_PATH_MAX);
-               strcat(file_path, "/");
-               strcat(file_path, dirent->d_name);
+               safestrcpy(file_path, sysdir->path);
+               safestrcat(file_path, "/");
+               safestrcat(file_path, dirent->d_name);
                if ((sysfs_path_is_link(file_path)) == 0) {
                        retval = add_link(sysdir, file_path);
                        if (retval != 0)
@@ -669,6 +673,8 @@ int sysfs_read_dir_links(struct sysfs_directory *sysdir)
                }
        }
        closedir(dir);
+       if (!retval)
+               errno = 0;
        return(retval);
 }
 
@@ -681,7 +687,7 @@ int sysfs_read_dir_subdirs(struct sysfs_directory *sysdir)
 {
        DIR *dir = NULL;
        struct dirent *dirent = NULL;
-       unsigned char file_path[SYSFS_PATH_MAX];
+       char file_path[SYSFS_PATH_MAX];
        int retval = 0;
 
        if (sysdir == NULL) {
@@ -699,13 +705,15 @@ int sysfs_read_dir_subdirs(struct sysfs_directory *sysdir)
                if (0 == strcmp(dirent->d_name, ".."))
                        continue;
                memset(file_path, 0, SYSFS_PATH_MAX);
-               strncpy(file_path, sysdir->path, SYSFS_PATH_MAX);
-               strcat(file_path, "/");
-               strcat(file_path, dirent->d_name);
+               safestrcpy(file_path, sysdir->path);
+               safestrcat(file_path, "/");
+               safestrcat(file_path, dirent->d_name);
                if ((sysfs_path_is_dir(file_path)) == 0)
                        retval = add_subdirectory(sysdir, file_path);
        }
        closedir(dir);
+       if (!retval)
+               errno = 0;
        return(retval);
 }
 
@@ -719,7 +727,7 @@ int sysfs_read_directory(struct sysfs_directory *sysdir)
        DIR *dir = NULL;
        struct dirent *dirent = NULL;
        struct stat astats;
-       unsigned char file_path[SYSFS_PATH_MAX];
+       char file_path[SYSFS_PATH_MAX];
        int retval = 0;
 
        if (sysdir == NULL) {
@@ -737,9 +745,9 @@ int sysfs_read_directory(struct sysfs_directory *sysdir)
                if (0 == strcmp(dirent->d_name, ".."))
                        continue;
                memset(file_path, 0, SYSFS_PATH_MAX);
-               strncpy(file_path, sysdir->path, SYSFS_PATH_MAX);
-               strcat(file_path, "/");
-               strcat(file_path, dirent->d_name);
+               safestrcpy(file_path, sysdir->path);
+               safestrcat(file_path, "/");
+               safestrcat(file_path, dirent->d_name);
                if ((lstat(file_path, &astats)) != 0) {
                        dprintf("stat failed\n");
                        continue;
@@ -754,6 +762,8 @@ int sysfs_read_directory(struct sysfs_directory *sysdir)
                        retval = add_attribute(sysdir, file_path);
        }
        closedir(dir);
+       if (!retval)
+               errno = 0;
        return(retval);
 }
 
@@ -782,6 +792,7 @@ int sysfs_refresh_dir_attributes(struct sysfs_directory *sysdir)
                                                        sysdir->path);
                return 1;
        }
+       errno = 0;
        return 0;
 }
 
@@ -810,6 +821,7 @@ int sysfs_refresh_dir_links(struct sysfs_directory *sysdir)
                                                        sysdir->path);
                return 1;
        }
+       errno = 0;
        return 0;
 }
 
@@ -838,6 +850,7 @@ int sysfs_refresh_dir_subdirs(struct sysfs_directory *sysdir)
                                                        sysdir->path);
                return 1;
        }
+       errno = 0;
        return 0;
 }
 
@@ -846,13 +859,17 @@ int sysfs_refresh_dir_subdirs(struct sysfs_directory *sysdir)
  *     directory only
  * @dir: directory to retrieve attribute from
  * @attrname: name of attribute to look for
+ *
+ * NOTE: Since we know the attribute to look for, this routine looks for the
+ *     attribute if it was created _after_ the attrlist was read initially.
+ *     
  * returns sysfs_attribute if found and NULL if not found
  */
 struct sysfs_attribute *sysfs_get_directory_attribute
-                       (struct sysfs_directory *dir, unsigned char *attrname)
+                       (struct sysfs_directory *dir, char *attrname)
 {
        struct sysfs_attribute *attr = NULL;
-       unsigned char new_path[SYSFS_PATH_MAX];
+       char new_path[SYSFS_PATH_MAX];
        
        if (dir == NULL || attrname == NULL) {
                errno = EINVAL;
@@ -873,9 +890,9 @@ struct sysfs_attribute *sysfs_get_directory_attribute
                }
        } else {
                memset(new_path, 0, SYSFS_PATH_MAX);
-               strcpy(new_path, dir->path);
-               strcat(new_path, "/");
-               strcat(new_path, attrname);
+               safestrcpy(new_path, dir->path);
+               safestrcat(new_path, "/");
+               safestrcat(new_path, attrname);
                if ((sysfs_path_is_file(new_path)) == 0) {
                        if ((add_attribute(dir, new_path)) == 0) {
                                attr = (struct sysfs_attribute *)
@@ -895,7 +912,7 @@ struct sysfs_attribute *sysfs_get_directory_attribute
  * returns reference to sysfs_link if found and NULL if not found
  */
 struct sysfs_link *sysfs_get_directory_link
-                       (struct sysfs_directory *dir, unsigned char *linkname)
+                       (struct sysfs_directory *dir, char *linkname)
 {
        if (dir == NULL || linkname == NULL) {
                errno = EINVAL;
@@ -920,7 +937,7 @@ struct sysfs_link *sysfs_get_directory_link
  * returns reference to subdirectory or NULL if not found
  */
 struct sysfs_directory *sysfs_get_subdirectory(struct sysfs_directory *dir,
-                                               unsigned char *subname)
+                                               char *subname)
 {
        struct sysfs_directory *sub = NULL, *cursub = NULL;
 
@@ -962,7 +979,7 @@ struct sysfs_directory *sysfs_get_subdirectory(struct sysfs_directory *dir,
  * returns reference to link or NULL if not found
  */
 struct sysfs_link *sysfs_get_subdirectory_link(struct sysfs_directory *dir,
-                                               unsigned char *linkname)
+                                               char *linkname)
 {
        struct sysfs_directory *cursub = NULL;
        struct sysfs_link *ln = NULL;
index cd202d9..9ffa9c9 100644 (file)
@@ -79,7 +79,7 @@ static struct sysfs_driver *alloc_driver(void)
  * @path: path to driver directory
  * returns struct sysfs_driver with success and NULL with error
  */
-struct sysfs_driver *sysfs_open_driver_path(const unsigned char *path)
+struct sysfs_driver *sysfs_open_driver_path(const char *path)
 {
        struct sysfs_driver *driver = NULL;
 
@@ -102,7 +102,7 @@ struct sysfs_driver *sysfs_open_driver_path(const unsigned char *path)
                free(driver);
                return NULL;
        }
-       strcpy(driver->path, path);
+       safestrcpy(driver->path, path);
        if ((sysfs_remove_trailing_slash(driver->path)) != 0) {
                dprintf("Invalid path to driver %s\n", driver->path);
                sysfs_close_driver(driver);
@@ -168,7 +168,7 @@ struct dlist *sysfs_refresh_driver_attributes(struct sysfs_driver *driver)
  * returns sysfs_attribute reference on success or NULL with error
  */ 
 struct sysfs_attribute *sysfs_get_driver_attr(struct sysfs_driver *drv,
-                                       const unsigned char *name)
+                                       const char *name)
 {
        struct dlist *attrlist = NULL;
 
@@ -178,11 +178,10 @@ struct sysfs_attribute *sysfs_get_driver_attr(struct sysfs_driver *drv,
         }
        
        attrlist = sysfs_get_driver_attributes(drv);
-       if (attrlist != NULL) 
+       if (attrlist == NULL) 
                return NULL;
 
-       return sysfs_get_directory_attribute(drv->directory,
-                                               (unsigned char *)name);
+       return sysfs_get_directory_attribute(drv->directory, (char *)name);
 }
 
 /**
@@ -197,12 +196,15 @@ struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver)
                errno = EINVAL;
                return NULL;
        }
-       if (driver->directory == NULL) {
+
+       if (driver->directory == NULL) 
                if ((open_driver_dir(driver)) == 1)
                        return NULL;
+       
+       if (driver->directory->links == NULL)
                if ((sysfs_read_dir_links(driver->directory)) != 0) 
                        return NULL;
-       }
+               
        return(driver->directory->links);
 }
 
@@ -224,12 +226,11 @@ struct dlist *sysfs_get_driver_devices(struct sysfs_driver *driver)
        if (driver->devices != NULL)
                return (driver->devices);
 
-       if (driver->directory == NULL) {
-               if ((open_driver_dir(driver)) == 1) 
-                       return NULL;
-               if ((sysfs_read_dir_links(driver->directory)) != 0) 
-                       return NULL;
+       if (driver->directory == NULL || driver->directory->links == NULL) {
+               struct dlist *list = NULL;
+               list = sysfs_get_driver_links(driver);
        }
+       
        if (driver->directory->links != NULL) {
                dlist_for_each_data(driver->directory->links, curlink, 
                                                struct sysfs_link) {
@@ -239,12 +240,12 @@ struct dlist *sysfs_get_driver_devices(struct sysfs_driver *driver)
                                                curlink->target);
                                return NULL;
                        }
-                       strcpy(device->driver_name, driver->name);
                        if (driver->devices == NULL) 
                                driver->devices = dlist_new_with_delete
                                                (sizeof(struct sysfs_device),
                                                 sysfs_close_driver_device);
-                       dlist_unshift(driver->devices, device);
+                       dlist_unshift_sorted(driver->devices, device, 
+                                                               sort_list);
                }
        }
        return (driver->devices);
@@ -290,7 +291,7 @@ struct dlist *sysfs_refresh_driver_devices(struct sysfs_driver *driver)
  * Returns a sysfs_device if found, NULL otherwise
  */
 struct sysfs_device *sysfs_get_driver_device(struct sysfs_driver *driver,
-                               const unsigned char *name)
+                               const char *name)
 {
        struct sysfs_device *device = NULL;
        struct dlist *devlist = NULL;
@@ -323,10 +324,10 @@ struct sysfs_device *sysfs_get_driver_device(struct sysfs_driver *driver,
  * @psize: size of "path"
  * Returns 0 on success and -1 on error
  */
-static int get_driver_path(const unsigned char *bus
-               const unsigned char *drv, unsigned char *path, size_t psize)
+static int get_driver_path(const char *bus, const char *drv
+                       char *path, size_t psize)
 {
-       if (bus == NULL || drv == NULL || path == NULL) {
+       if (bus == NULL || drv == NULL || path == NULL || psize == 0) {
                errno = EINVAL;
                return -1;
        }
@@ -334,14 +335,14 @@ static int get_driver_path(const unsigned char *bus,
                dprintf("Error getting sysfs mount path\n");
                return -1;
        }
-       strcat(path, "/");
-       strcat(path, SYSFS_BUS_NAME);
-       strcat(path, "/");
-       strcat(path, bus);
-       strcat(path, "/");
-       strcat(path, SYSFS_DRIVERS_NAME);
-       strcat(path, "/");
-       strcat(path, drv);
+       safestrncat(path, "/", psize);
+       safestrncat(path, SYSFS_BUS_NAME, psize);
+       safestrncat(path, "/", psize);
+       safestrncat(path, bus, psize);
+       safestrncat(path, "/", psize);
+       safestrncat(path, SYSFS_DRIVERS_NAME, psize);
+       safestrncat(path, "/", psize);
+       safestrncat(path, drv, psize);
        return 0;
 }
 
@@ -356,11 +357,11 @@ static int get_driver_path(const unsigned char *bus,
  *     A call to sysfs_close_attribute() is required to close the
  *     attribute returned and to free memory
  */ 
-struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus, 
-               const unsigned char *drv, const unsigned char *attrib)
+struct sysfs_attribute *sysfs_open_driver_attr(const char *bus, 
+               const char *drv, const char *attrib)
 {
        struct sysfs_attribute *attribute = NULL;
-       unsigned char path[SYSFS_PATH_MAX];
+       char path[SYSFS_PATH_MAX];
 
        if (bus == NULL || drv == NULL || attrib == NULL) {
                errno = EINVAL;
@@ -372,8 +373,8 @@ struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus,
                dprintf("Error getting to driver %s\n", drv);
                return NULL;
        }
-       strcat(path, "/");
-       strcat(path, attrib);
+       safestrcat(path, "/");
+       safestrcat(path, attrib);
        attribute = sysfs_open_attribute(path);
         if (attribute == NULL) {
                dprintf("Error opening attribute %s for driver %s\n",
@@ -391,14 +392,14 @@ struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus,
 
 /**
  * sysfs_open_driver: open driver by name, given its bus
- * @drv_name: Name of the driver
  * @bus_name: Name of the bus
+ * @drv_name: Name of the driver
  * Returns the sysfs_driver reference on success and NULL on failure
  */
-struct sysfs_driver *sysfs_open_driver(const unsigned char *drv_name,
-                               const unsigned char *bus_name)
+struct sysfs_driver *sysfs_open_driver(const char *bus_name, 
+                       const char *drv_name)
 {
-       unsigned char path[SYSFS_PATH_MAX];
+       char path[SYSFS_PATH_MAX];
        struct sysfs_driver *driver = NULL;
 
        if (drv_name == NULL || bus_name == NULL) {
index 2509c73..699a982 100644 (file)
 #include <mntent.h>
 #endif
 
+static int sort_char(void *new_elem, void *old_elem)
+{
+       return ((strncmp((char *)new_elem, (char *)old_elem, 
+                       strlen((char *)new_elem))) < 0 ? 1 : 0);
+}
+
 /**
  * sysfs_remove_trailing_slash: Removes any trailing '/' in the given path
  * @path: Path to look for the trailing '/'
  * Returns 0 on success 1 on error
  */ 
-int sysfs_remove_trailing_slash(unsigned char *path)
+int sysfs_remove_trailing_slash(char *path)
 {
-       unsigned char *c = NULL;
+       char *c = NULL;
 
        if (path == NULL) {
                errno = EINVAL;
@@ -51,17 +57,17 @@ int sysfs_remove_trailing_slash(unsigned char *path)
 }
 
 /**
- * sysfs_get_mnt_path: Gets the mount point for specified filesystem.
+ * sysfs_get_fs_mnt_path: Gets the mount point for specified filesystem.
  * @fs_type: filesystem type to retrieve mount point
  * @mnt_path: place to put the retrieved mount path
  * @len: size of mnt_path
  * returns 0 with success and -1 with error.
  */
-static int sysfs_get_fs_mnt_path(const unsigned char *fs_type, 
-                               unsigned char *mnt_path, size_t len)
+static int sysfs_get_fs_mnt_path(const char *fs_type, 
+                               char *mnt_path, size_t len)
 {
 #ifdef __KLIBC__
-       strcpy(mnt_path, "/sys");
+       safestrncpy(mnt_path, "/sys", len);
        return 0;
 #else
        FILE *mnt;
@@ -70,7 +76,7 @@ static int sysfs_get_fs_mnt_path(const unsigned char *fs_type,
        size_t dirlen = 0;
 
        /* check arg */
-       if (fs_type == NULL || mnt_path == NULL) {
+       if (fs_type == NULL || mnt_path == NULL || len == 0) {
                errno = EINVAL;
                return -1;
        }
@@ -83,7 +89,7 @@ static int sysfs_get_fs_mnt_path(const unsigned char *fs_type,
                if (strcmp(mntent->mnt_type, fs_type) == 0) {
                        dirlen = strlen(mntent->mnt_dir);
                        if (dirlen <= (len - 1)) {
-                               strcpy(mnt_path, mntent->mnt_dir);
+                               safestrncpy(mnt_path, mntent->mnt_dir, len);
                        } else {
                                dprintf("Error - mount path too long\n");
                                ret = -1;
@@ -109,18 +115,18 @@ static int sysfs_get_fs_mnt_path(const unsigned char *fs_type,
  * @len: size of mnt_path
  * returns 0 with success and -1 with error.
  */
-int sysfs_get_mnt_path(unsigned char *mnt_path, size_t len)
+int sysfs_get_mnt_path(char *mnt_path, size_t len)
 {
        char *sysfs_path = NULL;
        int ret = 0;
 
-       if (mnt_path == NULL) {
+       if (mnt_path == NULL || len == 0) {
                errno = EINVAL;
                return -1;
        }
        sysfs_path = getenv(SYSFS_PATH_ENV);
        if (sysfs_path != NULL) {
-               strncpy(mnt_path, sysfs_path, len);
+               safestrncpy(mnt_path, sysfs_path, len);
                if ((sysfs_remove_trailing_slash(mnt_path)) != 0)
                        return 1;
        } else
@@ -135,18 +141,17 @@ int sysfs_get_mnt_path(unsigned char *mnt_path, size_t len)
  * @name: where to put name
  * @len: size of name
  */
-int sysfs_get_name_from_path(const unsigned char *path, unsigned char *name, 
-                                                               size_t len)
+int sysfs_get_name_from_path(const char *path, char *name, size_t len)
 {
-       unsigned char tmp[SYSFS_PATH_MAX];
-       unsigned char *n = NULL;
+       char tmp[SYSFS_PATH_MAX];
+       char *n = NULL;
                                                                                 
-       if (path == NULL || name == NULL) {
+       if (path == NULL || name == NULL || len == 0) {
                errno = EINVAL;
                return -1;
        }
        memset(tmp, 0, SYSFS_PATH_MAX);
-       strcpy(tmp, path);
+       safestrcpy(tmp, path);
        n = strrchr(tmp, '/');
        if (n == NULL) {
                errno = EINVAL;
@@ -161,7 +166,7 @@ int sysfs_get_name_from_path(const unsigned char *path, unsigned char *name,
                }
        }
        n++;
-       strncpy(name, n, len);
+       safestrncpy(name, n, len);
        return 0;
 }
        
@@ -171,21 +176,23 @@ int sysfs_get_name_from_path(const unsigned char *path, unsigned char *name,
  * @target: where to put name
  * @len: size of name
  */
-int sysfs_get_link(const unsigned char *path, unsigned char *target, size_t len)
+int sysfs_get_link(const char *path, char *target, size_t len)
 {
-       unsigned char devdir[SYSFS_PATH_MAX];
-       unsigned char linkpath[SYSFS_PATH_MAX];
-       unsigned char *d = NULL, *s = NULL;
+       char devdir[SYSFS_PATH_MAX];
+       char linkpath[SYSFS_PATH_MAX];
+       char temp_path[SYSFS_PATH_MAX];
+       char *d = NULL, *s = NULL;
        int slashes = 0, count = 0;
 
-       if (path == NULL || target == NULL) {
+       if (path == NULL || target == NULL || len == 0) {
                errno = EINVAL;
                return -1;
        }
 
        memset(devdir, 0, SYSFS_PATH_MAX);
        memset(linkpath, 0, SYSFS_PATH_MAX);
-       strncpy(devdir, path, SYSFS_PATH_MAX);
+       memset(temp_path, 0, SYSFS_PATH_MAX);
+       safestrcpy(devdir, path);
 
        if ((readlink(path, linkpath, SYSFS_PATH_MAX)) < 0) {
                return -1;
@@ -202,18 +209,19 @@ int sysfs_get_link(const unsigned char *path, unsigned char *target, size_t len)
                        /* 
                         * handle the case where link is of type ./abcd/xxx
                         */
-                       strncpy(target, devdir, len);
+                       safestrcpy(temp_path, devdir);
                        if (*(d+1) == '/')
                                d += 2;
                        else if (*(d+1) == '.')
                                goto parse_path;
-                       s = strrchr(target, '/');
+                       s = strrchr(temp_path, '/');
                        if (s != NULL) {
                                *(s+1) = '\0';
-                               strcat(target, d);
+                               safestrcat(temp_path, d);
                        } else {
-                               strcpy(target, d);
+                               safestrcpy(temp_path, d);
                        }
+                       safestrncpy(target, temp_path, len);
                        break;
                        /* 
                         * relative path  
@@ -232,23 +240,24 @@ parse_path:
                                if (*s == '/')
                                        count++;
                        }
-                       strncpy(s, d, (SYSFS_PATH_MAX-strlen(devdir)));
-                       strncpy(target, devdir, len);
+                       safestrncpy(s, d, (SYSFS_PATH_MAX-strlen(devdir)));
+                       safestrncpy(target, devdir, len);
                        break;
                case '/':
                        /* absolute path - copy as is */
-                       strncpy(target, linkpath, len);
+                       safestrncpy(target, linkpath, len);
                        break;
                default:
                        /* relative path from this directory */
-                       strncpy(target, devdir, len);
-                       s = strrchr(target, '/');
+                       safestrcpy(temp_path, devdir);
+                       s = strrchr(temp_path, '/');
                        if (s != NULL) {
                                *(s+1) = '\0';
-                               strcat(target, linkpath);
+                               safestrcat(temp_path, linkpath);
                        } else {
-                               strcpy(target, linkpath);
-                       }                       
+                               safestrcpy(temp_path, linkpath);
+                       }
+                       safestrncpy(target, temp_path, len);
        }
        return 0;
 }
@@ -280,10 +289,10 @@ void sysfs_close_list(struct dlist *list)
  * @name: name of the subsystem, eg., "bus", "class", "devices"
  * Returns a dlist of supported names or NULL if subsystem not supported
  */ 
-struct dlist *sysfs_open_subsystem_list(unsigned char *name)
+struct dlist *sysfs_open_subsystem_list(char *name)
 {
-       unsigned char sysfs_path[SYSFS_PATH_MAX], *subsys_name = NULL;
-       unsigned char *c = NULL;
+       char sysfs_path[SYSFS_PATH_MAX], *subsys_name = NULL;
+       char *c = NULL;
        struct sysfs_directory *dir = NULL, *cur = NULL;
        struct dlist *list = NULL;
        
@@ -295,8 +304,8 @@ struct dlist *sysfs_open_subsystem_list(unsigned char *name)
                return NULL;
        }
 
-       strcat(sysfs_path, "/");
-       strcat(sysfs_path, name);
+       safestrcat(sysfs_path, "/");
+       safestrcat(sysfs_path, name);
        dir = sysfs_open_directory(sysfs_path);
        if (dir == NULL) {
                dprintf("Error opening sysfs_directory at %s\n", sysfs_path);
@@ -321,8 +330,8 @@ struct dlist *sysfs_open_subsystem_list(unsigned char *name)
                dlist_for_each_data(dir->subdirs, cur,
                                struct sysfs_directory) {
                        subsys_name = (char *)calloc(1, SYSFS_NAME_LEN);
-                       strcpy(subsys_name, cur->name);
-                       dlist_unshift(list, subsys_name);
+                       safestrncpy(subsys_name, cur->name, SYSFS_NAME_LEN);
+                       dlist_unshift_sorted(list, subsys_name, sort_char);
                }
        }
        sysfs_close_directory(dir);
@@ -335,11 +344,14 @@ struct dlist *sysfs_open_subsystem_list(unsigned char *name)
                c = strstr(sysfs_path, SYSFS_CLASS_NAME);
                if (c == NULL)
                        goto out;
-               strcpy(c, SYSFS_BLOCK_NAME);
+               *c = '\0';
+               safestrncpy(c, SYSFS_BLOCK_NAME, 
+                               sizeof(sysfs_path) - strlen(sysfs_path));
                if ((sysfs_path_is_dir(sysfs_path)) == 0) {
                        subsys_name = (char *)calloc(1, SYSFS_NAME_LEN);
-                       strcpy(subsys_name, SYSFS_BLOCK_NAME);
-                       dlist_unshift(list, subsys_name);
+                       safestrncpy(subsys_name, SYSFS_BLOCK_NAME, 
+                                       SYSFS_NAME_LEN);
+                       dlist_unshift_sorted(list, subsys_name, sort_char);
                }
        }
 out:
@@ -352,9 +364,9 @@ out:
  * @name: name of the subsystem, eg., "pci", "scsi", "usb"
  * Returns a dlist of supported names or NULL if subsystem not supported
  */ 
-struct dlist *sysfs_open_bus_devices_list(unsigned char *name)
+struct dlist *sysfs_open_bus_devices_list(char *name)
 {
-       unsigned char sysfs_path[SYSFS_PATH_MAX], *device_name = NULL;
+       char sysfs_path[SYSFS_PATH_MAX], *device_name = NULL;
        struct sysfs_directory *dir = NULL;
        struct sysfs_link *cur = NULL;
        struct dlist *list = NULL;
@@ -367,12 +379,12 @@ struct dlist *sysfs_open_bus_devices_list(unsigned char *name)
                return NULL;
        }
 
-       strcat(sysfs_path, "/");
-       strcat(sysfs_path, SYSFS_BUS_NAME);
-       strcat(sysfs_path, "/");
-       strcat(sysfs_path, name);
-       strcat(sysfs_path, "/");
-       strcat(sysfs_path, SYSFS_DEVICES_NAME);
+       safestrcat(sysfs_path, "/");
+       safestrcat(sysfs_path, SYSFS_BUS_NAME);
+       safestrcat(sysfs_path, "/");
+       safestrcat(sysfs_path, name);
+       safestrcat(sysfs_path, "/");
+       safestrcat(sysfs_path, SYSFS_DEVICES_NAME);
        dir = sysfs_open_directory(sysfs_path);
        if (dir == NULL) {
                dprintf("Error opening sysfs_directory at %s\n", sysfs_path);
@@ -397,8 +409,8 @@ struct dlist *sysfs_open_bus_devices_list(unsigned char *name)
                dlist_for_each_data(dir->links, cur,
                                struct sysfs_link) {
                        device_name = (char *)calloc(1, SYSFS_NAME_LEN);
-                       strcpy(device_name, cur->name);
-                       dlist_unshift(list, device_name);
+                       safestrncpy(device_name, cur->name, SYSFS_NAME_LEN);
+                       dlist_unshift_sorted(list, device_name, sort_char);
                }
        }
        sysfs_close_directory(dir);
@@ -410,7 +422,7 @@ struct dlist *sysfs_open_bus_devices_list(unsigned char *name)
  * @path: path to validate
  * Returns 0 if path points to dir, 1 otherwise
  */
-int sysfs_path_is_dir(const unsigned char *path)
+int sysfs_path_is_dir(const char *path)
 {
        struct stat astats;
 
@@ -433,7 +445,7 @@ int sysfs_path_is_dir(const unsigned char *path)
  * @path: path to validate
  * Returns 0 if path points to link, 1 otherwise
  */
-int sysfs_path_is_link(const unsigned char *path)
+int sysfs_path_is_link(const char *path)
 {
        struct stat astats;
 
@@ -456,7 +468,7 @@ int sysfs_path_is_link(const unsigned char *path)
  * @path: path to validate
  * Returns 0 if path points to file, 1 otherwise
  */
-int sysfs_path_is_file(const unsigned char *path)
+int sysfs_path_is_file(const char *path)
 {
        struct stat astats;