All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
To: linux-hotplug@vger.kernel.org
Subject: [PATCH] Libsysfs updates
Date: Thu, 11 Mar 2004 06:15:49 +0000	[thread overview]
Message-ID: <20040311065350.GA3371@in.ibm.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 574 bytes --]

Hello Greg,

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.


Thanks,
Ananth
-- 
Ananth Narayan
Linux Technology Center,
IBM Software Lab, INDIA


[-- Attachment #2: udev-libsysfs-take2.patch --]
[-- Type: text/plain, Size: 74738 bytes --]

diff -Naur temp/udev-021/libsysfs/dlist.c udev-021/libsysfs/dlist.c
--- temp/udev-021/libsysfs/dlist.c	2004-03-03 05:31:32.000000000 +0530
+++ udev-021/libsysfs/dlist.c	2004-03-10 22:42:14.000000000 +0530
@@ -260,6 +260,16 @@
   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.
diff -Naur temp/udev-021/libsysfs/dlist.h udev-021/libsysfs/dlist.h
--- temp/udev-021/libsysfs/dlist.h	2004-03-03 05:31:33.000000000 +0530
+++ udev-021/libsysfs/dlist.h	2004-03-10 22:19:07.000000000 +0530
@@ -76,13 +76,14 @@
 
 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 *);
 
diff -Naur temp/udev-021/libsysfs/sysfs/libsysfs.h udev-021/libsysfs/sysfs/libsysfs.h
--- temp/udev-021/libsysfs/sysfs/libsysfs.h	2004-03-03 05:31:32.000000000 +0530
+++ udev-021/libsysfs/sysfs/libsysfs.h	2004-03-10 22:17:28.000000000 +0530
@@ -24,6 +24,25 @@
 #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..
@@ -46,25 +65,28 @@
 #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_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_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_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_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_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 {
-	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 @@
 /*
  * 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 @@
 /* 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
 }
diff -Naur temp/udev-021/libsysfs/sysfs_bus.c udev-021/libsysfs/sysfs_bus.c
--- temp/udev-021/libsysfs/sysfs_bus.c	2004-03-03 05:31:31.000000000 +0530
+++ udev-021/libsysfs/sysfs_bus.c	2004-03-10 22:25:22.000000000 +0530
@@ -44,7 +44,7 @@
 	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 @@
 	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 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 @@
 		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 @@
 				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 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 @@
 				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 @@
  * 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 @@
 		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 @@
 		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 @@
  * @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 @@
  * 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 @@
  * 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 @@
 }
 
 /**
- * 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 @@
 	}
 
 	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;
diff -Naur temp/udev-021/libsysfs/sysfs_class.c udev-021/libsysfs/sysfs_class.c
--- temp/udev-021/libsysfs/sysfs_class.c	2004-03-03 05:31:31.000000000 +0530
+++ udev-021/libsysfs/sysfs_class.c	2004-03-11 10:19:39.000000000 +0530
@@ -38,8 +38,7 @@
 	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 @@
 
 /**
  * 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 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 @@
 	}
 
 	if (c == NULL)
-		strcpy(cdev->classname, SYSFS_UNKNOWN);
+		safestrcpy(cdev->classname, SYSFS_UNKNOWN);
 	else {
 		if (*c == '/')
 			c++;
@@ -134,8 +133,7 @@
  * @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 @@
 		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 @@
 
 /**
  * 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 @@
 				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 @@
  * 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 @@
 	 * 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 @@
 		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 @@
  * @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_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 @@
 	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_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 @@
 	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 @@
  */
 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 @@
 	 * 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 @@
  * @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 @@
                 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 @@
  * 	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 @@
  * 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 @@
 	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 @@
 			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 @@
  * 	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 @@
 						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",
diff -Naur temp/udev-021/libsysfs/sysfs_device.c udev-021/libsysfs/sysfs_device.c
--- temp/udev-021/libsysfs/sysfs_device.c	2004-03-03 05:31:31.000000000 +0530
+++ udev-021/libsysfs/sysfs_device.c	2004-03-10 22:26:54.000000000 +0530
@@ -24,6 +24,57 @@
 #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 @@
 	}
 
 	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 @@
 				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 @@
  * 	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 @@
  * @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 @@
  * @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 @@
 		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 @@
 	 * 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 @@
  * 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 @@
 				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 @@
 			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 @@
  * @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 @@
 		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 @@
 		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 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 @@
  * 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 @@
 	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 @@
  * @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 @@
 		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 @@
 
 /**
  * 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_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 @@
 		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 @@
 	/*
 	 * 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 @@
  * 	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 @@
 		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",
diff -Naur temp/udev-021/libsysfs/sysfs_dir.c udev-021/libsysfs/sysfs_dir.c
--- temp/udev-021/libsysfs/sysfs_dir.c	2004-03-03 05:31:33.000000000 +0530
+++ udev-021/libsysfs/sysfs_dir.c	2004-03-10 22:27:56.000000000 +0530
@@ -58,9 +58,9 @@
 	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 @@
 	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 @@
 	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 @@
  * @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 @@
 		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 @@
  * 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 @@
 	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 @@
 			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 @@
 	 */ 
 	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 @@
 	return 0;
 }
 
-
 /**
  * sysfs_read_attribute: reads value from attribute
  * @sysattr: attribute to read
@@ -258,8 +257,8 @@
  */
 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 @@
 	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 @@
 		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 @@
  * @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 @@
 	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 @@
  * 	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 @@
 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 @@
 	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 @@
  * @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 @@
 	}
 
 	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 @@
 		sysfs_close_directory(sdir);
 		return NULL;
 	}
-	strncpy(sdir->path, path, SYSFS_PATH_MAX);
+	safestrcpy(sdir->path, path);
 
 	return sdir;
 }
@@ -492,7 +496,7 @@
  * @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 @@
 		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 @@
  * @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 @@
 		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 @@
  * @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 @@
 	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 @@
  * @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 @@
 	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 @@
 {
 	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 @@
 		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 @@
 {
 	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 @@
 		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 @@
 		}
 	}
 	closedir(dir);
+	if (!retval)
+		errno = 0;
 	return(retval);
 }
 
@@ -681,7 +687,7 @@
 {
 	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 @@
 		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 @@
 	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 @@
 		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 @@
 			retval = add_attribute(sysdir, file_path);
 	}
 	closedir(dir);
+	if (!retval)
+		errno = 0;
 	return(retval);
 }
 
@@ -782,6 +792,7 @@
 							sysdir->path);
 		return 1;
 	}
+	errno = 0;
 	return 0;
 }
 
@@ -810,6 +821,7 @@
 							sysdir->path);
 		return 1;
 	}
+	errno = 0;
 	return 0;
 }
 
@@ -838,6 +850,7 @@
 							sysdir->path);
 		return 1;
 	}
+	errno = 0;
 	return 0;
 }
 
@@ -846,13 +859,17 @@
  *	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 @@
 		}
 	} 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 @@
  * 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 @@
  * 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 @@
  * 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;
diff -Naur temp/udev-021/libsysfs/sysfs_driver.c udev-021/libsysfs/sysfs_driver.c
--- temp/udev-021/libsysfs/sysfs_driver.c	2004-03-03 05:31:31.000000000 +0530
+++ udev-021/libsysfs/sysfs_driver.c	2004-03-10 22:28:50.000000000 +0530
@@ -79,7 +79,7 @@
  * @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 @@
 		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 @@
  * 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 @@
         }
 	
 	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 @@
 		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 @@
 	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 @@
 						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 @@
  * 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 @@
  * @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 @@
 		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 @@
  * 	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 @@
 		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 @@
 
 /**
  * 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) {
diff -Naur temp/udev-021/libsysfs/sysfs_utils.c udev-021/libsysfs/sysfs_utils.c
--- temp/udev-021/libsysfs/sysfs_utils.c	2004-03-03 05:31:32.000000000 +0530
+++ udev-021/libsysfs/sysfs_utils.c	2004-03-10 22:40:09.000000000 +0530
@@ -26,14 +26,20 @@
 #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 @@
 }
 
 /**
- * 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 @@
 	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 @@
 		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 @@
  * @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 @@
  * @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 @@
 		}
 	}
 	n++;
-	strncpy(name, n, len);
+	safestrncpy(name, n, len);
 	return 0;
 }
 	
@@ -171,21 +176,23 @@
  * @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 @@
 			/* 
 			 * 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 @@
 				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 @@
  * @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 @@
 		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 @@
 		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 @@
 		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 @@
  * @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 @@
 		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 @@
 		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 @@
  * @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 @@
  * @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 @@
  * @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;
 

             reply	other threads:[~2004-03-11  6:15 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-03-11  6:15 Ananth N Mavinakayanahalli [this message]
2004-03-12  1:06 ` [PATCH] Libsysfs updates Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20040311065350.GA3371@in.ibm.com \
    --to=ananth@in.ibm.com \
    --cc=linux-hotplug@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.