From 126777bc019a54afb4ec51299f2cf9d2841698aa Mon Sep 17 00:00:00 2001 From: Pascal Rigaux Date: Wed, 25 Apr 2007 12:26:16 +0000 Subject: re-sync after the big svn loss --- mdk-stage1/sysfs/Makefile | 39 +++++++ mdk-stage1/sysfs/libsysfs.h | 90 +++++++++++++++ mdk-stage1/sysfs/sysfs.h | 64 +++++++++++ mdk-stage1/sysfs/sysfs_attr.c | 241 +++++++++++++++++++++++++++++++++++++++++ mdk-stage1/sysfs/sysfs_utils.c | 59 ++++++++++ 5 files changed, 493 insertions(+) create mode 100644 mdk-stage1/sysfs/Makefile create mode 100644 mdk-stage1/sysfs/libsysfs.h create mode 100644 mdk-stage1/sysfs/sysfs.h create mode 100644 mdk-stage1/sysfs/sysfs_attr.c create mode 100644 mdk-stage1/sysfs/sysfs_utils.c (limited to 'mdk-stage1/sysfs') diff --git a/mdk-stage1/sysfs/Makefile b/mdk-stage1/sysfs/Makefile new file mode 100644 index 000000000..5cab07408 --- /dev/null +++ b/mdk-stage1/sysfs/Makefile @@ -0,0 +1,39 @@ + #****************************************************************************** + # + # Guillaume Cottenceau (gc@mandrakesoft.com) + # Olivier Blin (blino@mandriva.com) + # + # Copyright 2006 Mandriva + # + # This software may be freely redistributed under the terms of the GNU + # public license. + # + # You should have received a copy of the GNU General Public License + # along with this program; if not, write to the Free Software + # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + # + #***************************************************************************** + +# minimal sysfs library ripped from sysfsutils-2.0.0 + +top_dir = .. + +include $(top_dir)/Makefile.common + +TARGET = libsysfs.a + +all: $(TARGET) + +clean: + rm -f *.o $(TARGET) + +FLAGS = -D__linux__ -Wall -Werror -Wno-deprecated-declarations -Os -fomit-frame-pointer -pipe -c -I.. -D_BSD_SOURCE + +OBJS = sysfs_attr.o sysfs_utils.o + +$(TARGET): $(OBJS) + ar -cru $@ $^ + ranlib $@ + +$(OBJS): %.o: %.c + $(DIET) gcc $(FLAGS) $(INCLUDES) -c $< -o $@ diff --git a/mdk-stage1/sysfs/libsysfs.h b/mdk-stage1/sysfs/libsysfs.h new file mode 100644 index 000000000..7bdf54fea --- /dev/null +++ b/mdk-stage1/sysfs/libsysfs.h @@ -0,0 +1,90 @@ +/* + * libsysfs.h + * + * Header Definitions for libsysfs + * + * Copyright (C) IBM Corp. 2004-2005 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef _LIBSYSFS_H_ +#define _LIBSYSFS_H_ + +#include +#include + +#define SYSFS_FSTYPE_NAME "sysfs" +#define SYSFS_PROC_MNTS "/proc/mounts" +#define SYSFS_BUS_NAME "bus" +#define SYSFS_CLASS_NAME "class" +#define SYSFS_BLOCK_NAME "block" +#define SYSFS_DEVICES_NAME "devices" +#define SYSFS_DRIVERS_NAME "drivers" +#define SYSFS_MODULE_NAME "module" +#define SYSFS_NAME_ATTRIBUTE "name" +#define SYSFS_MOD_PARM_NAME "parameters" +#define SYSFS_MOD_SECT_NAME "sections" +#define SYSFS_UNKNOWN "unknown" +#define SYSFS_PATH_ENV "SYSFS_PATH" + +#define SYSFS_PATH_MAX 256 +#define SYSFS_NAME_LEN 64 +#define SYSFS_BUS_ID_SIZE 32 + +/* mount path for sysfs, can be overridden by exporting SYSFS_PATH */ +#define SYSFS_MNT_PATH "/sys" + +enum sysfs_attribute_method { + SYSFS_METHOD_SHOW = 0x01, /* attr can be read by user */ + SYSFS_METHOD_STORE = 0x02, /* attr can be changed by user */ +}; + +/* + * NOTE: + * 1. We have the statically allocated "name" as the first element of all + * the structures. This feature is used in the "sorter" function for dlists + * 2. As is the case with attrlist + * 3. As is the case with path + */ +struct sysfs_attribute { + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; + char *value; + unsigned short len; /* value length */ + enum sysfs_attribute_method method; /* show and store */ +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Function Prototypes + */ +extern int sysfs_get_name_from_path(const char *path, char *name, size_t len); + +/* sysfs directory and file access */ +extern void sysfs_close_attribute(struct sysfs_attribute *sysattr); +extern struct sysfs_attribute *sysfs_open_attribute(const char *path); +extern int sysfs_read_attribute(struct sysfs_attribute *sysattr); +extern int sysfs_write_attribute(struct sysfs_attribute *sysattr, + const char *new_value, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBSYSFS_H_ */ diff --git a/mdk-stage1/sysfs/sysfs.h b/mdk-stage1/sysfs/sysfs.h new file mode 100644 index 000000000..76754a421 --- /dev/null +++ b/mdk-stage1/sysfs/sysfs.h @@ -0,0 +1,64 @@ +/* + * sysfs.h + * + * Internal Header Definitions for libsysfs + * + * Copyright (C) IBM Corp. 2003-2005 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef _SYSFS_H_ +#define _SYSFS_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define safestrcpy(to, from) strncpy(to, from, sizeof(to)-1) +#define safestrcat(to, from) strncat(to, from, sizeof(to) - strlen(to)-1) + +#define safestrcpymax(to, from, max) \ +do { \ + to[max-1] = '\0'; \ + strncpy(to, from, max-1); \ +} while (0) + +#define safestrcatmax(to, from, max) \ +do { \ + to[max-1] = '\0'; \ + strncat(to, from, max - strlen(to)-1); \ +} while (0) + +extern struct sysfs_attribute *get_attribute(void *dev, const char *name); +extern struct dlist *read_dir_subdirs(const char *path); +extern struct dlist *read_dir_links(const char *path); +extern struct dlist *get_dev_attributes_list(void *dev); +extern struct dlist *get_attributes_list(struct dlist *alist, const char *path); + +/* Debugging */ +#ifdef DEBUG +#define dprintf(format, arg...) fprintf(stderr, format, ## arg) +#else +#define dprintf(format, arg...) do { } while (0) +#endif + +#endif /* _SYSFS_H_ */ diff --git a/mdk-stage1/sysfs/sysfs_attr.c b/mdk-stage1/sysfs/sysfs_attr.c new file mode 100644 index 000000000..6d6771188 --- /dev/null +++ b/mdk-stage1/sysfs/sysfs_attr.c @@ -0,0 +1,241 @@ +/* + * sysfs_dir.c + * + * Directory utility functions for libsysfs + * + * Copyright (C) IBM Corp. 2003-2005 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include "libsysfs.h" +#include "sysfs.h" + +/** + * sysfs_close_attribute: closes and cleans up attribute + * @sysattr: attribute to close. + */ +void sysfs_close_attribute(struct sysfs_attribute *sysattr) +{ + if (sysattr) { + if (sysattr->value) + free(sysattr->value); + free(sysattr); + } +} + +/** + * alloc_attribute: allocates and initializes attribute structure + * returns struct sysfs_attribute with success and NULL with error. + */ +static struct sysfs_attribute *alloc_attribute(void) +{ + return (struct sysfs_attribute *) + calloc(1, sizeof(struct sysfs_attribute)); +} + +/** + * sysfs_open_attribute: creates sysfs_attribute structure + * @path: path to attribute. + * returns sysfs_attribute struct with success and NULL with error. + */ +struct sysfs_attribute *sysfs_open_attribute(const char *path) +{ + struct sysfs_attribute *sysattr = NULL; + struct stat fileinfo; + + if (!path) { + errno = EINVAL; + return NULL; + } + sysattr = alloc_attribute(); + if (!sysattr) { + 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 attrib name from path: %s\n", path); + sysfs_close_attribute(sysattr); + return NULL; + } + safestrcpy(sysattr->path, path); + if ((stat(sysattr->path, &fileinfo)) != 0) { + dprintf("Stat failed: No such attribute?\n"); + sysattr->method = 0; + free(sysattr); + sysattr = NULL; + } else { + if (fileinfo.st_mode & S_IRUSR) + sysattr->method |= SYSFS_METHOD_SHOW; + if (fileinfo.st_mode & S_IWUSR) + sysattr->method |= SYSFS_METHOD_STORE; + } + + return sysattr; +} + +/** + * sysfs_read_attribute: reads value from attribute + * @sysattr: attribute to read + * returns 0 with success and -1 with error. + */ +int sysfs_read_attribute(struct sysfs_attribute *sysattr) +{ + char *fbuf = NULL; + char *vbuf = NULL; + ssize_t length = 0; + long pgsize = 0; + int fd; + + if (!sysattr) { + errno = EINVAL; + return -1; + } + if (!(sysattr->method & SYSFS_METHOD_SHOW)) { + dprintf("Show method not supported for attribute %s\n", + sysattr->path); + errno = EACCES; + return -1; + } + pgsize = getpagesize(); + fbuf = (char *)calloc(1, pgsize+1); + if (!fbuf) { + dprintf("calloc failed\n"); + return -1; + } + if ((fd = open(sysattr->path, O_RDONLY)) < 0) { + dprintf("Error reading attribute %s\n", sysattr->path); + free(fbuf); + return -1; + } + length = read(fd, fbuf, pgsize); + if (length < 0) { + dprintf("Error reading from attribute %s\n", sysattr->path); + close(fd); + free(fbuf); + return -1; + } + if (sysattr->len > 0) { + if ((sysattr->len == length) && + (!(strncmp(sysattr->value, fbuf, length)))) { + close(fd); + free(fbuf); + return 0; + } + free(sysattr->value); + } + sysattr->len = length; + close(fd); + vbuf = (char *)realloc(fbuf, length+1); + if (!vbuf) { + dprintf("realloc failed\n"); + free(fbuf); + return -1; + } + sysattr->value = vbuf; + + return 0; +} + +/** + * sysfs_write_attribute: write value to the attribute + * @sysattr: attribute to write + * @new_value: value to write + * @len: length of "new_value" + * returns 0 with success and -1 with error. + */ +int sysfs_write_attribute(struct sysfs_attribute *sysattr, + const char *new_value, size_t len) +{ + int fd; + int length; + + if (!sysattr || !new_value || len == 0) { + errno = EINVAL; + return -1; + } + + 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) { + /* + * read attribute again to see if we can get an updated value + */ + if ((sysfs_read_attribute(sysattr))) { + dprintf("Error reading attribute\n"); + return -1; + } + if ((strncmp(sysattr->value, new_value, sysattr->len)) == 0 && + (len == sysattr->len)) { + dprintf("Attr %s already has the requested value %s\n", + sysattr->name, new_value); + return 0; + } + } + /* + * open O_WRONLY since some attributes have no "read" but only + * "write" permission + */ + if ((fd = open(sysattr->path, O_WRONLY)) < 0) { + dprintf("Error reading attribute %s\n", sysattr->path); + return -1; + } + + length = write(fd, new_value, len); + if (length < 0) { + dprintf("Error writing to the attribute %s - invalid value?\n", + sysattr->name); + close(fd); + return -1; + } else if ((unsigned int)length != len) { + dprintf("Could not write %zd bytes to attribute %s\n", + len, sysattr->name); + /* + * since we could not write user supplied number of bytes, + * restore the old value if one available + */ + if (sysattr->method & SYSFS_METHOD_SHOW) { + length = write(fd, sysattr->value, sysattr->len); + close(fd); + return -1; + } + } + + /* + * Validate length that has been copied. Alloc appropriate area + * in sysfs_attribute. Verify first if the attribute supports reading + * (show method). If it does not, do not bother + */ + if (sysattr->method & SYSFS_METHOD_SHOW) { + if (length != sysattr->len) { + sysattr->value = (char *)realloc + (sysattr->value, length); + sysattr->len = length; + safestrcpymax(sysattr->value, new_value, length); + } else { + /*"length" of the new value is same as old one */ + safestrcpymax(sysattr->value, new_value, length); + } + } + + close(fd); + return 0; +} + diff --git a/mdk-stage1/sysfs/sysfs_utils.c b/mdk-stage1/sysfs/sysfs_utils.c new file mode 100644 index 000000000..a0354a8f8 --- /dev/null +++ b/mdk-stage1/sysfs/sysfs_utils.c @@ -0,0 +1,59 @@ +/* + * sysfs_utils.c + * + * System utility functions for libsysfs + * + * Copyright (C) IBM Corp. 2003-2005 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include "libsysfs.h" +#include "sysfs.h" + +/** + * sysfs_get_name_from_path: returns last name from a "/" delimited path + * @path: path to get name from + * @name: where to put name + * @len: size of name + */ +int sysfs_get_name_from_path(const char *path, char *name, size_t len) +{ + char tmp[SYSFS_PATH_MAX]; + char *n = NULL; + + if (!path || !name || len == 0) { + errno = EINVAL; + return -1; + } + memset(tmp, 0, SYSFS_PATH_MAX); + safestrcpy(tmp, path); + n = strrchr(tmp, '/'); + if (n == NULL) { + errno = EINVAL; + return -1; + } + if (*(n+1) == '\0') { + *n = '\0'; + n = strrchr(tmp, '/'); + if (n == NULL) { + errno = EINVAL; + return -1; + } + } + n++; + safestrcpymax(name, n, len); + return 0; +} -- cgit v1.2.1