1
0
mirror of https://github.com/systemd/systemd.git synced 2024-10-28 20:25:38 +03:00

[PATCH] Libsysfs updates

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.
This commit is contained in:
ananth@in.ibm.com 2004-03-12 00:57:30 -08:00 committed by Greg KH
parent 0a5417a0eb
commit d1fb871d99
9 changed files with 534 additions and 451 deletions

View 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.

View 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 *);

View File

@ -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_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
}

View 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;
@ -353,49 +352,6 @@ struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus,
return sysfs_get_directory_attribute(bus->directory, attrname);
}
/**
* 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
@ -403,10 +359,9 @@ struct sysfs_device *sysfs_open_bus_device(unsigned char *busname,
* @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;

View 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",

View File

@ -23,6 +23,57 @@
#include "sysfs/libsysfs.h"
#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.
@ -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",

View 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;

View 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) {

View File

@ -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 @@ 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;