chiark / gitweb /
replace libsysfs
authorKay Sievers <kay.sievers@suse.de>
Mon, 9 Jan 2006 20:18:00 +0000 (21:18 +0100)
committerKay Sievers <kay.sievers@suse.de>
Mon, 9 Jan 2006 20:18:00 +0000 (21:18 +0100)
We never used any of the libsysfs convenience features. Here we replace
it completely with 300 lines of code, which are much simpler and a bit
faster cause udev(d) does not open any syfs file for a simple event which
does not need any parent device information.

Signed-off-by: Kay Sievers <kay.sievers@suse.de>
69 files changed:
Makefile
RELEASE-NOTES
docs/udev.xml
docs/udevtest.xml
extras/ata_id/Makefile
extras/ata_id/ata_id.c
extras/cdrom_id/Makefile
extras/cdrom_id/cdrom_id.c
extras/dasd_id/Makefile
extras/dasd_id/dasd_id.c
extras/edd_id/Makefile
extras/edd_id/edd_id.c
extras/firmware/Makefile
extras/firmware/firmware_helper.c
extras/floppy/Makefile
extras/run_directory/Makefile
extras/run_directory/run_directory.c
extras/run_directory/udev_run_devd.c
extras/run_directory/udev_run_hotplugd.c
extras/scsi_id/Makefile
extras/scsi_id/scsi_id.c
extras/scsi_id/scsi_id.h
extras/scsi_id/scsi_serial.c
extras/usb_id/Makefile
extras/usb_id/usb_id.c
extras/volume_id/Makefile
extras/volume_id/vol_id.c
libsysfs/LGPL [deleted file]
libsysfs/dlist.c [deleted file]
libsysfs/libsysfs.txt [deleted file]
libsysfs/sysfs.h [deleted file]
libsysfs/sysfs/dlist.h [deleted file]
libsysfs/sysfs/libsysfs.h [deleted file]
libsysfs/sysfs_bus.c [deleted file]
libsysfs/sysfs_class.c [deleted file]
libsysfs/sysfs_device.c [deleted file]
libsysfs/sysfs_dir.c [deleted file]
libsysfs/sysfs_driver.c [deleted file]
libsysfs/sysfs_utils.c [deleted file]
test/simple-build-check.sh
test/udev-test.pl
udev.c
udev.h
udev_add.c
udev_config.c
udev_db.c
udev_device.c
udev_event.c [deleted file]
udev_libc_wrapper.c
udev_remove.c
udev_rules.c
udev_rules.h
udev_rules_parse.c
udev_selinux.c
udev_sysfs.c [new file with mode: 0644]
udev_utils.c
udev_utils.h [deleted file]
udev_utils_file.c
udev_utils_run.c
udev_utils_string.c
udevcontrol.c
udevd.c
udevd.h
udevinfo.c
udevmonitor.c
udevsend.c
udevstart.c
udevtest.8
udevtest.c

index 5edc76f..461f5ac 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -58,7 +58,6 @@ PROGRAMS = \
 
 HEADERS = \
        udev.h                          \
-       udev_utils.h                    \
        udev_rules.h                    \
        logging.h                       \
        udev_libc_wrapper.h             \
@@ -66,12 +65,12 @@ HEADERS = \
        list.h
 
 UDEV_OBJS = \
-       udev_event.o                    \
        udev_device.o                   \
        udev_config.o                   \
        udev_add.o                      \
        udev_remove.o                   \
        udev_db.o                       \
+       udev_sysfs.o                    \
        udev_rules.o                    \
        udev_rules_parse.o              \
        udev_utils.o                    \
@@ -90,15 +89,6 @@ MAN_PAGES = \
        udevinfo.8                      \
        udevstart.8
 
-SYSFS_OBJS = \
-       libsysfs/sysfs_class.o          \
-       libsysfs/sysfs_device.o         \
-       libsysfs/sysfs_dir.o            \
-       libsysfs/sysfs_driver.o         \
-       libsysfs/sysfs_utils.o          \
-       libsysfs/dlist.o
-LIBSYSFS = libsysfs/libsysfs.a
-
 # config files automatically generated
 GEN_CONFIGS = \
        $(LOCAL_CFG_DIR)/udev.conf
@@ -144,10 +134,6 @@ LDFLAGS = -Wl,-warn-common
 OPTFLAGS = -Os
 CFLAGS += $(OPTFLAGS)
 
-# include our local copy of libsysfs
-CFLAGS +=      -I$(PWD)/libsysfs/sysfs \
-               -I$(PWD)/libsysfs
-
 ifeq ($(strip $(USE_LOG)),true)
        CFLAGS += -DUSE_LOG
 endif
@@ -200,7 +186,6 @@ all: $(PROGRAMS) $(MAN_PAGES)
                        STRIPCMD="$(STRIPCMD)" \
                        LIB_OBJS="$(LIB_OBJS)" \
                        LIBUDEV="$(PWD)/$(LIBUDEV)" \
-                       LIBSYSFS="$(PWD)/$(LIBSYSFS)" \
                        QUIET="$(QUIET)" \
                        -C $$target $@ || exit 1; \
        done;
@@ -211,28 +196,21 @@ all: $(PROGRAMS) $(MAN_PAGES)
 .SUFFIXES:
 
 # build the objects
-%.o: %.c $(HOST_PROGS) $(GEN_HEADERS)
+%.o: %.c $(HOST_PROGS) $(HEADERS) $(GEN_HEADERS)
        $(QUIET) $(CC) -c $(CFLAGS) $< -o $@
 
 # "Static Pattern Rule" to build all programs
-$(PROGRAMS): %: $(HOST_PROGS) $(HEADERS) $(GEN_HEADERS) $(LIBSYSFS) $(LIBUDEV) %.o
-       $(QUIET) $(LD) $(LDFLAGS) $@.o -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS)
+$(PROGRAMS): %: $(HOST_PROGS) $(HEADERS) $(GEN_HEADERS) $(LIBUDEV) %.o
+       $(QUIET) $(LD) $(LDFLAGS) $@.o -o $@ $(LIBUDEV) $(LIB_OBJS)
 ifneq ($(STRIPCMD),)
        $(QUIET) $(STRIPCMD) $@
 endif
 
-$(UDEV_OBJS):
 $(LIBUDEV): $(HOST_PROGS) $(HEADERS) $(GEN_HEADERS) $(UDEV_OBJS)
        @rm -f $@
        $(QUIET) $(AR) cq $@ $(UDEV_OBJS)
        $(QUIET) $(RANLIB) $@
 
-$(SYSFS_OBJS):
-$(LIBSYSFS): $(HOST_PROGS) $(SYSFS_OBJS)
-       @rm -f $@
-       $(QUIET) $(AR) cq $@ $(SYSFS_OBJS)
-       $(QUIET) $(RANLIB) $@
-
 # generate config files
 $(GEN_CONFIGS):
        sed -e "s:@udevdir@:$(udevdir):" -e "s:@configdir@:$(configdir):" < $@.in > $@
index 4e35702..623ea0e 100644 (file)
@@ -1,5 +1,11 @@
 udev 080
 ========
+Complete removal of libsysfs, replaced by simple helper functions
+which are much simpler and a bit faster. The udev daemon operatesentirely
+on event parameters and does not use sysfs for simple rules anymore.
+Please report any new bugs/problems, that may be caused by this big
+change. They will be fixed immediately.
+
 The enumeration format character '%e' is deprecated and will be
 removed sometimes from a future udev version. It never worked correctly
 outside of udevstart, so we can't use it with the new parallel
@@ -10,6 +16,8 @@ MODALIAS and $modalias is not needed and will be removed from one of
 the next udev versions, replace it in all rules with ENV{MODALIAS} or
 the sysfs "modalias" value.
 
+Thanks a lot to Marco for all his help on finding and fixing bugs.
+
 udev 079
 ========
 Let scsi_id request libata drive serial numbers from page 0x80.
index e87dbab..7f6a30d 100644 (file)
             </varlistentry>
 
             <varlistentry>
-              <term><option>%b</option>, <option>$id</option></term>
-              <listitem>
-                <para>The kernel bus id for this device.</para>
-              </listitem>
-            </varlistentry>
-
-            <varlistentry>
               <term><option>%n</option>, <option>$number</option></term>
               <listitem>
                 <para>The kernel number for this device. For example, 'sda3' has
index ceea041..2b39eeb 100644 (file)
@@ -37,7 +37,7 @@
 
       <refsynopsisdiv>
         <cmdsynopsis>
-          <command>udevtest <filename>device-path</filename> <replaceable>subsystem</replaceable></command>
+          <command>udevtest <filename>device-path</filename></command>
         </cmdsynopsis>
       </refsynopsisdiv>
 
index ebf0f4e..0a881fb 100644 (file)
@@ -33,7 +33,7 @@ all: $(PROG) $(MAN_PAGES)
        $(QUIET) $(CC) -c $(CFLAGS) $< -o $@
 
 $(PROG): %: $(HEADERS) %.o $(OBJS)
-       $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS)
+       $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS)
 ifneq ($(STRIPCMD),)
        $(QUIET) $(STRIPCMD) $@
 endif
index a97cc28..aedebff 100644 (file)
@@ -17,6 +17,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <ctype.h>
+#include <string.h>
 #include <errno.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
@@ -24,8 +25,7 @@
 #include <linux/types.h>
 #include <linux/hdreg.h>
 
-#include "../../logging.h"
-#include "../../udev_utils.h"
+#include "../../udev.h"
 
 #ifdef USE_LOG
 void log_message(int priority, const char *format, ...)
index 985eb80..9a722d5 100644 (file)
@@ -33,7 +33,7 @@ all: $(PROG) $(MAN_PAGES)
        $(QUIET) $(CC) -c $(CFLAGS) $< -o $@
 
 $(PROG): %: $(HEADERS) %.o $(OBJS)
-       $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS)
+       $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS)
 ifneq ($(strip $(STRIPCMD)),)
        $(QUIET) $(STRIPCMD) $@
 endif
index ff6f89e..0d4a8c1 100644 (file)
 #include <unistd.h>
 #include <fcntl.h>
 #include <ctype.h>
+#include <string.h>
 #include <errno.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <linux/types.h>
 
-#include "../../logging.h"
-#include "../../udev_utils.h"
+#include "../../udev.h"
 
 /*
  * Taken from the cdrom.h kernel include file.
index 80680f2..79f14a4 100644 (file)
@@ -33,7 +33,7 @@ all: $(PROG) $(MAN_PAGES)
        $(QUIET) $(CC) -c $(CFLAGS) $< -o $@
 
 $(PROG): %: $(HEADERS) %.o $(OBJS)
-       $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS)
+       $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS)
 ifneq ($(strip $(STRIPCMD)),)
        $(QUIET) $(STRIPCMD) $@
 endif
index ca2582c..b2496e9 100644 (file)
@@ -24,8 +24,7 @@
 #include <errno.h>
 #include <sys/ioctl.h>
 
-#include "../../logging.h"
-#include "../../udev_utils.h"
+#include "../../udev.h"
 
 #ifdef USE_LOG
 void log_message(int priority, const char *format, ...)
index 5a6cdb6..db6afae 100644 (file)
@@ -33,7 +33,7 @@ all: $(PROG) $(MAN_PAGES)
        $(QUIET) $(CC) -c $(CFLAGS) $< -o $@
 
 $(PROG): %: $(HEADERS) %.o $(OBJS)
-       $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS)
+       $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS)
 ifneq ($(strip $(STRIPCMD)),)
        $(QUIET) $(STRIPCMD) $@
 endif
index f21362b..8fc690a 100644 (file)
 #include <unistd.h>
 #include <fcntl.h>
 #include <ctype.h>
+#include <string.h>
 #include <errno.h>
 #include <dirent.h>
 #include <stdint.h>
 
-#include "../../logging.h"
-#include "../../udev_utils.h"
+#include "../../udev.h"
 
 #ifdef USE_LOG
 void log_message(int priority, const char *format, ...)
index 1691886..da7fe9d 100644 (file)
@@ -33,7 +33,7 @@ all: $(PROG) $(MAN_PAGES)
        $(QUIET) $(CC) -c $(CFLAGS) $< -o $@
 
 $(PROG): %: $(HEADERS) %.o $(OBJS)
-       $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS)
+       $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS)
 ifneq ($(strip $(STRIPCMD)),)
        $(QUIET) $(STRIPCMD) $@
 endif
index 2bc6b50..ca1c438 100644 (file)
@@ -17,8 +17,7 @@
 #include <unistd.h>
 #include <sys/stat.h>
 
-#include "../../udev_utils.h"
-#include "../../logging.h"
+#include "../../udev.h"
 
 #define FIRMWARE_PATH                  "/lib/firmware"
 #define PATH_SIZE                      256
index 240af4c..e23191a 100644 (file)
@@ -33,7 +33,7 @@ all: $(PROG) $(MAN_PAGES)
        $(QUIET) $(CC) -c $(CFLAGS) $< -o $@
 
 $(PROG): %: $(HEADERS) %.o $(OBJS)
-       $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS)
+       $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS)
 ifneq ($(strip $(STRIPCMD)),)
        $(QUIET) $(STRIPCMD) $@
 endif
index d138f62..37a5959 100644 (file)
@@ -32,7 +32,7 @@ all: $(PROG) $(MAN_PAGES)
        $(QUIET) $(CC) -c $(CFLAGS) $< -o $@
 
 $(PROG): %: $(HEADERS) %.o $(OBJS)
-       $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS)
+       $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS)
 ifneq ($(strip $(STRIPCMD)),)
        $(QUIET) $(STRIPCMD) $@
 endif
index 69faecc..c715ca6 100644 (file)
@@ -22,9 +22,7 @@
 #include <sys/wait.h>
 #include <sys/stat.h>
 
-#include "../../udev_utils.h"
-#include "../../list.h"
-#include "../../logging.h"
+#include "../../udev.h"
 #include "run_directory.h"
 
 static int exec_program(const char *filename, const char *subsystem)
index e708de8..59ea766 100644 (file)
@@ -22,9 +22,7 @@
 #include <sys/wait.h>
 #include <sys/stat.h>
 
-#include "../../udev_utils.h"
-#include "../../list.h"
-#include "../../logging.h"
+#include "../../udev.h"
 #include "run_directory.h"
 
 
index a21835a..bfa82ab 100644 (file)
@@ -22,9 +22,7 @@
 #include <sys/wait.h>
 #include <sys/stat.h>
 
-#include "../../udev_utils.h"
-#include "../../list.h"
-#include "../../logging.h"
+#include "../../udev.h"
 #include "run_directory.h"
 
 
index 399de76..057594d 100644 (file)
@@ -29,7 +29,6 @@ INSTALL_DATA  = ${INSTALL} -m 644
 INSTALL_SCRIPT = ${INSTALL_PROGRAM}
 
 # be able to run without udev
-LIBSYSFS = -lsysfs
 CROSS =
 QUIET =
 CC = $(CROSS)gcc
@@ -47,7 +46,7 @@ all: $(PROG) $(MAN_PAGES)
        $(QUIET) $(CC) -c $(CFLAGS) $< -o $@
 
 $(PROG): %: $(HEADERS) %.o $(OBJS)
-       $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS)
+       $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS)
 ifneq ($(strip $(STRIPCMD)),)
        $(QUIET) $(STRIPCMD) $@
 endif
index aa1b160..3a4a374 100644 (file)
 #include <stdarg.h>
 #include <ctype.h>
 #include <sys/stat.h>
-#include <sysfs/libsysfs.h>
-#include "scsi_id_version.h"
-#include "scsi_id.h"
 
-#ifndef SCSI_ID_VERSION
-#warning No version
-#define SCSI_ID_VERSION        "unknown"
-#endif
+#include "../../udev.h"
+#include "scsi_id.h"
+#include "scsi_id_version.h"
 
-/*
- * temporary names for mknod.
- */
-#define TMP_DIR        "/dev"
-#define TMP_PREFIX "tmp-scsi"
+/* temporary names for mknod  */
+#define TMP_DIR                "/dev"
+#define TMP_PREFIX     "tmp-scsi"
 
-/*
- * XXX Note the 'e' (send output to stderr in all cases), and 'c' (callout)
- * options are not supported, but other code is still left in place for
- * now.
- */
 static const char short_options[] = "abd:f:gip:s:uvVx";
-/*
- * Just duplicate per dev options.
- */
 static const char dev_short_options[] = "bgp:";
 
-char sysfs_mnt_path[SYSFS_PATH_MAX];
-
 static int all_good;
 static int always_info;
-static char *default_callout;
 static int dev_specified;
 static int sys_specified;
 static char config_file[MAX_NAME_LEN] = SCSI_ID_CONFIG_FILE;
@@ -78,28 +61,30 @@ static char model_str[64];
 static char revision_str[16];
 static char type_str[16];
 
-void log_message (int level, const char *format, ...)
+#ifdef USE_LOG
+void log_message(int priority, const char *format, ...)
 {
-       va_list args;
+       va_list args;
+       static int udev_log = -1;
 
-       if (!debug && level == LOG_DEBUG)
-               return;
+       if (udev_log == -1) {
+               const char *value;
 
-       va_start (args, format);
-       if (!hotplug_mode || use_stderr) {
-               vfprintf(stderr, format, args);
-       } else {
-               static int logging_init = 0;
-               if (!logging_init) {
-                       openlog ("scsi_id", LOG_PID, LOG_DAEMON);
-                       logging_init = 1;
-               }
-
-               vsyslog(level, format, args);
+               value = getenv("UDEV_LOG");
+               if (value)
+                       udev_log = log_priority(value);
+               else
+                       udev_log = LOG_ERR;
        }
-       va_end (args);
-       return;
+
+       if (priority > udev_log)
+               return;
+
+       va_start(args, format);
+       vsyslog(priority, format, args);
+       va_end(args);
 }
+#endif
 
 static void set_str(char *to, const char *from, size_t count)
 {
@@ -171,68 +156,35 @@ static void set_type(char *to, const char *from, size_t len)
        to[len-1] = '\0';
 }
 
-static int get_major_minor(struct sysfs_class_device *class_dev, int *maj,
-                          int *min)
+static int create_tmp_dev(const char *devpath, char *tmpdev, int dev_type)
 {
-       struct sysfs_attribute *dev_attr;
+       unsigned int maj, min;
+       const char *attr;
 
-       dev_attr = sysfs_get_classdev_attr(class_dev, "dev");
-       if (!dev_attr) {
-               /*
-                * XXX This happens a lot, since sg has no dev attr.
-                * And now sysfsutils does not set a meaningful errno
-                * value. Someday change this back to a LOG_WARNING.
-                * And if sysfsutils changes, check for ENOENT and handle
-                * it separately.
-                */
-               log_message(LOG_DEBUG, "%s: could not get dev attribute: %s\n",
-                       class_dev->name, strerror(errno));
+       dbg("%s", devpath);
+       attr = sysfs_attr_get_value(devpath, "dev");
+       if (attr == NULL) {
+               dbg("%s: could not get dev attribute: %s", devpath, strerror(errno));
                return -1;
        }
 
-       dprintf("dev value %s", dev_attr->value); /* value has a trailing \n */
-       if (sscanf(dev_attr->value, "%u:%u", maj, min) != 2) {
-               log_message(LOG_WARNING, "%s: invalid dev major/minor\n",
-                           class_dev->name);
+       dbg("dev value %s", attr);
+       if (sscanf(attr, "%u:%u", &maj, &min) != 2) {
+               err("%s: invalid dev major/minor", devpath);
                return -1;
        }
 
-       return 0;
-}
-
-static int create_tmp_dev(struct sysfs_class_device *class_dev, char *tmpdev,
-                         int dev_type)
-{
-       int maj, min;
-
-       dprintf("(%s)\n", class_dev->name);
-
-       if (get_major_minor(class_dev, &maj, &min))
-               return -1;
        snprintf(tmpdev, MAX_NAME_LEN, "%s/%s-maj%d-min%d-%u",
                 TMP_DIR, TMP_PREFIX, maj, min, getpid());
 
-       dprintf("tmpdev '%s'\n", tmpdev);
-
+       dbg("tmpdev '%s'", tmpdev);
        if (mknod(tmpdev, 0600 | dev_type, makedev(maj, min))) {
-               log_message(LOG_WARNING, "mknod failed: %s\n", strerror(errno));
+               err("mknod failed: %s", strerror(errno));
                return -1;
        }
        return 0;
 }
 
-static int has_sysfs_prefix(const char *path, const char *prefix)
-{
-       char match[MAX_NAME_LEN];
-
-       strncpy(match, sysfs_mnt_path, MAX_NAME_LEN);
-       strncat(match, prefix, MAX_NAME_LEN);
-       if (strncmp(path, match, strlen(match)) == 0)
-               return 1;
-       else
-               return 0;
-}
-
 /*
  * get_value:
  *
@@ -289,8 +241,8 @@ static int argc_count(char *opts)
  *
  * vendor and model can end in '\n'.
  */
-static int get_file_options(char *vendor, char *model, int *argc,
-                           char ***newargv)
+static int get_file_options(const char *vendor, const char *model,
+                           int *argc, char ***newargv)
 {
        char *buffer;
        FILE *fd;
@@ -301,15 +253,14 @@ static int get_file_options(char *vendor, char *model, int *argc,
        int c;
        int retval = 0;
 
-       dprintf("vendor='%s'; model='%s'\n", vendor, model);
+       dbg("vendor='%s'; model='%s'\n", vendor, model);
        fd = fopen(config_file, "r");
        if (fd == NULL) {
-               dprintf("can't open %s\n", config_file);
+               dbg("can't open %s\n", config_file);
                if (errno == ENOENT) {
                        return 1;
                } else {
-                       log_message(LOG_WARNING, "can't open %s: %s\n",
-                               config_file, strerror(errno));
+                       err("can't open %s: %s", config_file, strerror(errno));
                        return -1;
                }
        }
@@ -321,7 +272,7 @@ static int get_file_options(char *vendor, char *model, int *argc,
         */
        buffer = malloc(MAX_BUFFER_LEN);
        if (!buffer) {
-               log_message(LOG_WARNING, "Can't allocate memory.\n");
+               err("Can't allocate memory.");
                return -1;
        }
 
@@ -335,29 +286,22 @@ static int get_file_options(char *vendor, char *model, int *argc,
                        break;
                lineno++;
                if (buf[strlen(buffer) - 1] != '\n') {
-                       log_message(LOG_WARNING,
-                                   "Config file line %d too long.\n", lineno);
+                       info("Config file line %d too long.\n", lineno);
                        break;
                }
 
                while (isspace(*buf))
                        buf++;
 
+               /* blank or all whitespace line */
                if (*buf == '\0')
-                       /*
-                        * blank or all whitespace line
-                        */
                        continue;
 
+               /* comment line */
                if (*buf == '#')
-                       /*
-                        * comment line
-                        */
                        continue;
 
-#ifdef LOTS
-               dprintf("lineno %d: '%s'\n", lineno, buf);
-#endif
+               dbg("lineno %d: '%s'\n", lineno, buf);
                str1 = strsep(&buf, "=");
                if (str1 && strcasecmp(str1, "VENDOR") == 0) {
                        str1 = get_value(&buf);
@@ -387,22 +331,20 @@ static int get_file_options(char *vendor, char *model, int *argc,
                        }
                        options_in = str1;
                }
-               dprintf("config file line %d:"
+               dbg("config file line %d:"
                        " vendor '%s'; model '%s'; options '%s'\n",
                        lineno, vendor_in, model_in, options_in);
                /*
                 * Only allow: [vendor=foo[,model=bar]]options=stuff
                 */
                if (!options_in || (!vendor_in && model_in)) {
-                       log_message(LOG_WARNING,
-                                   "Error parsing config file line %d '%s'\n",
-                                   lineno, buffer);
+                       info("Error parsing config file line %d '%s'", lineno, buffer);
                        retval = -1;
                        break;
                }
                if (vendor == NULL) {
                        if (vendor_in == NULL) {
-                               dprintf("matched global option\n");
+                               dbg("matched global option\n");
                                break;
                        }
                } else if ((vendor_in && strncmp(vendor, vendor_in,
@@ -416,10 +358,10 @@ static int get_file_options(char *vendor, char *model, int *argc,
                                 * give a partial match (that is FOO
                                 * matches FOOBAR).
                                 */
-                               dprintf("matched vendor/model\n");
+                               dbg("matched vendor/model\n");
                                break;
                } else {
-                       dprintf("no match\n");
+                       dbg("no match\n");
                }
        }
 
@@ -434,8 +376,7 @@ static int get_file_options(char *vendor, char *model, int *argc,
                        c = argc_count(buffer) + 2;
                        *newargv = calloc(c, sizeof(**newargv));
                        if (!*newargv) {
-                               log_message(LOG_WARNING,
-                                           "Can't allocate memory.\n");
+                               err("Can't allocate memory.");
                                retval = -1;
                        } else {
                                *argc = c;
@@ -450,9 +391,7 @@ static int get_file_options(char *vendor, char *model, int *argc,
                                        (*newargv)[c] = strsep(&buffer, " ");
                        }
                } else {
-                       /*
-                        * No matches.
-                        */
+                       /* No matches  */
                        retval = 1;
                }
        }
@@ -480,9 +419,9 @@ static int set_options(int argc, char **argv, const char *short_opts,
                        break;
 
                if (optarg)
-                       dprintf("option '%c' arg '%s'\n", option, optarg);
+                       dbg("option '%c' arg '%s'\n", option, optarg);
                else
-                       dprintf("option '%c'\n", option);
+                       dbg("option '%c'\n", option);
 
                switch (option) {
                case 'a':
@@ -492,10 +431,6 @@ static int set_options(int argc, char **argv, const char *short_opts,
                        all_good = 0;
                        break;
 
-               case 'c':
-                       default_callout = optarg;
-                       break;
-
                case 'd':
                        dev_specified = 1;
                        strncpy(maj_min_dev, optarg, MAX_NAME_LEN);
@@ -525,16 +460,15 @@ static int set_options(int argc, char **argv, const char *short_opts,
                        } else if (strcmp(optarg, "pre-spc3-83") == 0) {
                                default_page_code = PAGE_83_PRE_SPC3; 
                        } else {
-                               log_message(LOG_WARNING,
-                                           "Unknown page code '%s'\n", optarg);
+                               info("Unknown page code '%s'", optarg);
                                return -1;
                        }
                        break;
 
                case 's':
                        sys_specified = 1;
-                       strncpy(target, sysfs_mnt_path, MAX_NAME_LEN);
-                       strncat(target, optarg, MAX_NAME_LEN);
+                       strncpy(target, optarg, MAX_NAME_LEN);
+                       target[MAX_NAME_LEN-1] = '\0';
                        break;
 
                case 'u':
@@ -550,71 +484,58 @@ static int set_options(int argc, char **argv, const char *short_opts,
                        break;
 
                case 'V':
-                       log_message(LOG_WARNING, "scsi_id version: %s\n",
-                                   SCSI_ID_VERSION);
+                       info("scsi_id version: %s\n", SCSI_ID_VERSION);
                        exit(0);
                        break;
 
                default:
-                       log_message(LOG_WARNING,
-                                   "Unknown or bad option '%c' (0x%x)\n",
-                                   option, option);
+                       info("Unknown or bad option '%c' (0x%x)", option, option);
                        return -1;
                }
        }
        return 0;
 }
 
-static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad,
-                          int *page_code, char *callout)
+static int per_dev_options(struct sysfs_device *dev_scsi, int *good_bad, int *page_code)
 {
        int retval;
        int newargc;
        char **newargv = NULL;
-       struct sysfs_attribute *vendor, *model, *type;
+       const char *vendor, *model, *type;
        int option;
 
        *good_bad = all_good;
        *page_code = default_page_code;
-       if (default_callout && (callout != default_callout))
-               strncpy(callout, default_callout, MAX_NAME_LEN);
-       else
-               callout[0] = '\0';
 
-       vendor = sysfs_get_device_attr(scsi_dev, "vendor");
+       vendor = sysfs_attr_get_value(dev_scsi->devpath, "vendor");
        if (!vendor) {
-               log_message(LOG_WARNING, "%s: cannot get vendor attribute\n",
-                           scsi_dev->name);
+               info("%s: cannot get vendor attribute", dev_scsi->devpath);
                return -1;
        }
-       set_str(vendor_str, vendor->value, sizeof(vendor_str)-1);
+       set_str(vendor_str, vendor, sizeof(vendor_str)-1);
 
-       model = sysfs_get_device_attr(scsi_dev, "model");
+       model = sysfs_attr_get_value(dev_scsi->devpath, "model");
        if (!model) {
-               log_message(LOG_WARNING, "%s: cannot get model attribute\n",
-                           scsi_dev->name);
+               info("%s: cannot get model attribute\n", dev_scsi->devpath);
                return -1;
        }
-       set_str(model_str, model->value, sizeof(model_str)-1);
+       set_str(model_str, model, sizeof(model_str)-1);
 
-       type = sysfs_get_device_attr(scsi_dev, "type");
+       type = sysfs_attr_get_value(dev_scsi->devpath, "type");
        if (!type) {
-               log_message(LOG_WARNING, "%s: cannot get type attribute\n",
-                           scsi_dev->name);
+               info("%s: cannot get type attribute", dev_scsi->devpath);
                return -1;
        }
-       set_type(type_str, type->value, sizeof(type_str));
+       set_type(type_str, type, sizeof(type_str));
 
-       type = sysfs_get_device_attr(scsi_dev, "rev");
+       type = sysfs_attr_get_value(dev_scsi->devpath, "rev");
        if (!type) {
-               log_message(LOG_WARNING, "%s: cannot get type attribute\n",
-                           scsi_dev->name);
+               info("%s: cannot get type attribute\n", dev_scsi->devpath);
                return -1;
        }
-       set_str(revision_str, type->value, sizeof(revision_str)-1);
+       set_str(revision_str, type, sizeof(revision_str)-1);
 
-       retval = get_file_options(vendor->value, model->value, &newargc,
-                                 &newargv);
+       retval = get_file_options(vendor, model, &newargc, &newargv);
 
        optind = 1; /* reset this global extern */
        while (retval == 0) {
@@ -623,19 +544,15 @@ static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad,
                        break;
 
                if (optarg)
-                       dprintf("option '%c' arg '%s'\n", option, optarg);
+                       dbg("option '%c' arg '%s'\n", option, optarg);
                else
-                       dprintf("option '%c'\n", option);
+                       dbg("option '%c'\n", option);
 
                switch (option) {
                case 'b':
                        *good_bad = 0;
                        break;
 
-               case 'c':
-                       strncpy(callout, default_callout, MAX_NAME_LEN);
-                       break;
-
                case 'g':
                        *good_bad = 1;
                        break;
@@ -648,16 +565,13 @@ static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad,
                        } else if (strcmp(optarg, "pre-spc3-83") == 0) {
                                *page_code = PAGE_83_PRE_SPC3; 
                        } else {
-                               log_message(LOG_WARNING,
-                                           "Unknown page code '%s'\n", optarg);
+                               info("Unknown page code '%s'", optarg);
                                retval = -1;
                        }
                        break;
 
                default:
-                       log_message(LOG_WARNING,
-                                   "Unknown or bad option '%c' (0x%x)\n",
-                                   option, option);
+                       info("Unknown or bad option '%c' (0x%x)", option, option);
                        retval = -1;
                        break;
                }
@@ -702,129 +616,62 @@ static void format_serial(char *serial)
  * memory etc. return 2, and return 1 for expected cases (like broken
  * device found) that do not print an id.
  */
-static int scsi_id(const char *target_path, char *maj_min_dev)
+static int scsi_id(const char *devpath, char *maj_min_dev)
 {
        int retval;
        int dev_type = 0;
        char *serial, *unaligned_buf;
-       struct sysfs_class_device *class_dev; /* of target_path */
-       struct sysfs_class_device *class_dev_parent; /* for partitions */
-       struct sysfs_device *scsi_dev; /* the scsi_device */
+       struct sysfs_device *dev;
+       struct sysfs_device *dev_scsi;
        int good_dev;
        int page_code;
-       char callout[MAX_NAME_LEN];
-
-       dprintf("target_path %s\n", target_path);
 
-       /*
-        * Ugly: depend on the sysfs path to tell us whether this is a
-        * block or char device. This should probably be encoded in the
-        * "dev" along with the major/minor.
-        */
-       if (has_sysfs_prefix(target_path, "/block")) {
-               dev_type = S_IFBLK;
-       } else if (has_sysfs_prefix(target_path, "/class")) {
-               dev_type = S_IFCHR;
-       } else {
-               if (!hotplug_mode) {
-                       log_message(LOG_WARNING,
-                                   "Non block or class device '%s'\n",
-                                   target_path);
-                       return 1;
-               } else {
-                       /*
-                        * Expected in some cases.
-                        */
-                       dprintf("Non block or class device\n");
-                       return 0;
-               }
-       }
+       dbg("devpath %s\n", devpath);
 
-       class_dev = sysfs_open_class_device_path(target_path);
-       if (!class_dev) {
-               log_message(LOG_WARNING, "open class %s failed: %s\n",
-                           target_path, strerror(errno));
+       dev = sysfs_device_get(devpath);
+       if (dev == NULL) {
+               err("unable to access '%s'", devpath);
                return 1;
        }
-       class_dev_parent = sysfs_get_classdev_parent(class_dev);
-       dprintf("class_dev 0x%p; class_dev_parent 0x%p\n", class_dev,
-               class_dev_parent);
-       if (class_dev_parent) {
-               scsi_dev = sysfs_get_classdev_device(class_dev_parent);
-       } else {
-               scsi_dev = sysfs_get_classdev_device(class_dev);
-       }
 
-       /*
-        * The close of scsi_dev will close class_dev or class_dev_parent.
-        */
+       if (strcmp(dev->subsystem, "block") == 0)
+               dev_type = S_IFBLK;
+       else
+               dev_type = S_IFCHR;
 
-       /*
-        * We assume we are called after the device is completely ready,
-        * so we don't have to loop here like udev. (And we are usually
-        * called via udev.)
-        */
-       if (!scsi_dev) {
-               /*
-                * errno is not set if we can't find the device link, so
-                * don't print it out here.
-                */
-               log_message(LOG_WARNING, "Cannot find sysfs device associated with %s\n",
-                           target_path);
+       /* get scsi parent device */
+       dev_scsi = sysfs_device_get_parent(dev);
+       if (dev_scsi == NULL) {
+               err("unable to access parent device of '%s'", devpath);
                return 1;
        }
 
-
-       /*
-        * Allow only scsi devices.
-        *
-        * Other block devices can support SG IO, but only ide-cd does, so
-        * for now, don't bother with anything else.
-        */
-       if (strcmp(scsi_dev->bus, "scsi") != 0) {
-               if (hotplug_mode)
-                       /*
-                        * Expected in some cases.
-                        */
-                       dprintf("%s is not a scsi device\n", target_path);
-               else
-                       log_message(LOG_WARNING, "%s is not a scsi device\n",
-                                   target_path);
+       /* allow only scsi devices */
+       if (strcmp(dev_scsi->subsystem, "scsi") != 0) {
+               info("%s is not a scsi device", devpath);
                return 1;
        }
 
-       /*
-        * mknod a temp dev to communicate with the device.
-        */
-       if (!dev_specified && create_tmp_dev(class_dev, maj_min_dev,
-                                            dev_type)) {
-               dprintf("create_tmp_dev failed\n");
+       /* mknod a temp dev to communicate with the device */
+       if (!dev_specified && create_tmp_dev(dev->devpath, maj_min_dev, dev_type)) {
+               dbg("create_tmp_dev failed\n");
                return 1;
        }
 
-       /*
-        * Get any per device (vendor + model) options from the config
-        * file.
-        */
-       retval = per_dev_options(scsi_dev, &good_dev, &page_code, callout);
-       dprintf("per dev options: good %d; page code 0x%x; callout '%s'\n",
-               good_dev, page_code, callout);
+       /* get per device (vendor + model) options from the config file */
+       retval = per_dev_options(dev_scsi, &good_dev, &page_code);
+       dbg("per dev options: good %d; page code 0x%x", good_dev, page_code);
 
 #define ALIGN   512
        unaligned_buf = malloc(MAX_SERIAL_LEN + ALIGN);
        serial = (char*) (((unsigned long) unaligned_buf + (ALIGN - 1))
                          & ~(ALIGN - 1));
-       dprintf("buffer unaligned 0x%p; aligned 0x%p\n", unaligned_buf, serial);
+       dbg("buffer unaligned 0x%p; aligned 0x%p\n", unaligned_buf, serial);
 #undef ALIGN
 
        if (!good_dev) {
                retval = 1;
-       } else if (callout[0] != '\0') {
-               /*
-                * XXX Disabled for now ('c' is not in any options[]).
-                */
-               retval = 1;
-       } else if (scsi_get_serial(scsi_dev, maj_min_dev, page_code,
+       } else if (scsi_get_serial(dev_scsi, maj_min_dev, page_code,
                                   serial, MAX_SERIAL_LEN)) {
                retval = always_info?0:1;
        } else {
@@ -844,13 +691,12 @@ static int scsi_id(const char *target_path, char *maj_min_dev)
                        if (reformat_serial)
                                format_serial(serial);
                        if (display_bus_id)
-                               printf("%s: ", scsi_dev->name);
+                               printf("%s: ", dev_scsi->kernel_name);
                        printf("%s\n", serial);
                }
-               dprintf("%s\n", serial);
+               dbg("%s\n", serial);
                retval = 0;
        }
-       sysfs_close_device(scsi_dev);
 
        if (!dev_specified)
                unlink(maj_min_dev);
@@ -860,32 +706,31 @@ static int scsi_id(const char *target_path, char *maj_min_dev)
 
 int main(int argc, char **argv)
 {
-       int retval;
-       char *devpath;
-       char target_path[MAX_NAME_LEN];
+       int retval = 0;
+       char devpath[MAX_NAME_LEN];
        char maj_min_dev[MAX_NAME_LEN];
        int newargc;
+       const char *env;
        char **newargv;
 
-       if (getenv("DEBUG"))
-               debug++;
+       logging_init("scsi_id");
+       sysfs_init();
+       dbg("argc is %d\n", argc);
 
-       dprintf("argc is %d\n", argc);
-       if (sysfs_get_mnt_path(sysfs_mnt_path, MAX_NAME_LEN)) {
-               log_message(LOG_WARNING, "sysfs_get_mnt_path failed: %s\n",
-                       strerror(errno));
-               exit(1);
-       }
+       /* sysfs path can be overridden for testing */
+       env = getenv("SYSFS_PATH");
+       if (env) {
+               strncpy(sysfs_path, env, sizeof(sysfs_path));
+               sysfs_path[sizeof(sysfs_path)-1] = '\0';
+       } else
+               strcpy(sysfs_path, "/sys");
 
-       devpath = getenv("DEVPATH");
-       if (devpath) {
-               /*
-                * This implies that we were invoked via udev or hotplug.
-                */
+       env = getenv("DEVPATH");
+       if (env) {
                hotplug_mode = 1;
                sys_specified = 1;
-               strncpy(target_path, sysfs_mnt_path, MAX_NAME_LEN);
-               strncat(target_path, devpath, MAX_NAME_LEN);
+               strncpy(devpath, env, MAX_NAME_LEN);
+               devpath[sizeof(devpath)-1] = '\0';
        }
 
        /*
@@ -894,26 +739,35 @@ int main(int argc, char **argv)
        newargv = NULL;
        retval = get_file_options(NULL, NULL, &newargc, &newargv);
        if (retval < 0) {
-               exit(1);
-       } else if (newargv && (retval == 0)) {
-               if (set_options(newargc, newargv, short_options, target_path,
-                               maj_min_dev) < 0)
-                       exit(1);
+               retval = 1;
+               goto exit;
+       }
+       if (newargv && (retval == 0)) {
+               if (set_options(newargc, newargv, short_options, devpath,
+                               maj_min_dev) < 0) {
+                       retval = 2;
+                       goto exit;
+               }
                free(newargv);
        }
+
        /*
         * Get command line options (overriding any config file or DEVPATH
         * settings).
         */
-       if (set_options(argc, argv, short_options, target_path,
-                       maj_min_dev) < 0)
+       if (set_options(argc, argv, short_options, devpath, maj_min_dev) < 0)
                exit(1);
 
        if (!sys_specified) {
-               log_message(LOG_WARNING, "-s must be specified\n");
-               exit(1);
+               info("-s must be specified\n");
+               retval = 1;
+               goto exit;
        }
 
-       retval = scsi_id(target_path, maj_min_dev);
-       exit(retval);
+       retval = scsi_id(devpath, maj_min_dev);
+
+exit:
+       sysfs_cleanup();
+       logging_close();
+       return retval;
 }
index 1c9ed96..b5312b8 100644 (file)
@@ -21,9 +21,6 @@
  *  USA
  */
 
-#define dprintf(format, arg...) \
-       log_message(LOG_DEBUG, "%s: " format, __FUNCTION__ , ## arg)
-
 #define        MAX_NAME_LEN    72
 
 /*
  */
 #define MAX_BUFFER_LEN 256
 
-extern int scsi_get_serial (struct sysfs_device *scsi_dev, const char
-                           *devname, int page_code, char *serial, int
-                           len);
-extern void log_message (int level, const char *format, ...)
-       __attribute__ ((format (printf, 2, 3)));
-
-#ifndef u8
-typedef unsigned char u8;
-#endif
+extern int scsi_get_serial (struct sysfs_device *dev_scsi, const char *devname,
+                           int page_code, char *serial, int len);
 
 /*
  * Page code values. 
index 14955e6..bdebe94 100644 (file)
 #include <stdlib.h>
 #include <unistd.h>
 #include <syslog.h>
-#include <linux/compiler.h> /* need __user when built via klibc */
 #include <scsi/sg.h>
-#include <sysfs/libsysfs.h>
-#include "scsi_id.h"
+
+#include "../../udev.h"
 #include "scsi.h"
+#include "scsi_id.h"
+#include "scsi_id_version.h"
 
 /*
  * A priority based list of id, naa, and binary/ascii for the identifier
@@ -75,23 +76,21 @@ static const char hex_str[]="0123456789abcdef";
  * are used here.
  */
 
-#define DID_NO_CONNECT 0x01     /* Unable to connect before timeout */
-
-#define DID_BUS_BUSY 0x02       /* Bus remain busy until timeout */
-#define DID_TIME_OUT 0x03       /* Timed out for some other reason */
-
-#define DRIVER_TIMEOUT 0x06
-#define DRIVER_SENSE 0x08       /* Sense_buffer has been set */
+#define DID_NO_CONNECT                 0x01    /* Unable to connect before timeout */
+#define DID_BUS_BUSY                   0x02    /* Bus remain busy until timeout */
+#define DID_TIME_OUT                   0x03    /* Timed out for some other reason */
+#define DRIVER_TIMEOUT                 0x06
+#define DRIVER_SENSE                   0x08    /* Sense_buffer has been set */
 
 /* The following "category" function returns one of the following */
-#define SG_ERR_CAT_CLEAN       0      /* No errors or other information */
-#define SG_ERR_CAT_MEDIA_CHANGED       1 /* interpreted from sense buffer */
-#define SG_ERR_CAT_RESET       2      /* interpreted from sense buffer */
-#define SG_ERR_CAT_TIMEOUT     3
-#define SG_ERR_CAT_RECOVERED   4  /* Successful command after recovered err */
-#define SG_ERR_CAT_NOTSUPPORTED 5 /* Illegal / unsupported command */
-#define SG_ERR_CAT_SENSE       98     /* Something else in the sense buffer */
-#define SG_ERR_CAT_OTHER       99     /* Some other error/warning */
+#define SG_ERR_CAT_CLEAN               0       /* No errors or other information */
+#define SG_ERR_CAT_MEDIA_CHANGED       1       /* interpreted from sense buffer */
+#define SG_ERR_CAT_RESET               2       /* interpreted from sense buffer */
+#define SG_ERR_CAT_TIMEOUT             3
+#define SG_ERR_CAT_RECOVERED           4       /* Successful command after recovered err */
+#define SG_ERR_CAT_NOTSUPPORTED        5       /* Illegal / unsupported command */
+#define SG_ERR_CAT_SENSE               98      /* Something else in the sense buffer */
+#define SG_ERR_CAT_OTHER               99      /* Some other error/warning */
 
 static int sg_err_category_new(int scsi_status, int msg_status, int
                               host_status, int driver_status, const
@@ -157,7 +156,7 @@ static int sg_err_category3(struct sg_io_hdr *hp)
                                   hp->sbp, hp->sb_len_wr);
 }
 
-static int scsi_dump_sense(struct sysfs_device *scsi_dev, struct sg_io_hdr *io)
+static int scsi_dump_sense(struct sysfs_device *dev_scsi, struct sg_io_hdr *io)
 {
        unsigned char *sense_buffer;
        int s;
@@ -184,12 +183,11 @@ static int scsi_dump_sense(struct sysfs_device *scsi_dev, struct sg_io_hdr *io)
         * we'll retry the command.
         */
 
-       dprintf("got check condition\n");
+       dbg("got check condition\n");
 
        sb_len = io->sb_len_wr;
        if (sb_len < 1) {
-               log_message(LOG_WARNING, "%s: sense buffer empty\n",
-                           scsi_dev->name);
+               info("%s: sense buffer empty", dev_scsi->kernel_name);
                return -1;
        }
 
@@ -203,10 +201,8 @@ static int scsi_dump_sense(struct sysfs_device *scsi_dev, struct sg_io_hdr *io)
                 */
                s = sense_buffer[7] + 8;
                if (sb_len < s) {
-                       log_message(LOG_WARNING,
-                                   "%s: sense buffer too small %d bytes,"
-                                   " %d bytes too short\n", scsi_dev->name,
-                                   sb_len, s - sb_len);
+                       info("%s: sense buffer too small %d bytes, %d bytes too short",
+                           dev_scsi->kernel_name, sb_len, s - sb_len);
                        return -1;
                }
                if ((code == 0x0) || (code == 0x1)) {
@@ -216,9 +212,8 @@ static int scsi_dump_sense(struct sysfs_device *scsi_dev, struct sg_io_hdr *io)
                                /*
                                 * Possible?
                                 */
-                               log_message(LOG_WARNING, "%s: sense result too"
-                                           " small %d bytes\n",
-                                           scsi_dev->name, s);
+                               info("%s: sense result too" " small %d bytes",
+                                   dev_scsi->kernel_name, s);
                                return -1;
                        }
                        asc = sense_buffer[12];
@@ -229,72 +224,64 @@ static int scsi_dump_sense(struct sysfs_device *scsi_dev, struct sg_io_hdr *io)
                        asc = sense_buffer[2];
                        ascq = sense_buffer[3];
                } else {
-                       log_message(LOG_WARNING,
-                                   "%s: invalid sense code 0x%x\n",
-                                   scsi_dev->name, code);
+                       info("%s: invalid sense code 0x%x",
+                           dev_scsi->kernel_name, code);
                        return -1;
                }
-               log_message(LOG_WARNING,
-                           "%s: sense key 0x%x ASC 0x%x ASCQ 0x%x\n",
-                           scsi_dev->name, sense_key, asc, ascq);
+               info("%s: sense key 0x%x ASC 0x%x ASCQ 0x%x",
+                   dev_scsi->kernel_name, sense_key, asc, ascq);
        } else {
                if (sb_len < 4) {
-                       log_message(LOG_WARNING,
-                                   "%s: sense buffer too small %d bytes, %d bytes too short\n",
-                                   scsi_dev->name, sb_len, 4 - sb_len);
+                       info("%s: sense buffer too small %d bytes, %d bytes too short",
+                           dev_scsi->kernel_name, sb_len, 4 - sb_len);
                        return -1;
                }
 
                if (sense_buffer[0] < 15)
-                       log_message(LOG_WARNING, "%s: old sense key: 0x%x\n",
-                                   scsi_dev->name, sense_buffer[0] & 0x0f);
+                       info("%s: old sense key: 0x%x", dev_scsi->kernel_name, sense_buffer[0] & 0x0f);
                else
-                       log_message(LOG_WARNING, "%s: sense = %2x %2x\n",
-                                   scsi_dev->name,  sense_buffer[0],
-                                   sense_buffer[2]);
-               log_message(LOG_WARNING,
-                           "%s: non-extended sense class %d code 0x%0x\n",
-                           scsi_dev->name, sense_class, code);
+                       info("%s: sense = %2x %2x",
+                           dev_scsi->kernel_name, sense_buffer[0], sense_buffer[2]);
+               info("%s: non-extended sense class %d code 0x%0x",
+                   dev_scsi->kernel_name, sense_class, code);
 
        }
 
 #ifdef DUMP_SENSE
        for (i = 0, j = 0; (i < s) && (j < 254); i++) {
-               dprintf("i %d, j %d\n", i, j);
+               dbg("i %d, j %d\n", i, j);
                out_buffer[j++] = hex_str[(sense_buffer[i] & 0xf0) >> 4];
                out_buffer[j++] = hex_str[sense_buffer[i] & 0x0f];
                out_buffer[j++] = ' ';
        }
        out_buffer[j] = '\0';
-       log_message(LOG_WARNING, "%s: sense dump:\n", scsi_dev->name);
-       log_message(LOG_WARNING, "%s: %s\n", scsi_dev->name, out_buffer);
+       info("%s: sense dump:", dev_scsi->kernel_name);
+       info("%s: %s", dev_scsi->kernel_name, out_buffer);
 
 #endif
        return -1;
 }
 
-static int scsi_dump(struct sysfs_device *scsi_dev, struct sg_io_hdr *io)
+static int scsi_dump(struct sysfs_device *dev_scsi, struct sg_io_hdr *io)
 {
        if (!io->status && !io->host_status && !io->msg_status &&
            !io->driver_status) {
                /*
                 * Impossible, should not be called.
                 */
-               log_message(LOG_WARNING, "%s: called with no error\n",
-                           __FUNCTION__);
+               info("%s: called with no error", __FUNCTION__);
                return -1;
        }
 
-       log_message(LOG_WARNING, "%s: sg_io failed status 0x%x 0x%x 0x%x 0x%x\n",
-                   scsi_dev->name, io->driver_status, io->host_status,
-                   io->msg_status, io->status);
+       info("%s: sg_io failed status 0x%x 0x%x 0x%x 0x%x",
+           dev_scsi->kernel_name, io->driver_status, io->host_status, io->msg_status, io->status);
        if (io->status == SCSI_CHECK_CONDITION)
-               return scsi_dump_sense(scsi_dev, io);
+               return scsi_dump_sense(dev_scsi, io);
        else
                return -1;
 }
 
-static int scsi_inquiry(struct sysfs_device *scsi_dev, int fd,
+static int scsi_inquiry(struct sysfs_device *dev_scsi, int fd,
                        unsigned char evpd, unsigned char page,
                        unsigned char *buf, unsigned int buflen)
 {
@@ -306,12 +293,12 @@ static int scsi_inquiry(struct sysfs_device *scsi_dev, int fd,
        int retry = 3; /* rather random */
 
        if (buflen > SCSI_INQ_BUFF_LEN) {
-               log_message(LOG_WARNING, "buflen %d too long\n", buflen);
+               info("buflen %d too long", buflen);
                return -1;
        }
 
 resend:
-       dprintf("%s evpd %d, page 0x%x\n", scsi_dev->name, evpd, page);
+       dbg("%s evpd %d, page 0x%x\n", dev_scsi->kernel_name, evpd, page);
 
        memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
        io_hdr.interface_id = 'S';
@@ -325,8 +312,7 @@ resend:
        io_hdr.timeout = DEF_TIMEOUT;
 
        if (ioctl(fd, SG_IO, &io_hdr) < 0) {
-               log_message(LOG_WARNING, "%s: ioctl failed: %s\n",
-                           scsi_dev->name, strerror(errno));
+               info("%s: ioctl failed: %s", dev_scsi->kernel_name, strerror(errno));
                retval = -1;
                goto error;
        }
@@ -343,14 +329,14 @@ resend:
                        break;
 
                default:
-                       retval = scsi_dump(scsi_dev, &io_hdr);
+                       retval = scsi_dump(dev_scsi, &io_hdr);
        }
 
        if (!retval) {
                retval = buflen;
        } else if (retval > 0) {
                if (--retry > 0) {
-                       dprintf("%s: Retrying ...\n", scsi_dev->name);
+                       dbg("%s: Retrying ...\n", dev_scsi->kernel_name);
                        goto resend;
                }
                retval = -1;
@@ -358,33 +344,30 @@ resend:
 
 error:
        if (retval < 0)
-               log_message(LOG_WARNING,
-                           "%s: Unable to get INQUIRY vpd %d page 0x%x.\n",
-                           scsi_dev->name, evpd, page);
+               info("%s: Unable to get INQUIRY vpd %d page 0x%x.",
+                   dev_scsi->kernel_name, evpd, page);
 
        return retval;
 }
 
 /* Get list of supported EVPD pages */
-static int do_scsi_page0_inquiry(struct sysfs_device *scsi_dev, int fd,
+static int do_scsi_page0_inquiry(struct sysfs_device *dev_scsi, int fd,
                                 unsigned char *buffer, unsigned int len)
 {
        int retval;
-       struct sysfs_attribute *vendor;
+       const char *vendor;
 
        memset(buffer, 0, len);
-       retval = scsi_inquiry(scsi_dev, fd, 1, 0x0, buffer, len);
+       retval = scsi_inquiry(dev_scsi, fd, 1, 0x0, buffer, len);
        if (retval < 0)
                return 1;
 
        if (buffer[1] != 0) {
-               log_message(LOG_WARNING, "%s: page 0 not available.\n",
-                           scsi_dev->name);
+               info("%s: page 0 not available.", dev_scsi->kernel_name);
                return 1;
        }
        if (buffer[3] > len) {
-               log_message(LOG_WARNING, "%s: page 0 buffer too long %d\n",
-                          scsi_dev->name,  buffer[3]);
+               info("%s: page 0 buffer too long %d", dev_scsi->kernel_name,  buffer[3]);
                return 1;
        }
 
@@ -400,17 +383,13 @@ static int do_scsi_page0_inquiry(struct sysfs_device *scsi_dev, int fd,
                 * If the vendor id appears in the page assume the page is
                 * invalid.
                 */
-               vendor = sysfs_get_device_attr(scsi_dev, "vendor");
+               vendor = sysfs_attr_get_value(dev_scsi->devpath, "vendor");
                if (!vendor) {
-                       log_message(LOG_WARNING,
-                                   "%s: cannot get model attribute\n",
-                                   scsi_dev->name);
+                       info("%s: cannot get model attribute", dev_scsi->kernel_name);
                        return 1;
                }
-               if (!strncmp((char *)&buffer[VENDOR_LENGTH], vendor->value,
-                            VENDOR_LENGTH)) {
-                       log_message(LOG_WARNING, "%s: invalid page0 data\n",
-                                   scsi_dev->name);
+               if (!strncmp((char *)&buffer[VENDOR_LENGTH], vendor, VENDOR_LENGTH)) {
+                       info("%s: invalid page0 data", dev_scsi->kernel_name);
                        return 1;
                }
        }
@@ -421,46 +400,35 @@ static int do_scsi_page0_inquiry(struct sysfs_device *scsi_dev, int fd,
  * The caller checks that serial is long enough to include the vendor +
  * model.
  */
-static int prepend_vendor_model(struct sysfs_device *scsi_dev, char *serial)
+static int prepend_vendor_model(struct sysfs_device *dev_scsi, char *serial)
 {
-       struct sysfs_attribute *attr;
+       const char *attr;
        int ind;
 
-       attr = sysfs_get_device_attr(scsi_dev, "vendor");
+       attr = sysfs_attr_get_value(dev_scsi->devpath, "vendor");
        if (!attr) {
-               log_message(LOG_WARNING, "%s: cannot get vendor attribute\n",
-                           scsi_dev->name);
+               info("%s: cannot get vendor attribute", dev_scsi->kernel_name);
                return 1;
        }
-       strncpy(serial, attr->value, VENDOR_LENGTH);
+       strncpy(serial, attr, VENDOR_LENGTH);
        ind = strlen(serial) - 1;
-       /*
-        * Remove sysfs added newlines.
-        */
-       if (serial[ind] == '\n')
-               serial[ind] = '\0';
 
-       attr = sysfs_get_device_attr(scsi_dev, "model");
+       attr = sysfs_attr_get_value(dev_scsi->devpath, "model");
        if (!attr) {
-               log_message(LOG_WARNING, "%s: cannot get model attribute\n",
-                           scsi_dev->name);
+               info("%s: cannot get model attribute", dev_scsi->kernel_name);
                return 1;
        }
-       strncat(serial, attr->value, MODEL_LENGTH);
+       strncat(serial, attr, MODEL_LENGTH);
        ind = strlen(serial) - 1;
-       if (serial[ind] == '\n')
-               serial[ind] = '\0';
-       else
-               ind++;
+       ind++;
 
        /*
         * This is not a complete check, since we are using strncat/cpy
         * above, ind will never be too large.
         */
        if (ind != (VENDOR_LENGTH + MODEL_LENGTH)) {
-               log_message(LOG_WARNING, "%s: expected length %d, got length %d\n",
-                           scsi_dev->name, (VENDOR_LENGTH + MODEL_LENGTH),
-                           ind);
+               info("%s: expected length %d, got length %d",
+                    dev_scsi->kernel_name, (VENDOR_LENGTH + MODEL_LENGTH), ind);
                return 1;
        }
        return ind;
@@ -470,7 +438,7 @@ static int prepend_vendor_model(struct sysfs_device *scsi_dev, char *serial)
  * check_fill_0x83_id - check the page 0x83 id, if OK allocate and fill
  * serial number.
  **/
-static int check_fill_0x83_id(struct sysfs_device *scsi_dev,
+static int check_fill_0x83_id(struct sysfs_device *dev_scsi,
                              unsigned char *page_83,
                              const struct scsi_id_search_values
                              *id_search, char *serial, int max_len)
@@ -517,8 +485,8 @@ static int check_fill_0x83_id(struct sysfs_device *scsi_dev,
                len += VENDOR_LENGTH + MODEL_LENGTH;
 
        if (max_len < len) {
-               log_message(LOG_WARNING, "%s: length %d too short - need %d\n",
-                           scsi_dev->name, max_len, len);
+               info("%s: length %d too short - need %d",
+                   dev_scsi->kernel_name, max_len, len);
                return 1;
        }
 
@@ -531,8 +499,8 @@ static int check_fill_0x83_id(struct sysfs_device *scsi_dev,
         * included in the identifier.
         */
        if (id_search->id_type == SCSI_ID_VENDOR_SPECIFIC)
-               if (prepend_vendor_model(scsi_dev, &serial[1]) < 0) {
-                       dprintf("prepend failed\n");
+               if (prepend_vendor_model(dev_scsi, &serial[1]) < 0) {
+                       dbg("prepend failed\n");
                        return 1;
                }
 
@@ -559,7 +527,7 @@ static int check_fill_0x83_id(struct sysfs_device *scsi_dev,
 }
 
 /* Extract the raw binary from VPD 0x83 pre-SPC devices */
-static int check_fill_0x83_prespc3(struct sysfs_device *scsi_dev,
+static int check_fill_0x83_prespc3(struct sysfs_device *dev_scsi,
                                   unsigned char *page_83,
                                   const struct scsi_id_search_values
                                   *id_search, char *serial, int max_len)
@@ -574,13 +542,13 @@ static int check_fill_0x83_prespc3(struct sysfs_device *scsi_dev,
                serial[j++] = hex_str[(page_83[4+i] & 0xf0) >> 4];
                serial[j++] = hex_str[ page_83[4+i] & 0x0f];
        }
-       dprintf("using pre-spc3-83 for %s.\n", scsi_dev->name);
+       dbg("using pre-spc3-83 for %s.\n", dev_scsi->kernel_name);
        return 0;
 }
 
 
 /* Get device identification VPD page */
-static int do_scsi_page83_inquiry(struct sysfs_device *scsi_dev, int fd,
+static int do_scsi_page83_inquiry(struct sysfs_device *dev_scsi, int fd,
                                  char *serial, int len)
 {
        int retval;
@@ -588,14 +556,13 @@ static int do_scsi_page83_inquiry(struct sysfs_device *scsi_dev, int fd,
        unsigned char page_83[SCSI_INQ_BUFF_LEN];
 
        memset(page_83, 0, SCSI_INQ_BUFF_LEN);
-       retval = scsi_inquiry(scsi_dev, fd, 1, PAGE_83, page_83,
+       retval = scsi_inquiry(dev_scsi, fd, 1, PAGE_83, page_83,
                              SCSI_INQ_BUFF_LEN);
        if (retval < 0)
                return 1;
 
        if (page_83[1] != PAGE_83) {
-               log_message(LOG_WARNING, "%s: Invalid page 0x83\n",
-                           scsi_dev->name);
+               info("%s: Invalid page 0x83", dev_scsi->kernel_name);
                return 1;
        }
        
@@ -629,7 +596,7 @@ static int do_scsi_page83_inquiry(struct sysfs_device *scsi_dev, int fd,
         */
        
        if (page_83[6] != 0) 
-               return check_fill_0x83_prespc3(scsi_dev, page_83, 
+               return check_fill_0x83_prespc3(dev_scsi, page_83, 
                                               id_search_list, serial, len);
 
        /*
@@ -643,21 +610,21 @@ static int do_scsi_page83_inquiry(struct sysfs_device *scsi_dev, int fd,
                 * one or a small number of descriptors.
                 */
                for (j = 4; j <= (unsigned int)page_83[3] + 3; j += page_83[j + 3] + 4) {
-                       retval = check_fill_0x83_id(scsi_dev, &page_83[j],
+                       retval = check_fill_0x83_id(dev_scsi, &page_83[j],
                                                    &id_search_list[id_ind],
                                                    serial, len);
-                       dprintf("%s id desc %d/%d/%d\n", scsi_dev->name,
+                       dbg("%s id desc %d/%d/%d\n", dev_scsi->kernel_name,
                                id_search_list[id_ind].id_type,
                                id_search_list[id_ind].naa_type,
                                id_search_list[id_ind].code_set);
                        if (!retval) {
-                               dprintf("       used\n");
+                               dbg("   used\n");
                                return retval;
                        } else if (retval < 0) {
-                               dprintf("       failed\n");
+                               dbg("   failed\n");
                                return retval;
                        } else {
-                               dprintf("       not used\n");
+                               dbg("   not used\n");
                        }
                }
        }
@@ -671,7 +638,7 @@ static int do_scsi_page83_inquiry(struct sysfs_device *scsi_dev, int fd,
  * Return the hard coded error code value 2 if the page 83 reply is not
  * conformant to the SCSI-2 format.
  */
-static int do_scsi_page83_prespc3_inquiry(struct sysfs_device *scsi_dev, int fd,
+static int do_scsi_page83_prespc3_inquiry(struct sysfs_device *dev_scsi, int fd,
                                          char *serial, int len)
 {
        int retval;
@@ -679,12 +646,12 @@ static int do_scsi_page83_prespc3_inquiry(struct sysfs_device *scsi_dev, int fd,
        unsigned char page_83[SCSI_INQ_BUFF_LEN];
 
        memset(page_83, 0, SCSI_INQ_BUFF_LEN);
-       retval = scsi_inquiry(scsi_dev, fd, 1, PAGE_83, page_83, SCSI_INQ_BUFF_LEN);
+       retval = scsi_inquiry(dev_scsi, fd, 1, PAGE_83, page_83, SCSI_INQ_BUFF_LEN);
        if (retval < 0)
                return 1;
 
        if (page_83[1] != PAGE_83) {
-               log_message(LOG_WARNING, "%s: Invalid page 0x83\n", scsi_dev->name);
+               info("%s: Invalid page 0x83", dev_scsi->kernel_name);
                return 1;
        }
        /*
@@ -728,12 +695,12 @@ static int do_scsi_page83_prespc3_inquiry(struct sysfs_device *scsi_dev, int fd,
                serial[j++] = hex_str[page_83[i] & 0x0f];
                i++;
        }
-       dprintf("using pre-spc3-83 for %s.\n", scsi_dev->name);
+       dbg("using pre-spc3-83 for %s.\n", dev_scsi->kernel_name);
        return 0;
 }
 
 /* Get unit serial number VPD page */
-static int do_scsi_page80_inquiry(struct sysfs_device *scsi_dev, int fd,
+static int do_scsi_page80_inquiry(struct sysfs_device *dev_scsi, int fd,
                                  char *serial, int max_len)
 {
        int retval;
@@ -743,20 +710,19 @@ static int do_scsi_page80_inquiry(struct sysfs_device *scsi_dev, int fd,
        unsigned char buf[SCSI_INQ_BUFF_LEN];
 
        memset(buf, 0, SCSI_INQ_BUFF_LEN);
-       retval = scsi_inquiry(scsi_dev, fd, 1, PAGE_80, buf, SCSI_INQ_BUFF_LEN);
+       retval = scsi_inquiry(dev_scsi, fd, 1, PAGE_80, buf, SCSI_INQ_BUFF_LEN);
        if (retval < 0)
                return retval;
 
        if (buf[1] != PAGE_80) {
-               log_message(LOG_WARNING, "%s: Invalid page 0x80\n",
-                           scsi_dev->name);
+               info("%s: Invalid page 0x80", dev_scsi->kernel_name);
                return 1;
        }
 
        len = 1 + VENDOR_LENGTH + MODEL_LENGTH + buf[3];
        if (max_len < len) {
-               log_message(LOG_WARNING, "%s: length %d too short - need %d\n",
-                           scsi_dev->name, max_len, len);
+               info("%s: length %d too short - need %d",
+                   dev_scsi->kernel_name, max_len, len);
                return 1;
        }
        /*
@@ -764,7 +730,7 @@ static int do_scsi_page80_inquiry(struct sysfs_device *scsi_dev, int fd,
         * specific type where we prepend '0' + vendor + model.
         */
        serial[0] = 'S';
-       ser_ind = prepend_vendor_model(scsi_dev, &serial[1]);
+       ser_ind = prepend_vendor_model(dev_scsi, &serial[1]);
        if (ser_ind < 0)
                return 1;
        len = buf[3];
@@ -773,7 +739,7 @@ static int do_scsi_page80_inquiry(struct sysfs_device *scsi_dev, int fd,
        return 0;
 }
 
-int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname,
+int scsi_get_serial (struct sysfs_device *dev_scsi, const char *devname,
                     int page_code, char *serial, int len)
 {
        unsigned char page0[SCSI_INQ_BUFF_LEN];
@@ -782,16 +748,16 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname,
        int retval;
 
        memset(serial, 0, len);
-       dprintf("opening %s\n", devname);
+       dbg("opening %s\n", devname);
        fd = open(devname, O_RDONLY | O_NONBLOCK);
        if (fd < 0) {
-               log_message(LOG_WARNING, "%s: cannot open %s: %s\n",
-                           scsi_dev->name, devname, strerror(errno));
+               info("%s: cannot open %s: %s",
+                   dev_scsi->kernel_name, devname, strerror(errno));
                return 1;
        }
 
        if (page_code == PAGE_80) {
-               if (do_scsi_page80_inquiry(scsi_dev, fd, serial, len)) {
+               if (do_scsi_page80_inquiry(dev_scsi, fd, serial, len)) {
                        retval = 1;
                        goto completed;
                } else  {
@@ -799,7 +765,7 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname,
                        goto completed;
                }
        } else if (page_code == PAGE_83) {
-               if (do_scsi_page83_inquiry(scsi_dev, fd, serial, len)) {
+               if (do_scsi_page83_inquiry(dev_scsi, fd, serial, len)) {
                        retval = 1;
                        goto completed;
                } else  {
@@ -807,7 +773,7 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname,
                        goto completed;
                }
        } else if (page_code == PAGE_83_PRE_SPC3) {
-               retval = do_scsi_page83_prespc3_inquiry(scsi_dev, fd, serial, len);
+               retval = do_scsi_page83_prespc3_inquiry(dev_scsi, fd, serial, len);
                if (retval) {
                        /*
                         * Fallback to servicing a SPC-2/3 compliant page 83
@@ -815,7 +781,7 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname,
                         * conform to pre-SPC3 expectations.
                         */
                        if (retval == 2) {
-                               if (do_scsi_page83_inquiry(scsi_dev, fd, serial, len)) {
+                               if (do_scsi_page83_inquiry(dev_scsi, fd, serial, len)) {
                                        retval = 1;
                                        goto completed;
                                } else  {
@@ -832,8 +798,7 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname,
                        goto completed;
                }
        } else if (page_code != 0x00) {
-               log_message(LOG_WARNING, "%s: unsupported page code 0x%d\n",
-                           scsi_dev->name, page_code);
+               info("%s: unsupported page code 0x%d", dev_scsi->kernel_name, page_code);
                return 1;
        }
 
@@ -841,7 +806,7 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname,
         * Get page 0, the page of the pages. By default, try from best to
         * worst of supported pages: 0x83 then 0x80.
         */
-       if (do_scsi_page0_inquiry(scsi_dev, fd, page0, SCSI_INQ_BUFF_LEN)) {
+       if (do_scsi_page0_inquiry(dev_scsi, fd, page0, SCSI_INQ_BUFF_LEN)) {
                /*
                 * Don't try anything else. Black list if a specific page
                 * should be used for this vendor+model, or maybe have an
@@ -851,11 +816,11 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname,
                goto completed;
        }
 
-       dprintf("%s: Checking page0\n", scsi_dev->name);
+       dbg("%s: Checking page0\n", dev_scsi->kernel_name);
 
        for (ind = 4; ind <= page0[3] + 3; ind++)
                if (page0[ind] == PAGE_83)
-                       if (!do_scsi_page83_inquiry(scsi_dev, fd, serial,
+                       if (!do_scsi_page83_inquiry(dev_scsi, fd, serial,
                                                    len)) {
                                /*
                                 * Success
@@ -866,7 +831,7 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname,
 
        for (ind = 4; ind <= page0[3] + 3; ind++)
                if (page0[ind] == PAGE_80)
-                       if (!do_scsi_page80_inquiry(scsi_dev, fd, serial,
+                       if (!do_scsi_page80_inquiry(dev_scsi, fd, serial,
                                                    len)) {
                                /*
                                 * Success
@@ -877,7 +842,6 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname,
        retval = 1;
 completed:
        if (close(fd) < 0)
-               log_message(LOG_WARNING, "%s: close failed: %s\n", 
-                           scsi_dev->name, strerror(errno));
+               info("%s: close failed: %s", dev_scsi->kernel_name, strerror(errno));
        return retval;
 }
index f6d26e1..91b4d57 100644 (file)
@@ -33,7 +33,7 @@ all: $(PROG) $(MAN_PAGES)
        $(QUIET) $(CC) -c $(CFLAGS) $< -o $@
 
 $(PROG): %: $(HEADERS) %.o $(OBJS)
-       $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS)
+       $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS)
 ifneq ($(strip $(STRIPCMD)),)
        $(QUIET) $(STRIPCMD) $@
 endif
index b7d6795..0bcd267 100644 (file)
 #include <ctype.h>
 #include <errno.h>
 
-#include <../../libsysfs/sysfs/libsysfs.h>
-#include "../../udev_utils.h"
-#include "../../logging.h"
+#include "../../udev.h"
 
-#define        MAX_NAME_LEN                    72
-#define        MAX_SERIAL_LEN                  256
+#define MAX_NAME_LEN                   72
+#define MAX_SERIAL_LEN                 256
 #define BLKGETSIZE64 _IOR(0x12,114,size_t)
 
 #ifdef USE_LOG
@@ -54,7 +52,6 @@ void log_message(int priority, const char *format, ...)
 }
 #endif
 
-char sysfs_mnt_path[SYSFS_PATH_MAX];
 static char vendor_str[64];
 static char model_str[64];
 static char serial_str[MAX_SERIAL_LEN];
@@ -245,182 +242,176 @@ static void set_scsi_type(char *to, const char *from, int count)
  * 6.) If the device supplies a serial number, this number
  *     is concatenated with the identification with an underscore '_'.
  */
-static int usb_id(const char *target_path)
+static int usb_id(const char *devpath)
 {
-       struct sysfs_class_device *class_dev; /* of target_path */
-       struct sysfs_class_device *class_dev_parent; /* for partitions */
-       struct sysfs_device *scsi_dev; /* the scsi_device */
-       struct sysfs_device *target_dev;
-       struct sysfs_device *host_dev, *interface_dev, *usb_dev;
-       struct sysfs_attribute *scsi_model, *scsi_vendor, *scsi_type, *scsi_rev;
-       struct sysfs_attribute *usb_model = NULL, *usb_vendor = NULL, *usb_rev, *usb_serial;
-       struct sysfs_attribute *if_class, *if_subclass;
+       struct sysfs_device *dev;
+       struct sysfs_device *dev_scsi;
+       struct sysfs_device *dev_target;
+       struct sysfs_device *dev_host, *dev_interface, *dev_usb;
+       const char *scsi_model, *scsi_vendor, *scsi_type, *scsi_rev;
+       const char *usb_model = NULL, *usb_vendor = NULL, *usb_rev, *usb_serial;
+       const char *if_class, *if_subclass;
        int if_class_num;
        int protocol = 0;
 
-       class_dev = sysfs_open_class_device_path(target_path);
-       if (!class_dev) {
-               info("open class %s failed: %s", target_path, strerror(errno));
+       dbg("devpath %s\n", devpath);
+
+       dev = sysfs_device_get(devpath);
+       if (dev == NULL) {
+               err("unable to access '%s'", devpath);
                return 1;
        }
-       class_dev_parent = sysfs_get_classdev_parent(class_dev);
-       if (class_dev_parent) {
-               scsi_dev = sysfs_get_classdev_device(class_dev_parent);
-       } else {
-               scsi_dev = sysfs_get_classdev_device(class_dev);
-       }
 
-       /*
-        * The close of scsi_dev will close class_dev or class_dev_parent.
-        */
-
-       /*
-        * We assume we are called after the device is completely ready,
-        * so we don't have to loop here like udev. (And we are usually
-        * called via udev.)
-        */
-       if (!scsi_dev) {
-               /*
-                * errno is not set if we can't find the device link, so
-                * don't print it out here.
-                */
-               info("Cannot find sysfs device associated with %s", target_path);
+       /* get scsi parent device */
+       dev_scsi = sysfs_device_get_parent(dev);
+       if (dev_scsi == NULL) {
+               err("unable to access parent device of '%s'", devpath);
                return 1;
        }
-
-       /*
-        * Allow only scsi devices.
-        *
-        * Other block devices can support SG IO, but only ide-cd does, so
-        * for now, don't bother with anything else.
-        */
-       if (strcmp(scsi_dev->bus, "scsi") != 0) {
-               info("%s is not a scsi device", target_path);
+       /* allow only scsi devices */
+       if (strcmp(dev_scsi->subsystem, "scsi") != 0) {
+               info("%s is not a scsi device", devpath);
                return 1;
        }
 
        /* target directory */
-       target_dev = sysfs_get_device_parent(scsi_dev);
+       dev_target = sysfs_device_get_parent(dev_scsi);
+       if (dev_target == NULL) {
+               err("unable to access parent device of '%s'", devpath);
+               return 1;
+       }
+
        /* host directory */
-       host_dev = sysfs_get_device_parent(target_dev);
+       dev_host = sysfs_device_get_parent(dev_target);
+       if (dev_host == NULL) {
+               err("unable to access parent device of '%s'", devpath);
+               return 1;
+       }
+
        /* usb interface directory */
-       interface_dev = sysfs_get_device_parent(host_dev);
-       /* usb device directory */
-       usb_dev = sysfs_get_device_parent(interface_dev);
+       dev_interface = sysfs_device_get_parent(dev_host);
+       if (dev_interface == NULL) {
+               err("unable to access parent device of '%s'", devpath);
+               return 1;
+       }
 
-       if (strcmp(interface_dev->bus, "usb") != 0) {
-               info("%s is not an usb device", target_path);
+       /* usb device directory */
+       dev_usb = sysfs_device_get_parent(dev_interface);
+       if (dev_usb == NULL) {
+               err("unable to access parent device of '%s'", devpath);
+               return 1;
+       }
+       if (strcmp(dev_interface->subsystem, "usb") != 0) {
+               info("%s is not an usb device", devpath);
                return 1;
        }
 
-       if_class = sysfs_get_device_attr(interface_dev, "bInterfaceClass");
+       if_class = sysfs_attr_get_value(dev_interface->devpath, "bInterfaceClass");
        if (!if_class) {
-               info("%s: cannot get bInterfaceClass attribute", interface_dev->name);
+               info("%s: cannot get bInterfaceClass attribute", dev_interface->kernel_name);
                return 1;
        }
-       if_class_num = strtoul(if_class->value, NULL, 16);
+       if_class_num = strtoul(if_class, NULL, 16);
        if (if_class_num != 8) {
-               set_usb_iftype(type_str, if_class->value, sizeof(type_str) - 1);
+               set_usb_iftype(type_str, if_class, sizeof(type_str)-1);
                protocol = 0;
        } else {
-               if_subclass = sysfs_get_device_attr(interface_dev, 
-                                                   "bInterfaceSubClass");
-               protocol = set_usb_ifsubtype(type_str, if_subclass->value, 
-                                            sizeof(type_str) -1 );
+               if_subclass = sysfs_attr_get_value(dev_interface->devpath, "bInterfaceSubClass");
+               protocol = set_usb_ifsubtype(type_str, if_subclass, sizeof(type_str)-1);
        }
 
        if (!use_usb_info && protocol == 6) {
                /* Generic SPC-2 device */
-               scsi_vendor = sysfs_get_device_attr(scsi_dev, "vendor");
+               scsi_vendor = sysfs_attr_get_value(dev_scsi->devpath, "vendor");
                if (!scsi_vendor) {
-                       info("%s: cannot get SCSI vendor attribute", scsi_dev->name);
+                       info("%s: cannot get SCSI vendor attribute", dev_scsi->kernel_name);
                        return 1;
                }
-               set_str(vendor_str, scsi_vendor->value, sizeof(vendor_str)-1);
+               set_str(vendor_str, scsi_vendor, sizeof(vendor_str)-1);
 
-               scsi_model = sysfs_get_device_attr(scsi_dev, "model");
+               scsi_model = sysfs_attr_get_value(dev_scsi->devpath, "model");
                if (!scsi_model) {
-                       info("%s: cannot get SCSI model attribute", scsi_dev->name);
+                       info("%s: cannot get SCSI model attribute", dev_scsi->kernel_name);
                        return 1;
                }
-               set_str(model_str, scsi_model->value, sizeof(model_str)-1);
+               set_str(model_str, scsi_model, sizeof(model_str)-1);
 
-               scsi_type = sysfs_get_device_attr(scsi_dev, "type");
+               scsi_type = sysfs_attr_get_value(dev_scsi->devpath, "type");
                if (!scsi_type) {
-                       info("%s: cannot get SCSI type attribute", scsi_dev->name);
+                       info("%s: cannot get SCSI type attribute", dev_scsi->kernel_name);
                        return 1;
                }
-               set_scsi_type(type_str, scsi_type->value, sizeof(type_str)-1);
+               set_scsi_type(type_str, scsi_type, sizeof(type_str)-1);
 
-               scsi_rev = sysfs_get_device_attr(scsi_dev, "rev");
+               scsi_rev = sysfs_attr_get_value(dev_scsi->devpath, "rev");
                if (!scsi_rev) {
-                       info("%s: cannot get SCSI revision attribute", scsi_dev->name);
+                       info("%s: cannot get SCSI revision attribute", dev_scsi->kernel_name);
                        return 1;
                }
-               set_str(revision_str, scsi_rev->value, sizeof(revision_str)-1);
+               set_str(revision_str, scsi_rev, sizeof(revision_str)-1);
 
        }
 
        /* Fallback to USB vendor & device */
        if (vendor_str[0] == '\0') {
                if (!use_num_info)
-                       if (!(usb_vendor = sysfs_get_device_attr(usb_dev, "manufacturer")))
+                       if (!(usb_vendor = sysfs_attr_get_value(dev_usb->devpath, "manufacturer")))
                                dbg("No USB vendor string found, using idVendor");
 
                if (!usb_vendor) {
-                       if (!(usb_vendor = sysfs_get_device_attr(usb_dev, "idVendor"))) {
+                       if (!(usb_vendor = sysfs_attr_get_value(dev_usb->devpath, "idVendor"))) {
                                dbg("No USB vendor information available\n");
                                sprintf(vendor_str,"0000");
                        }
                }
-               set_str(vendor_str,usb_vendor->value, sizeof(vendor_str) - 1);
+               set_str(vendor_str,usb_vendor, sizeof(vendor_str) - 1);
        }
        
        if (model_str[0] == '\0') {
                if (!use_num_info)
-                       if (!(usb_model = sysfs_get_device_attr(usb_dev, "product")))
+                       if (!(usb_model = sysfs_attr_get_value(dev_usb->devpath, "product")))
                                dbg("No USB model string found, using idProduct");
                
                if (!usb_model) {
-                       if (!(usb_model = sysfs_get_device_attr(usb_dev, "idProduct"))) {
-                               dbg("No USB model information available\n");
-                               sprintf(model_str,"0000");
-                       }
+                       if (!(usb_model = sysfs_attr_get_value(dev_usb->devpath, "idProduct")))
+                               dbg("No USB model information available\n"); sprintf(model_str,"0000");
                }
-               set_str(model_str, usb_model->value, sizeof(model_str) - 1);
+               set_str(model_str, usb_model, sizeof(model_str) - 1);
        }
 
        if (revision_str[0] == '\0') {
-               usb_rev = sysfs_get_device_attr(usb_dev, "bcdDevice");
-               if (usb_rev) {
-                       set_str(revision_str, usb_rev->value, 
-                               sizeof(revision_str) - 1);
-               }
+               usb_rev = sysfs_attr_get_value(dev_usb->devpath, "bcdDevice");
+               if (usb_rev)
+                       set_str(revision_str, usb_rev, sizeof(revision_str)-1);
        }
 
        if (serial_str[0] == '\0') {
-               usb_serial = sysfs_get_device_attr(usb_dev, "serial");
-               if (usb_serial) {
-                       set_str(serial_str, usb_serial->value,
-                               sizeof(serial_str) - 1);
-               }
+               usb_serial = sysfs_attr_get_value(dev_usb->devpath, "serial");
+               if (usb_serial)
+                       set_str(serial_str, usb_serial, sizeof(serial_str)-1);
        }
        return 0;
 }
 
 int main(int argc, char **argv)
 {
-       int retval;
-       char *devpath;
-       char target_path[MAX_NAME_LEN];
+       int retval = 0;
+       const char *env;
+       char devpath[MAX_NAME_LEN];
        int option;
 
+       logging_init("usb_id");
+       sysfs_init();
+
        dbg("argc is %d", argc);
-       if (sysfs_get_mnt_path(sysfs_mnt_path, MAX_NAME_LEN)) {
-               info("sysfs_get_mnt_path failed: %s",
-                       strerror(errno));
-               exit(1);
-       }
+
+       /* sysfs path can be overridden for testing */
+       env = getenv("SYSFS_PATH");
+       if (env) {
+               strlcpy(sysfs_path, env, sizeof(sysfs_path));
+               remove_trailing_chars(sysfs_path, '/');
+       } else
+               strcpy(sysfs_path, "/sys");
 
        while ((option = getopt(argc, argv, "dnux")) != -1 ) {
                if (optarg)
@@ -433,14 +424,14 @@ int main(int argc, char **argv)
                        debug = 1;
                        break;
                case 'n':
-                       use_num_info=1;
-                       use_usb_info=1;
+                       use_num_info = 1;
+                       use_usb_info = 1;
                        break;
                case 'u':
-                       use_usb_info=1;
+                       use_usb_info = 1;
                        break;
                case 'x':
-                       export=1;
+                       export = 1;
                        break;
                default:
                        info("Unknown or bad option '%c' (0x%x)", option, option);
@@ -449,20 +440,19 @@ int main(int argc, char **argv)
                }
        }
 
-       devpath = getenv("DEVPATH");
-       if (devpath) {
-               strncpy(target_path, sysfs_mnt_path, MAX_NAME_LEN);
-               strncat(target_path, devpath, MAX_NAME_LEN);
-       } else {
+       env = getenv("DEVPATH");
+       if (env != NULL)
+               strlcpy(devpath, env, sizeof(devpath));
+       else {
                if (optind == argc) {
                        fprintf(stderr, "No device specified\n");
-                       exit(1);
+                       retval = 1;
+                       goto exit;
                }
-               devpath = argv[optind];
-               strncpy(target_path, devpath, MAX_NAME_LEN);
+               strlcpy(devpath, argv[optind], sizeof(devpath));
        }
 
-       retval = usb_id(target_path);
+       retval = usb_id(devpath);
 
        if (retval == 0) {
                if (export) {
@@ -488,5 +478,9 @@ int main(int argc, char **argv)
                        }
                }
        }
-       exit(retval);
+
+exit:
+       sysfs_cleanup();
+       logging_close();
+       return retval;
 }
index 6201044..edb5d3a 100644 (file)
@@ -35,7 +35,7 @@ $(LIBVOLUME_ID):
        $(MAKE) -C libvolume_id
 
 $(PROG): %: $(HEADERS) %.o $(LIBVOLUME_ID)
-       $(QUIET) $(LD) $(LDFLAGS) $@.o $(LIBVOLUME_ID) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS)
+       $(QUIET) $(LD) $(LDFLAGS) $@.o $(LIBVOLUME_ID) -o $@ $(LIBUDEV) $(LIB_OBJS)
 ifneq ($(strip $(STRIPCMD)),)
        $(QUIET) $(STRIPCMD) $@
 endif
index 6f99c52..a291eda 100644 (file)
@@ -29,8 +29,7 @@
 #include <ctype.h>
 #include <sys/ioctl.h>
 
-#include "../../udev_utils.h"
-#include "../../logging.h"
+#include "../../udev.h"
 #include "libvolume_id/volume_id.h"
 
 #define BLKGETSIZE64 _IOR(0x12,114,size_t)
diff --git a/libsysfs/LGPL b/libsysfs/LGPL
deleted file mode 100644 (file)
index e00a829..0000000
+++ /dev/null
@@ -1,441 +0,0 @@
-      
-      GNU Lesser Public License
-      Version 2.1, February 1999
-
-        Copyright (C) 1991, 1999 Free Software Foundation, Inc.
-        59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-        Everyone is permitted to copy and distribute verbatim copies
-        of this license document, but changing it is not allowed.
-
-        [This is the first released version of the Lesser GPL. It also counts
-        as the successor of the GNU Library Public License, version 2, hence
-        the version number 2.1.]
-
-      Preamble
-
-      The licenses for most software are designed to take away your freedom to 
-      share and change it. By contrast, the GNU General Public Licenses are 
-      intended to guarantee your freedom to share and change free software--to 
-      make sure the software is free for all its users.
-      This license, the Lesser General Public License, applies to some specially 
-      designated software packages--typically libraries--of the Free Software 
-      Foundation and other authors who decide to use it. You can use it too, but 
-      we suggest you first think carefully about whether this license or the 
-      ordinary General Public License is the better strategy to use in any 
-      particular case, based on the explanations below. 
-
-      When we speak of free software, we are referring to freedom of use, not 
-      price. Our General Public Licenses are designed to make sure that you have 
-      the freedom to distribute copies of free software (and charge for this 
-      service if you wish); that you receive source code or can get it if you 
-      want it; that you can change the software and use pieces of it in new free 
-      programs; and that you are informed that you can do these things.
-
-      To protect your rights, we need to make restrictions that forbid 
-      distributors to deny you these rights or to ask you to surrender these 
-      rights. These restrictions translate to certain responsibilities for you 
-      if you distribute copies of the library or if you modify it. 
-
-      For example, if you distribute copies of the library, whether gratis or 
-      for a fee, you must give the recipients all the rights that we gave you. 
-      You must make sure that they, too, receive or can get the source code. If 
-      you link other code with the library, you must provide complete object 
-      files to the recipients, so that they can relink them with the library 
-      after making changes to the library and recompiling it. And you must show 
-      them these terms so they know their rights. 
-
-      We protect your rights with a two-step method: (1) we copyright the 
-      library, and (2) we offer you this license, which gives you legal 
-      permission to copy, distribute and/or modify the library. 
-
-      To protect each distributor, we want to make it very clear that there is 
-      no warranty for the free library. Also, if the library is modified by 
-      someone else and passed on, the recipients should know that what they have 
-      is not the original version, so that the original author's reputation will 
-      not be affected by problems that might be introduced by others. 
-
-      Finally, software patents pose a constant threat to the existence of any 
-      free program. We wish to make sure that a company cannot effectively 
-      restrict the users of a free program by obtaining a restrictive license 
-      from a patent holder. Therefore, we insist that any patent license 
-      obtained for a version of the library must be consistent with the full 
-      freedom of use specified in this license. 
-
-      Most GNU software, including some libraries, is covered by the ordinary 
-      GNU General Public License. This license, the GNU Lesser General Public 
-      License, applies to certain designated libraries, and is quite different 
-      from the ordinary General Public License. We use this license for certain 
-      libraries in order to permit linking those libraries into non-free 
-      programs. 
-
-      When a program is linked with a library, whether statically or using a 
-      shared library, the combination of the two is legally speaking a combined 
-      work, a derivative of the original library. The ordinary General Public 
-      License therefore permits such linking only if the entire combination fits 
-      its criteria of freedom. The Lesser General Public License permits more 
-      lax criteria for linking other code with the library. 
-
-      We call this license the "Lesser" General Public License because it does 
-      Less to protect the user's freedom than the ordinary General Public 
-      License. It also provides other free software developers Less of an 
-      advantage over competing non-free programs. These disadvantages are the 
-      reason we use the ordinary General Public License for many libraries. 
-      However, the Lesser license provides advantages in certain special 
-      circumstances. 
-
-      For example, on rare occasions, there may be a special need to encourage 
-      the widest possible use of a certain library, so that it becomes a 
-      de-facto standard. To achieve this, non-free programs must be allowed to 
-      use the library. A more frequent case is that a free library does the same 
-      job as widely used non-free libraries. In this case, there is little to 
-      gain by limiting the free library to free software only, so we use the 
-      Lesser General Public License. 
-
-      In other cases, permission to use a particular library in non-free 
-      programs enables a greater number of people to use a large body of free 
-      software. For example, permission to use the GNU C Library in non-free 
-      programs enables many more people to use the whole GNU operating system, 
-      as well as its variant, the GNU/Linux operating system. 
-
-      Although the Lesser General Public License is Less protective of the 
-      users' freedom, it does ensure that the user of a program that is linked 
-      with the Library has the freedom and the wherewithal to run that program 
-      using a modified version of the Library. 
-
-      The precise terms and conditions for copying, distribution and 
-      modification follow. Pay close attention to the difference between a "work 
-      based on the library" and a "work that uses the library". The former 
-      contains code derived from the library, whereas the latter must be 
-      combined with the library in order to run. 
-
-      TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-      0. This License Agreement applies to any software library or other program 
-      which contains a notice placed by the copyright holder or other authorized 
-      party saying it may be distributed under the terms of this Lesser General 
-      Public License (also called "this License"). Each licensee is addressed as 
-      "you".
-
-      A "library" means a collection of software functions and/or data prepared 
-      so as to be conveniently linked with application programs (which use some 
-      of those functions and data) to form executables. 
-
-      The "Library", below, refers to any such software library or work which 
-      has been distributed under these terms. A "work based on the Library" 
-      means either the Library or any derivative work under copyright law: that 
-      is to say, a work containing the Library or a portion of it, either 
-      verbatim or with modifications and/or translated straightforwardly into 
-      another language. (Hereinafter, translation is included without limitation 
-      in the term "modification".) 
-
-      "Source code" for a work means the preferred form of the work for making 
-      modifications to it. For a library, complete source code means all the 
-      source code for all modules it contains, plus any associated interface 
-      definition files, plus the scripts used to control compilation and 
-      installation of the library.
-
-      Activities other than copying, distribution and modification are not 
-      covered by this License; they are outside its scope. The act of running a 
-      program using the Library is not restricted, and output from such a 
-      program is covered only if its contents constitute a work based on the 
-      Library (independent of the use of the Library in a tool for writing it). 
-      Whether that is true depends on what the Library does and what the program 
-      that uses the Library does. 
-
-      1. You may copy and distribute verbatim copies of the Library's complete 
-      source code as you receive it, in any medium, provided that you 
-      conspicuously and appropriately publish on each copy an appropriate 
-      copyright notice and disclaimer of warranty; keep intact all the notices 
-      that refer to this License and to the absence of any warranty; and 
-      distribute a copy of this License along with the Library. 
-
-      You may charge a fee for the physical act of transferring a copy, and you 
-      may at your option offer warranty protection in exchange for a fee. 
-
-      2. You may modify your copy or copies of the Library or any portion of it, 
-      thus forming a work based on the Library, and copy and distribute such 
-      modifications or work under the terms of Section 1 above, provided that 
-      you also meet all of these conditions: 
-
-        a) The modified work must itself be a software library. 
-
-        b) You must cause the files modified to carry prominent notices stating 
-        that you changed the files and the date of any change.
-
-        c) You must cause the whole of the work to be licensed at no charge to 
-        all third parties under the terms of this License. 
-
-        d) If a facility in the modified Library refers to a function or a table 
-        of data to be supplied by an application program that uses the facility, 
-        other than as an argument passed when the facility is invoked, then you 
-        must make a good faith effort to ensure that, in the event an 
-        application does not supply such function or table, the facility still 
-        operates, and performs whatever part of its purpose remains meaningful. 
-
-        (For example, a function in a library to compute square roots has a 
-        purpose that is entirely well-defined independent of the application. 
-        Therefore, Subsection 2d requires that any application-supplied function 
-        or table used by this function must be optional: if the application does 
-        not supply it, the square root function must still compute square 
-        roots.) 
-
-        These requirements apply to the modified work as a whole. If 
-        identifiable sections of that work are not derived from the Library, and 
-        can be reasonably considered independent and separate works in 
-        themselves, then this License, and its terms, do not apply to those 
-        sections when you distribute them as separate works. But when you 
-        distribute the same sections as part of a whole which is a work based on 
-        the Library, the distribution of the whole must be on the terms of this 
-        License, whose permissions for other licensees extend to the entire 
-        whole, and thus to each and every part regardless of who wrote it. 
-
-        Thus, it is not the intent of this section to claim rights or contest 
-        your rights to work written entirely by you; rather, the intent is to 
-        exercise the right to control the distribution of derivative or 
-        collective works based on the Library. 
-
-        In addition, mere aggregation of another work not based on the Library 
-        with the Library (or with a work based on the Library) on a volume of a 
-        storage or distribution medium does not bring the other work under the 
-        scope of this License. 
-
-      3. You may opt to apply the terms of the ordinary GNU General Public 
-      License instead of this License to a given copy of the Library. To do 
-      this, you must alter all the notices that refer to this License, so that 
-      they refer to the ordinary GNU General Public License, version 2, instead 
-      of to this License. (If a newer version than version 2 of the ordinary GNU 
-      General Public License has appeared, then you can specify that version 
-      instead if you wish.) Do not make any other change in these notices. 
-
-      Once this change is made in a given copy, it is irreversible for that 
-      copy, so the ordinary GNU General Public License applies to all subsequent 
-      copies and derivative works made from that copy. 
-
-      This option is useful when you wish to copy part of the code of the 
-      Library into a program that is not a library. 
-
-      4. You may copy and distribute the Library (or a portion or derivative of 
-      it, under Section 2) in object code or executable form under the terms of 
-      Sections 1 and 2 above provided that you accompany it with the complete 
-      corresponding machine-readable source code, which must be distributed 
-      under the terms of Sections 1 and 2 above on a medium customarily used for 
-      software interchange. 
-
-      If distribution of object code is made by offering access to copy from a 
-      designated place, then offering equivalent access to copy the source code 
-      from the same place satisfies the requirement to distribute the source 
-      code, even though third parties are not compelled to copy the source along 
-      with the object code.
-
-      5. A program that contains no derivative of any portion of the Library, 
-      but is designed to work with the Library by being compiled or linked with 
-      it, is called a "work that uses the Library". Such a work, in isolation, 
-      is not a derivative work of the Library, and therefore falls outside the 
-      scope of this License. 
-
-      However, linking a "work that uses the Library" with the Library creates 
-      an executable that is a derivative of the Library (because it contains 
-      portions of the Library), rather than a "work that uses the library". The 
-      executable is therefore covered by this License. Section 6 states terms 
-      for distribution of such executables. 
-
-      When a "work that uses the Library" uses material from a header file that 
-      is part of the Library, the object code for the work may be a derivative 
-      work of the Library even though the source code is not. Whether this is 
-      true is especially significant if the work can be linked without the 
-      Library, or if the work is itself a library. The threshold for this to be 
-      true is not precisely defined by law. 
-
-      If such an object file uses only numerical parameters, data structure 
-      layouts and accessors, and small macros and small inline functions (ten 
-      lines or less in length), then the use of the object file is unrestricted, 
-      regardless of whether it is legally a derivative work. (Executables 
-      containing this object code plus portions of the Library will still fall 
-      under Section 6.) 
-
-      Otherwise, if the work is a derivative of the Library, you may distribute 
-      the object code for the work under the terms of Section 6. Any executables 
-      containing that work also fall under Section 6, whether or not they are 
-      linked directly with the Library itself. 
-
-      6. As an exception to the Sections above, you may also combine or link a 
-      "work that uses the Library" with the Library to produce a work containing 
-      portions of the Library, and distribute that work under terms of your 
-      choice, provided that the terms permit modification of the work for the 
-      customer's own use and reverse engineering for debugging such 
-      modifications.
-      You must give prominent notice with each copy of the work that the Library 
-      is used in it and that the Library and its use are covered by this 
-      License. You must supply a copy of this License. If the work during 
-      execution displays copyright notices, you must include the copyright 
-      notice for the Library among them, as well as a reference directing the 
-      user to the copy of this License. Also, you must do one of these things: 
-
-        a) Accompany the work with the complete corresponding machine-readable 
-        source code for the Library including whatever changes were used in the 
-        work (which must be distributed under Sections 1 and 2 above); and, if 
-        the work is an executable linked with the Library, with the complete 
-        machine-readable "work that uses the Library", as object code and/or 
-        source code, so that the user can modify the Library and then relink to 
-        produce a modified executable containing the modified Library. (It is 
-        understood that the user who changes the contents of definitions files 
-        in the Library will not necessarily be able to recompile the application 
-        to use the modified definitions.) 
-
-        b) Use a suitable shared library mechanism for linking with the Library. 
-        A suitable mechanism is one that (1) uses at run time a copy of the 
-        library already present on the user's computer system, rather than 
-        copying library functions into the executable, and (2) will operate 
-        properly with a modified version of the library, if the user installs 
-        one, as long as the modified version is interface-compatible with the 
-        version that the work was made with. 
-
-        c) Accompany the work with a written offer, valid for at least three 
-        years, to give the same user the materials specified in Subsection 6a, 
-        above, for a charge no more than the cost of performing this 
-        distribution. 
-
-        d) If distribution of the work is made by offering access to copy from a 
-        designated place, offer equivalent access to copy the above specified 
-        materials from the same place.
-        e) Verify that the user has already received a copy of these materials 
-        or that you have already sent this user a copy.
-
-      For an executable, the required form of the "work that uses the Library" 
-      must include any data and utility programs needed for reproducing the 
-      executable from it. However, as a special exception, the materials to be 
-      distributed need not include anything that is normally distributed (in 
-      either source or binary form) with the major components (compiler, kernel, 
-      and so on) of the operating system on which the executable runs, unless 
-      that component itself accompanies the executable.
-      It may happen that this requirement contradicts the license restrictions 
-      of other proprietary libraries that do not normally accompany the 
-      operating system. Such a contradiction means you cannot use both them and 
-      the Library together in an executable that you distribute. 
-
-      7. You may place library facilities that are a work based on the Library 
-      side-by-side in a single library together with other library facilities 
-      not covered by this License, and distribute such a combined library, 
-      provided that the separate distribution of the work based on the Library 
-      and of the other library facilities is otherwise permitted, and provided 
-      that you do these two things: 
-
-        a) Accompany the combined library with a copy of the same work based on 
-        the Library, uncombined with any other library facilities. This must be 
-        distributed under the terms of the Sections above. 
-
-        b) Give prominent notice with the combined library of the fact that part 
-        of it is a work based on the Library, and explaining where to find the 
-        accompanying uncombined form of the same work.
-
-      8. You may not copy, modify, sublicense, link with, or distribute the 
-      Library except as expressly provided under this License. Any attempt 
-      otherwise to copy, modify, sublicense, link with, or distribute the 
-      Library is void, and will automatically terminate your rights under this 
-      License. However, parties who have received copies, or rights, from you 
-      under this License will not have their licenses terminated so long as such 
-      parties remain in full compliance. 
-
-      9. You are not required to accept this License, since you have not signed 
-      it. However, nothing else grants you permission to modify or distribute 
-      the Library or its derivative works. These actions are prohibited by law 
-      if you do not accept this License. Therefore, by modifying or distributing 
-      the Library (or any work based on the Library), you indicate your 
-      acceptance of this License to do so, and all its terms and conditions for 
-      copying, distributing or modifying the Library or works based on it.
-      10. Each time you redistribute the Library (or any work based on the 
-      Library), the recipient automatically receives a license from the original 
-      licensor to copy, distribute, link with or modify the Library subject to 
-      these terms and conditions. You may not impose any further restrictions on 
-      the recipients' exercise of the rights granted herein. You are not 
-      responsible for enforcing compliance by third parties with this License. 
-
-      11. If, as a consequence of a court judgment or allegation of patent 
-      infringement or for any other reason (not limited to patent issues), 
-      conditions are imposed on you (whether by court order, agreement or 
-      otherwise) that contradict the conditions of this License, they do not 
-      excuse you from the conditions of this License. If you cannot distribute 
-      so as to satisfy simultaneously your obligations under this License and 
-      any other pertinent obligations, then as a consequence you may not 
-      distribute the Library at all. For example, if a patent license would not 
-      permit royalty-free redistribution of the Library by all those who receive 
-      copies directly or indirectly through you, then the only way you could 
-      satisfy both it and this License would be to refrain entirely from 
-      distribution of the Library. 
-
-      If any portion of this section is held invalid or unenforceable under any 
-      particular circumstance, the balance of the section is intended to apply, 
-      and the section as a whole is intended to apply in other circumstances. 
-
-      It is not the purpose of this section to induce you to infringe any 
-      patents or other property right claims or to contest validity of any such 
-      claims; this section has the sole purpose of protecting the integrity of 
-      the free software distribution system which is implemented by public 
-      license practices. Many people have made generous contributions to the 
-      wide range of software distributed through that system in reliance on 
-      consistent application of that system; it is up to the author/donor to 
-      decide if he or she is willing to distribute software through any other 
-      system and a licensee cannot impose that choice. 
-
-      This section is intended to make thoroughly clear what is believed to be a 
-      consequence of the rest of this License. 
-
-      12. If the distribution and/or use of the Library is restricted in certain 
-      countries either by patents or by copyrighted interfaces, the original 
-      copyright holder who places the Library under this License may add an 
-      explicit geographical distribution limitation excluding those countries, 
-      so that distribution is permitted only in or among countries not thus 
-      excluded. In such case, this License incorporates the limitation as if 
-      written in the body of this License. 
-
-      13. The Free Software Foundation may publish revised and/or new versions 
-      of the Lesser General Public License from time to time. Such new versions 
-      will be similar in spirit to the present version, but may differ in detail 
-      to address new problems or concerns.
-
-      Each version is given a distinguishing version number. If the Library 
-      specifies a version number of this License which applies to it and "any 
-      later version", you have the option of following the terms and conditions 
-      either of that version or of any later version published by the Free 
-      Software Foundation. If the Library does not specify a license version 
-      number, you may choose any version ever published by the Free Software 
-      Foundation. 
-
-      14. If you wish to incorporate parts of the Library into other free 
-      programs whose distribution conditions are incompatible with these, write 
-      to the author to ask for permission. For software which is copyrighted by 
-      the Free Software Foundation, write to the Free Software Foundation; we 
-      sometimes make exceptions for this. Our decision will be guided by the two 
-      goals of preserving the free status of all derivatives of our free 
-      software and of promoting the sharing and reuse of software generally. 
-
-      NO WARRANTY 
-
-      15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 
-      FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 
-      OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 
-      PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 
-      OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
-      MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 
-      TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE 
-      LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 
-      REPAIR OR CORRECTION. 
-
-      16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 
-      WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 
-      REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 
-      INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES 
-      ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT 
-      LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES 
-      SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE 
-      WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN 
-      ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-      END OF TERMS AND CONDITIONS
-
diff --git a/libsysfs/dlist.c b/libsysfs/dlist.c
deleted file mode 100644 (file)
index 5579602..0000000
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- * dlist.c
- *
- * Copyright (C) 2003 Eric J Bohm
- *
- *  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 021110307 USA
- *
- */
-
-
-/* Double linked list implementation.
-
- * You allocate the data and give dlist the pointer.
- * If your data is complex set the dlist->del_func to a an appropriate
- * delete function.  Otherwise dlist will just use free.
-
-*/
-#include "stdlib.h"
-#include "dlist.h"
-
-/*
- * Return pointer to node at marker.
- * else null if no nodes.
- */
-
-inline void *dlist_mark(Dlist *list)
-{
-  if(list->marker!=NULL)
-    return(list->marker->data);
-  else
-    return(NULL);
-}
-
-/* 
- * Set marker to start.
- */
-
-inline void dlist_start(Dlist *list)
-{
-  list->marker=list->head;
-}
-
-/* 
- * Set marker to end.
- */
-
-inline void dlist_end(Dlist *list)
-{
-  list->marker=list->head;
-}
-
-/* internal use function
- * quickie inline to consolidate the marker movement logic
- * in one place
- *
- * when direction true it moves marker after 
- * when direction false it moves marker before.
- * return pointer to data at new marker
- * if nowhere to move the marker in desired direction return null 
- */
-inline void *_dlist_mark_move(Dlist *list,int direction)
-{
-  if(direction)
-    {
-      if( list->marker && list->marker->next!=NULL)
-       list->marker=list->marker->next;
-      else
-       return(NULL);
-    }
-  else
-    {
-      if( list->marker && list->marker->prev!=NULL)
-       list->marker=list->marker->prev;
-      else
-       return(NULL);
-    }
-  if(list->marker!=list->head)
-    return(list->marker->data);
-  else
-    return(NULL);
-}
-
-/*
- * Create new linked list to store nodes of datasize.
- * return null if list cannot be created.
- */
-Dlist *dlist_new(size_t datasize)
-{
-  Dlist *list=NULL;
-  if((list=malloc(sizeof(Dlist))))
-    {
-      list->marker=NULL;
-      list->count=0L;
-      list->data_size=datasize;
-      list->del_func=free;
-      list->head=&(list->headnode);
-      list->head->prev=NULL;
-      list->head->next=NULL;
-      list->head->data=NULL;
-    }
-  return(list);
-}
-
-/*
- * Create new linked list to store nodes of datasize set list
- * data node delete function to the passed in del_func
- * return null if list cannot be created.
- */
-Dlist *dlist_new_with_delete(size_t datasize,void (*del_func)(void*))
-{
-  Dlist *list=NULL;
-  list=dlist_new(datasize);
-  if(list!=NULL)
-    list->del_func=del_func;
-  return(list);
-}
-
-
-/*
- * remove marker node from list
- * call data_delete function on data if registered.
- * otherwise call free.
- * when direction true it moves marker after 
- * when direction false it moves marker before.
- * free marker node
- * return nothing.
- */
-void dlist_delete(Dlist *list,int direction)
-{
-  if((list->marker != list->head)&&(list->marker!=NULL)) 
-    {
-      DL_node *corpse;
-      corpse=list->marker;
-      _dlist_mark_move(list,direction);
-      if(list->head->next==corpse)
-       list->head->next=corpse->next;
-      if(list->head->prev==corpse)
-       list->head->prev=corpse->prev;
-      if(corpse->prev!=NULL) //should be impossible
-       corpse->prev->next=corpse->next;
-      if(corpse->next!=NULL) //should be impossible
-       corpse->next->prev=corpse->prev;
-      list->del_func(corpse->data);
-      list->count--;
-      free(corpse);
-    }
-}
-
-/*
- * Insert node containing data at marker.
- * If direction true it inserts after.
- * If direction false it inserts before.
- * move marker to inserted node
- * return pointer to inserted node
- */
-void *dlist_insert(Dlist *list,void *data,int direction)
-{
-  DL_node *new_node=NULL;
-  if(list==NULL || data==NULL)
-    return(NULL);
-  if(list->marker==NULL) //in case the marker ends up unset
-    list->marker=list->head;
-  if((new_node=malloc(sizeof(DL_node))))
-    {
-      new_node->data=data;
-      new_node->prev=NULL;
-      new_node->next=NULL;
-      list->count++;
-      if(list->head->next==NULL) //no l
-       {
-         list->head->next=list->head->prev=new_node;
-         new_node->prev=list->head;
-         new_node->next=list->head;
-       }
-      else if(direction)
-       {
-         new_node->next=list->marker->next;
-         new_node->prev=list->marker;
-         list->marker->next->prev=new_node;
-         list->marker->next=new_node;
-       }
-      else
-       {
-         new_node->prev=list->marker->prev;
-         new_node->next=list->marker;
-         list->marker->prev->next=new_node;
-         list->marker->prev=new_node;
-       }
-       list->marker=new_node;
-    }
-  else
-    {
-      return(NULL);
-    }
-  return(list->marker->data);
-}
-
-/* internal use only
- * Insert dl_node  at marker.
- * If direction true it inserts after.
- * If direction false it inserts before.
- * move marker to inserted node
- * return pointer to inserted node
- */
-void *_dlist_insert_dlnode(struct dlist *list,struct dl_node *new_node,int direction)
-{
-  if(list==NULL || new_node==NULL)
-    return(NULL);
-  if(list->marker==NULL) //in case the marker ends up unset
-    list->marker=list->head;
-  list->count++;
-  if(list->head->next==NULL) 
-    {
-      list->head->next=list->head->prev=new_node;
-      new_node->prev=list->head;
-      new_node->next=list->head;
-    }
-  else if(direction)
-    {
-      new_node->next=list->marker->next;
-      new_node->prev=list->marker;
-      list->marker->next->prev=new_node;
-      list->marker->next=new_node;
-    }
-  else
-    {
-      new_node->prev=list->marker->prev;
-      new_node->next=list->marker;
-      list->marker->prev->next=new_node;
-      list->marker->prev=new_node;
-    }
-  list->marker=new_node;
-  return(list->marker);
-}
-
-
-
-/* 
- * Remove DL_node from list without deallocating data.
- * if marker == killme .
- *  when direction true it moves marker after 
- *  when direction false it moves marker before.
- * to previous if there is no next.
- */
-void *_dlist_remove(Dlist *list,DL_node *killme,int direction)
-{
-  if(killme!=NULL)
-    {
-      void *killer_data=killme->data;
-      // take care of head and marker pointers.
-      if(list->marker==killme)
-       _dlist_mark_move(list,direction);
-      if(killme ==list->head->next)
-       list->head->next=killme->next;
-      if(killme==list->head->prev)  
-       list->head->prev=killme->prev;
-      // remove from list
-      if(killme->prev !=NULL)
-       killme->prev->next=killme->next;
-      if(killme->next !=NULL)
-       killme->next->prev=killme->prev;
-      list->count--;
-      free(killme);
-      return(killer_data);
-    }
-  else
-    return (NULL);
-}
-
-/* 
- * move dl_node from source to dest
- * if marker == target .
- *  when direction true it moves marker after 
- *  when direction false it moves marker before.
- * to previous if there is no next.
- */
-void dlist_move(struct dlist *source, struct dlist *dest, struct dl_node *target,int direction)
-{
-
-  if(target!=NULL)
-    {
-      if(target==source->head)
-       {
-         //not even going to try
-       }
-      else
-       {
-         // take care of head and marker pointers.
-         if(source->marker==target)
-           _dlist_mark_move(source,direction);
-         if(target ==source->head->next)
-           source->head->next=target->next;
-         if(target==source->head->prev)  
-           source->head->prev=target->prev;
-         // remove from list
-         if(source->count==1)
-           {
-             target->prev=NULL;
-             target->next=NULL;
-             source->head->next=NULL;
-             source->head->prev=NULL;
-           }
-         else
-           {
-             if(target->prev !=NULL)
-               target->prev->next=target->next;
-             if(target->next !=NULL)
-               target->next->prev=target->prev;
-             target->prev=NULL;
-             target->next=NULL;
-           }
-         source->count--;
-         _dlist_insert_dlnode(dest,target,direction);
-       }
-    }
-}
-
-
-/*
- * Insert node containing data after end.
- */
-void dlist_push(Dlist *list,void *data)
-{
-  list->marker=list->head->prev;
-  dlist_insert(list,data,1);
-}
-
-/*
- * Insert node containing data at start.
- */
-
-void dlist_unshift(Dlist *list,void *data)
-
-{
-  list->marker=list->head->next;
-  dlist_insert(list,data,0);
-}
-
-void dlist_unshift_sorted(Dlist *list, void *data, 
-                       int (*sorter)(void *new_elem, void *old_elem))
-{
-       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.
- * Return pointer to data in removed node.
- * Null if no nodes.
- */
-
-void *dlist_pop(Dlist *list)
-{
-  return(_dlist_remove(list,list->head->prev,0));
-}
-
-/* 
- * Remove start node from list.
- * Return pointer to data in removed node.
- * Null if no nodes.
- */
-
-void *dlist_shift(Dlist *list)
-{
-  return(_dlist_remove(list,list->head->next,1));
-}
-
-
-/* 
- * destroy the list freeing all memory
- */
-
-
-void dlist_destroy(Dlist *list)
-{
-  if(list !=NULL)
-    {
-      dlist_start(list);
-      dlist_next(list);
-      while (dlist_mark(list)) {
-             dlist_delete(list,1);
-      }
-      free(list);
-    }
-}
-
-/**
- *  Return void pointer to list_data element matching comp function criteria
- *  else null
- *  Does not move the marker.
- */
-
-void *dlist_find_custom(struct dlist *list, void *target, int (*comp)(void *, void *))
-{
-       /* test the comp function on each node */
-       struct dl_node *nodepointer;
-       dlist_for_each_nomark(list,nodepointer)
-               if(comp(target,nodepointer->data))
-                       return(nodepointer->data);
-       return(NULL);
-}
-
-/**
- * Apply the node_operation function to each data node in the list
- */
-void dlist_transform(struct dlist *list, void (*node_operation)(void *))
-{
-       struct dl_node *nodepointer;
-       dlist_for_each_nomark(list,nodepointer)
-               node_operation(nodepointer->data);
-}
-
-/**
- * insert new into list in sorted order
- * sorter function in form int sorter(new,ith)
- *       must return 1 for when new should go before ith
- *       else 0
- * return pointer to inserted node
- * NOTE: assumes list is already sorted
- */
-void *dlist_insert_sorted(struct dlist *list, void *new, int (*sorter)(void *, void *))
-{
-       for(dlist_start(list),dlist_next(list); \
-               list->marker!=list->head && !sorter(new,list->marker->data);dlist_next(list));
-       return(dlist_insert_before(list,new));
-}
-
-/*
- * NOTE: internal use only
- */
-int _dlist_merge(struct dlist *listsource, struct dlist *listdest, unsigned int passcount, int (*compare)(void *, void *))
-{
-
-  struct dl_node *l1head;
-  struct dl_node *l2head;
-  struct dl_node *target;
-  unsigned int l1count=0;
-  unsigned int l2count=0;
-  unsigned int mergecount=0;
-  while(listsource->count>0)
-    {
-      l1head=listsource->head->next;
-      l2head=l1head;
-      while((l1count<passcount)&&(l2head!=listsource->head))
-       {
-         l2head=l2head->next;
-         l1count++;
-       }
-      // so now we have two lists to merge
-      
-      if(l2head==listsource->head)
-       {// l2count
-         l2count=0;
-       }
-      else
-       {
-         l2count=passcount;
-       }
-      while(l1count>0 || l2count>0)
-       {
-         mergecount++;
-         if((l2count>0)&&(l1count>0))
-           {
-             // we have things to merge
-             int result=compare(l1head->data,l2head->data);
-             if(result>0)
-               {
-                 // move from l2
-                 target=l2head;
-                 l2head=l2head->next;
-                 dlist_move(listsource,listdest,target,1);
-                 l2count--;
-                 if(l2head==listsource->head)
-                   l2count=0;
-               }
-             else
-               {
-                 // move from l1
-                 target=l1head;
-                 l1head=l1head->next;
-                 dlist_move(listsource,listdest,target,1);
-                 l1count--;
-               }
-           }
-         else if(l1count>0)
-           {
-             // only have l1 to work with
-             while(l1count>0)
-               {
-                 target=l1head;
-                 l1head=l1head->next;
-                 dlist_move(listsource,listdest,target,1);
-                 l1count--;
-               }
-           }
-         else if(l2count>0)
-           {
-             // only have l2 to work with
-             while(l2count>0)
-               {
-                 if(l2head==listsource->head)
-                   {
-                     l2count=0;
-                   }
-                 else
-                   {
-                     target=l2head;
-                     l2head=l2head->next;
-                     dlist_move(listsource,listdest,target,1);
-                     l2count--;
-                   }
-               }
-           }
-         else
-           { //nothing left and this should be unreachable
-           }
-       }  
-    }
-  return(mergecount);
-}
-
-/**
- * mergesort the list based on compare
- * compare function in form int sorter(void * a,void * b)
- *       must return >0 for a after b
- *       must return <0 for a before b
- *       else 0
-
- * NOTE: mergesort changes the mark pointer
- */
-void dlist_sort_custom(struct dlist *list, int (*compare)(void *, void *))
-{
-
-  struct dlist *listsource, *listdest, *swap;
-  struct dlist *templist;
-  unsigned int passcount = 1;
-  unsigned int mergecount = 1;
-  
-  dlist_start(list);
-  templist = dlist_new(list->data_size);
-
-  // do nothing if there isn't anything to sort
-  listsource = list;
-  listdest = templist;
-  if(listsource->count<2)
-    { //nothing to do
-      return;
-    }
-  else
-    {
-      while(mergecount>0)
-       {
-         mergecount=_dlist_merge(listsource, listdest, passcount, compare);
-         if(mergecount>1)
-           {
-             passcount=passcount*2;
-             //start new pass
-             swap=listsource;
-             listsource=listdest;
-             listdest=swap;
-           }
-       }
-    }
-  // now put the input list pointers right
-  // list pointers = newlist pointers
-  // including the forward and next nodes prev and back pointers
-  if(list->count==0)
-    {//copy
-      list->marker = listdest->marker;
-      list->count = listdest->count;
-      list->data_size = listdest->data_size;
-      list->del_func = listdest->del_func;
-      list->head->prev = listdest->head->prev;
-      list->head->next = listdest->head->next;
-      list->head->data = listdest->head->data;
-      list->head->next->prev=list->head;
-      list->head->prev->next=list->head;
-      templist->head->next=NULL;
-      templist->head->prev=NULL;
-      templist->count=0;
-    }
-  else
-    {// no need to copy
-      
-    }
-
-  dlist_destroy(templist);
-}
-
-
-
-/* internal use function
-   swaps elements a and b
-   No sense in juggling node pointers when we can just swap the data pointers
-*/
-
-void _dlist_swap(struct dlist *list, struct dl_node *a, struct dl_node *b)
-{
-
-  void *swap=a->data;
-  a->data=b->data;
-  b->data=swap;
-  
-}
-  
diff --git a/libsysfs/libsysfs.txt b/libsysfs/libsysfs.txt
deleted file mode 100644 (file)
index b877cb8..0000000
+++ /dev/null
@@ -1,1954 +0,0 @@
-
-       System Utilities sysfs Library - libsysfs
-       =========================================
-
-Version: 1.2.0 
-September 13, 2004
-
-Contents
---------
-1. Introduction
-2. Requirements
-3. Definitions
-4. Overview
-5. Data Structures
-   5.1 Directory and Attribute Data Structures
-       5.1.1 Attribute Structure
-       5.1.2 Link Structure
-       5.1.3 Directory Structure
-   5.2 Bus Data Structure
-   5.3 Class Data Structures
-   5.4 Root Device Data Structure
-   5.5 Device Data Structure
-   5.6 Driver Data Structure
-6. Functions
-   6.1 Calling Conventions in Libsysfs
-   6.2 Utility Functions
-   6.3 Filesystem Functions
-       6.3.1 Attribute Functions
-       6.3.2 Directory Link Functions
-       6.3.3 Directory Functions
-   6.4 Bus Functions
-   6.5 Class Functions
-   6.6 Device Functions
-   6.7 Driver Functions
-7. Dlists
-   7.1 Navigating a dlist
-   7.2 Custom sorting using dlist_sort_custom()
-8. Usage
-9. Testsuite
-10. Conclusion
-
-
-1. Introduction
----------------
-
-Libsysfs' purpose is to provide a consistent and stable interface for
-querying system device information exposed through the sysfs filesystem.
-The library implements functions for querying filesystem information, 
-such as reading directories and files. It also contains routines for
-working with buses, classes, and the device tree. 
-
-
-2. Requirements
----------------
-
-The library must satisfy the following requirements:
-
-- It must provide a stable programming interfaces that applications can
-  be built upon. 
-
-- It must provide functions to retrieve device Vital Product Data (VPD)
-  information for Error Log Analysis (ELA) support. ELA will provide
-  device driver and device bus address information.
-
-- It must provide access to all system devices and information exposed
-  by sysfs.
-
-- It must provide a function to find sysfs' current mount point.
-
-- It must provide a function for udev to retrieve a device's major and
-  minor numbers.
-
-
-3. Definitions
---------------
-
-- sysfs: Sysfs is a virtual filesystem in 2.5+ Linux kernels that 
-  presents a hierarchical representation of all system physical and
-  virtual devices. It presents system devices by bus, by class, and
-  by topology. Callbacks to device drivers are exposed as files in
-  device directories. Sysfs, for all purposes, is our tree of system
-  devices. For more information, please see:
-
-       http://www.kernel.org/pub/linux/kernel/people/mochel/doc/
-
-- udev: Udev is Greg Kroah-Hartman's User Space implementation of devfs.
-  Udev creates /dev nodes for devices upon Hotplug events. The Hotplug
-  event provides udev with a sysfs directory location of the device. Udev
-  must use that directory to grab device's major and minor number, which it
-  will use to create the /dev node. For more information, please see:
-
-       http://www.kernel.org/pub/linux/utils/kernel/hotplug/
-
-  Udev provides persistent device naming based on a set of user specified
-  rules. The rules a device name is based on could one or a combination of a
-  number of parameters such as the bus the device is on, the serial number 
-  of the device (in case of USB), the vendor name (in case of SCSI) and so
-  on. Udev uses Libsysfs to retrieve relevent information to appropriately
-  name devices.
-
-
-4. Overview
------------
-
-Libsysfs grew from a common need. There are several applications under
-development that need access to sysfs and system devices. Udev, on a
-hotplug event, must take a sysfs device path and create a /dev node. Our
-diagnostic client needs to list all system devices. Finally, our Error
-Log Analysis piece is required to retrieve VPD information for a 
-failing device. We divided to create a single library interface rather 
-than having these separate applications create their own accesses to 
-sysfs involving reading directories and files.
-
-Libsysfs will also provide stability for applications to be built upon. Sysfs
-currently doesn't enforce any standards for callback or file names. File
-names change depending on bus or class. Sysfs is also changing, it is
-currently being developed. Libsysfs will provide a stable interface to
-applications while allowing sysfs to change underneath it.
-
-Like sysfs, the library will provide devices to applications by bus, by
-class, and by topology. The library will function similar to directories
-and files that lie underneath it. To query a device on a PCI bus, one would
-"open" the bus to scan or read devices and "close" the bus when 
-completed. Besides supplying functions to retrieve devices, the library
-will also provide some utility functions like getting sysfs mount point.
-
-A paper on Libsysfs was presented at Linux.Conf.Au 2004 (Adelaide, January
-2004). The paper is available online at:
-
-http://oss.software.ibm.com/linux/papers/libsysfs/libsysfs-linuxconfau2004.pdf
-
-
-5. Data Structures
-------------------
-
-Libsysfs will classify system devices following sysfs' example, dividing 
-them by bus, class, and devices. The library presents this information
-generically. It doesn't, for example, differentiate between PCI and USB 
-buses. Device attributes are presented with values as they are exposed
-by sysfs, the values are not formatted.
-
-The library will provide standard definitions for working with sysfs
-and devices, here's some examples:
-
-#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_NAME_ATTRIBUTE    "name"
-
-The library uses some definitions to mark maximum size of a sysfs name or
-path length:
-
-#define SYSFS_PATH_MAX          255
-#define SYSFS_NAME_LEN          50
-#define SYSFS_BUS_ID_SIZE       20
-
-
-NOTE:
-     a. As of release 0.4.0 of sysfsutils, a number of changes have been 
-       made so that the dlists and "directory" references in all libsysfs's 
-       structures are not populated until such time that it is absolutely
-       necessary. Hence, these elements may not contain valid data at all
-       times (as was the case before).
-     b. As of release 1.0.0 of sysfsutils, all dlists in the library are
-       sorted in alphabetical order. It is now a requirement that the 
-       "name" and "path" be the first two elements of all libsysfs
-       structures.
-
-
-5.1 Directory and Attribute Data Structures
--------------------------------------------
-
-The library implements structures to represent sysfs directories, links, 
-and files. 
-
-
-5.1.1 Attribute Structure
--------------------------
-
-A file in sysfs represents a device or driver attribute. Attributes can be
-read only, write only, or read and write. File data can be ASCII and 
-binary. The library has the following structure to represent files:
-
-struct sysfs_attribute {
-        char name[SYSFS_NAME_LEN];
-        char path[SYSFS_PATH_MAX];
-        char *value;
-        unsigned short len;             /* value length */
-        unsigned short method;          /* show and store */
-};
-
-Path represents the file/attribute's full path. Value is used when reading
-from or writing to an attribute. "len" is the length of data in "value". 
-Method is a bitmask for defining if the attribute supports show(read) 
-and/or store(write). 
-
-
-5.1.2 Link Structure
---------------------
-
-Symbolic links are used in sysfs to link bus or class views with 
-particular devices. 
-
-struct sysfs_link {
-        char name[SYSFS_NAME_LEN];
-        char path[SYSFS_PATH_MAX];
-        char target[SYSFS_PATH_MAX];
-};
-
-Link's name is stored in "name' and it's target stored in "target". Absolute 
-path to the link is stored in "path".
-
-
-5.1.3 Directory Structure
--------------------------
-
-The directory structure represents a sysfs directory:
-
-struct sysfs_directory {
-        char name[SYSFS_NAME_LEN];
-        char path[SYSFS_PATH_MAX];
-
-       /* Private: for internal use only */
-        struct dlist *subdirs;
-        struct dlist *links;
-        struct dlist *attributes;
-};
-
-The sysfs_directory structure includes the list of subdirectories, links and
-attributes. The "name" and absolute "path" are also stored in the structure.
-The sysfs_directory structure is intended for use internal to the library.
-Applications needing access to attributes and links from the directory
-will need to make appropriate calls (described below) to get the same.
-
-
-5.2 Bus Data Structure
-----------------------
-
-All buses look similar in sysfs including lists of devices and drivers,
-therefore we use the following structure to represent all sysfs buses:
-
-struct sysfs_bus {
-        char name[SYSFS_NAME_LEN];
-        char path[SYSFS_PATH_MAX];
-
-        /* Private: for internal use only */
-        struct dlist *drivers;
-        struct dlist *devices;
-        struct sysfs_directory *directory;
-};
-
-The sysfs_bus structure contains the bus "name", while the "path" to bus 
-directory is also stored. It also contains lists of devices on the bus 
-and drivers that are registered on it. The bus' directory is represented 
-by the sysfs_directory structure and it contains references to all the 
-subdirectories, links, and attributes. The sysfs_directory structure 
-is for internal use only. The following functions may be used by 
-applications to retrieve data from the sysfs_directory structure:
-
-struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus)
-struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus,
-                                               char *attrname)
-
-
-5.3 Class Data Structures
--------------------------
-
-The library uses two data structures to represent classes in sysfs. Sysfs
-classes contains a class directory like "net" or "scsi_host" and then
-class devices like "eth0", "lo", or "eth1" for the "net" class.
-
-struct sysfs_class {
-        char name[SYSFS_NAME_LEN];
-        char path[SYSFS_PATH_MAX];
-
-        /* Private: for internal use only */
-        struct dlist *devices;
-        struct sysfs_directory *directory;
-};
-
-The sysfs_class represents device classes in sysfs like "net". It contains  
-the class "name", "path" to the class, a list of class devices and the 
-directory representation (for internal use only). 
-
-struct sysfs_class_device {
-        char name[SYSFS_NAME_LEN];
-        char path[SYSFS_PATH_MAX];
-        char classname[SYSFS_NAME_LEN];
-
-        /* Private: for internal use only */
-       struct sysfs_class_device *parent;
-        struct sysfs_device *sysdevice;         /* NULL if virtual */
-        struct sysfs_driver *driver;            /* NULL if not implemented */
-        struct sysfs_directory *directory;
-};
-
-A class device isn't the same as a sysfs_device, it's specific to the class in 
-which it belongs. The class device structure contains the name of the class
-the class device belongs to, its sysfs_device reference and that device's 
-driver reference (if any). It also contains the name of the class device 
-- like "eth0", its parent point (if present) and its sysfs directory 
-information including links and attributes (for internal use only). 
-The following function may be used by applications to retrieve data
-from the sysfs_directory structure:
-
-struct dlist *sysfs_get_classdev_attributes(struct sysfs_class_device *cdev);
-
-
-5.4 Root Device Data Structure
-------------------------------
-
-Device hierarchies in sysfs are represented under the /sys/devices directory 
-structure. Sysfs devices typically spawn off from base devices which are 
-represented by a sysfs_root_device. 
-
-struct sysfs_root_device {
-        char name[SYSFS_NAME_LEN];
-        char path[SYSFS_PATH_MAX];
-
-        /* Private: for internal use only */
-        struct dlist *devices;
-        struct sysfs_directory *directory;
-};
-
-The sysfs_root_device structure contains a list of "devices" that spawn off it.
-The name of the root device as represented under /sys/devices is read into 
-"name" and the absolute path into "path" and its sysfs_directory information 
-intended to be used internal to the library. 
-
-
-5.5 Device Data Structure
--------------------------
-
-The sysfs_device structure represents a system device that's exposed
-in sysfs under the /sys/devices directory structure.
-
-struct sysfs_device {
-        char name[SYSFS_NAME_LEN];
-        char path[SYSFS_PATH_MAX];
-        char bus_id[SYSFS_NAME_LEN];
-        char bus[SYSFS_NAME_LEN];
-        char driver_name[SYSFS_NAME_LEN];
-
-        /* Private: for internal use only */
-        struct sysfs_device *parent;
-        struct dlist *children;
-        struct sysfs_directory *directory;
-};
-
-The sysfs_device structure contains a "parent" pointer, a list of child
-devices, if any, device's directory, its bus id - which is the name of 
-device's directory, the bus name on which this device is registered and 
-its driver name. The device structure also contains the absolute path
-to the device and a directory structure, which contains a list of the 
-device's attributes (for internal use only). The following functions 
-may be used to obtain information from sysfs_directory structure:
-
-struct sysfs_attribute *sysfs_get_device_attribute(struct sysfs_device *dev,
-                                               const char *name)
-struct dlist *sysfs_get_device_attributes(struct sysfs_device *device)
-
-
-5.6 Driver Data Structure
--------------------------
-
-The sysfs_driver structure represents a device driver.
-
-struct sysfs_driver {
-        char name[SYSFS_NAME_LEN];
-        char path[SYSFS_PATH_MAX];
-
-        /* Private: for internal use only */
-        struct dlist *devices;
-        struct sysfs_directory *directory;
-};
-
-The sysfs_driver structure contains a list of devices that use this driver,
-the name of the driver, its path, and its directory information, which 
-includes the driver's attributes (for internal use only). The following
-function may be used to retrieve driver attribute information from the
-sysfs_directory structure:
-
-struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver)
-
-
-6. Functions
-------------
-
-Libsysfs will provide functions to access system devices by bus, by class,
-and by device. Functions will act like accessing directories and files, 
-using "open" and "close". Open returns a structure and close is used
-to clean that structure up.
-
-
-6.1 Calling Conventions in Libsysfs
------------------------------------
-
-Libsysfs uses a simple API calling convention. APIs are classified to be 
-one of "open", "get", "close" types. The convention is as follows:
-
-       a. All "open" APIs have a corresponding "close" API.
-       b. References obtained using "get" calls should not be closed
-               explicitly.
-       c. All "opened" references have to be closed with a call to
-               their corresponding "close" call. This takes care of
-               freeing structure references obtained with "get" calls.
-
-
-6.2 Utility Functions
----------------------
-
-The library will provide a few utility functions for working with sysfs.
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_mnt_path
-
-Description:   Function finds the mount path for filesystem type "sysfs".
-
-Arguments:     char *mnt_path          Mount path buffer
-               size_t len              Size of mount path buffer       
-
-Returns:       Zero with success.
-               -1 with error. Errno will be set with error:
-                       - EINVAL for invalid argument, if buffer is NULL or
-                               if len is zero
-
-Prototype:     sysfs_get_mnt_path(char *mnt_path, size_t len);
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_name_from_path
-
-Description:   Function returns the last directory or file name from the
-               included path.
-
-Arguments:     const char *path        Path to parse name from
-               char *name              Buffer to put parsed name into
-               size_t *len             Size of name buffer
-
-Returns:       0 with success.
-               -1 on Error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     int sysfs_get_name_from_path(const char *path, 
-                                       char *name, size_t *len)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_link
-
-Description:   Sysfs readlink function, reads the link at supplied path
-               and returns its target path.
-
-Arguments:     const char *path        Link's path
-               char *target            Buffer to place link's target 
-               size_t len              Size of target buffer
-
-Returns:       0 with success 
-               -1 with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     int sysfs_get_link(const char *path, char *target, size_t len)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_open_subsystem_list
-
-Description:   Function returns the list of entries for the given subsystem. If
-               the argument is "bus", this function will return a list of buses
-               ("pci", "scsi", etc) supported on the system.
-
-               sysfs_close_list() has to be called to free the list obtained
-               from this call.
-
-Arguments:     char *name              Subsystem to open, like "bus"..
-
-Returns:       dlist of entries for the subsystem on success
-               NULL with error indicating the "name" subsystem is invalid.
-
-Prototype:     struct dlist *sysfs_open_subsystem_list(char *name)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_open_bus_devices_list
-
-Description:   Function returns the list of devices on the given bus. 
-
-               sysfs_close_list() has to be called to free the list obtained
-               from this call.
-
-Arguments:     char *name              Bus name to open "pci"/"scsi"/"usb"..
-
-Returns:       dlist of device names for the given bus on success
-               NULL with error indicating the bus is not supported.
-
-Prototype:     struct dlist *sysfs_open_bus_devices_list(char *name)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_close_list
-
-Description:   Closes a given dlist. This can be used as a generic list close
-               routine.
-
-Arguments:     struct dlist *list      List to be closed
-
-Prototype:     void sysfs_close_list(struct dlist *list)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_path_is_dir
-
-Description:   Utility function to verify if a given path is to a directory.
-
-Arguments:     const char *path        Path to verify
-
-Returns:       0 on success, 1 on error
-                       - EINVAL for invalid arguments
-
-Prototype:     int sysfs_path_is_dir(const char *path)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_path_is_file
-
-Description:   Utility function to verify if a given path is to a file.
-
-Arguments:     const char *path        Path to verify
-
-Returns:       0 on success, 1 on error
-                       - EINVAL for invalid arguments
-
-Prototype:     int sysfs_path_is_file(const char *path)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_path_is_link
-
-Description:   Utility function to verify if a given path is to a link.
-
-Arguments:     const char *path        Path to verify
-
-Returns:       0 on success, 1 on error
-                       - EINVAL for invalid arguments
-
-Prototype:     int sysfs_path_is_link(const char *path)
--------------------------------------------------------------------------------
-
-
-6.3 Filesystem Functions
-------------------------
-
-Libsysfs provides a set of functions to open, read, and close directories
-and attributes/files in sysfs. These functions mirror their filesystem
-function counterparts. 
-
-
-6.3.1 Attribute Functions
--------------------------
-
-Along with the usual open, read, and close functions, libsysfs provides
-a couple other functions for accessing attribute values. 
-
--------------------------------------------------------------------------------
-Name:          sysfs_open_attribute
-
-Description:   Opens up a file in sysfs and creates a sysfs_attribute
-               structure. File isn't read with this function.
-
-Arguments:     const char *path        File/Attribute's path
-
-Returns:       struct sysfs_attribute * with success.
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_attribute *sysfs_open_attribute(const char *path)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_close_attribute
-
-Description:   Cleans up and closes sysfs_attribute structure.
-
-Arguments:     struct sysfs_attribute *sysattr Attribute to close
-
-Prototype:     void sysfs_close_attribute(struct sysfs_attribute *sysattr)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_read_dir_attributes
-
-Description:   Reads the given sysfs_directory to create a list of attributes.
-
-Arguments:     struct sysfs_directory *sysdir  sysfs_directory whose 
-                                               attributes to read
-
-Returns:       struct dlist * of attributes on success
-               NULL with error. Errno will be set on error, returning EINVAL
-                               for invalid arguments
-               
-Prototype:     struct dlist *sysfs_read_dir_attributes
-                                       (struct sysfs_directory *sysdir)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_refresh_dir_attributes
-
-Description:   Given a list sysfs_directory, this function refreshes the list
-               of attributes for the given directory.
-
-Arguments:     struct sysfs_directory *sysdir  sysfs_ directory whose 
-                                               attributes list to refresh
-
-Returns:       0 with success.
-               1 with error. Errno will be set on error, returning EINVAL
-                               for invalid arguments
-
-Prototype:     int sysfs_refresh_dir_attributes(struct sysfs_directory *sysdir)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_dir_attributes
-
-Description:   Returns a list of attributes for the given sysfs_directory.
-
-Arguments:     struct sysfs_directory *sysdir  sysfs_directory whose 
-                                               attributes list to return
-
-Returns:       struct dlist * of attributes with success
-               NULL with error. Errno will be set on error, returning EINVAL
-                               for invalid arguments
-               
-Prototype:     struct dlist *sysfs_read_dir_attributes
-                                       (struct sysfs_directory *sysdir)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_read_attribute
-
-Description:   Reads the supplied attribute. Since the maximum transfer
-               from a sysfs attribute is a pagesize, function reads in
-               up to a page from the file and stores it in the "value"
-               field in the attribute.
-
-Arguments:     struct sysfs_attribute *sysattr         Attribute to read
-
-Returns:       0 with success.
-               -1 with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     int sysfs_read_attribute(struct sysfs_attribute *sysattr)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_write_attribute
-
-Description:   Writes to the supplied attribute. Function validates if the
-               given attribute is writable, and writes the new value to the 
-               attribute. Value to write as well as its length is user 
-               supplied. In case the length written is not equal to the 
-               length requested to be written, the original value is 
-               restored and an error is returned.
-
-Arguments:     struct sysfs_attribute *sysattr         Attribute to write to
-               const char *new_value                   sysattr's new value
-               size_t len                              Length of "new_value"
-
-Returns:       0 with success.
-               -1 with error. Errno will be set with error, returning 
-                       - EINVAL for invalid arguments
-
-Prototype:     int sysfs_write_attribute(struct sysfs_attribute *sysattr,
-                               const char *new_value, size_t len)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_read_attribute_value
-
-Description:   Given a path to a specific attribute, function reads and
-               returns its value to the supplied value buffer.
-
-Arguments:     const char *attrpath    Attribute path to read
-               char *value             Buffer to read in attribute's value
-               size_t vsize            Size of buffer
-
-Returns:       0 with success.
-               -1 with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     int sysfs_read_attribute_value(const char *attrpath, 
-                                       char *value, size_t vsize)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_value_from_attributes
-
-Description:   Function takes a single or linked list of sysfs attribute
-               structures and returns the value of the specified attribute
-               name.
-
-Arguments:     struct dlist *attr      Attribute list to search through
-               const char *name        Name of attribute whose value
-                                       to retrieve
-
-Returns:       char * attribute value with success.
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     char *sysfs_get_value_from_attributes
-                       (struct sysfs_attribute *attr, const char *name)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_directory_attribute
-
-Description:   Function walks the list of attributes for the given sysfs 
-               directory and returns the sysfs_attribute structure for
-               the specified attribute name.
-
-Arguments:     struct sysfs_directory *dir     Directory in which to search
-               char *attrname                  Attribute name to look for
-
-Returns:       struct sysfs_attribute on success.
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_attribute *sysfs_get_directory_attribute
-                       (struct sysfs_directory *dir, char *attrname)
--------------------------------------------------------------------------------
-               
-
-6.3.2 Link Functions
---------------------
-
-Sysfs contains many symbolic links, like bus links to bus devices. Libsysfs
-treats links differently than directories due to processing differences. A
-link in the /sys/bus/"busname"/devices/ directory indicates a device in the
-/sys/devices directory. Through links we give the functionality to know
-what is and what isn't a link and the ability to query the links target.
-
--------------------------------------------------------------------------------
-Name:          sysfs_open_link
-
-Description:   Opens a directory link. 
-
-Arguments:     const char *linkpath            Path to link
-
-Returns:       struct sysfs_link * with success.
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_link *sysfs_open_link(const char *linkpath)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_close_link
-
-Description:   Closes a directory link structure.
-
-Arguments:     struct sysfs_link *ln           Link to close
-
-Prototype:     void sysfs_close_link(struct sysfs_link *ln)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_read_dir_links
-
-Description:   Reads the given sysfs_directory to create a list of links.
-
-Arguments:     struct sysfs_directory *sysdir  sysfs_directory whose 
-                                               links to read
-
-Returns:       struct dlist * of links with success
-               NULL with error. Errno will be set on error, returning EINVAL
-                               for invalid arguments
-               
-Prototype:     struct dlist *sysfs_read_dir_links
-                                       (struct sysfs_directory *sysdir)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_dir_links
-
-Description:   Returns a list of links for the given sysfs_directory.
-
-Arguments:     struct sysfs_directory *sysdir  sysfs_directory whose 
-                                               list of links to return
-
-Returns:       struct dlist * of links with success
-               NULL with error. Errno will be set on error, returning EINVAL
-                               for invalid arguments
-               
-Prototype:     struct dlist *sysfs_read_dir_links
-                                       (struct sysfs_directory *sysdir)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_directory_link
-
-Description:   Function walks the list of links for the given sysfs directory 
-               and returns the sysfs_link structure for the specified link 
-               name.
-
-Arguments:     struct sysfs_directory *dir     Directory in which to search
-               char *linkname                  Link name to look for
-
-Returns:       struct sysfs_link * with success.
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_link *sysfs_get_directory_link
-                       (struct sysfs_directory *dir, char *linkname)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_subdirectory_link
-
-Description:   Function walks the list of links for the given sysfs directory 
-               and its subdirectories returns the sysfs_link structure for 
-               the specified link name.
-
-Arguments:     struct sysfs_directory *dir     Directory in which to search
-               char *linkname                  Link name to look for
-
-Returns:       struct sysfs_link * with success.
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_link *sysfs_get_subdirectory_link
-                       (struct sysfs_directory *dir, char *linkname)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_refresh_dir_links
-
-Description:   Given a list sysfs_directory, this function refreshes the list
-               of links under the given directory.
-
-Arguments:     struct sysfs_directory *sysdir  sysfs_ directory whose 
-                                               links list to refresh
-
-Returns:       0 with success.
-               1 with error. Errno will be set on error, returning EINVAL
-                               for invalid arguments
-
-Prototype:     int sysfs_refresh_dir_links(struct sysfs_directory *sysdir)
--------------------------------------------------------------------------------
-
-
-6.3.3 Directory Functions
--------------------------
-
-Sysfs directories can represent every directory under sysfs. The structures
-keep track of subdirectories, links, and files. Like opendir, readdir, and
-closedir, libsysfs provides open, read, and close functions for working with
-sysfs directories. Open creates the sysfs_directory structure. Read reads in
-its contents - like subdirectories, links, and files. Close cleans it all
-up.
-
--------------------------------------------------------------------------------
-Name:          sysfs_open_directory
-
-Description:   Opens a sysfs directory at a specific path
-
-Arguments:     const char *path        Directory path to open
-
-Returns:       struct sysfs_directory * with success.
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_directory *sysfs_open_directory(const char *path)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_close_directory
-
-Description:   Closes specific directory, its subdirectories, links, and
-               files.
-
-Arguments:     struct sysfs_directory *sysdir  Directory to close
-
-Prototype:     void sysfs_close_directory(struct sysfs_directory *sysdir)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_read_dir_subdirs
-
-Description:   Reads the given sysfs_directory to create a list of subdirs.
-
-Arguments:     struct sysfs_directory *sysdir  sysfs_directory whose 
-                                               subdirs have to be read
-
-Returns:       struct dlist * of links with success
-               NULL with error. Errno will be set on error, returning EINVAL
-                               for invalid arguments
-               
-Prototype:     struct dlist *sysfs_read_dir_subdirs
-                                       (struct sysfs_directory *sysdir)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_read_directory
-
-Description:   Read the supplied directory. Reading fills in the directory's
-               contents like subdirectories, links, and attributes.
-
-Arguments:     struct sysfs_directory *sysdir  Directory to read
-
-Returns:       0 with success.
-               -1 with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     int sysfs_read_directory(struct sysfs_directory *sysdir)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_read_all_subdirs
-
-Description:   Reads all subdirs under a given supplied directory. 
-
-Arguments:     struct sysfs_directory *sysdir  Directory to read
-
-Returns:       0 with success.
-               -1 with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     int sysfs_read_all_subdirs(struct sysfs_directory *sysdir)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_subdirectory
-
-Description:   Function walks the directory tree for the given directory and
-               returns a sysfs_directory structure for the specified directory
-               name.
-
-Arguments:     struct sysfs_directory *dir     Directory in which to search
-               char *subname                   Name of directory to look for
-
-Returns:       struct sysfs_directory with success.
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_directory *sysfs_get_subdirectory
-                               (struct sysfs_directory *dir, char *subname)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_dir_subdirs
-
-Description:   Returns a list of subdirs for the given sysfs_directory.
-
-Arguments:     struct sysfs_directory *sysdir  sysfs_directory whose 
-                                               subdirectories list to return
-
-Returns:       struct dlist * of directories with success
-               NULL with error. Errno will be set on error, returning EINVAL
-                               for invalid arguments
-               
-Prototype:     struct dlist *sysfs_read_dir_subdirs
-                                       (struct sysfs_directory *sysdir)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_refresh_dir_subdirs
-
-Description:   Given a list sysfs_directory, this function refreshes the list
-               of subdirectories under the given directory.
-
-Arguments:     struct sysfs_directory *sysdir  sysfs_ directory whose 
-                                               subdirs list to refresh
-
-Returns:       0 with success.
-               1 with error. Errno will be set on error, returning EINVAL
-                               for invalid arguments
-
-Prototype:     int sysfs_refresh_dir_subdirs(struct sysfs_directory *sysdir)
--------------------------------------------------------------------------------
-
-
-6.4 Bus Functions
------------------
-
-The library provides a functions for viewing buses represented in sysfs. 
-The sysfs_open_bus opens a bus in the /sys/bus directory, such as "pci",
-"usb", or "scsi". The open command returns a sysfs_bus structure that 
-contains a list of the bus' devices. The sysfs_close_bus function is 
-used to clean up the bus structure. Given a device or a driver, 
-functions are provided to determine what bus they are on.
-
--------------------------------------------------------------------------------
-Name:          sysfs_open_bus
-
-Description:   Function opens up one of the buses represented in sysfs in
-               the /sys/bus directory. It returns a sysfs_bus structure
-               that includes a list of bus devices and drivers.
-
-Arguments:     const char *name        Bus name to open, like "pci"...
-
-Returns:       struct sysfs_bus * with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_bus *sysfs_open_bus(const char *name)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_close_bus
-
-Description:   Function closes up the sysfs_bus structure including its
-               devices, drivers, and directory.
-
-Arguments:     sysfs_bus *bus          Bus structure to close
-
-Prototype:     void sysfs_close_bus(struct sysfs_bus *bus)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_bus_devices
-
-Description:   Function returns a list of devices that are registered with
-               this bus.
-
-Arguments:     struct sysfs_bus *bus   Bus whose devices list to return
-
-Returns:       struct dlist * of sysfs_devices on success
-               NULL with error. Errno will be sent with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_bus_drivers
-
-Description:   Function returns a list of drivers that are registered with
-               this bus.
-
-Arguments:     struct sysfs_bus *bus   Bus whose drivers list to return
-
-Returns:       struct dlist * of sysfs_drivers on success
-               NULL with error. Errno will be sent with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_bus_device
-
-Description:   Function takes a sysfs_bus structure(obtained on a successful 
-               return from a sysfs_open_bus() call) and looks for the given 
-               device on this bus. On success, it returns a sysfs_device 
-               structure corresponding to the device.
-
-Arguments:     struct sysfs_bus *bus   Bus structure on which to search
-               char *id                Device to look for
-
-Returns:       struct sysfs_device * with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_device *sysfs_get_bus_device
-                               (struct sysfs_bus *bus, char *id)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_bus_driver
-
-Description:   Function takes a sysfs_bus structure (obtained on a successful 
-               return from a sysfs_open_bus() call) and looks for the given 
-               driver on this bus. On success, it returns a sysfs_driver 
-               structure corresponding to the driver.
-
-Arguments:     struct sysfs_bus *bus   Bus structure on which to search
-               char *drvname           Driver to look for
-
-Returns:       struct sysfs_driver * with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_device *sysfs_get_bus_driver
-                               (struct sysfs_bus *bus, char *drvname)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_bus_attributes
-
-Description:   Function takes a sysfs_bus structure and returns a list of
-               attributes for the bus.
-
-Arguments:     struct sysfs_bus *bus   Bus for which attributes are required
-
-Returns:       struct dlist * of attributes with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_bus_attribute
-
-Description:   Function takes a sysfs_bus structure and looks for the required
-               attribute on the bus. On success, it returns a sysfs_attribute
-               structure corresponding to the given attribute.
-
-Arguments:     struct sysfs_bus *bus           Bus structure on which to search
-               char *attrname                  Attribute to look for
-
-Returns:       struct sysfs_attribute * with success
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_attribute *sysfs_get_bus_attribute
-                               (struct sysfs_bus *bus, char *attrname)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_refresh_bus_attributes
-
-Description:   Function refreshes the list of attributes for a given sysfs_bus
-
-Arguments:     struct sysfs_bus *bus   Bus whose attributes list to refresh
-
-Returns:       struct dlist * of attributes with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_find_driver_bus
-
-Description:   Given the name of a driver, this function finds the name of the
-               bus the driver is on
-
-Arguments:     const char *driver      Name of the driver to look for
-               char *busname           Buffer to return the bus name
-               size_t bsize            Size of the "busname" buffer
-
-Returns:       0 with success.
-               -1 with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     int sysfs_find_driver_bus(const char *driver,
-                                       char *busname, size_t bsize)
--------------------------------------------------------------------------------
-
-
-6.5 Class Functions
--------------------
-
-Libsysfs provides functions to open sysfs classes and their class devices.
-These functions too operate with open and close, close must be called to
-clean up the class structures. Given a class device name, functions are
-provided to determine what class they belong to. Once a class device
-name and the class it belongs to is known, a function to open the
-class device is provided. This method can be used when details of
-a single class device is required.
-
--------------------------------------------------------------------------------
-Name:          sysfs_open_class
-
-Description:   Function opens up one of the classes represented in sysfs in
-               the /sys/class directory. It returns a sysfs_class structure
-               that includes a list of class devices.
-
-Arguments:     const char *name        Class name to open, like "net"..
-
-Returns:       struct sysfs_class * with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_class *sysfs_open_class(const char *name)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_close_class
-
-Description:   Function closes up the sysfs_class structure including its
-               class devices.
-
-Arguments:     sysfs_class *cls        Class structure to close
-
-Prototype:     void sysfs_close_class(struct sysfs_class *cls);
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_open_class_device_path
-
-Description:   Function opens up one of the class devices represented in 
-               sysfs in sysfs/class/"class"/ directory. It returns a
-               sysfs_class_device structure.
-
-Arguments:     const char *path        Path to class device
-
-Returns:       struct sysfs_class_device * with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_class_device *sysfs_open_class_device_path
-                                       (const char *path)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_close_class_device
-
-Description:   Function closes up the sysfs_class_device structure.
-
-Arguments:     sysfs_class_device *dev Class device structure to close
-
-Prototype:     void sysfs_close_class_device(struct sysfs_class_device *dev)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_class_device
-
-Description:   Function takes a sysfs_class structure(obtained on a successful 
-               return from a sysfs_open_class() call) and looks for the given 
-               device in this class. On success, it returns a sysfs_class_device 
-               structure corresponding to the class device.
-
-Arguments:     struct sysfs_class *cls         Class on which to search
-               char *name                      Class device "name" to look for
-
-Returns:       struct sysfs_class_device * with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_class_device *sysfs_get_class_device
-                               (struct sysfs_class *cls, char *name)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_class_devices
-
-Description:   Function returns a list of class devices for the given class.
-
-Arguments:     struct sysfs_class *cls         Class whose class device list
-                                               is required
-
-Returns:       struct dlist * of sysfs_class_devices on success
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct dlist *sysfs_get_class_devices(struct sysfs_class *cls)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_open_class_device
-
-Description:   Given the name of the class on which to look for, this function 
-               locates a given class device and returns a sysfs_class_device 
-               structure corresponding to the requested class device.
-
-       NOTE:   
-               1. The sysfs_class_device structure obtained upon successful 
-                  return from this function has to be closed by calling 
-                  sysfs_close_class_device().
-               2. Class this device belongs to must be known prior to calling
-                  this function. 
-
-Arguments:     const char *classname   Class on which to search
-               char *name              Class device "name" to open
-
-Returns:       struct sysfs_class_device * with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_class_device *sysfs_open_class_device
-                       (const char *classname, char *name)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_classdev_device
-
-Description:   Function returns the sysfs_device reference (if present) for the 
-               given class device.
-
-Arguments:     struct sysfs_class_device *clsdev       Class device whose
-                                                       sysfs_device reference
-                                                       is required
-
-Returns:       struct sysfs_device * on success
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-               
-Prototype:     struct sysfs_device *sysfs_get_classdev_device
-                                       (struct sysfs_class_device *clsdev)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_classdev_driver
-
-Description:   Function returns the sysfs_driver reference (if present) for 
-               the given class device.
-
-Arguments:     struct sysfs_class_device *clsdev       Class device whose
-                                                       sysfs_driver reference
-                                                       is required
-
-Returns:       struct sysfs_driver * on success
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-               
-Prototype:     struct sysfs_driver *sysfs_get_classdev_driver
-                                       (struct sysfs_class_device *clsdev)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_classdev_parent
-
-Description:   Function returns the sysfs_class_device reference for the
-               parent (if present) of the given class device.
-
-Arguments:     struct sysfs_class_device *clsdev       Class device whose
-                                                       parent reference
-                                                       is required
-
-Returns:       struct sysfs_class_device * on success
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-               
-Prototype:     struct sysfs_class_device *sysfs_get_classdev_parent
-                                       (struct sysfs_class_device *clsdev)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_classdev_attributes
-
-Description:   Function takes a sysfs_class_device structure and returns a 
-               list of attributes for the class device.
-
-Arguments:     struct sysfs_class_device *cdev         Class device for which 
-                                                       attributes are required
-
-Returns:       struct dlist * of attributes with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct dlist *sysfs_get_classdev_attributes
-                                       (struct sysfs_class_device *cdev)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_classdev_attr
-
-Description:   Searches supplied class device's attributes by name and returns
-               the attribute.
-       
-Arguments:     struct sysfs_class_device *clsdev       Device to search
-               const char *name                        Attribute name to find
-
-Returns:       struct sysfs_attribute * with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_attribute *sysfs_get_classdev_attr
-               (struct sysfs_class_device *clsdev, const char *name)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_refresh_classdev_attributes
-
-Description:   Function refreshes the list of attributes for a given
-               sysfs_class_device.
-
-Arguments:     struct sysfs_class_device *cdev Class device whose attributes 
-                                               list to refresh
-
-Returns:       struct dlist * of attributes with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct dlist *sysfs_get_classdev_attributes
-                                       (struct sysfs_class_device *cdev)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_open_classdev_attr
-
-Description:   Function takes as arguments, a the name of the class, the class
-               device name and the name of the required attribute.
-
-       NOTE:
-               1. The struct sysfs_attribute * obtained upon successful
-                       return from this function has to be closed by making
-                       a call to sysfs_close_attribute()
-
-Arguments:     char *classname         Class name on which to search
-               char *dev               Name of the class device
-               char *attrib            Attribute to open
-
-Returns:       struct sysfs_attribute * with success.
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_attribute *sysfs_write_classdev_attr
-                       (const char *classname, const char *dev, 
-                                                       const char *attrib)
--------------------------------------------------------------------------------
-
-
-6.6 Device Functions
---------------------
-
-Devices represent everything in sysfs under /sys/devices, which is a
-hierarchical view of system devices. Besides the expected open and 
-close functions, libsysfs provides open and close functions for
-root devices. These functions recursively open or close a device 
-and all of its children. 
-
--------------------------------------------------------------------------------
-Name:          sysfs_open_device_path
-
-Description:   Opens up a device at a specific path. It opens the device's
-               directory, reads the directory, and returns a sysfs_device
-               structure.
-
-Arguments:     const char *path        Path to device
-
-Returns:       struct sysfs_device * with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_device *sysfs_open_device_path(const char *path)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_close_device
-
-Description:   Function closes up the sysfs_device structure.
-
-Arguments:     sysfs_device *dev               Device structure to close
-
-Prototype:     void sysfs_close_device(struct sysfs_device *dev)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_open_root_device
-
-Description:   Function opens up one of the root devices represented in sysfs 
-               in the /sys/devices directory. It returns a sysfs_root_device
-               structure that includes a list of devices in the tree.
-
-Arguments:     const char *name        Name of the root device to open
-
-Returns:       struct sysfs_root_device * with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_device *sysfs_open_root_device(const char *name)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_close_root_device
-
-Description:   Function closes up the sysfs_root_device structure including the
-               devices in the root device tree.
-
-Arguments:     sysfs_device *root      Root device structure to close
-
-Prototype:     void sysfs_close_root_device(struct sysfs_root_device *root)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_open_device_tree
-
-Description:   Function opens up the device tree at the specified path.
-
-Arguments:     const char *path        Path at which to open the device tree
-
-Returns:       struct sysfs_device * with success
-               NULL with error, Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_device *sysfs_open_device_tree(const char *path)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_close_device_tree
-
-Description:   Function closes the device tree originating at the given 
-               sysfs_device.
-
-Arguments:     struct sysfs_device *devroot    Device from which the device
-                                               tree has to be closed
-
-Prototype:     void sysfs_close_device_tree(struct sysfs_device *devroot)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_device_parent
-
-Description:   Function returns the sysfs_device reference for the parent 
-               (if present) of the given sysfs_device.
-
-Arguments:     struct sysfs_device *dev        sysfs_device whose parent 
-                                               reference is required
-
-Returns:       struct sysfs_device * on success
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-               
-Prototype:     struct sysfs_device *sysfs_get_device_parent
-                                               (struct sysfs_device *dev)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_root_devices
-
-Description:   Function returns a list of devices under the given root device.
-
-Arguments:     struct sysfs_root_device *root  sysfs_root_device whose devices
-                                               list is required
-
-Returns:       struct dlist * of sysfs_devices on success
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct dlist *sysfs_get_root_devices
-                                       (struct sysfs_root_device *root)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_device_attr
-
-Description:   Searches supplied device's attributes by name and returns
-               the attribute.
-
-Arguments:     struct sysfs_device *dev        Device to search
-               const char *name                Attribute name to find
-
-Returns:       struct sysfs_attribute * with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_attribute *sysfs_get_device_attr
-                       (struct sysfs_device *dev, const char *name)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_device_attributes
-
-Description:   Function takes a sysfs_device structure and returns a list 
-               of attributes for the device.
-
-Arguments:     struct sysfs_device *device     Device for which 
-                                               attributes are required
-
-Returns:       struct dlist * of attributes with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct dlist *sysfs_get_device_attributes
-                                       (struct sysfs_device *device)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_refresh_device_attributes
-
-Description:   Function refreshes the list of attributes for a given
-               sysfs_device.
-
-Arguments:     struct sysfs_device *device     Device whose attributes list 
-                                               to refresh
-
-Returns:       struct dlist * of attributes with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct dlist *sysfs_refresh_device_attributes
-                                       (struct sysfs_device *device)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_open_device
-
-Description:   Given the name of the bus on which to look for, this function 
-               locates a given device and returns a sysfs_device structure 
-               corresponding to the requested device.
-
-Arguments:     const char *bus         Bus on which to search
-               const char *bus_id      Device to look for
-
-Returns:       struct sysfs_device * with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_device *sysfs_open_device
-                       (const char *bus, const char *bus_id)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_device_bus
-
-Description:   Given a sysfs_device, this function fills in the bus this 
-               device is on in the sysfs_device->bus field.
-
-Arguments:     struct sysfs_device *dev        Device whose bus name to find
-
-Returns:       0 with success.
-               -1 with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     int sysfs_get_device_bus(struct sysfs_device *dev)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_open_device_attr
-
-Description:   Function takes as arguments, the bus on which to search for a 
-               device, and an attribute of the device to open. 
-
-       NOTE:
-               1. The struct sysfs_attribute * obtained upon successful
-                       return from this function has to be closed by making
-                       a call to sysfs_close_attribute()
-
-Arguments:     char *bus               Bus on which to search
-               char *bus_id            Device to look for
-               char *attrib            Name of the attribute to open
-
-Returns:       struct sysfs_attribute * with success.
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_attribute *sysfs_open_device_attr
-               (const char *bus, const char *bus_id, const char *attrib)
--------------------------------------------------------------------------------
-
-
-6.7 Driver Functions
---------------------
-
-Drivers are represented in sysfs under the /sys/bus/xxx/drivers (xxx being
-the bus type, such as "pci", "usb, and so on). Functions are provided to
-open and close drivers.
-
--------------------------------------------------------------------------------
-Name:          sysfs_open_driver_path
-
-Description:   Opens driver at specific path.
-
-Arguments:     const char *path        Path to driver
-
-Returns:       struct sysfs_driver * with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_driver *sysfs_open_driver_path(const char *path)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_close_driver
-
-Description:   Closes and cleans up sysfs_driver structure.
-
-Arguments:     sysfs_driver *driver    Driver structure to close
-
-Prototype:     void sysfs_close_driver(struct sysfs_driver *driver)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_driver_devices
-
-Description:   Function returns a list of devices that use this driver.
-
-Arguments:     struct sysfs_driver *driver     Driver whose devices list is
-                                               required
-
-Returns:       struct dlist * of sysfs_devices on success
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct dlist *sysfs_get_driver_devices
-                                       (struct sysfs_driver *driver)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_refresh_driver_devices
-
-Description:   Function refreshes the list of devices that use this driver.
-
-Arguments:     struct sysfs_driver *driver     Driver whose devices list is
-                                               required to be refreshed
-
-Returns:       struct dlist * of sysfs_devices on success
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct dlist *sysfs_refresh_driver_devices
-                                       (struct sysfs_driver *driver)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_driver_device
-
-Description:   Function returns a sysfs_device reference for the device with 
-               "name" that uses this driver
-
-Arguments:     struct sysfs_driver *driver     Driver on which to search
-               const char *name                Name of the device to look for
-
-Returns:       struct sysfs_device * corresponding to "name" on success
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct dlist *sysfs_get_driver_device
-                       (struct sysfs_driver *driver, const char *name)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_driver_attr
-
-Description:   Searches supplied driver's attributes by name and returns
-               the attribute.
-
-Arguments:     struct sysfs_driver *drv        Driver to search
-               const char *name                Attribute name to find
-
-Returns:       struct sysfs_attribute * with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_attribute *sysfs_get_driver_attr
-                       (struct sysfs_driver *drv, const char *name)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_driver_attributes
-
-Description:   Function takes a sysfs_driver structure and returns a list 
-               of attributes for the driver.
-
-Arguments:     struct sysfs_driver *driver     Driver for which attributes 
-                                               are required
-
-Returns:       struct dlist * of attributes with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct dlist *sysfs_get_driver_attributes
-                                       (struct sysfs_driver *driver)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_refresh_driver_attributes
-
-Description:   Function refreshes the list of attributes for a given
-               sysfs_driver.
-
-Arguments:     struct sysfs_driver *driver     Driver whose attributes list 
-                                               to refresh
-
-Returns:       struct dlist * of attributes with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct dlist *sysfs_refresh_driver_attributes
-                                       (struct sysfs_driver *driver)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_open_driver
-
-Description:   Given the name of the bus on which to look for, this function 
-               locates a given driver and returns a sysfs_driver structure 
-               corresponding to the requested device.
-
-       NOTE:   
-               1. The sysfs_driver structure obtained upon successful return 
-                  from this function has to be closed by calling 
-                  sysfs_close_driver_by_name().
-               2. Bus on which to look for this driver should be known prior 
-                  to calling this function. Use sysfs_find_driver_bus() 
-                  to determine this.
-
-Arguments:     const char *bus_name    Bus on which to search
-               const char *drv_name    Driver name to look for
-
-Returns:       struct sysfs_driver * with success 
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_driver *sysfs_open_driver(const char *bus_name,
-                                                       const char *drv_name)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_get_driver_links
-
-Description:   Function returns a list of links for a given driver 
-
-Arguments:     struct sysfs_driver *driver     Driver to get links from
-
-Returns:       struct dlist * of links on success
-               NULL with error
-
-Prototype:     struct dlist *sysfs_get_driver_links
-                                               (struct sysfs_driver *driver)
--------------------------------------------------------------------------------
-
--------------------------------------------------------------------------------
-Name:          sysfs_open_driver_attr
-
-Description:   Function takes as arguments, the bus the driver is registered 
-               on, the driver name and the name of the attribute to open.
-       
-       NOTE:
-               1. The struct sysfs_attribute * obtained upon successful
-                       return from this function has to be closed by making
-                       a call to sysfs_close_attribute()
-
-Arguments:     char *bus               Bus on which driver is present
-               char *drv               Driver to look for
-               char *attrib            Name of the attribute to open
-
-Returns:       struct sysfs_attribute * with success.
-               NULL with error. Errno will be set with error, returning
-                       - EINVAL for invalid arguments
-
-Prototype:     struct sysfs_attribute *sysfs_open_driver_attr
-                       (const char *bus, const char *drv, const char *attrib)
--------------------------------------------------------------------------------
-
-
-7 Dlists
---------
-
-Libsysfs uses (yet another) list implementation thanks to Eric J Bohm.
-
-
-7.1 Navigating a dlist
-----------------------
-
-Some library functions return a dlist of devices/drivers/attributes, etc.
-To navigate the list returned the macro "dlist_for_each_data" is to be used.
-
-------------------------------------------------------------------------------
-Function/Macro name:    dlist_for_each_data
-
-Description:            Walk the given list, returning a known data type/
-                        structure in each iteration.
-
-Arguments:              struct dlist *list      List pointer
-                        data_iterator           Data type/structure variable
-                                               contained in the list
-                       datatype                Data type/structure contained
-                                               in the list
-
-Returns:                On each iteration, "data_iterator" will contain a list
-                       element of "datatype"
-
-Usage example:          The function sysfs_get_classdev_attributes() returns a
-                       dlist of attributes. To navigate the list:
-                               
-                       struct sysfs_attribute *attr = NULL;
-                       struct dlist *attrlist = NULL;
-                       .
-                       .
-                       .
-                       attrlist = sysfs_get_classdev_attributes
-                                       (struct sysfs_class_device *cdev)
-                       if (attrlist != NULL) {
-                               dlist_for_each_data(attrlist, attr,
-                                               struct sysfs_attribute) {
-                               .
-                               .
-                               .
-                               }
-                       }
--------------------------------------------------------------------------------
-
-
-7.2 Custom sorting using dlist_sort_custom()
---------------------------------------------
-
-As of release 1.2.0, libsysfs provides a new interface for custom sorting
-of dlists. The API dlist_sort_custom() has been added for this purpose.
-Applications that would like to define their own sorter function can now
-make use of this API.
-
-The sorter function must conform to the following prototype:
-
-       int compare(void *a, void*b)
-
-dlist_sort_custom() expects that the compare function will:
-       return >0 for a before b
-       return <0 for b before a
-       return  0 for a == b
-
-
-8. Usage
---------
-
-Accessing devices through libsysfs is supposed to mirror accessing devices
-in the filesystem it represents. Here's a typical order of operation:
-
-       - get sysfs mount point
-       - "open" sysfs category, ie. bus, class, or device
-       - work with category
-       - "close" sysfs category
-
-
-9. Testsuite
-------------
-
-Version 1.0.0 of sysfsutils ships with a comprehensive testsuite. The testsuite
-shipped as part of the "test" directory of the sysfsutils source package,
-results in an executable "testlibsysfs" which will be installed in the
-/usr/local/bin directory. Some of the salient features of the testsuite are:
-
-a. Tests _every_ API exported by the library.
-b. Tests are performed for all possible combinations of input parameters.
-c. Detailed output is provided for the correct case.
-d. Facility to redirect output of the tests to a normal file.
-e. Number of iterations of tests can be specified.
-
-The testsuite comes with its own configuration file "libsysfs.conf" in the
-"test" directory. This file is used to generate a header file at the time
-the tests are built. 
-
-To use the testsuite:
-
-a. Modify the variables libsysfs.conf file to appropriate values for your
-   system. (The libsysfs.conf file contains comments describing what each
-   variable stands for and, in some cases, how to determine an appropriate 
-   value for the system under test).
-
-b. Build and install the testsuite.
-
-c. Run the testsuite:
-
-       testlibsysfs <number of iterations> <logfile>
-
-The default logfile is stdout.
-
-NOTE: If the libsysfs.conf file is changed, make sure to run "make clean" in 
-the test directory and then a "make" for the changes to take effect.
-
-
-10. Conclusion
---------------
-
-Libsysfs is meant to provide a stable application programming interface to
-sysfs. Applications can depend upon the library to access system devices
-and functions exposed through sysfs.
diff --git a/libsysfs/sysfs.h b/libsysfs/sysfs.h
deleted file mode 100644 (file)
index 2add822..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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 <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <ctype.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#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_attributes_list(void *dev);
-
-/* Debugging */
-#ifdef DEBUG
-#include "../logging.h"
-#define dprintf(format, arg...) dbg(format, ## arg)
-#else
-#define dprintf(format, arg...) do { } while (0)
-#endif
-
-#endif /* _SYSFS_H_ */
diff --git a/libsysfs/sysfs/dlist.h b/libsysfs/sysfs/dlist.h
deleted file mode 100644 (file)
index 335a490..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * dlist.h
- *
- * Copyright (C) 2003 Eric J Bohm
- *
- *  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 _DLIST_H_
-#define _DLIST_H_
-
-/* Double linked list header.
-   
-* navigate your list with DLIST_PREV and DLIST_NEXT.  These are macros
-* so function call overhead is minimized.
-
-* Supports perl style push, pop, shift, unshift list semantics.
-
-* You allocate the data and give dlist the pointer.  If your data is
-* complex set the dlist->del_func to a an appropriate delete using
-* dlist_new_with_delete.  Your delete function must match 
-(void * )(del(void *)
-*Otherwise dlist will just use free.
-
-* NOTE: The small amount of pain involved in doing that allows us to
-* avoid copy in copy out semantics.
-
-* Dlist uses an internal mark pointer to keep track of where you are
-* in the list.
-
-* insert and delete take a directional parameter. Where direction
-* corresponds to the direction in which you want the list to go.
-* true direction corresponded to progressing forward in the last
-* false to regressing in the list.
-* so a dlist_insert(yourlist,item,1) will insert it after the mark
-* so a dlist_insert(yourlist,item,0) will insert it before the mark
-* any insert will move the mark to the new node regardless of the direction.
-
-* Just use the dlist_(insert|delete)_(before|after) macros if you do not want
-* to think about it.
-
-*/
-
-#include <stddef.h>
-
-typedef struct dl_node {
-  struct dl_node *prev;
-  struct dl_node *next;
-  void *data;
-} DL_node;
-
-typedef struct dlist {
-  DL_node *marker;
-  unsigned long count;
-  size_t data_size;
-  void (*del_func)(void *);
-  DL_node headnode;
-  DL_node *head;
-} Dlist;
-
-Dlist *dlist_new(size_t datasize);
-Dlist *dlist_new_with_delete(size_t datasize,void (*del_func)(void*));
-void *_dlist_mark_move(Dlist *list,int direction);
-void *dlist_mark(Dlist *);
-void dlist_start(Dlist *);
-void dlist_end(Dlist *);
-void dlist_move(struct dlist *source, struct dlist *dest, struct dl_node *target,int direction);
-void *dlist_insert(Dlist *,void *,int) ;
-
-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 *);
-
-void *dlist_shift(Dlist *);
-
-void dlist_destroy(Dlist *);
-
-int _dlist_merge(struct dlist *listsource, struct dlist *listdest, unsigned int passcount, int (*compare)(void *, void *));
-
-void *dlist_find_custom(struct dlist *list, void *target, int (*comp)(void *, void *));
-
-void dlist_sort_custom(struct dlist *list, int (*compare)(void *, void *));
-
-
-void _dlist_swap(struct dlist *list, struct dl_node *a, struct dl_node *b);
-
-void dlist_transform(struct dlist *list, void (*node_operation)(void *));
-
-
-/* 
- * _dlist_remove is for internal use only
- * _dlist_mark_move is for internal use only
- */
-void *_dlist_remove(struct dlist *,struct dl_node *,int );
-void *_dlist_insert_dlnode(struct dlist *list,struct dl_node *new_node,int direction);
-
-#define dlist_prev(A) _dlist_mark_move((A),0)
-#define dlist_next(A) _dlist_mark_move((A),1)
-
-#define dlist_insert_before(A,B) dlist_insert((A),(B),0)
-#define dlist_insert_after(A,B) dlist_insert((A),(B),1)
-
-#define dlist_delete_before(A) dlist_delete((A),0)
-#define dlist_delete_after(A) dlist_delete((A),1)
-
-/**
- * provide for loop header which iterates the mark from start to end
- * list: the dlist pointer, use dlist_mark(list) to get iterator
- */
-#define dlist_for_each(list) \
-       for(dlist_start(list),dlist_next(list); \
-               (list)->marker!=(list)->head;dlist_next(list))
-
-/**
- * provide for loop header which iterates the mark from end to start
- * list: the dlist pointer, use dlist_mark(list) to get iterator
- */
-#define dlist_for_each_rev(list) \
-       for(dlist_end(list),dlist_prev(list); \
-               (list)->marker!=(list)->head;dlist_prev(list))
-
-/**
- * provide for loop header which iterates through the list without moving mark
- * list: the dlist_pointer
- * iterator: dl_node pointer to iterate
- */
-#define dlist_for_each_nomark(list,iterator) \
-       for((iterator)=(list)->head->next; (iterator)!=(list)->head; \
-               (iterator)=(iterator)->next)
-
-/**
- * provide for loop header which iterates through the list without moving mark
- * in reverse
- * list: the dlist_pointer
- * iterator: dl_node pointer to iterate
- */
-#define dlist_for_each_nomark_rev(list,iterator) \
-       for((iterator)=(list)->head->prev; (iterator)!=(list)->head; \
-               (iterator)=(iterator)->prev)
-/**
- * provide for loop header which iterates through the list providing a
- * data iterator
- * list: the dlist pointer
- * data_iterator: the pointer of type datatype to iterate
- * datatype:  actual type of the contents in the dl_node->data
- */
-
-#define dlist_for_each_data(list,data_iterator,datatype) \
-       for(dlist_start(list), (data_iterator)=(datatype *) dlist_next(list); \
-       (list)->marker!=(list)->head;(data_iterator)=(datatype *) dlist_next(list))
-
-/**
- * provide for loop header which iterates through the list providing a
- * data iterator in reverse
- * list: the dlist pointer
- * data_iterator: the pointer of type datatype to iterate
- * datatype:  actual type of the contents in the dl_node->data
- */
-#define dlist_for_each_data_rev(list,data_iterator,datatype) \
-       for(dlist_end(list), (data_iterator)=(datatype *) dlist_prev(list); \
-       (list)->marker!=(list)->head;(data_iterator)=(datatype *) dlist_prev(list))
-
-/**
- * provide for loop header which iterates through the list providing a
- * data iterator without moving the mark
- * list: the dlist pointer
- * iterator: the dl_node pointer to iterate
- * data_iterator: the pointer of type datatype to iterate
- * datatype:  actual type of the contents in the dl_node->data
- */
-
-#define dlist_for_each_data_nomark(list,iterator,data_iterator,datatype) \
-       for((iterator)=(list)->head->next, (data_iterator)=(datatype *) (iterator)->data; \
-       (iterator)!=(list)->head;(iterator)=(iterator)->next,(data_iterator)=(datatype *) (iterator))
-
-/**
- * provide for loop header which iterates through the list providing a
- * data iterator in reverse without moving the mark
- * list: the dlist pointer
- * iterator: the dl_node pointer to iterate
- * data_iterator: the pointer of type datatype to iterate
- * datatype:  actual type of the contents in the dl_node->data
- */
-#define dlist_for_each_data_nomark_rev(list,iterator, data_iterator,datatype) \
-       for((iterator)=(list)->head->prev, (data_iterator)=(datatype *) (iterator)->data; \
-       (iterator)!=(list)->head;(iterator)=(iterator)->prev,(data_iterator)=(datatype *) (iterator))
-
-#endif /* _DLIST_H_ */
diff --git a/libsysfs/sysfs/libsysfs.h b/libsysfs/sysfs/libsysfs.h
deleted file mode 100644 (file)
index 12e7cc5..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * 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 <sys/types.h>
-#include <string.h>
-#include "dlist.h"
-
-#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_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 */
-};
-
-struct sysfs_driver {
-       char name[SYSFS_NAME_LEN];
-       char path[SYSFS_PATH_MAX];
-       struct dlist *attrlist;
-       char bus[SYSFS_NAME_LEN];
-
-       /* Private: for internal use only */
-       struct dlist *devices;
-};
-
-struct sysfs_device {
-       char name[SYSFS_NAME_LEN];
-       char path[SYSFS_PATH_MAX];
-       struct dlist *attrlist;
-       char bus_id[SYSFS_NAME_LEN];
-       char bus[SYSFS_NAME_LEN];
-       char driver_name[SYSFS_NAME_LEN];
-
-       /* Private: for internal use only */
-       struct sysfs_device *parent;            
-       /* NOTE - we still don't populate this */
-       struct dlist *children; 
-};
-
-/* NOTE: not used as of now */
-struct sysfs_bus {
-       char name[SYSFS_NAME_LEN];
-       char path[SYSFS_PATH_MAX];
-       struct dlist *attrlist;
-
-       /* Private: for internal use only */
-       struct dlist *drivers;
-       struct dlist *devices;
-};
-
-struct sysfs_class_device {
-       char name[SYSFS_NAME_LEN];
-       char path[SYSFS_PATH_MAX];
-       struct dlist *attrlist;
-       char classname[SYSFS_NAME_LEN];
-
-       /* Private: for internal use only */
-       struct sysfs_class_device *parent;      
-       struct sysfs_device *sysdevice;         /* NULL if virtual */
-};
-
-/* NOTE: not used as of now */
-struct sysfs_class {
-       char name[SYSFS_NAME_LEN];
-       char path[SYSFS_PATH_MAX];
-       struct dlist *attrlist;
-
-       /* Private: for internal use only */
-       struct dlist *devices;
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Function Prototypes
- */
-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_directory_list(const char *path);
-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 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);
-
-/* sysfs driver access */
-extern void sysfs_close_driver(struct sysfs_driver *driver);
-extern struct sysfs_driver *sysfs_open_driver
-       (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 char *name);
-extern struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver);
-extern struct dlist *sysfs_get_driver_devices(struct sysfs_driver *driver);
-
-/* generic sysfs device access */
-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 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 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 char *name);
-extern struct dlist *sysfs_get_device_attributes
-       (struct sysfs_device *dev);
-
-/* 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 char *path);
-extern struct sysfs_class_device *sysfs_open_class_device
-       (const char *classname, const char *name);
-extern struct sysfs_class_device *sysfs_get_classdev_parent
-       (struct sysfs_class_device *clsdev);
-extern struct sysfs_attribute *sysfs_get_classdev_attr
-       (struct sysfs_class_device *clsdev, const char *name);
-extern struct dlist *sysfs_get_classdev_attributes
-       (struct sysfs_class_device *clsdev);
-extern struct sysfs_device *sysfs_get_classdev_device
-       (struct sysfs_class_device *clsdev);
-extern void sysfs_close_class(struct sysfs_class *cls);
-extern struct sysfs_class *sysfs_open_class(const char *name);
-extern struct sysfs_class_device *sysfs_get_class_device
-       (struct sysfs_class *cls, const char *name);
-extern struct dlist *sysfs_get_class_devices(struct sysfs_class *cls);
-
-/* generic sysfs bus access */
-extern void sysfs_close_bus(struct sysfs_bus *bus);
-extern struct sysfs_bus *sysfs_open_bus(const char *name);
-extern struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus);
-extern struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus);
-extern struct sysfs_device *sysfs_get_bus_device
-       (struct sysfs_bus *bus, const char *id);
-extern struct sysfs_driver *sysfs_get_bus_driver
-       (struct sysfs_bus *bus, const char *drvname);
-
-/**
- * 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
-}
-#endif
-
-#endif /* _LIBSYSFS_H_ */
diff --git a/libsysfs/sysfs_bus.c b/libsysfs/sysfs_bus.c
deleted file mode 100644 (file)
index 921ef32..0000000
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * sysfs_bus.c
- *
- * Generic bus 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"
-
-static void sysfs_close_dev(void *dev)
-{
-        sysfs_close_device((struct sysfs_device *)dev);
-}
-
-static void sysfs_close_drv(void *drv)
-{
-        sysfs_close_driver((struct sysfs_driver *)drv);
-}
-
-/*
- * compares names.
- * @a: name looked for
- * @b: sysfs_device comparing being compared
- * returns 1 if a==b->name or 0 not equal
- */
-static int name_equal(void *a, void *b)
-{
-       if (!a || !b)
-               return 0;
-
-       if (strcmp(((char *)a), ((struct sysfs_device *)b)->name) == 0)
-               return 1;
-
-       return 0;
-}
-
-/**
- * sysfs_close_bus: close single bus
- * @bus: bus structure
- */
-void sysfs_close_bus(struct sysfs_bus *bus)
-{
-       if (bus) {
-               if (bus->attrlist)
-                       dlist_destroy(bus->attrlist);
-               if (bus->devices)
-                       dlist_destroy(bus->devices);
-               if (bus->drivers)
-                       dlist_destroy(bus->drivers);
-               free(bus);
-       }
-}
-
-/**
- * alloc_bus: mallocs new bus structure
- * returns sysfs_bus_bus struct or NULL
- */
-static struct sysfs_bus *alloc_bus(void)
-{
-       return (struct sysfs_bus *)calloc(1, sizeof(struct sysfs_bus));
-}
-
-/**
- * sysfs_get_bus_devices: gets all devices for bus
- * @bus: bus to get devices for
- * returns dlist of devices with success and NULL with failure
- */
-struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus)
-{
-       struct sysfs_device *dev;
-       struct dlist *linklist;
-       char path[SYSFS_PATH_MAX], devpath[SYSFS_PATH_MAX];
-       char target[SYSFS_PATH_MAX];
-       char *curlink;
-
-       if (!bus) {
-               errno = EINVAL;
-               return NULL;
-       }
-       memset(path, 0, SYSFS_PATH_MAX);
-       safestrcpy(path, bus->path);
-       safestrcat(path, "/");
-       safestrcat(path, SYSFS_DEVICES_NAME);
-
-       linklist = read_dir_links(path);
-       if (linklist) {
-               dlist_for_each_data(linklist, curlink, char) {
-                       if (bus->devices) {
-                               dev = (struct sysfs_device *)
-                                       dlist_find_custom(bus->devices,
-                                       (void *)curlink, name_equal);
-                               if (dev)
-                                       continue;
-                       }
-                       safestrcpy(devpath, path);
-                       safestrcat(devpath, "/");
-                       safestrcat(devpath, curlink);
-                       if (sysfs_get_link(devpath, target, SYSFS_PATH_MAX)) {
-                               dprintf("Error getting link - %s\n", devpath);
-                               continue;
-                       }
-                       dev = sysfs_open_device_path(target);
-                       if (!dev) {
-                               dprintf("Error opening device at %s\n", 
-                                                               target);
-                               continue;
-                       }
-                       if (!bus->devices)
-                               bus->devices = dlist_new_with_delete
-                                       (sizeof(struct sysfs_device), 
-                                                       sysfs_close_dev);
-                       dlist_unshift_sorted(bus->devices, dev, sort_list);
-               }
-               sysfs_close_list(linklist);
-       }
-       return (bus->devices);
-}
-
-/**
- * sysfs_get_bus_drivers: gets all drivers for bus
- * @bus: bus to get devices for
- * returns dlist of devices with success and NULL with failure
- */
-struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus)
-{
-       struct sysfs_driver *drv;
-       struct dlist *dirlist;
-       char path[SYSFS_PATH_MAX], drvpath[SYSFS_PATH_MAX];
-       char *curdir;
-
-       if (!bus) {
-               errno = EINVAL;
-               return NULL;
-       }
-       memset(path, 0, SYSFS_PATH_MAX);
-       safestrcpy(path, bus->path);
-       safestrcat(path, "/");
-       safestrcat(path, SYSFS_DRIVERS_NAME);
-
-       dirlist = read_dir_subdirs(path);
-       if (dirlist) {
-               dlist_for_each_data(dirlist, curdir, char) {
-                       if (bus->drivers) {
-                               drv = (struct sysfs_driver *)
-                                       dlist_find_custom(bus->drivers,
-                                       (void *)curdir, name_equal);
-                               if (drv)
-                                       continue;
-                       }
-                       safestrcpy(drvpath, path);
-                       safestrcat(drvpath, "/");
-                       safestrcat(drvpath, curdir);
-                       drv = sysfs_open_driver_path(drvpath);
-                       if (!drv) {
-                               dprintf("Error opening driver at %s\n", 
-                                                               drvpath);
-                               continue;
-                       }
-                       if (!bus->drivers)
-                               bus->drivers = dlist_new_with_delete
-                                       (sizeof(struct sysfs_driver), 
-                                                       sysfs_close_drv);
-                       dlist_unshift_sorted(bus->drivers, drv, sort_list);
-               }
-               sysfs_close_list(dirlist);
-       }
-       return (bus->drivers);
-}
-
-/**
- * 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 char *name)
-{
-       struct sysfs_bus *bus;
-       char buspath[SYSFS_PATH_MAX];
-
-       if (!name) {
-               errno = EINVAL;
-               return NULL;
-       }
-
-       memset(buspath, 0, SYSFS_PATH_MAX);
-       if (sysfs_get_mnt_path(buspath, SYSFS_PATH_MAX)) {
-               dprintf("Sysfs not supported on this system\n");
-               return NULL;
-       }
-
-       safestrcat(buspath, "/");
-       safestrcat(buspath, SYSFS_BUS_NAME);
-       safestrcat(buspath, "/");
-       safestrcat(buspath, name);
-       if (sysfs_path_is_dir(buspath)) {
-               dprintf("Invalid path to bus: %s\n", buspath);
-               return NULL;
-       }
-       bus = alloc_bus();
-       if (!bus) {
-               dprintf("calloc failed\n");
-               return NULL;
-       }
-       safestrcpy(bus->name, name);    
-       safestrcpy(bus->path, buspath);
-       if (sysfs_remove_trailing_slash(bus->path)) {
-               dprintf("Incorrect path to bus %s\n", bus->path);
-               sysfs_close_bus(bus);
-               return NULL;
-       }
-
-       return bus;
-}
-
-/**
- * sysfs_get_bus_device: Get specific device on bus using device's id
- * @bus: bus to find device on
- * @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, 
-               const char *id)
-{
-       struct sysfs_device *dev = NULL;
-       char devpath[SYSFS_PATH_MAX], target[SYSFS_PATH_MAX];
-       
-       if (!bus || !id) {
-               errno = EINVAL;
-               return NULL;
-       }
-
-       if (bus->devices) {
-               dev = (struct sysfs_device *)dlist_find_custom
-                       (bus->devices, (void *)id, name_equal);
-               if (dev)
-                       return dev;
-       }
-       safestrcpy(devpath, bus->path);
-       safestrcat(devpath, "/");
-       safestrcat(devpath, SYSFS_DEVICES_NAME);
-       safestrcat(devpath, "/");
-       safestrcat(devpath, id);
-       if (sysfs_path_is_link(devpath)) {
-               dprintf("No such device %s on bus %s?\n", id, bus->name);
-               return NULL;
-       }
-       if (!sysfs_get_link(devpath, target, SYSFS_PATH_MAX)) {
-               dev = sysfs_open_device_path(target);
-               if (!dev) {
-                       dprintf("Error opening device at %s\n", target);
-                       return NULL;
-               }
-               if (!bus->devices)
-                       bus->devices = dlist_new_with_delete
-                                       (sizeof(struct sysfs_device), 
-                                                       sysfs_close_dev);
-               dlist_unshift_sorted(bus->devices, dev, sort_list);
-       }
-       return dev;
-}
-
-/**
- * sysfs_get_bus_driver: Get specific driver on bus using driver name
- * @bus: bus to find driver on
- * @drvname: name of driver
- * returns struct sysfs_driver reference or NULL if not found.
- */
-struct sysfs_driver *sysfs_get_bus_driver(struct sysfs_bus *bus,
-               const char *drvname)
-{
-       struct sysfs_driver *drv;
-       char drvpath[SYSFS_PATH_MAX];
-       
-       if (!bus || !drvname) {
-               errno = EINVAL;
-               return NULL;
-       }
-
-       if (bus->drivers) {
-               drv = (struct sysfs_driver *)dlist_find_custom
-                       (bus->drivers, (void *)drvname, name_equal);
-               if (drv)
-                       return drv;
-       }
-       safestrcpy(drvpath, bus->path);
-       safestrcat(drvpath, "/");
-       safestrcat(drvpath, SYSFS_DRIVERS_NAME);
-       safestrcat(drvpath, "/");
-       safestrcat(drvpath, drvname);
-       drv = sysfs_open_driver_path(drvpath);
-       if (!drv) {
-               dprintf("Error opening driver at %s\n", drvpath);
-               return NULL;
-       }
-       if (!bus->drivers)
-               bus->drivers = dlist_new_with_delete
-                               (sizeof(struct sysfs_driver), 
-                                               sysfs_close_drv);
-       dlist_unshift_sorted(bus->drivers, drv, sort_list);
-       return drv;
-}
-
diff --git a/libsysfs/sysfs_class.c b/libsysfs/sysfs_class.c
deleted file mode 100644 (file)
index 102f09f..0000000
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- * sysfs_class.c
- *
- * Generic class 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_class_device: closes a single class device.
- * @dev: class device to close.
- */
-void sysfs_close_class_device(struct sysfs_class_device *dev)
-{
-       if (dev) {
-               if (dev->parent)
-                       sysfs_close_class_device(dev->parent);
-               if (dev->sysdevice)
-                       sysfs_close_device(dev->sysdevice);
-               if (dev->attrlist)
-                       dlist_destroy(dev->attrlist);
-               free(dev);
-       }
-}
-
-static void sysfs_close_cls_dev(void *dev)
-{
-       sysfs_close_class_device((struct sysfs_class_device *)dev);
-}
-
-/**
- * sysfs_close_class: close the given class
- * @cls: sysfs_class to close
- */ 
-void sysfs_close_class(struct sysfs_class *cls)
-{
-       if (cls) {
-               if (cls->devices)
-                       dlist_destroy(cls->devices);
-               if (cls->attrlist)
-                       dlist_destroy(cls->attrlist);
-               free(cls);
-       }
-}
-
-static int cdev_name_equal(void *a, void *b)
-{
-       if (!a || !b)
-               return 0;
-
-       if (strncmp((char *)a, ((struct sysfs_class_device *)b)->name, 
-                               strlen((char *)a)) == 0)
-               return 1;
-
-       return 0;
-}
-
-static struct sysfs_class *alloc_class(void)
-{
-       return (struct sysfs_class *) calloc(1, sizeof(struct sysfs_class));
-}
-
-/**
- * alloc_class_device: mallocs and initializes new class device struct.
- * returns sysfs_class_device or NULL.
- */
-static struct sysfs_class_device *alloc_class_device(void)
-{
-       struct sysfs_class_device *dev;
-
-       dev = calloc(1, sizeof(struct sysfs_class_device));
-       return dev;
-}
-
-/**
- * set_classdev_classname: Grabs classname from path
- * @cdev: class device to set
- * Returns nothing
- */
-static void set_classdev_classname(struct sysfs_class_device *cdev)
-{
-       char *c, *e;
-       int count = 0;
-
-       c = strstr(cdev->path, SYSFS_CLASS_NAME);
-       if (c == NULL) {
-               c = strstr(cdev->path, SYSFS_BLOCK_NAME);
-       } else {
-               c = strstr(c, "/");
-       }
-
-       if (c == NULL)
-               safestrcpy(cdev->classname, SYSFS_UNKNOWN);
-       else {
-               if (*c == '/')
-                       c++;
-               e = c;
-               while (e != NULL && *e != '/' && *e != '\0') {
-                       e++;
-                       count++;
-               }
-               strncpy(cdev->classname, c, count);
-       }
-}
-
-/**
- * sysfs_open_class_device_path: Opens and populates class device
- * @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 char *path)
-{
-       struct sysfs_class_device *cdev;
-       char temp_path[SYSFS_PATH_MAX];
-
-       if (!path) {
-               errno = EINVAL;
-               return NULL;
-       }
-
-       /*
-        * Post linux-2.6.14 driver model supports nested classes with
-        * links to the nested hierarchy at /sys/class/xxx/. Check for
-        * a link to the actual class device if a directory isn't found
-        */
-       if (sysfs_path_is_dir(path)) {
-               dprintf("%s: Directory not found, checking for a link\n", path);
-               if (!sysfs_path_is_link(path)) {
-                       if (sysfs_get_link(path, temp_path, SYSFS_PATH_MAX)) {
-                               dprintf("Error retrieving link at %s\n", path);
-                               return NULL;
-                       }
-               } else {
-                       dprintf("%s is not a valid class device path\n", path);
-                       return NULL;
-               }
-       } else
-               safestrcpy(temp_path, path);
-
-       cdev = alloc_class_device();
-       if (!cdev) {
-               dprintf("calloc failed\n");
-               return NULL;
-       }
-       if (sysfs_get_name_from_path(temp_path, cdev->name, SYSFS_NAME_LEN)) {
-               errno = EINVAL;
-               dprintf("Error getting class device name\n");
-               sysfs_close_class_device(cdev);
-               return NULL;
-       }
-
-       safestrcpy(cdev->path, temp_path);
-       if (sysfs_remove_trailing_slash(cdev->path)) {
-               dprintf("Invalid path to class device %s\n", cdev->path);
-               sysfs_close_class_device(cdev);
-               return NULL;
-       }
-       set_classdev_classname(cdev);
-
-       return cdev;
-}
-
-/** 
- * get_blockdev_parent: Get the parent class device for a "block" subsystem 
- *             device if present
- * @clsdev: block subsystem class device whose parent needs to be found
- * Returns 0 on success and 1 on error
- */
-static int get_blockdev_parent(struct sysfs_class_device *clsdev)
-{
-       char parent_path[SYSFS_PATH_MAX];
-       char *c;
-
-       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++;
-       else
-               goto errout;
-
-       /* validate whether the given class device is a partition or not */
-       if ((strncmp(c, clsdev->name, strlen(clsdev->name))) == 0) {
-               dprintf("%s not a partition\n", clsdev->name);
-               return 1;
-       }
-
-       c = strchr(c, '/');
-       if (c == NULL)
-               goto errout;
-
-       *c = '\0';
-
-       clsdev->parent = sysfs_open_class_device_path(parent_path);
-       if (!clsdev->parent) {
-               dprintf("Error opening the parent class device at %s\n", 
-                                                               parent_path);
-               return 1;
-       }
-       return 0;
-
-errout:
-       dprintf("Invalid path %s\n", clsdev->path);
-       return 1;
-}
-
-/**
- * sysfs_get_classdev_parent: Retrieves the parent of a class device. 
- *     eg., when working with hda1, this function can be used to retrieve the
- *             sysfs_class_device for hda
- *             
- * @clsdev: class device whose parent details are required.
- * Returns sysfs_class_device of the parent on success, NULL on failure
- */ 
-struct sysfs_class_device *sysfs_get_classdev_parent
-                               (struct sysfs_class_device *clsdev)
-{
-       if (!clsdev) {
-               errno = EINVAL;
-               return NULL;
-       }
-       if (clsdev->parent)
-               return (clsdev->parent);
-
-       /*
-        * As of now, only block devices have a parent child heirarchy in sysfs
-        * We do not know, if, in the future, more classes will have a similar
-        * structure. Hence, we now call a specialized function for block and
-        * later we can add support functions for other subsystems as required.
-        */
-       if (!(strncmp(clsdev->classname, SYSFS_BLOCK_NAME, 
-                                       sizeof(SYSFS_BLOCK_NAME)))) {
-               if ((get_blockdev_parent(clsdev)) == 0) 
-                       return (clsdev->parent);
-       }
-       return NULL;
-}
-
-/**
- * get_classdev_path: given the class and a device in the class, return the
- *             absolute path to the device
- * @classname: name of the class
- * @clsdev: the class device
- * @path: buffer to return path
- * @psize: size of "path"
- * Returns 0 on SUCCESS or -1 on error
- */
-static int get_classdev_path(const char *classname, const char *clsdev, 
-               char *path, size_t len)
-{
-       if (!classname || !clsdev || !path) {
-               errno = EINVAL;
-               return -1;
-       }
-       if (sysfs_get_mnt_path(path, len) != 0) {
-               dprintf("Error getting sysfs mount path\n");
-               return -1;
-       }
-       if (strncmp(classname, SYSFS_BLOCK_NAME,
-                               sizeof(SYSFS_BLOCK_NAME)) == 0) {
-               safestrcatmax(path, "/", len);
-               safestrcatmax(path, SYSFS_BLOCK_NAME, len);
-       } else {
-               safestrcatmax(path, "/", len);
-               safestrcatmax(path, SYSFS_CLASS_NAME, len);
-               safestrcatmax(path, "/", len);
-               safestrcatmax(path, classname, len);
-       }
-       safestrcatmax(path, "/", len);
-       safestrcatmax(path, clsdev, len);
-       return 0;
-}
-
-/**
- * sysfs_open_class_device: Locates a specific class_device and returns it.
- * Class_device must be closed using sysfs_close_class_device
- * @classname: Class to search
- * @name: name of the class_device
- * 
- * NOTE:
- *     Call sysfs_close_class_device() to close the class device
- */
-struct sysfs_class_device *sysfs_open_class_device
-               (const char *classname, const char *name)
-{
-       char devpath[SYSFS_PATH_MAX];
-       struct sysfs_class_device *cdev;
-
-       if (!classname || !name) {
-               errno = EINVAL;
-               return NULL;
-       }
-       
-       memset(devpath, 0, SYSFS_PATH_MAX);
-       if ((get_classdev_path(classname, name, devpath, 
-                                       SYSFS_PATH_MAX)) != 0) {
-               dprintf("Error getting to device %s on class %s\n",
-                                                       name, classname);
-               return NULL;
-       }
-
-       cdev = sysfs_open_class_device_path(devpath);
-       if (!cdev) {
-               dprintf("Error getting class device %s from class %s\n",
-                               name, classname);
-               return NULL;
-       }
-       return cdev;
-}
-
-/**
- * sysfs_get_classdev_attr: searches class device's attributes by name
- * @clsdev: class device to look through
- * @name: attribute name to get
- * returns sysfs_attribute reference with success or NULL with error
- */
-struct sysfs_attribute *sysfs_get_classdev_attr
-               (struct sysfs_class_device *clsdev, const char *name)
-{
-       if (!clsdev || !name) {
-               errno = EINVAL;
-               return NULL;
-       }
-       return get_attribute(clsdev, (char *)name);
-}
-
-/**
- * sysfs_get_classdev_attributes: gets list of classdev attributes
- * @clsdev: class device whose attributes list is needed
- * returns dlist of attributes on success or NULL on error
- */
-struct dlist *sysfs_get_classdev_attributes(struct sysfs_class_device *clsdev)
-{
-       if (!clsdev) {
-               errno = EINVAL;
-               return NULL;
-       }
-       return get_attributes_list(clsdev);
-}
-
-/**
- * sysfs_get_classdev_device: gets the sysfs_device associated with the
- *     given sysfs_class_device
- * @clsdev: class device whose associated sysfs_device is needed
- * returns struct sysfs_device * on success or NULL on error
- */
-struct sysfs_device *sysfs_get_classdev_device
-               (struct sysfs_class_device *clsdev)
-{
-       char linkpath[SYSFS_PATH_MAX], devpath[SYSFS_PATH_MAX];
-
-       if (!clsdev) {
-               errno = EINVAL;
-               return NULL;
-       }
-
-       if (clsdev->sysdevice)
-               return clsdev->sysdevice;
-
-       memset(linkpath, 0, SYSFS_PATH_MAX);
-       safestrcpy(linkpath, clsdev->path);
-       safestrcat(linkpath, "/device");
-       if (!sysfs_path_is_link(linkpath)) {
-               memset(devpath, 0, SYSFS_PATH_MAX);
-               if (!sysfs_get_link(linkpath, devpath, SYSFS_PATH_MAX))
-                       clsdev->sysdevice = sysfs_open_device_path(devpath);
-       }
-       return clsdev->sysdevice;
-}
-
-/**
- * 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 char *name)
-{
-       struct sysfs_class *cls = NULL;
-       char classpath[SYSFS_PATH_MAX];
-
-       if (!name) {
-               errno = EINVAL;
-               return NULL;
-       }
-
-       memset(classpath, 0, SYSFS_PATH_MAX);
-        if ((sysfs_get_mnt_path(classpath, SYSFS_PATH_MAX)) != 0) {
-                dprintf("Sysfs not supported on this system\n");
-                return NULL;
-        }
-
-       /* 
-        * We shall now treat "block" also as a class. Hence, check here
-        * if "name" is "block" and proceed accordingly
-        */
-       if (strcmp(name, SYSFS_BLOCK_NAME) == 0) {
-               safestrcat(classpath, "/");
-               safestrcat(classpath, SYSFS_BLOCK_NAME);
-       } else {
-               safestrcat(classpath, "/");
-               safestrcat(classpath, SYSFS_CLASS_NAME);
-               safestrcat(classpath, "/");
-               safestrcat(classpath, name);
-       }
-       if (sysfs_path_is_dir(classpath)) {
-               dprintf("Class %s not found on the system\n", name);
-               return NULL;
-       }
-
-       cls = alloc_class();
-       if (cls == NULL) {
-               dprintf("calloc failed\n");
-               return NULL;
-       }
-       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);
-               return NULL;
-       }
-
-       return cls;
-}
-
-/**
- * sysfs_get_class_device: get specific class device using the device's id
- * @cls: sysfs_class to find the device on
- * @name: name of the class device to look for
- * 
- * Returns sysfs_class_device * on success and NULL on failure
- */ 
-struct sysfs_class_device *sysfs_get_class_device(struct sysfs_class *cls,
-               const char *name)
-{
-       char path[SYSFS_PATH_MAX];
-       struct sysfs_class_device *cdev = NULL;
-
-       if (!cls || !name) {
-               errno = EINVAL;
-               return NULL;
-       }
-
-       if (cls->devices) {
-               cdev = (struct sysfs_class_device *)dlist_find_custom
-                       (cls->devices, (void *)name, cdev_name_equal);
-               if (cdev)
-                       return cdev;
-       }
-
-       safestrcpy(path, cls->path);
-       safestrcat(path, "/");
-       safestrcat(path, name);
-       cdev = sysfs_open_class_device_path(path);
-       if (!cdev) {
-               dprintf("Error opening class device at %s\n", path);
-               return NULL;
-       }
-       if (!cls->devices)
-               cls->devices = dlist_new_with_delete
-                       (sizeof(struct sysfs_class_device),
-                                sysfs_close_cls_dev);
-       
-       dlist_unshift_sorted(cls->devices, cdev, sort_list);
-       return cdev;
-}
-
-/**
- * Add class devices to list
- */
-static void add_cdevs_to_classlist(struct sysfs_class *cls, struct dlist *list)
-{
-       char path[SYSFS_PATH_MAX], *cdev_name;
-       struct sysfs_class_device *cdev = NULL;
-
-       if (cls == NULL || list == NULL)
-               return;
-
-       dlist_for_each_data(list, cdev_name, char) {
-               if (cls->devices) {
-                       cdev = (struct sysfs_class_device *)
-                               dlist_find_custom(cls->devices,
-                               (void *)cdev_name, cdev_name_equal);
-                       if (cdev)
-                               continue;
-               }
-               safestrcpy(path, cls->path);
-               safestrcat(path, "/");
-               safestrcat(path, cdev_name);
-               cdev = sysfs_open_class_device_path(path);
-               if (cdev) {
-                       if (!cls->devices)
-                               cls->devices = dlist_new_with_delete
-                               (sizeof(struct sysfs_class_device),
-                                sysfs_close_cls_dev);
-                       dlist_unshift_sorted(cls->devices, cdev,
-                                       sort_list);
-               }
-       }
-}
-
-/**
- * sysfs_get_class_devices: get all class devices in the given class
- * @cls: sysfs_class whose devices list is needed
- *
- * Returns a dlist of sysfs_class_device * on success and NULL on failure
- */
-struct dlist *sysfs_get_class_devices(struct sysfs_class *cls)
-{
-       char path[SYSFS_PATH_MAX];
-       struct dlist *dirlist, *linklist;
-
-       if (!cls) {
-               errno = EINVAL;
-               return NULL;
-       }
-
-       /*
-        * Post linux-2.6.14, we have nested classes and links under
-        * /sys/class/xxx/. are also valid class devices
-        */
-       safestrcpy(path, cls->path);
-       dirlist = read_dir_subdirs(path);
-       if (dirlist) {
-               add_cdevs_to_classlist(cls, dirlist);
-               sysfs_close_list(dirlist);
-       }
-
-       linklist = read_dir_links(path);
-       if (linklist) {
-               add_cdevs_to_classlist(cls, linklist);
-               sysfs_close_list(linklist);
-       }
-
-       return cls->devices;
-}
diff --git a/libsysfs/sysfs_device.c b/libsysfs/sysfs_device.c
deleted file mode 100644 (file)
index e3d7014..0000000
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * sysfs_device.c
- *
- * Generic device 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"
-
-/**
- * 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)
-{
-       char path[SYSFS_PATH_MAX];
-       char devpath[SYSFS_PATH_MAX];
-
-       if (!dev) {
-               errno = EINVAL;
-               return -1;
-       }
-       memset(path, 0, SYSFS_PATH_MAX);
-       memset(devpath, 0, SYSFS_PATH_MAX);
-       safestrcpymax(path, dev->path, SYSFS_PATH_MAX);
-       safestrcatmax(path, "/driver", SYSFS_PATH_MAX);
-       if (!sysfs_path_is_link(path)) {
-               if (!sysfs_get_link(path, devpath, SYSFS_PATH_MAX)) {
-                       if (sysfs_get_name_from_path(devpath, 
-                                       dev->driver_name, SYSFS_NAME_LEN))
-                               return -1;
-               }
-               return 0;
-       }
-       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.
- * returns 0 with success and -1 with error.
- */
-int sysfs_get_device_bus(struct sysfs_device *dev)
-{
-       char devpath[SYSFS_PATH_MAX];
-       char path[SYSFS_PATH_MAX];
-
-       if (!dev) {
-               errno = EINVAL;
-               return -1;
-       }
-
-       memset(path, 0, SYSFS_PATH_MAX);
-       memset(devpath, 0, SYSFS_PATH_MAX);
-       safestrcpymax(path, dev->path, SYSFS_PATH_MAX);
-       safestrcatmax(path, "/bus", SYSFS_PATH_MAX);
-       if (!sysfs_path_is_link(path)) {
-               if (!sysfs_get_link(path, devpath, SYSFS_PATH_MAX)) {
-                       if (sysfs_get_name_from_path(devpath, 
-                                       dev->bus, SYSFS_NAME_LEN))
-                               return -1;
-               }
-               return 0;
-       }
-       return -1;
-}
-
-/**
- * sysfs_close_device_tree: closes every device in the supplied tree, 
- *     closing children only.
- * @devroot: device root of tree.
- */
-void sysfs_close_device_tree(struct sysfs_device *devroot)
-{
-       if (devroot) {
-               if (devroot->children) {
-                       struct sysfs_device *child = NULL;
-
-                       dlist_for_each_data(devroot->children, child,
-                                       struct sysfs_device) {
-                               sysfs_close_device_tree(child);
-                       }
-               }
-               sysfs_close_device(devroot);
-       }
-}
-
-/**
- * sysfs_close_device: closes and cleans up a device
- * @dev = device to clean up
- */
-void sysfs_close_device(struct sysfs_device *dev)
-{
-       if (dev) {
-               if (dev->parent)
-                       sysfs_close_device(dev->parent);
-               if (dev->children && dev->children->count)
-                       dlist_destroy(dev->children);
-               if (dev->attrlist)
-                       dlist_destroy(dev->attrlist);
-               free(dev);
-       }
-}
-
-/**
- * alloc_device: allocates and initializes device structure
- * returns struct sysfs_device
- */
-static struct sysfs_device *alloc_device(void)
-{
-       return (struct sysfs_device *) calloc(1, sizeof(struct sysfs_device));
-}
-
-/**
- * sysfs_open_device_path: opens and populates device structure
- * @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 char *path)
-{
-       struct sysfs_device *dev;
-
-       if (!path) {
-               errno = EINVAL;
-               return NULL;
-       }
-       if (sysfs_path_is_dir(path)) {
-               dprintf("Incorrect path to device: %s\n", path);
-               return NULL;
-       }
-       dev = alloc_device();
-       if (!dev) {
-               dprintf("Error allocating device at %s\n", path);
-               return NULL;
-       }
-       if (sysfs_get_name_from_path(path, dev->bus_id, SYSFS_NAME_LEN)) {
-               errno = EINVAL;
-               dprintf("Error getting device bus_id\n");
-               sysfs_close_device(dev);
-               return NULL;
-       }
-       safestrcpy(dev->path, path);
-       if (sysfs_remove_trailing_slash(dev->path)) {
-               dprintf("Invalid path to device %s\n", dev->path);
-               sysfs_close_device(dev);
-               return NULL;
-       }
-       /*
-        * The "name" attribute no longer exists... return the device's
-        * sysfs representation instead, in the "dev->name" field, which
-        * implies that the dev->name and dev->bus_id contain same data.
-        */
-       safestrcpy(dev->name, dev->bus_id);
-
-       if (sysfs_get_device_bus(dev))
-               dprintf("Could not get device bus\n");
-
-       if (get_dev_driver(dev)) {
-               dprintf("Could not get device %s's driver\n", dev->bus_id);
-               safestrcpy(dev->driver_name, SYSFS_UNKNOWN);
-       }
-
-       return dev;
-}
-
-/**
- * sysfs_get_device_attr: searches dev's attributes by name
- * @dev: device to look through
- * @name: attribute name to get
- * returns sysfs_attribute reference with success or NULL with error.
- */
-struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev,
-                                               const char *name)
-{
-       if (!dev || !name) {
-               errno = EINVAL;
-               return NULL;
-       }
-       return get_attribute(dev, (char *)name);
-}
-
-/**
- * sysfs_get_device_attributes: gets list of device attributes
- * @dev: device whose attributes list is needed
- * returns dlist of attributes on success or NULL on error
- */
-struct dlist *sysfs_get_device_attributes(struct sysfs_device *dev)
-{
-       if (!dev) {
-               errno = EINVAL;
-               return NULL;
-       }
-       return get_attributes_list(dev);
-}
-
-/**
- * get_device_absolute_path: looks up the bus the device is on, gets 
- *             absolute path to the device
- * @device: device for which path is needed
- * @path: buffer to store absolute path
- * @psize: size of "path"
- * Returns 0 on success -1 on failure
- */
-static int get_device_absolute_path(const char *device,        const char *bus, 
-                               char *path, size_t psize)
-{
-       char bus_path[SYSFS_PATH_MAX];
-
-       if (!device || !path) {
-               errno = EINVAL;
-               return -1;
-       }
-
-       memset(bus_path, 0, SYSFS_PATH_MAX);
-       if (sysfs_get_mnt_path(bus_path, SYSFS_PATH_MAX)) {
-               dprintf ("Sysfs not supported on this system\n");
-               return -1;
-       }
-       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, psize)) {
-               dprintf("Error getting to device %s\n", device);
-               return -1;
-       }
-       return 0;
-}
-
-/**
- * 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
- * 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 char *bus,        const char *bus_id)
-{
-       char sysfs_path[SYSFS_PATH_MAX];
-       struct sysfs_device *device;
-
-       if (!bus_id || !bus) {
-               errno = EINVAL;
-               return NULL;
-       }
-       memset(sysfs_path, 0, SYSFS_PATH_MAX);
-       if (get_device_absolute_path(bus_id, bus, sysfs_path, 
-                               SYSFS_PATH_MAX)) {
-               dprintf("Error getting to device %s\n", bus_id);
-               return NULL;
-       }
-       
-       device = sysfs_open_device_path(sysfs_path);
-       if (!device) {
-               dprintf("Error opening device %s\n", bus_id);
-               return NULL;
-       }
-       return device;
-}
-
-/**
- * sysfs_get_device_parent: opens up given device's parent and returns a 
- *     reference to its sysfs_device
- * @dev: sysfs_device whose parent is requested
- * Returns sysfs_device of the parent on success and NULL on failure
- */
-struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev)
-{
-       char ppath[SYSFS_PATH_MAX], dpath[SYSFS_PATH_MAX], *tmp;
-
-       if (!dev) {
-               errno = EINVAL;
-               return NULL;
-       }
-
-       if (dev->parent)
-               return (dev->parent);
-
-       memset(ppath, 0, SYSFS_PATH_MAX);
-       memset(dpath, 0, SYSFS_PATH_MAX);
-       safestrcpy(ppath, dev->path);
-       tmp = strrchr(ppath, '/');
-       if (!tmp) {
-               dprintf("Invalid path to device %s\n", ppath);
-               return NULL;
-       }
-       if (*(tmp + 1) == '\0') {
-               *tmp = '\0';
-               tmp = strrchr(tmp, '/');
-               if (tmp == NULL) {
-                       dprintf("Invalid path to device %s\n", ppath);
-                       return NULL;
-               }
-       }
-       *tmp = '\0';
-
-       /* Make sure we're not at the top of the device tree */
-       sysfs_get_mnt_path(dpath, SYSFS_PATH_MAX);
-       safestrcat(dpath, "/" SYSFS_DEVICES_NAME);
-       if (strcmp(dpath, ppath) == 0) {
-               dprintf("Device at %s does not have a parent\n", dev->path);
-               return NULL;
-       }
-
-       dev->parent = sysfs_open_device_path(ppath);
-       if (!dev->parent) {
-               dprintf("Error opening device %s's parent at %s\n", 
-                                       dev->bus_id, ppath);
-               return NULL;
-       }
-       return (dev->parent);
-}
diff --git a/libsysfs/sysfs_dir.c b/libsysfs/sysfs_dir.c
deleted file mode 100644 (file)
index 7d98c66..0000000
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- * 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"
-
-static int sort_char(void *new, void *old)
-{
-       return ((strncmp((char *)new, (char *)old, 
-                       strlen((char *)new))) < 0 ? 1 : 0);
-}
-
-/**
- * sysfs_del_name: free function for sysfs_open_subsystem_list
- * @name: memory area to be freed
- */
-static void sysfs_del_name(void *name)
-{
-       free(name);
-}
-
-/**
- * sysfs_del_attribute: routine for dlist integration
- */
-static void sysfs_del_attribute(void *attr)
-{
-       sysfs_close_attribute((struct sysfs_attribute *)attr);
-}
-
-/**
- * attr_name_equal: compares attributes by name
- * @a: attribute name for comparison
- * @b: sysfs_attribute to be compared.
- * returns 1 if a==b->name or 0 if not equal
- */
-static int attr_name_equal(void *a, void *b)
-{
-       if (!a || !b)
-               return 0;
-
-       if (strcmp(((char *)a), ((struct sysfs_attribute *)b)->name) == 0)
-               return 1;
-
-       return 0;
-}
-
-/**
- * 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) {
-                       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;
-}
-
-/**
- * add_attribute: open and add attribute at path to given directory
- * @dev: device whose attribute is to be added
- * @path: path to attribute
- * returns pointer to attr added with success and NULL with error.
- */
-static struct sysfs_attribute *add_attribute(void *dev, const char *path)
-{
-       struct sysfs_attribute *attr;
-
-       attr = sysfs_open_attribute(path);
-       if (!attr) {
-               dprintf("Error opening attribute %s\n", path);
-               return NULL;
-       }
-       if (attr->method & SYSFS_METHOD_SHOW) {
-               if (sysfs_read_attribute(attr)) {
-                       dprintf("Error reading attribute %s\n", path);
-                       sysfs_close_attribute(attr);
-                       return NULL;
-               }
-       }
-
-       if (!((struct sysfs_device *)dev)->attrlist) {
-               ((struct sysfs_device *)dev)->attrlist = dlist_new_with_delete
-                       (sizeof(struct sysfs_attribute), sysfs_del_attribute);
-       }
-       dlist_unshift_sorted(((struct sysfs_device *)dev)->attrlist, 
-                       attr, sort_list);
-
-       return attr;
-}
-
-/*
- * get_attribute - given a sysfs_* struct and a name, return the 
- * sysfs_attribute corresponding to "name"
- * returns sysfs_attribute on success and NULL on error
- */
-struct sysfs_attribute *get_attribute(void *dev, const char *name)
-{
-       struct sysfs_attribute *cur = NULL;
-       char path[SYSFS_PATH_MAX];
-
-       if (!dev || !name) {
-               errno = EINVAL;
-               return NULL;
-       }
-
-       if (((struct sysfs_device *)dev)->attrlist) {
-               /* check if attr is already in the list */
-               cur = (struct sysfs_attribute *)dlist_find_custom
-                       ((((struct sysfs_device *)dev)->attrlist), 
-                               (void *)name, attr_name_equal);
-               if (cur)
-                       return cur;
-       }
-       safestrcpymax(path, ((struct sysfs_device *)dev)->path, 
-                       SYSFS_PATH_MAX);
-       safestrcatmax(path, "/", SYSFS_PATH_MAX);
-       safestrcatmax(path, name, SYSFS_PATH_MAX);
-       if (!sysfs_path_is_file(path))
-               cur = add_attribute((void *)dev, path);
-       return cur;
-}
-
-/**
- * read_dir_links: grabs links in a specific directory
- * @sysdir: sysfs directory to read
- * returns list of link names with success and NULL with error.
- */
-struct dlist *read_dir_links(const char *path)
-{
-       DIR *dir = NULL;
-       struct dirent *dirent = NULL;
-       char file_path[SYSFS_PATH_MAX], *linkname;
-       struct dlist *linklist = NULL;
-
-       if (!path) {
-               errno = EINVAL;
-               return NULL;
-       }
-       dir = opendir(path);
-       if (!dir) {
-               dprintf("Error opening directory %s\n", path);
-               return NULL;
-       }
-       while ((dirent = readdir(dir)) != NULL) {
-               if (0 == strcmp(dirent->d_name, "."))
-                        continue;
-               if (0 == strcmp(dirent->d_name, ".."))
-                       continue;
-               memset(file_path, 0, SYSFS_PATH_MAX);
-               safestrcpy(file_path, path);
-               safestrcat(file_path, "/");
-               safestrcat(file_path, dirent->d_name);
-               if (!sysfs_path_is_link(file_path)) {
-                       if (!linklist) {
-                               linklist = dlist_new_with_delete
-                                       (SYSFS_NAME_LEN, sysfs_del_name);
-                               if (!linklist) {
-                                       dprintf("Error creating list\n");
-                                       return NULL;
-                               }
-                       }
-                       linkname = (char *)calloc(1, SYSFS_NAME_LEN);
-                       safestrcpymax(linkname, dirent->d_name, SYSFS_NAME_LEN);
-                       dlist_unshift_sorted(linklist, linkname, sort_char);
-               }
-       }
-       closedir(dir);
-       return linklist;
-}
-
-/**
- * read_dir_subdirs: grabs subdirs in a specific directory
- * @sysdir: sysfs directory to read
- * returns list of directory names with success and NULL with error.
- */
-struct dlist *read_dir_subdirs(const char *path)
-{
-       DIR *dir = NULL;
-       struct dirent *dirent = NULL;
-       char file_path[SYSFS_PATH_MAX], *dir_name;
-       struct dlist *dirlist = NULL;
-
-       if (!path) {
-               errno = EINVAL;
-               return NULL;
-       }
-       dir = opendir(path);
-       if (!dir) {
-               dprintf("Error opening directory %s\n", path);
-               return NULL;
-       }
-       while ((dirent = readdir(dir)) != NULL) {
-               if (0 == strcmp(dirent->d_name, "."))
-                        continue;
-               if (0 == strcmp(dirent->d_name, ".."))
-                       continue;
-               memset(file_path, 0, SYSFS_PATH_MAX);
-               safestrcpy(file_path, path);
-               safestrcat(file_path, "/");
-               safestrcat(file_path, dirent->d_name);
-               if (!sysfs_path_is_dir(file_path)) {
-                       if (!dirlist) {
-                               dirlist = dlist_new_with_delete
-                                       (SYSFS_NAME_LEN, sysfs_del_name);
-                               if (!dirlist) {
-                                       dprintf("Error creating list\n");
-                                       return NULL;
-                               }
-                       }
-                       dir_name = (char *)calloc(1, SYSFS_NAME_LEN);
-                       safestrcpymax(dir_name, dirent->d_name, SYSFS_NAME_LEN);
-                       dlist_unshift_sorted(dirlist, dir_name, sort_char);
-               }
-       }
-       closedir(dir);
-       return dirlist;
-}
-
-/**
- * get_attributes_list: build a list of attributes for the given device
- * @dev: devices whose attributes list is required
- * returns dlist of attributes on success and NULL on failure
- */
-struct dlist *get_attributes_list(void *dev)
-{
-       DIR *dir = NULL;
-       struct dirent *dirent = NULL;
-       struct sysfs_attribute *attr = NULL;
-       char file_path[SYSFS_PATH_MAX], path[SYSFS_PATH_MAX];
-
-       if (!dev) {
-               errno = EINVAL;
-               return NULL;
-       }
-       memset(path, 0, SYSFS_PATH_MAX);
-       safestrcpy(path, ((struct sysfs_device *)dev)->path);
-       dir = opendir(path);
-       if (!dir) {
-               dprintf("Error opening directory %s\n", path);
-               return NULL;
-       }
-       while ((dirent = readdir(dir)) != NULL) {
-               if (0 == strcmp(dirent->d_name, "."))
-                        continue;
-               if (0 == strcmp(dirent->d_name, ".."))
-                       continue;
-               memset(file_path, 0, SYSFS_PATH_MAX);
-               safestrcpy(file_path, path);
-               safestrcat(file_path, "/");
-               safestrcat(file_path, dirent->d_name);
-               if (!sysfs_path_is_file(file_path)) {
-                       if (((struct sysfs_device *)dev)->attrlist) {
-                               /* check if attr is already in the list */
-                               attr = (struct sysfs_attribute *)
-                               dlist_find_custom
-                               ((((struct sysfs_device *)dev)->attrlist), 
-                               (void *)dirent->d_name, attr_name_equal);
-                               if (attr) 
-                                       continue;
-                               else 
-                                       add_attribute(dev, file_path);
-                       } else 
-                               attr = add_attribute(dev, file_path);
-               }
-       }
-       closedir(dir);
-       return ((struct sysfs_device *)dev)->attrlist;
-}
diff --git a/libsysfs/sysfs_driver.c b/libsysfs/sysfs_driver.c
deleted file mode 100644 (file)
index c2464fa..0000000
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * sysfs_driver.c
- *
- * Driver 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"
-
-static void sysfs_close_driver_device(void *device)
-{
-       sysfs_close_device((struct sysfs_device *)device);
-}
-
-/**
- * sysfs_close_driver: closes driver and deletes device lists too
- * @driver: driver to close
- */
-void sysfs_close_driver(struct sysfs_driver *driver)
-{
-       if (driver) {
-               if (driver->devices) 
-                       dlist_destroy(driver->devices);
-               if (driver->attrlist)
-                       dlist_destroy(driver->attrlist);
-               free(driver);
-       }
-}
-
-/**
- * alloc_driver: allocates and initializes driver
- * returns struct sysfs_driver with success and NULL with error.
- */
-static struct sysfs_driver *alloc_driver(void)
-{
-       return (struct sysfs_driver *)calloc(1, sizeof(struct sysfs_driver));
-}
-
-/**
- * get_driver_bus: gets bus the driver is on
- * Returns 0 on success and 1 on error
- */
-static int get_driver_bus(struct sysfs_driver *drv)
-{
-