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 5edc76f81a85e9ddcb3dc1b7592ee2c0bdf03c4f..461f5ac012e981e3b0015f1cfee44a593c192bab 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 4e3570205e87b9b4eb84d2202efe1ff6aba44537..623ea0ed6011d6b77c806b1c80f7fd66eb242dcc 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 e87dbab88078cea4509a0e0796aa0c16e3c3ade1..7f6a30df521de55a379bf8c8b957b59f09ff03d5 100644 (file)
               </listitem>
             </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>
index ceea0413c5a5d9c384aa1dfeb1d0e5616d62e506..2b39eebab0c04a9a910cac52b08d1db88e4a0751 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 ebf0f4e9b43c05fc3be091d10e366bd1dce84fec..0a881fb194fb28341b1876299bbb137c1a99e4fd 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 a97cc284cc515765ba111ccaf67ad993d0c82d7e..aedebff711a2494a52f3273d968dea00ccd13e3a 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 985eb805a55e9189ad3840b451bd0bfd5bcde97c..9a722d52f9e8024386e3560482343871d9122a84 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 ff6f89e16375966094de7c4383f0e0a70675ce7e..0d4a8c10f02fa0fb2a08bc1b1776110278745fdc 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 80680f22fea727e25627580508e69e49767c8381..79f14a49ba2d44f3e647c6b76663ce43e0266933 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 ca2582cde666d86e1725a7cdc6493646d800ed7d..b2496e99f811f79860ed919961a47acc9612956a 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 5a6cdb65c360f0758f3c1e0e38a3131a0c3cf60f..db6afae18c4f569ca9477d6ecc355f4d2594cc69 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 f21362b90214a2797cbba57b597cca7b45925320..8fc690a49c6ff82214f90349b0d20e0298f7b20c 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 16918867fc2c0bb62c8ef12df3cde0af89ec0778..da7fe9d1a803f20b69dc0d1f92c12bf720b6324e 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 2bc6b50f0672df99ef46f23b3974f71694d60194..ca1c43814f754a21709a93f6cedbd6eef264c491 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 240af4ce059a4bd3b7d323d2d67c71459196fda9..e23191a533214f48ccba6f452cba830771a64e23 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 d138f62c033b2ec7825ff5b0a1d5d4c098236d46..37a59597b9715b8da246bb939518646d37583aea 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 69faecc15e4e31b7caeba7e8e629c24a608fdc14..c715ca6bd337dcd7fe6032e794bcc1e5d7ac8131 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 e708de8aa49d7d38b56a3be7f9f2b477bd3e9b5b..59ea766ac28578d5af759d7fa366c89763160d3e 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 a21835ae4e16d2ca06a15187341c7c01a2ec902c..bfa82ab91701f96031ae7f4d77d242b98f67f8aa 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 399de76911370ebc0c2f85b084358ff687fff56f..057594d5bf06803bea13357d964dd5d0e09b7ec6 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 aa1b16009e9f989cd301dfe9d78acd16391de767..3a4a374d3e20e807531ac69cb20d8b690e0a3f6d 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 1c9ed969a7cb0cdba3a25d65f79a09fefd002dbf..b5312b89888d02ef78fbff275b056f45da23bdbb 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 14955e676c595e04e3e291099f66f9007c62f438..bdebe94eb30cce99ae00a8e2641eac6df96c6985 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 f6d26e1c4ce52af44e5e2a14376744839b18a341..91b4d57d7639f2d6c58e37b85e11c343c3726b53 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 b7d67958c9a1bd6d4edec4902da1af95b3d30344..0bcd267f67aff5d385c25283aa82b11eacace2b5 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 6201044941029982b39fec23f5b343f568fa3dc2..edb5d3ac68906ec66917d09aa548f8fe94e360ba 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 6f99c52728f26b4412dd444f60819f780e7267a7..a291eda51d5db44a1e88df7f290793af9d1d2315 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)
-{
-       char drvpath[SYSFS_PATH_MAX], *c = NULL;
-       
-       if (!drv) {
-               errno = EINVAL;
-               return 1;
-       }
-
-       safestrcpy(drvpath, drv->path);
-       c = strstr(drvpath, SYSFS_DRIVERS_NAME);
-       if (c == NULL)
-               return 1;
-       *--c = '\0';
-       c = strstr(drvpath, SYSFS_BUS_NAME);
-       if (c == NULL)
-               return 1;
-       c = strstr(c, "/");
-       if (c == NULL)
-               return 1;
-       c++;
-       safestrcpy(drv->bus, c);
-       return 0;
-}
-
-/**
- * sysfs_get_driver_attr: searches drv's attributes by name
- * @drv: driver to look through
- * @name: attribute name to get
- * returns sysfs_attribute reference with success or NULL with error.
- */
-struct sysfs_attribute *sysfs_get_driver_attr(struct sysfs_driver *drv,
-                                               const char *name)
-{
-       if (!drv || !name) {
-               errno = EINVAL;
-               return NULL;
-       }
-       return get_attribute(drv, (char *)name);
-}
-
-/**
- * sysfs_get_driver_attributes: gets list of driver attributes
- * @dev: driver whose attributes list is needed
- * returns dlist of attributes on success or NULL on error
- */
-struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *drv)
-{
-       if (!drv) {
-               errno = EINVAL;
-               return NULL;
-       }
-       return get_attributes_list(drv);
-}
-
-/**
- * sysfs_open_driver_path: opens and initializes driver structure
- * @path: path to driver directory
- * returns struct sysfs_driver with success and NULL with error
- */
-struct sysfs_driver *sysfs_open_driver_path(const char *path)
-{
-       struct sysfs_driver *driver = NULL;
-
-       if (!path) {
-               errno = EINVAL;
-               return NULL;
-       }
-       if (sysfs_path_is_dir(path)) {
-               dprintf("Invalid path to driver: %s\n", path);
-               return NULL;
-       }
-       driver = alloc_driver();
-       if (!driver) {
-               dprintf("Error allocating driver at %s\n", path);
-               return NULL;
-       }
-       if (sysfs_get_name_from_path(path, driver->name, SYSFS_NAME_LEN)) {
-               dprintf("Error getting driver name from path\n");
-               free(driver);
-               return NULL;
-       }
-       safestrcpy(driver->path, path);
-       if (sysfs_remove_trailing_slash(driver->path)) {
-               dprintf("Invalid path to driver %s\n", driver->path);
-               sysfs_close_driver(driver);
-               return NULL;
-       }
-       if (get_driver_bus(driver)) {
-               dprintf("Could not get the bus driver is on\n");
-               sysfs_close_driver(driver);
-               return NULL;
-       }
-
-       return driver;
-}
-
-/**
- * get_driver_path: looks up the bus the driver is on and builds path to
- *             the driver.
- * @bus: bus on which to search
- * @drv: driver to look for
- * @path: buffer to return path to driver
- * @psize: size of "path"
- * Returns 0 on success and -1 on error
- */
-static int get_driver_path(const char *bus, const char *drv, 
-                       char *path, size_t psize)
-{
-       if (!bus || !drv || !path || psize == 0) {
-               errno = EINVAL;
-               return -1;
-       }
-       if (sysfs_get_mnt_path(path, psize)) {
-               dprintf("Error getting sysfs mount path\n");
-               return -1;
-       }
-       safestrcatmax(path, "/", psize);
-       safestrcatmax(path, SYSFS_BUS_NAME, psize);
-       safestrcatmax(path, "/", psize);
-       safestrcatmax(path, bus, psize);
-       safestrcatmax(path, "/", psize);
-       safestrcatmax(path, SYSFS_DRIVERS_NAME, psize);
-       safestrcatmax(path, "/", psize);
-       safestrcatmax(path, drv, psize);
-       return 0;
-}
-
-/**
- * sysfs_open_driver: open driver by name, given its bus
- * @bus_name: Name of the bus
- * @drv_name: Name of the driver
- * Returns the sysfs_driver reference on success and NULL on failure
- */
-struct sysfs_driver *sysfs_open_driver(const char *bus_name, 
-                       const char *drv_name)
-{
-       char path[SYSFS_PATH_MAX];
-       struct sysfs_driver *driver = NULL;
-
-       if (!drv_name || !bus_name) {
-               errno = EINVAL;
-               return NULL;
-       }
-
-       memset(path, 0, SYSFS_PATH_MAX);
-       if (get_driver_path(bus_name, drv_name, path, SYSFS_PATH_MAX)) {
-               dprintf("Error getting to driver %s\n", drv_name);
-               return NULL;
-       }
-       driver = sysfs_open_driver_path(path);
-       if (!driver) {
-               dprintf("Error opening driver at %s\n", path);
-               return NULL;
-       }
-       return driver;
-}
-
-/**
- * sysfs_get_driver_devices: gets list of devices that use the driver
- * @drv: sysfs_driver whose device list is needed
- * Returns dlist of struct sysfs_device on success and NULL on failure
- */
-struct dlist *sysfs_get_driver_devices(struct sysfs_driver *drv)
-{
-       char *ln = NULL;
-       struct dlist *linklist = NULL;
-       struct sysfs_device *dev = NULL;
-
-       if (!drv) {
-               errno = EINVAL;
-               return NULL;
-       }
-
-       linklist = read_dir_links(drv->path);
-       if (linklist) {
-               dlist_for_each_data(linklist, ln, char) {
-                       
-                       if (!strncmp(ln, SYSFS_MODULE_NAME, strlen(ln)))
-                               continue;
-
-                       dev = sysfs_open_device(drv->bus, ln);
-                       if (!dev) {
-                               dprintf("Error opening driver's device\n");
-                               sysfs_close_list(linklist);
-                               return NULL;
-                       }
-                       if (!drv->devices) {
-                               drv->devices = dlist_new_with_delete
-                                       (sizeof(struct sysfs_device),
-                                        sysfs_close_driver_device);
-                               if (!drv->devices) {
-                                       dprintf("Error creating device list\n");
-                                       sysfs_close_list(linklist);
-                                       return NULL;
-                               }
-                       }
-                       dlist_unshift_sorted(drv->devices, dev, sort_list);
-               }
-               sysfs_close_list(linklist);
-       }
-       return drv->devices;
-}
diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c
deleted file mode 100644 (file)
index c5558a4..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * sysfs_utils.c
- *
- * System utility functions for libsysfs
- *
- * Copyright (C) IBM Corp. 2003-2005
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#include "libsysfs.h"
-#include "sysfs.h"
-
-/**
- * sysfs_remove_trailing_slash: Removes any trailing '/' in the given path
- * @path: Path to look for the trailing '/'
- * Returns 0 on success 1 on error
- */ 
-int sysfs_remove_trailing_slash(char *path)
-{
-       size_t len;
-
-       if (!path) {
-               errno = EINVAL;
-               return 1;
-       }
-
-       len = strlen(path);
-       while (len > 0 && path[len-1] == '/')
-               path[--len] = '\0';
-       return 0;
-}
-
-/*
- * sysfs_get_mnt_path: Gets the sysfs mount point.
- * @mnt_path: place to put "sysfs" mount point
- * @len: size of mnt_path
- * returns 0 with success and -1 with error.
- */
-int sysfs_get_mnt_path(char *mnt_path, size_t len)
-{
-       static char sysfs_path[SYSFS_PATH_MAX] = "";
-       const char *sysfs_path_env;
-
-       /* evaluate only at the first call */
-       if (sysfs_path[0] == '\0') {
-               /* possible overrride of real mount path */
-               sysfs_path_env = getenv(SYSFS_PATH_ENV);
-               if (sysfs_path_env != NULL) {
-                       safestrcpymax(mnt_path, sysfs_path_env, len);
-                       sysfs_remove_trailing_slash(mnt_path);
-                       return 0;
-               }
-               safestrcpymax(mnt_path, SYSFS_MNT_PATH, len);
-       }
-
-       return 0;
-}
-
-/**
- * sysfs_get_name_from_path: returns last name from a "/" delimited path
- * @path: path to get name from
- * @name: where to put name
- * @len: size of name
- */
-int sysfs_get_name_from_path(const char *path, char *name, size_t len)
-{
-       char tmp[SYSFS_PATH_MAX];
-       char *n = NULL;
-
-       if (!path || !name || len == 0) {
-               errno = EINVAL;
-               return -1;
-       }
-       memset(tmp, 0, SYSFS_PATH_MAX);
-       safestrcpy(tmp, path);
-       n = strrchr(tmp, '/');
-       if (n == NULL) {
-               errno = EINVAL;
-               return -1;
-       }
-       if (*(n+1) == '\0') {
-               *n = '\0';
-               n = strrchr(tmp, '/');
-               if (n == NULL) {
-                       errno = EINVAL;
-                       return -1;
-               }
-       }
-       n++;
-       safestrcpymax(name, n, len);
-       return 0;
-}
-
-/**
- * sysfs_get_link: returns link source
- * @path: symbolic link's path
- * @target: where to put name
- * @len: size of name
- */
-int sysfs_get_link(const char *path, char *target, size_t len)
-{
-       char devdir[SYSFS_PATH_MAX];
-       char linkpath[SYSFS_PATH_MAX];
-       char temp_path[SYSFS_PATH_MAX];
-       char *d = NULL, *s = NULL;
-       int slashes = 0, count = 0;
-
-       if (!path || !target || len == 0) {
-               errno = EINVAL;
-               return -1;
-       }
-
-       memset(devdir, 0, SYSFS_PATH_MAX);
-       memset(linkpath, 0, SYSFS_PATH_MAX);
-       memset(temp_path, 0, SYSFS_PATH_MAX);
-       safestrcpy(devdir, path);
-
-       if ((readlink(path, linkpath, SYSFS_PATH_MAX)) < 0) {
-               return -1;
-       }
-       d = linkpath;
-       /*
-        * Three cases here:
-        * 1. relative path => format ../..
-        * 2. absolute path => format /abcd/efgh
-        * 3. relative path _from_ this dir => format abcd/efgh
-        */
-       switch (*d) {
-               case '.': 
-                       /*
-                        * handle the case where link is of type ./abcd/xxx
-                        */
-                       safestrcpy(temp_path, devdir);
-                       if (*(d+1) == '/')
-                               d += 2;
-                       else if (*(d+1) == '.')
-                               goto parse_path;
-                       s = strrchr(temp_path, '/');
-                       if (s != NULL) {
-                               *(s+1) = '\0';
-                               safestrcat(temp_path, d);
-                       } else {
-                               safestrcpy(temp_path, d);
-                       }
-                       safestrcpymax(target, temp_path, len);
-                       break;
-                       /*
-                        * relative path, getting rid of leading "../.."
-                        */
-parse_path:
-                       while (*d == '/' || *d == '.') {
-                               if (*d == '/')
-                                       slashes++;
-                               d++;
-                       }
-                       d--;
-                       s = &devdir[strlen(devdir)-1];
-                       while (s != NULL && count != (slashes+1)) {
-                               s--;
-                               if (*s == '/')
-                                       count++;
-                       }
-                       safestrcpymax(s, d, (SYSFS_PATH_MAX-strlen(devdir)));
-                       safestrcpymax(target, devdir, len);
-                       break;
-               case '/':
-                       /* absolute path - copy as is */
-                       safestrcpymax(target, linkpath, len);
-                       break;
-               default:
-                       /* relative path from this directory */
-                       safestrcpy(temp_path, devdir);
-                       s = strrchr(temp_path, '/');
-                       if (s != NULL) {
-                               *(s+1) = '\0';
-                               safestrcat(temp_path, linkpath);
-                       } else {
-                               safestrcpy(temp_path, linkpath);
-                       }
-                       safestrcpymax(target, temp_path, len);
-       }
-       return 0;
-}
-
-/**
- * sysfs_close_list: generic list free routine
- * @list: dlist to free
- * Returns nothing
- */
-void sysfs_close_list(struct dlist *list)
-{
-       if (list)
-               dlist_destroy(list);
-}
-
-/**
- * sysfs_open_directory_list: gets a list of all directories under "path"
- * @path: path to read
- * Returns a dlist of supported names or NULL no directories (errno is set
- *     in case of error
- */
-struct dlist *sysfs_open_directory_list(const char *path)
-{
-       if (!path)
-               return NULL;
-
-       return (read_dir_subdirs(path));
-}
-
-/**
- * sysfs_path_is_dir: Check if the path supplied points to a directory
- * @path: path to validate
- * Returns 0 if path points to dir, 1 otherwise
- */
-int sysfs_path_is_dir(const char *path)
-{
-       struct stat astats;
-
-       if (!path) {
-               errno = EINVAL;
-               return 1;
-       }
-       if ((lstat(path, &astats)) != 0) {
-               dprintf("stat() failed\n");
-               return 1;
-       }
-       if (S_ISDIR(astats.st_mode))
-               return 0;
-
-       return 1;
-}
-
-/**
- * sysfs_path_is_link: Check if the path supplied points to a link
- * @path: path to validate
- * Returns 0 if path points to link, 1 otherwise
- */
-int sysfs_path_is_link(const char *path)
-{
-       struct stat astats;
-
-       if (!path) {
-               errno = EINVAL;
-               return 1;
-       }
-       if ((lstat(path, &astats)) != 0) {
-               dprintf("stat() failed\n");
-               return 1;
-       }
-       if (S_ISLNK(astats.st_mode))
-               return 0;
-
-       return 1;
-}
-
-/**
- * sysfs_path_is_file: Check if the path supplied points to a file
- * @path: path to validate
- * Returns 0 if path points to file, 1 otherwise
- */
-int sysfs_path_is_file(const char *path)
-{
-       struct stat astats;
-
-       if (!path) {
-               errno = EINVAL;
-               return 1;
-       }
-       if ((lstat(path, &astats)) != 0) {
-               dprintf("stat() failed\n");
-               return 1;
-       }
-       if (S_ISREG(astats.st_mode))
-               return 0;
-
-       return 1;
-}
index d1c28749fb7117b2aed55056d33c6bbf6d3789b6..faa7c46432dcde340eb36ec5f3e69112ad0429b5 100755 (executable)
@@ -23,8 +23,7 @@ make all $MAKEOPTS USE_LOG=false EXTRAS="$EXTRAS" || exit
 echo -e "\n\n"
 
 # klibc build
-[ -z "$KLCC" ] && KLCC=/usr/bin/klcc
-if [ -e "$KLCC" ]; then
+if [ -n "$KLCC" -a -e "$KLCC" ]; then
        echo KLCC: "$KLCC"
        make clean EXTRAS="$EXTRAS" >/dev/null
        make all -j4 $MAKEOPTS USE_KLIBC=true DEBUG=true EXTRAS="$EXTRAS" KLCC="$KLCC" || exit
index c33c79b1c096adbe0793748484235da3a197a406..7ce920092fc05b0a99d888ca592ef84f62a01a5e 100755 (executable)
@@ -243,18 +243,18 @@ EOF
                desc            => "test substitution chars",
                subsys          => "block",
                devpath         => "/block/sda/sda3",
-               exp_name        => "Major:8:minor:3:kernelnumber:3:bus:0:0:0:0" ,
+               exp_name        => "Major:8:minor:3:kernelnumber:3" ,
                rules           => <<EOF
-BUS=="scsi", ID=="0:0:0:0", NAME="Major:%M:minor:%m:kernelnumber:%n:bus:%b"
+BUS=="scsi", ID=="0:0:0:0", NAME="Major:%M:minor:%m:kernelnumber:%n"
 EOF
        },
        {
                desc            => "test substitution chars (with length limit)",
                subsys          => "block",
                devpath         => "/block/sda/sda3",
-               exp_name        => "M8-m3-n3-b0:0-sIBM" ,
+               exp_name        => "M8-m3-n3-bsd-sIBM" ,
                rules           => <<EOF
-BUS=="scsi", ID=="0:0:0:0", NAME="M%M-m%m-n%n-b%3b-s%3s{vendor}"
+BUS=="scsi", ID=="0:0:0:0", NAME="M%M-m%m-n%n-b%2k-s%3s{vendor}"
 EOF
        },
        {
@@ -322,9 +322,9 @@ EOF
                desc            => "program result substitution",
                subsys          => "block",
                devpath         => "/block/sda/sda3",
-               exp_name        => "test-0:0:0:0" ,
+               exp_name        => "test-3" ,
                rules           => <<EOF
-BUS=="scsi", PROGRAM=="/bin/echo -n test-%b", RESULT=="test-0:0*", NAME="%c"
+BUS=="scsi", PROGRAM=="/bin/echo -n test-%n", RESULT=="test-3*", NAME="%c"
 EOF
        },
        {
@@ -385,27 +385,27 @@ EOF
                desc            => "test substitution by variable name",
                subsys          => "block",
                devpath         => "/block/sda/sda3",
-               exp_name        => "Major:8-minor:3-kernelnumber:3-bus:0:0:0:0" ,
+               exp_name        => "Major:8-minor:3-kernelnumber:3" ,
                rules           => <<EOF
-BUS=="scsi", ID=="0:0:0:0", NAME="Major:\$major-minor:\$minor-kernelnumber:\$number-bus:\$id"
+BUS=="scsi", ID=="0:0:0:0", NAME="Major:\$major-minor:\$minor-kernelnumber:\$number"
 EOF
        },
        {
                desc            => "test substitution by variable name 2",
                subsys          => "block",
                devpath         => "/block/sda/sda3",
-               exp_name        => "Major:8-minor:3-kernelnumber:3-bus:0:0:0:0" ,
+               exp_name        => "Major:8-minor:3-kernelnumber:3-name:sda3" ,
                rules           => <<EOF
-BUS=="scsi", ID=="0:0:0:0", DEVPATH="*/sda/*", NAME="Major:\$major-minor:%m-kernelnumber:\$number-bus:%b"
+BUS=="scsi", ID=="0:0:0:0", DEVPATH="*/sda/*", NAME="Major:\$major-minor:%m-kernelnumber:\$number-name:\$kernel"
 EOF
        },
        {
                desc            => "test substitution by variable name 3",
                subsys          => "block",
                devpath         => "/block/sda/sda3",
-               exp_name        => "830:0:0:03" ,
+               exp_name        => "83sda33" ,
                rules           => <<EOF
-BUS=="scsi", ID=="0:0:0:0", DEVPATH="*/sda/*", NAME="%M%m%b%n"
+BUS=="scsi", ID=="0:0:0:0", DEVPATH="*/sda/*", NAME="%M%m%k%n"
 EOF
        },
        {
@@ -421,9 +421,9 @@ EOF
                desc            => "test substitution by variable name 5",
                subsys          => "block",
                devpath         => "/block/sda/sda3",
-               exp_name        => "8330:0:0:0" ,
+               exp_name        => "833sda3" ,
                rules           => <<EOF
-BUS=="scsi", ID=="0:0:0:0", DEVPATH="*/sda/*", NAME="\$major%m%n\$id"
+BUS=="scsi", ID=="0:0:0:0", DEVPATH="*/sda/*", NAME="\$major%m%n\$kernel"
 EOF
        },
        {
@@ -470,11 +470,11 @@ EOF
                desc            => "program and bus type match",
                subsys          => "block",
                devpath         => "/block/sda",
-               exp_name        => "scsi-0:0:0:0" ,
+               exp_name        => "scsi-sda" ,
                rules           => <<EOF
-BUS=="usb", PROGRAM=="/bin/echo -n usb-%b", NAME="%c"
-BUS=="scsi", PROGRAM=="/bin/echo -n scsi-%b", NAME="%c"
-BUS=="foo", PROGRAM=="/bin/echo -n foo-%b", NAME="%c"
+BUS=="usb", PROGRAM=="/bin/echo -n usb-%k", NAME="%c"
+BUS=="scsi", PROGRAM=="/bin/echo -n scsi-%k", NAME="%c"
+BUS=="foo", PROGRAM=="/bin/echo -n foo-%k", NAME="%c"
 EOF
        },
        {
@@ -797,7 +797,7 @@ EOF
                exp_name        => "symlink2-ttyUSB0",
                exp_target      => "ttyUSB0",
                rules           => <<EOF
-KERNEL=="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="symlink1-%n symlink2-%k symlink3-%b"
+KERNEL=="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="symlink1-%n symlink2-%k"
 EOF
        },
        {
@@ -918,13 +918,13 @@ KERNEL=="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK+="major-%M:%m"
 EOF
        },
        {
-               desc            => "symlink %b substitution",
+               desc            => "symlink %k substitution",
                subsys          => "block",
                devpath         => "/block/sda",
-               exp_name        => "symlink-0:0:0:0",
+               exp_name        => "symlink-sda",
                exp_target      => "node",
                rules           => <<EOF
-BUS=="scsi", KERNEL=="sda", NAME="node", SYMLINK+="symlink-%b"
+BUS=="scsi", KERNEL=="sda", NAME="node", SYMLINK+="symlink-%k"
 EOF
        },
        {
@@ -1564,6 +1564,13 @@ sub udev {
 
        $ENV{DEVPATH} = $devpath;
 
+       open my $fd, "$sysfs$devpath/dev";
+       my $dev = <$fd>;
+       close $fd;
+       $dev =~ m/^(.+):(.+)$/;
+       $ENV{MAJOR} = $1;
+       $ENV{MINOR} = $2;
+
        # create temporary rules
        open CONF, ">$udev_rules" || die "unable to create rules file: $udev_rules";
        print CONF $$rules;
diff --git a/udev.c b/udev.c
index f2d6f6653c3bc167ffdf3f981798f6d0241e3a84..4762ab1cef022cf0a0d68221803f2bbd10da81ce 100644 (file)
--- a/udev.c
+++ b/udev.c
 #include <unistd.h>
 #include <syslog.h>
 
-#include "libsysfs/sysfs/libsysfs.h"
-#include "udev_libc_wrapper.h"
 #include "udev.h"
-#include "udev_utils.h"
-#include "udev_version.h"
 #include "udev_rules.h"
-#include "logging.h"
 
 #ifdef USE_LOG
 void log_message(int priority, const char *format, ...)
@@ -65,7 +60,9 @@ static void asmlinkage sig_handler(int signum)
 
 int main(int argc, char *argv[], char *envp[])
 {
-       struct udevice udev;
+       struct sysfs_device *dev;
+       struct udevice *udev;
+       const char *maj, *min;
        struct udev_rules rules;
        const char *action;
        const char *devpath;
@@ -95,7 +92,7 @@ int main(int argc, char *argv[], char *envp[])
        logging_init("udev");
        if (devnull < 0)
                err("fatal, could not open /dev/null: %s", strerror(errno));
-       udev_init_config();
+       udev_config_init();
        dbg("version %s", UDEV_VERSION);
 
        /* set signal handlers */
@@ -114,10 +111,10 @@ int main(int argc, char *argv[], char *envp[])
        devpath = getenv("DEVPATH");
        subsystem = getenv("SUBSYSTEM");
        /* older kernels passed the SUBSYSTEM only as argument */
-       if (!subsystem && argc == 2)
+       if (subsystem == NULL && argc == 2)
                subsystem = argv[1];
 
-       if (!action || !subsystem || !devpath) {
+       if (action == NULL || subsystem == NULL || devpath == NULL) {
                err("action, subsystem or devpath missing");
                goto exit;
        }
@@ -130,25 +127,49 @@ int main(int argc, char *argv[], char *envp[])
                setenv("UDEV_LOG", priority, 1);
        }
 
-       udev_init_device(&udev, devpath, subsystem, action);
+       sysfs_init();
        udev_rules_init(&rules, 0);
 
-       retval = udev_process_event(&rules, &udev);
+       dev = sysfs_device_get(devpath);
+       if (dev == NULL) {
+               info("unable to open '%s'", devpath);
+               goto fail;
+       }
+
+       udev = udev_device_init();
+       if (udev == NULL)
+               goto fail;
+
+       /* override built-in sysfs device */
+       udev->dev = dev;
+       strlcpy(udev->action, action, sizeof(udev->action));
+
+       /* get dev_t from environment, which is needed for "remove" to work, "add" works also from sysfs */
+       maj = getenv("MAJOR");
+       min = getenv("MINOR");
+       if (maj != NULL && min != NULL)
+               udev->devt = makedev(atoi(maj), atoi(min));
+       else
+               udev->devt = udev_device_get_devt(udev);
+
+       retval = udev_device_event(&rules, udev);
 
-       if (!retval && udev_run && !list_empty(&udev.run_list)) {
+       if (!retval && udev_run && !list_empty(&udev->run_list)) {
                struct name_entry *name_loop;
 
                dbg("executing run list");
-               list_for_each_entry(name_loop, &udev.run_list, node) {
+               list_for_each_entry(name_loop, &udev->run_list, node) {
                        if (strncmp(name_loop->name, "socket:", strlen("socket:")) == 0)
                                pass_env_to_socket(&name_loop->name[strlen("socket:")], devpath, action);
                        else
-                               run_program(name_loop->name, udev.subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO));
+                               run_program(name_loop->name, udev->dev->subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO));
                }
        }
 
-       udev_rules_close(&rules);
-       udev_cleanup_device(&udev);
+       udev_device_cleanup(udev);
+fail:
+       udev_rules_cleanup(&rules);
+       sysfs_cleanup();
 
 exit:
        logging_close();
diff --git a/udev.h b/udev.h
index ca99da512d9d0f06d35f7f2eb4220cf27b1977f9..c060b8d6fff6bb28c36d67d107fe551c47c00c84 100644 (file)
--- a/udev.h
+++ b/udev.h
 
 #include <sys/types.h>
 #include <sys/param.h>
-#include "libsysfs/sysfs/libsysfs.h"
+
 #include "list.h"
+#include "logging.h"
+#include "udev_libc_wrapper.h"
+#include "udev_version.h"
 
 #define COMMENT_CHARACTER              '#'
 #define PATH_TO_NAME_CHAR              '@'
 #define DEFAULT_PARTITIONS_COUNT       15
 #define UDEV_ALARM_TIMEOUT             180
 
+#define UDEV_MAX(a,b) ((a) > (b) ? (a) : (b))
+
+/* pipes */
+#define READ_END                       0
+#define WRITE_END                      1
+
 #define DB_DIR                         ".udev/db"
 
 struct udev_rules;
 
-enum device_type {
-       DEV_UNKNOWN,
-       DEV_CLASS,
-       DEV_BLOCK,
-       DEV_NET,
-       DEV_DEVICE,
+struct sysfs_device {
+       struct list_head node;          /* for device cache */
+       char devpath[PATH_SIZE];
+       char subsystem[NAME_SIZE];      /* $class/$bus/"drivers */
+       char kernel_name[NAME_SIZE];    /* device instance name */
+       char kernel_number[NAME_SIZE];
+       char driver[NAME_SIZE];         /* device driver name */
 };
 
 struct udevice {
-       char devpath[PATH_SIZE];
-       char subsystem[NAME_SIZE];
+       /* device event */
+       struct sysfs_device *dev;
+       struct sysfs_device dev_local;
        char action[NAME_SIZE];
 
-       enum device_type type;
+       /* node */
        char name[PATH_SIZE];
        struct list_head symlink_list;
        int symlink_final;
@@ -67,42 +78,83 @@ struct udevice {
        mode_t mode;
        int mode_final;
        dev_t devt;
+
+       /* event processing */
        struct list_head run_list;
        int run_final;
        struct list_head env_list;
-
        char tmp_node[PATH_SIZE];
        int partitions;
        int ignore_device;
        int ignore_remove;
-       char bus_id[NAME_SIZE];
        char program_result[PATH_SIZE];
-       char kernel_number[NAME_SIZE];
-       char kernel_name[NAME_SIZE];
        int test_run;
 };
 
-extern int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem, const char *action);
-extern void udev_cleanup_device(struct udevice *udev);
-extern dev_t get_devt(struct sysfs_class_device *class_dev);
-extern int udev_process_event(struct udev_rules *rules, struct udevice *udev);
-extern int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev);
-extern int udev_remove_device(struct udevice *udev);
-extern void udev_init_config(void);
-extern int udev_start(void);
+/* udev_config.c */
+extern char udev_root[PATH_SIZE];
+extern char udev_config_filename[PATH_SIZE];
+extern char udev_rules_filename[PATH_SIZE];
+extern int udev_log_priority;
+extern int udev_run;
+extern void udev_config_init(void);
+
+/* udev_device.c */
+extern struct udevice *udev_device_init(void);
+extern void udev_device_cleanup(struct udevice *udev);
+extern int udev_device_event(struct udev_rules *rules, struct udevice *udev);
+extern dev_t udev_device_get_devt(struct udevice *udev);
+
+/* udev_sysfs.c */
+extern char sysfs_path[PATH_SIZE];
+extern int sysfs_init(void);
+extern void sysfs_cleanup(void);
+extern void sysfs_device_set_values(struct sysfs_device *dev, const char *devpath, const char *subsystem);
+extern struct sysfs_device *sysfs_device_get(const char *devpath);
+extern struct sysfs_device *sysfs_device_get_parent(struct sysfs_device *dev);
+extern char *sysfs_attr_get_value(const char *devpath, const char *attr_name);
+
+/* udev_add.c / udev_remove.c */
+extern int udev_add_device(struct udevice *udev);
 extern int udev_make_node(struct udevice *udev, const char *file, dev_t devt, mode_t mode, uid_t uid, gid_t gid);
+extern int udev_remove_device(struct udevice *udev);
 
+/* udev_db.c */
 extern int udev_db_add_device(struct udevice *dev);
 extern int udev_db_delete_device(struct udevice *dev);
 extern int udev_db_get_device(struct udevice *udev, const char *devpath);
 extern int udev_db_lookup_name(const char *name, char *devpath, size_t len);
 extern int udev_db_get_all_entries(struct list_head *name_list);
 
-extern char sysfs_path[PATH_SIZE];
-extern char udev_root[PATH_SIZE];
-extern char udev_config_filename[PATH_SIZE];
-extern char udev_rules_filename[PATH_SIZE];
-extern int udev_log_priority;
-extern int udev_run;
+/* udev_utils.c */
+struct name_entry {
+       struct list_head node;
+       char name[PATH_SIZE];
+};
+extern int log_priority(const char *priority);
+extern int name_list_add(struct list_head *name_list, const char *name, int sort);
+extern int name_list_key_add(struct list_head *name_list, const char *key, const char *value);
+extern void name_list_cleanup(struct list_head *name_list);
+extern int add_matching_files(struct list_head *name_list, const char *dirname, const char *suffix);
+
+/* udev_utils_string.c */
+extern int strcmp_pattern(const char *p, const char *s);
+extern int string_is_true(const char *str);
+extern void remove_trailing_chars(char *path, char c);
+extern int utf8_encoded_valid_unichar(const char *str);
+extern int replace_untrusted_chars(char *str);
+
+/* udev_utils_file.c */
+extern int create_path(const char *path);
+extern int delete_path(const char *path);
+extern int file_map(const char *filename, char **buf, size_t *bufsize);
+extern void file_unmap(void *buf, size_t bufsize);
+extern int unlink_secure(const char *filename);
+extern size_t buf_get_line(const char *buf, size_t buflen, size_t cur);
+
+/* udev_utils_run.c */
+extern int pass_env_to_socket(const char *name, const char *devpath, const char *action);
+extern int run_program(const char *command, const char *subsystem,
+                      char *result, size_t ressize, size_t *reslen, int log);
 
 #endif
index bf2d59d1989900c7e05f62d339d7a949233dac56..2c66a0ba8d071733a4d69923cca38f573472e97e 100644 (file)
@@ -22,6 +22,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
+#include <stddef.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
 #include <sys/types.h>
 #include <grp.h>
 #include <net/if.h>
-#include <sys/socket.h>
 #include <sys/ioctl.h>
 #include <linux/sockios.h>
 
-#include "libsysfs/sysfs/libsysfs.h"
-#include "udev_libc_wrapper.h"
 #include "udev.h"
-#include "udev_utils.h"
-#include "udev_version.h"
-#include "logging.h"
 #include "udev_rules.h"
 #include "udev_selinux.h"
 
@@ -48,25 +43,18 @@ int udev_make_node(struct udevice *udev, const char *file, dev_t devt, mode_t mo
        struct stat stats;
        int retval = 0;
 
-       switch (udev->type) {
-       case DEV_BLOCK:
+       if (major(devt) != 0 && strcmp(udev->dev->subsystem, "block") == 0)
                mode |= S_IFBLK;
-               break;
-       case DEV_CLASS:
+       else
                mode |= S_IFCHR;
-               break;
-       default:
-               dbg("unknown node type %c\n", udev->type);
-               return -EINVAL;
-       }
 
        if (stat(file, &stats) != 0)
                goto create;
 
-       /* preserve node with already correct numbers, to not change the inode number */
+       /* preserve node with already correct numbers, to prevent changing the inode number */
        if ((stats.st_mode & S_IFMT) == (mode & S_IFMT) && (stats.st_rdev == devt)) {
                info("preserve file '%s', cause it has correct dev_t", file);
-               selinux_setfilecon(file, udev->kernel_name, stats.st_mode);
+               selinux_setfilecon(file, udev->dev->kernel_name, stats.st_mode);
                goto perms;
        }
 
@@ -76,7 +64,7 @@ int udev_make_node(struct udevice *udev, const char *file, dev_t devt, mode_t mo
                dbg("already present file '%s' unlinked", file);
 
 create:
-       selinux_setfscreatecon(file, udev->kernel_name, mode);
+       selinux_setfscreatecon(file, udev->dev->kernel_name, mode);
        retval = mknod(file, mode, devt);
        selinux_resetfscreatecon();
        if (retval != 0) {
@@ -105,7 +93,7 @@ exit:
        return retval;
 }
 
-static int create_node(struct udevice *udev, struct sysfs_class_device *class_dev)
+static int create_node(struct udevice *udev)
 {
        char filename[PATH_SIZE];
        struct name_entry *name_loop;
@@ -161,13 +149,13 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de
        /* create all_partitions if requested */
        if (udev->partitions) {
                char partitionname[PATH_SIZE];
-               struct sysfs_attribute *attr;
+               char *attr;
                int range;
 
                /* take the maximum registered minor range */
-               attr = sysfs_get_classdev_attr(class_dev, "range");
+               attr = sysfs_attr_get_value(udev->dev->devpath, "range");
                if (attr) {
-                       range = atoi(attr->value);
+                       range = atoi(attr);
                        if (range > 1)
                                udev->partitions = range-1;
                }
@@ -247,7 +235,7 @@ static int rename_net_if(struct udevice *udev)
        struct ifreq ifr;
        int retval;
 
-       info("changing net interface name from '%s' to '%s'", udev->kernel_name, udev->name);
+       info("changing net interface name from '%s' to '%s'", udev->dev->kernel_name, udev->name);
        if (udev->test_run)
                return 0;
 
@@ -258,7 +246,7 @@ static int rename_net_if(struct udevice *udev)
        }
 
        memset(&ifr, 0x00, sizeof(struct ifreq));
-       strlcpy(ifr.ifr_name, udev->kernel_name, IFNAMSIZ);
+       strlcpy(ifr.ifr_name, udev->dev->kernel_name, IFNAMSIZ);
        strlcpy(ifr.ifr_newname, udev->name, IFNAMSIZ);
 
        retval = ioctl(sk, SIOCSIFNAME, &ifr);
@@ -269,7 +257,7 @@ static int rename_net_if(struct udevice *udev)
        return retval;
 }
 
-int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev)
+int udev_add_device(struct udevice *udev)
 {
        char *pos;
        int retval = 0;
@@ -277,16 +265,16 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev)
        dbg("adding name='%s'", udev->name);
        selinux_init();
 
-       if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS) {
-               retval = create_node(udev, class_dev);
+       if (major(udev->devt)) {
+               retval = create_node(udev);
                if (retval != 0)
                        goto exit;
 
                if (udev_db_add_device(udev) != 0)
                        dbg("udev_db_add_dev failed, remove might not work for custom names");
-       } else if (udev->type == DEV_NET) {
+       } else if (strcmp(udev->dev->subsystem, "net") == 0) {
                /* look if we want to change the name of the netif */
-               if (strcmp(udev->name, udev->kernel_name) != 0) {
+               if (strcmp(udev->name, udev->dev->kernel_name) != 0) {
                        retval = rename_net_if(udev);
                        if (retval != 0)
                                goto exit;
@@ -296,12 +284,12 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev)
                         * original kernel name sleeps with the fishes and we don't
                         * get an event from the kernel with the new name
                         */
-                       pos = strrchr(udev->devpath, '/');
+                       pos = strrchr(udev->dev->devpath, '/');
                        if (pos != NULL) {
                                pos[1] = '\0';
-                               strlcat(udev->devpath, udev->name, sizeof(udev->devpath));
-                               strlcpy(udev->kernel_name, udev->name, sizeof(udev->kernel_name));
-                               setenv("DEVPATH", udev->devpath, 1);
+                               strlcat(udev->dev->devpath, udev->name, sizeof(udev->dev->devpath));
+                               strlcpy(udev->dev->kernel_name, udev->name, sizeof(udev->dev->kernel_name));
+                               setenv("DEVPATH", udev->dev->devpath, 1);
                                setenv("INTERFACE", udev->name, 1);
                        }
                }
index c1af7c12ca8149c11e9981c79d19915d8e9e6d72..a7e19fe8646f6ea80e352299cec621a31a33694f 100644 (file)
 #include <ctype.h>
 #include <syslog.h>
 
-#include "libsysfs/sysfs/libsysfs.h"
-#include "udev_libc_wrapper.h"
 #include "udev.h"
-#include "udev_utils.h"
-#include "udev_version.h"
-#include "logging.h"
 
 /* global variables */
-char sysfs_path[PATH_SIZE];
 char udev_root[PATH_SIZE];
 char udev_config_filename[PATH_SIZE];
 char udev_rules_filename[PATH_SIZE];
@@ -168,7 +162,7 @@ static int parse_config_file(void)
        return retval;
 }
 
-void udev_init_config(void)
+void udev_config_init(void)
 {
        const char *env;
 
@@ -177,7 +171,6 @@ void udev_init_config(void)
        strcpy(udev_rules_filename, UDEV_RULES_FILE);
        udev_log_priority = LOG_ERR;
        udev_run = 1;
-       sysfs_get_mnt_path(sysfs_path, sizeof(sysfs_path));
 
        /* disable RUN key execution */
        env = getenv("UDEV_RUN");
@@ -202,7 +195,6 @@ void udev_init_config(void)
        if (env)
                udev_log_priority = log_priority(env);
 
-       dbg("sysfs_path='%s'", sysfs_path);
        dbg("UDEV_CONFIG_FILE='%s'", udev_config_filename);
        dbg("udev_root='%s'", udev_root);
        dbg("udev_rules='%s'", udev_rules_filename);
index 6b9d5e8426ccd2bb36be409d2a891bd151771b3d..e9ae799132a1be4282e1bbc016d59293091a893a 100644 (file)
--- a/udev_db.c
+++ b/udev_db.c
 #include <errno.h>
 #include <dirent.h>
 
-#include "libsysfs/sysfs/libsysfs.h"
-#include "udev_libc_wrapper.h"
 #include "udev.h"
-#include "udev_utils.h"
-#include "logging.h"
 
 
 static int devpath_to_db_path(const char *devpath, char *filename, size_t len)
@@ -83,21 +79,21 @@ int udev_db_add_device(struct udevice *udev)
        /* don't write anything if udev created only the node with the
         * kernel name without any interesting data to remember
         */
-       if (strcmp(udev->name, udev->kernel_name) == 0 &&
+       if (strcmp(udev->name, udev->dev->kernel_name) == 0 &&
            list_empty(&udev->symlink_list) && list_empty(&udev->env_list) &&
            !udev->partitions && !udev->ignore_remove) {
                dbg("nothing interesting to store in udevdb, skip");
                goto exit;
        }
 
-       devpath_to_db_path(udev->devpath, filename, sizeof(filename));
+       devpath_to_db_path(udev->dev->devpath, filename, sizeof(filename));
        create_path(filename);
        f = fopen(filename, "w");
        if (f == NULL) {
                err("unable to create db file '%s': %s", filename, strerror(errno));
                return -1;
        }
-       dbg("storing data for device '%s' in '%s'", udev->devpath, filename);
+       dbg("storing data for device '%s' in '%s'", udev->dev->devpath, filename);
 
        fprintf(f, "N:%s\n", udev->name);
        list_for_each_entry(name_loop, &udev->symlink_list, node)
@@ -132,7 +128,7 @@ int udev_db_get_device(struct udevice *udev, const char *devpath)
                return -1;
        }
 
-       strlcpy(udev->devpath, devpath, sizeof(udev->devpath));
+       strlcpy(udev->dev->devpath, devpath, sizeof(udev->dev->devpath));
        cur = 0;
        while (cur < bufsize) {
                count = buf_get_line(buf, bufsize, cur);
@@ -196,7 +192,7 @@ int udev_db_delete_device(struct udevice *udev)
 {
        char filename[PATH_SIZE];
 
-       devpath_to_db_path(udev->devpath, filename, sizeof(filename));
+       devpath_to_db_path(udev->dev->devpath, filename, sizeof(filename));
        unlink(filename);
 
        return 0;
index 7821c91cb44a0e0d90efa797ccf7138028c97240..032500142808fe8c36adfaa6ab37b5c9d6202e94 100644 (file)
 #include <fcntl.h>
 #include <errno.h>
 #include <ctype.h>
-#include <dirent.h>
-#include <syslog.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/utsname.h>
-
-#include "udev_libc_wrapper.h"
+
 #include "udev.h"
-#include "logging.h"
-#include "udev_utils.h"
-#include "list.h"
+#include "udev_rules.h"
 
 
-int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem, const char *action)
+struct udevice *udev_device_init(void)
 {
-       char *pos;
+       struct udevice *udev;
 
+       udev = malloc(sizeof(struct udevice));
+       if (udev == NULL)
+               return NULL;
        memset(udev, 0x00, sizeof(struct udevice));
+
        INIT_LIST_HEAD(&udev->symlink_list);
        INIT_LIST_HEAD(&udev->run_list);
        INIT_LIST_HEAD(&udev->env_list);
 
-       if (subsystem)
-               strlcpy(udev->subsystem, subsystem, sizeof(udev->subsystem));
-
-       if (action)
-               strlcpy(udev->action, action, sizeof(udev->action));
-
-       if (devpath) {
-               strlcpy(udev->devpath, devpath, sizeof(udev->devpath));
-               remove_trailing_chars(udev->devpath, '/');
-
-               if (strncmp(udev->devpath, "/block/", 7) == 0)
-                       udev->type = DEV_BLOCK;
-               else if (strncmp(udev->devpath, "/class/net/", 11) == 0)
-                       udev->type = DEV_NET;
-               else if (strncmp(udev->devpath, "/class/", 7) == 0)
-                       udev->type = DEV_CLASS;
-               else if (strncmp(udev->devpath, "/devices/", 9) == 0)
-                       udev->type = DEV_DEVICE;
-
-               /* get kernel name */
-               pos = strrchr(udev->devpath, '/');
-               if (pos) {
-                       strlcpy(udev->kernel_name, &pos[1], sizeof(udev->kernel_name));
-                       dbg("kernel_name='%s'", udev->kernel_name);
-
-                       /* Some block devices have '!' in their name, change that to '/' */
-                       pos = udev->kernel_name;
-                       while (pos[0] != '\0') {
-                               if (pos[0] == '!')
-                                       pos[0] = '/';
-                               pos++;
-                       }
-
-                       /* get kernel number */
-                       pos = &udev->kernel_name[strlen(udev->kernel_name)];
-                       while (isdigit(pos[-1]))
-                               pos--;
-                       strlcpy(udev->kernel_number, pos, sizeof(udev->kernel_number));
-                       dbg("kernel_number='%s'", udev->kernel_number);
-               }
-       }
+       /* set sysfs device to local storage, can be overridden if needed */
+       udev->dev = &udev->dev_local;
 
-       if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS) {
-               udev->mode = 0660;
-               strcpy(udev->owner, "root");
-               strcpy(udev->group, "root");
-       }
+       /* default node permissions */
+       udev->mode = 0660;
+       strcpy(udev->owner, "root");
+       strcpy(udev->group, "root");
 
-       return 0;
+       return udev;
 }
 
-void udev_cleanup_device(struct udevice *udev)
+void udev_device_cleanup(struct udevice *udev)
 {
        name_list_cleanup(&udev->symlink_list);
        name_list_cleanup(&udev->run_list);
        name_list_cleanup(&udev->env_list);
+       free(udev);
+}
+
+dev_t udev_device_get_devt(struct udevice *udev)
+{
+       const char *attr;
+       unsigned int major, minor;
+
+       /* read it from sysfs  */
+       attr = sysfs_attr_get_value(udev->dev->devpath, "dev");
+       if (attr != NULL) {
+               if (sscanf(attr, "%u:%u", &major, &minor) == 2)
+                       return makedev(major, minor);
+       }
+       return makedev(0, 0);
+}
+
+int udev_device_event(struct udev_rules *rules, struct udevice *udev)
+{
+       int retval = 0;
+
+       /* device node or netif */
+       if ((major(udev->devt) != 0 || strcmp(udev->dev->subsystem, "net") == 0) &&
+           strcmp(udev->action, "add") == 0) {
+               dbg("device node or netif add '%s'", udev->dev->devpath);
+               udev_rules_get_name(rules, udev);
+               if (udev->ignore_device) {
+                       info("device event will be ignored");
+                       return 0;
+               }
+               /* create node, store in db */
+               if (udev->name[0] != '\0')
+                       retval = udev_add_device(udev);
+               else
+                       info("device node creation supressed");
+               return 0;
+       }
+
+       if (major(udev->devt) != 0 && strcmp(udev->action, "remove") == 0) {
+               struct name_entry *name_loop;
+
+               udev_rules_get_run(rules, udev);
+               if (udev->ignore_device) {
+                       info("device event will be ignored");
+                       return 0;
+               }
+               /* get data from db, remove db-entry, delete node */
+               retval = udev_remove_device(udev);
+
+               /* restore stored persistent data */
+               list_for_each_entry(name_loop, &udev->env_list, node)
+                       putenv(name_loop->name);
+               return 0;
+       }
+
+       /* default devices */
+       udev_rules_get_run(rules, udev);
+       if (udev->ignore_device)
+               info("device event will be ignored");
+
+       return retval;
 }
diff --git a/udev_event.c b/udev_event.c
deleted file mode 100644 (file)
index 887537e..0000000
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * udev_event.c - udev event process
- *
- * Copyright (C) 2004, 2005 Kay Sievers <kay.sievers@vrfy.org>
- *
- *     This program is free software; you can redistribute it and/or modify it
- *     under the terms of the GNU General Public License as published by the
- *     Free Software Foundation version 2 of the License.
- * 
- *     This program 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
- *     General Public License for more details.
- * 
- *     You should have received a copy of the GNU General Public License along
- *     with this program; if not, write to the Free Software Foundation, Inc.,
- *     675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <ctype.h>
-#include <dirent.h>
-#include <syslog.h>
-#include <sys/stat.h>
-
-#include "libsysfs/sysfs/libsysfs.h"
-#include "udev_libc_wrapper.h"
-#include "udev.h"
-#include "logging.h"
-#include "udev_rules.h"
-#include "udev_utils.h"
-#include "list.h"
-
-
-dev_t get_devt(struct sysfs_class_device *class_dev)
-{
-       struct sysfs_attribute *attr = NULL;
-       unsigned int major, minor;
-       char *maj, *min;
-
-       maj = getenv("MAJOR");
-       min = getenv("MINOR");
-
-       if (maj && min) {
-               major = atoi(maj);
-               minor = atoi(min);
-       } else {
-               attr = sysfs_get_classdev_attr(class_dev, "dev");
-               if (attr == NULL)
-                       return 0;
-               dbg("dev='%s'", attr->value);
-
-               if (sscanf(attr->value, "%u:%u", &major, &minor) != 2)
-                       return 0;
-       }
-
-       dbg("found major=%d, minor=%d", major, minor);
-       return makedev(major, minor);
-}
-
-int udev_process_event(struct udev_rules *rules, struct udevice *udev)
-{
-       int retval;
-       char path[PATH_SIZE];
-
-       if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS || udev->type == DEV_NET) {
-               /* handle device node */
-               if (strcmp(udev->action, "add") == 0) {
-                       struct sysfs_class_device *class_dev;
-
-                       dbg("node add");
-                       snprintf(path, sizeof(path), "%s%s", sysfs_path, udev->devpath);
-                       path[sizeof(path)-1] = '\0';
-                       class_dev = sysfs_open_class_device_path(path);
-                       if (class_dev == NULL) {
-                               dbg("open class device failed");
-                               return 0;
-                       }
-                       dbg("opened class_dev->name='%s'", class_dev->name);
-
-                       /* get major/minor */
-                       if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS)
-                               udev->devt = get_devt(class_dev);
-
-                       if (udev->type == DEV_NET || udev->devt) {
-                               /* name device */
-                               udev_rules_get_name(rules, udev, class_dev);
-                               if (udev->ignore_device) {
-                                       info("device event will be ignored");
-                                       sysfs_close_class_device(class_dev);
-                                       return 0;
-                               }
-                               if (udev->name[0] != '\0') {
-                                       /* create node, store in db */
-                                       retval = udev_add_device(udev, class_dev);
-                               } else {
-                                       info("device node creation supressed");
-                               }
-                       } else {
-                               dbg("no dev-file found");
-                               udev_rules_get_run(rules, udev, class_dev, NULL);
-                               if (udev->ignore_device) {
-                                       info("device event will be ignored");
-                                       sysfs_close_class_device(class_dev);
-                                       return 0;
-                               }
-                       }
-                       sysfs_close_class_device(class_dev);
-               } else if (strcmp(udev->action, "remove") == 0) {
-                       struct name_entry *name_loop;
-
-                       /* get data from db, remove db-entry, delete node */
-                       dbg("node remove");
-                       retval = udev_remove_device(udev);
-
-                       /* restore stored persistent data */
-                       list_for_each_entry(name_loop, &udev->env_list, node)
-                               putenv(name_loop->name);
-
-                       udev_rules_get_run(rules, udev, NULL, NULL);
-                       if (udev->ignore_device) {
-                               dbg("device event will be ignored");
-                               return 0;
-                       }
-               }
-       } else if (udev->type == DEV_DEVICE && strcmp(udev->action, "add") == 0) {
-               struct sysfs_device *devices_dev;
-
-               dbg("devices add");
-               snprintf(path, sizeof(path), "%s%s", sysfs_path, udev->devpath);
-               path[sizeof(path)-1] = '\0';
-               devices_dev = sysfs_open_device_path(path);
-               if (!devices_dev) {
-                       dbg("devices device unavailable (probably remove has beaten us)");
-                       return 0;
-               }
-
-               dbg("devices device opened '%s'", path);
-               udev_rules_get_run(rules, udev, NULL, devices_dev);
-               sysfs_close_device(devices_dev);
-               if (udev->ignore_device) {
-                       info("device event will be ignored");
-                       return 0;
-               }
-       } else {
-               dbg("default handling");
-               udev_rules_get_run(rules, udev, NULL, NULL);
-               if (udev->ignore_device) {
-                       info("device event will be ignored");
-                       return 0;
-               }
-       }
-       return 0;
-}
index fe38993cd729be146090b76b15b439db966ef64f..02a1f8d016c2a7273e0d5e31f547964105d212d9 100644 (file)
 #include <fcntl.h>
 #include <sys/types.h>
 
-#include "udev_libc_wrapper.h"
 #include "udev.h"
-#include "udev_utils.h"
-#include "logging.h"
 
 #ifdef __KLIBC__
 #define __OWN_USERDB_PARSER__
index f9592b4c701a93cf432e5cc2f8147b25ab92ec22..945618ce5a0c6a8f5e32091076eb17595da171eb 100644 (file)
 #include <errno.h>
 #include <sys/stat.h>
 
-#include "udev_libc_wrapper.h"
 #include "udev.h"
-#include "udev_utils.h"
-#include "udev_version.h"
-#include "logging.h"
 
 static int delete_node(struct udevice *udev)
 {
@@ -112,10 +108,10 @@ static int delete_node(struct udevice *udev)
  */
 int udev_remove_device(struct udevice *udev)
 {
-       if (udev->type != DEV_BLOCK && udev->type != DEV_CLASS)
+       if (major(udev->devt) == 0)
                return 0;
 
-       if (udev_db_get_device(udev, udev->devpath) == 0) {
+       if (udev_db_get_device(udev, udev->dev->devpath) == 0) {
                if (udev->ignore_remove) {
                        dbg("remove event for '%s' requested to be ignored by rule", udev->name);
                        return 0;
@@ -123,8 +119,8 @@ int udev_remove_device(struct udevice *udev)
                dbg("remove name='%s'", udev->name);
                udev_db_delete_device(udev);
        } else {
-               dbg("'%s' not found in database, using kernel name '%s'", udev->devpath, udev->kernel_name);
-               strlcpy(udev->name, udev->kernel_name, sizeof(udev->name));
+               dbg("'%s' not found in database, using kernel name '%s'", udev->dev->devpath, udev->dev->kernel_name);
+               strlcpy(udev->name, udev->dev->kernel_name, sizeof(udev->name));
        }
 
        return delete_node(udev);
index 492a9b0dfc89e81bd6333d65a142256ca5cdabae..8693b71c08bf28b388aee987a68181b4700cde0c 100644 (file)
 #include <sys/wait.h>
 #include <sys/stat.h>
 
-#include "libsysfs/sysfs/libsysfs.h"
-#include "list.h"
-#include "udev_libc_wrapper.h"
 #include "udev.h"
-#include "udev_utils.h"
-#include "udev_version.h"
-#include "logging.h"
 #include "udev_rules.h"
 
 
@@ -221,26 +215,29 @@ static int import_program_into_env(struct udevice *udev, const char *program)
        char result[1024];
        size_t reslen;
 
-       if (run_program(program, udev->subsystem, result, sizeof(result), &reslen, (udev_log_priority >= LOG_INFO)) != 0)
+       if (run_program(program, udev->dev->subsystem, result, sizeof(result), &reslen, (udev_log_priority >= LOG_INFO)) != 0)
                return -1;
        return import_keys_into_env(udev, result, reslen);
 }
 
-static int import_parent_into_env(struct udevice *udev, struct sysfs_class_device *class_dev, const char *filter)
+static int import_parent_into_env(struct udevice *udev, const char *filter)
 {
-       struct sysfs_class_device *parent = sysfs_get_classdev_parent(class_dev);
+       struct sysfs_device *dev_parent;
        int rc = -1;
 
-       if (parent != NULL) {
-               struct udevice udev_parent;
+       dev_parent = sysfs_device_get_parent(udev->dev);
+       if (dev_parent != NULL) {
+               struct udevice *udev_parent;
                struct name_entry *name_loop;
 
-               dbg("found parent '%s', get the node name", parent->path);
-               udev_init_device(&udev_parent, NULL, NULL, NULL);
+               dbg("found parent '%s', get the node name", dev_parent->devpath);
+               udev_parent = udev_device_init();
+               if (udev_parent == NULL)
+                       return -1;
                /* import the udev_db of the parent */
-               if (udev_db_get_device(&udev_parent, &parent->path[strlen(sysfs_path)]) == 0) {
-                       dbg("import stored parent env '%s'", udev_parent.name);
-                       list_for_each_entry(name_loop, &udev_parent.env_list, node) {
+               if (udev_db_get_device(udev_parent, dev_parent->devpath) == 0) {
+                       dbg("import stored parent env '%s'", udev_parent->name);
+                       list_for_each_entry(name_loop, &udev_parent->env_list, node) {
                                char name[NAME_SIZE];
                                char *pos;
 
@@ -260,7 +257,7 @@ static int import_parent_into_env(struct udevice *udev, struct sysfs_class_devic
                        rc = 0;
                } else
                        dbg("parent not found in database");
-               udev_cleanup_device(&udev_parent);
+               udev_device_cleanup(udev_parent);
        }
 
        return rc;
@@ -291,22 +288,24 @@ static int find_free_number(const char *base, const char *devpath)
 {
        char db_devpath[PATH_SIZE];
        char filename[PATH_SIZE];
-       struct udevice udev_db;
+       struct udevice *udev_db;
        int num = 0;
 
        /* check if the device already owns a matching name */
-       udev_init_device(&udev_db, NULL, NULL, NULL);
-       if (udev_db_get_device(&udev_db, devpath) == 0) {
+       udev_db = udev_device_init();
+       if (udev_db == NULL)
+               return -1;
+       if (udev_db_get_device(udev_db, devpath) == 0) {
                struct name_entry *name_loop;
                int devnum;
 
-               devnum = match_name_and_get_number(base, udev_db.name);
+               devnum = match_name_and_get_number(base, udev_db->name);
                if (devnum >= 0) {
                        num = devnum;
                        dbg("device '%s', already has the node '%s' with num %u, use it", devpath, base, num);
                        goto out;
                }
-               list_for_each_entry(name_loop, &udev_db.symlink_list, node) {
+               list_for_each_entry(name_loop, &udev_db->symlink_list, node) {
                        devnum = match_name_and_get_number(base, name_loop->name);
                        if (devnum >= 0) {
                                num = devnum;
@@ -336,45 +335,10 @@ static int find_free_number(const char *base, const char *devpath)
        }
 
 out:
-       udev_cleanup_device(&udev_db);
+       udev_device_cleanup(udev_db);
        return num;
 }
 
-static int find_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device,
-                               const char *name, char *value, size_t len)
-{
-       struct sysfs_class_device *class_dev_parent;
-       struct sysfs_attribute *tmpattr;
-
-       dbg("look for device attribute '%s'", name);
-       if (class_dev) {
-               dbg("look for class attribute '%s/%s'", class_dev->path, name);
-               tmpattr = sysfs_get_classdev_attr(class_dev, name);
-               if (tmpattr)
-                       goto attr_found;
-               class_dev_parent = sysfs_get_classdev_parent(class_dev);
-               if (class_dev_parent) {
-                       tmpattr = sysfs_get_classdev_attr(class_dev_parent, name);
-                       if (tmpattr)
-                               goto attr_found;
-               }
-       }
-       if (sysfs_device) {
-               dbg("look for devices attribute '%s/%s'", sysfs_device->path, name);
-               tmpattr = sysfs_get_device_attr(sysfs_device, name);
-               if (tmpattr)
-                       goto attr_found;
-       }
-       return -1;
-
-attr_found:
-       strlcpy(value, tmpattr->value, len);
-       remove_trailing_chars(value, '\n');
-
-       dbg("found attribute '%s'", tmpattr->path);
-       return 0;
-}
-
 #define WAIT_LOOP_PER_SECOND           50
 static int wait_for_sysfs(struct udevice *udev, const char *file, int timeout)
 {
@@ -382,7 +346,7 @@ static int wait_for_sysfs(struct udevice *udev, const char *file, int timeout)
        struct stat stats;
        int loop = timeout * WAIT_LOOP_PER_SECOND;
 
-       snprintf(filename, sizeof(filename), "%s%s/%s", sysfs_path, udev->devpath, file);
+       snprintf(filename, sizeof(filename), "%s%s/%s", sysfs_path, udev->dev->devpath, file);
        filename[sizeof(filename)-1] = '\0';
        dbg("wait %i sec for '%s'", timeout, filename);
 
@@ -398,8 +362,7 @@ static int wait_for_sysfs(struct udevice *udev, const char *file, int timeout)
        return -1;
 }
 
-static void apply_format(struct udevice *udev, char *string, size_t maxsize,
-                        struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device)
+static void apply_format(struct udevice *udev, char *string, size_t maxsize)
 {
        char temp[PATH_SIZE];
        char temp2[PATH_SIZE];
@@ -408,11 +371,9 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize,
        int i;
        int count;
        unsigned int next_free_number;
-       struct sysfs_class_device *class_dev_parent;
        enum subst_type {
                SUBST_UNKNOWN,
                SUBST_DEVPATH,
-               SUBST_ID,
                SUBST_KERNEL_NUMBER,
                SUBST_KERNEL_NAME,
                SUBST_MAJOR,
@@ -432,7 +393,6 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize,
                enum subst_type type;
        } map[] = {
                { .name = "devpath",            .fmt = 'p',     .type = SUBST_DEVPATH },
-               { .name = "id",                 .fmt = 'b',     .type = SUBST_ID },
                { .name = "number",             .fmt = 'n',     .type = SUBST_KERNEL_NUMBER },
                { .name = "kernel",             .fmt = 'k',     .type = SUBST_KERNEL_NAME },
                { .name = "major",              .fmt = 'M',     .type = SUBST_MAJOR },
@@ -502,25 +462,20 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize,
 found:
                attr = get_format_attribute(&tail);
                strlcpy(temp, tail, sizeof(temp));
-               dbg("format=%i, string='%s', tail='%s', class_dev=%p, sysfs_dev=%p",
-                   type ,string, tail, class_dev, sysfs_device);
+               dbg("format=%i, string='%s', tail='%s'", type ,string, tail);
 
                switch (type) {
                case SUBST_DEVPATH:
-                       strlcat(string, udev->devpath, maxsize);
-                       dbg("substitute devpath '%s'", udev->devpath);
-                       break;
-               case SUBST_ID:
-                       strlcat(string, udev->bus_id, maxsize);
-                       dbg("substitute bus_id '%s'", udev->bus_id);
+                       strlcat(string, udev->dev->devpath, maxsize);
+                       dbg("substitute devpath '%s'", udev->dev->devpath);
                        break;
                case SUBST_KERNEL_NAME:
-                       strlcat(string, udev->kernel_name, maxsize);
-                       dbg("substitute kernel name '%s'", udev->kernel_name);
+                       strlcat(string, udev->dev->kernel_name, maxsize);
+                       dbg("substitute kernel name '%s'", udev->dev->kernel_name);
                        break;
                case SUBST_KERNEL_NUMBER:
-                       strlcat(string, udev->kernel_number, maxsize);
-                       dbg("substitute kernel number '%s'", udev->kernel_number);
+                       strlcat(string, udev->dev->kernel_number, maxsize);
+                       dbg("substitute kernel number '%s'", udev->dev->kernel_number);
                        break;
                case SUBST_MAJOR:
                        sprintf(temp2, "%d", major(udev->devt));
@@ -570,54 +525,59 @@ found:
                        if (attr == NULL) {
                                dbg("missing attribute");
                                break;
-                       }
-                       if (find_sysfs_attribute(class_dev, sysfs_device, attr, temp2, sizeof(temp2)) != 0) {
-                               struct sysfs_device *parent_device;
-
-                               dbg("sysfs attribute '%s' not found, walk up the physical devices", attr);
-                               parent_device = sysfs_get_device_parent(sysfs_device);
-                               while (parent_device) {
-                                       dbg("looking at '%s'", parent_device->path);
-                                       if (find_sysfs_attribute(NULL, parent_device, attr, temp2, sizeof(temp2)) == 0)
+                       } else {
+                               struct sysfs_device *dev_parent;
+                               const char *value;
+
+                               dev_parent = udev->dev;
+                               do {
+                                       dbg("looking at '%s'", dev_parent->devpath);
+                                       value = sysfs_attr_get_value(dev_parent->devpath, attr);
+                                       if (value != NULL) {
+                                               strlcpy(temp2, value, sizeof(temp2));
                                                break;
-                                       parent_device = sysfs_get_device_parent(parent_device);
-                               }
-                               if (!parent_device)
-                                       break;
+                                       }
+                                       dev_parent = sysfs_device_get_parent(dev_parent);
+                               } while (dev_parent != NULL);
+
+                               /* strip trailing whitespace of sysfs value */
+                               i = strlen(temp2);
+                               while (i > 0 && isspace(temp2[i-1]))
+                                       temp2[--i] = '\0';
+                               count = replace_untrusted_chars(temp2);
+                               if (count)
+                                       info("%i untrusted character(s) replaced" , count);
+                               strlcat(string, temp2, maxsize);
+                               dbg("substitute sysfs value '%s'", temp2);
                        }
-                       /* strip trailing whitespace of sysfs value */
-                       i = strlen(temp2);
-                       while (i > 0 && isspace(temp2[i-1]))
-                               temp2[--i] = '\0';
-                       count = replace_untrusted_chars(temp2);
-                       if (count)
-                               info("%i untrusted character(s) replaced" , count);
-                       strlcat(string, temp2, maxsize);
-                       dbg("substitute sysfs value '%s'", temp2);
                        break;
                case SUBST_ENUM:
-                       next_free_number = find_free_number(string, udev->devpath);
+                       next_free_number = find_free_number(string, udev->dev->devpath);
                        if (next_free_number > 0) {
                                sprintf(temp2, "%d", next_free_number);
                                strlcat(string, temp2, maxsize);
                        }
                        break;
                case SUBST_PARENT:
-                       if (!class_dev)
-                               break;
-                       class_dev_parent = sysfs_get_classdev_parent(class_dev);
-                       if (class_dev_parent != NULL) {
-                               struct udevice udev_parent;
-
-                               dbg("found parent '%s', get the node name", class_dev_parent->path);
-                               udev_init_device(&udev_parent, NULL, NULL, NULL);
-                               /* lookup the name in the udev_db with the DEVPATH of the parent */
-                               if (udev_db_get_device(&udev_parent, &class_dev_parent->path[strlen(sysfs_path)]) == 0) {
-                                       strlcat(string, udev_parent.name, maxsize);
-                                       dbg("substitute parent node name'%s'", udev_parent.name);
-                               } else
-                                       dbg("parent not found in database");
-                               udev_cleanup_device(&udev_parent);
+                       {
+                               struct sysfs_device *dev_parent;
+
+                               dev_parent = sysfs_device_get_parent(udev->dev);
+                               if (dev_parent != NULL) {
+                                       struct udevice *udev_parent;
+
+                                       dbg("found parent '%s', get the node name", dev_parent->devpath);
+                                       udev_parent = udev_device_init();
+                                       if (udev_parent != NULL) {
+                                               /* lookup the name in the udev_db with the DEVPATH of the parent */
+                                               if (udev_db_get_device(udev_parent, dev_parent->devpath) == 0) {
+                                                       strlcat(string, udev_parent->name, maxsize);
+                                                       dbg("substitute parent node name'%s'", udev_parent->name);
+                                               } else
+                                                       dbg("parent not found in database");
+                                               udev_device_cleanup(udev_parent);
+                                       }
+                               }
                        }
                        break;
                case SUBST_TEMP_NODE:
@@ -636,10 +596,15 @@ found:
                        dbg("substitute udev_root '%s'", udev_root);
                        break;
                case SUBST_MODALIAS:
-                       if (find_sysfs_attribute(NULL, sysfs_device, "modalias", temp2, sizeof(temp2)) != 0)
-                               break;
-                       strlcat(string, temp2, maxsize);
-                       dbg("substitute MODALIAS '%s'", temp2);
+                       {
+                               const char *value;
+
+                               value = sysfs_attr_get_value(udev->dev->devpath, "modalias");
+                               if (value != NULL) {
+                                       strlcat(string, value, maxsize);
+                                       dbg("substitute MODALIAS '%s'", temp2);
+                               }
+                       }
                        break;
                case SUBST_ENV:
                        if (attr == NULL) {
@@ -714,28 +679,28 @@ static int match_key(const char *key_name, struct udev_rule *rule, struct key *k
 }
 
 /* match a single rule against a given device and possibly its parent devices */
-static int match_rule(struct udevice *udev, struct udev_rule *rule,
-                     struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device)
+static int match_rule(struct udevice *udev, struct udev_rule *rule)
 {
-       struct sysfs_device *parent_device = sysfs_device;
+       struct sysfs_device *dev_parent;
        int i;
 
        if (match_key("ACTION", rule, &rule->action, udev->action))
                goto exit;
 
-       if (match_key("KERNEL", rule, &rule->kernel_name, udev->kernel_name))
+       if (match_key("KERNEL", rule, &rule->kernel_name, udev->dev->kernel_name))
                goto exit;
 
-       if (match_key("SUBSYSTEM", rule, &rule->subsystem, udev->subsystem))
+       if (match_key("SUBSYSTEM", rule, &rule->subsystem, udev->dev->subsystem))
                goto exit;
 
-       if (match_key("DEVPATH", rule, &rule->devpath, udev->devpath))
+       if (match_key("DEVPATH", rule, &rule->devpath, udev->dev->devpath))
                goto exit;
 
        if (rule->modalias.operation != KEY_OP_UNSET) {
-               char value[NAME_SIZE];
+               const char *value;
 
-               if (find_sysfs_attribute(NULL, sysfs_device, "modalias", value, sizeof(value)) != 0) {
+               value = sysfs_attr_get_value(udev->dev->devpath, "modalias");
+               if (value == NULL) {
                        dbg("MODALIAS value not found");
                        goto exit;
                }
@@ -777,34 +742,23 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule,
        }
 
        /* walk up the chain of physical devices and find a match */
+       dev_parent = udev->dev;
        while (1) {
                /* check for matching driver */
                if (rule->driver.operation != KEY_OP_UNSET) {
-                       if (parent_device == NULL) {
-                               dbg("device has no sysfs_device");
-                               goto exit;
-                       }
-                       if (match_key("DRIVER", rule, &rule->driver, parent_device->driver_name))
+                       if (match_key("DRIVER", rule, &rule->driver, dev_parent->driver))
                                goto try_parent;
                }
 
                /* check for matching bus value */
                if (rule->bus.operation != KEY_OP_UNSET) {
-                       if (parent_device == NULL) {
-                               dbg("device has no sysfs_device");
-                               goto exit;
-                       }
-                       if (match_key("BUS", rule, &rule->bus, parent_device->bus))
+                       if (match_key("BUS", rule, &rule->bus, dev_parent->subsystem))
                                goto try_parent;
                }
 
                /* check for matching bus id */
                if (rule->id.operation != KEY_OP_UNSET) {
-                       if (parent_device == NULL) {
-                               dbg("device has no sysfs_device");
-                               goto exit;
-                       }
-                       if (match_key("ID", rule, &rule->id, parent_device->bus_id))
+                       if (match_key("ID", rule, &rule->id, dev_parent->kernel_name))
                                goto try_parent;
                }
 
@@ -815,36 +769,39 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule,
                                struct key_pair *pair = &rule->sysfs.keys[i];
                                const char *key_name = key_pair_name(rule, pair);
                                const char *key_value = key_val(rule, &pair->key);
-                               char value[VALUE_SIZE];
+                               const char *value;
+                               char val[VALUE_SIZE];
                                size_t len;
 
-                               if (find_sysfs_attribute(class_dev, parent_device, key_name, value, sizeof(value)) != 0)
+                               value = sysfs_attr_get_value(dev_parent->devpath, key_name);
+                               if (value == NULL)
                                        goto try_parent;
+                               strlcpy(val, value, sizeof(val));
 
                                /* strip trailing whitespace of value, if not asked to match for it */
                                len = strlen(key_value);
-                               if (len && !isspace(key_value[len-1])) {
-                                       len = strlen(value);
-                                       while (len > 0 && isspace(value[len-1]))
-                                               value[--len] = '\0';
-                                       dbg("removed %zi trailing whitespace chars from '%s'", strlen(value)-len, value);
+                               if (len > 0 && !isspace(key_value[len-1])) {
+                                       len = strlen(val);
+                                       while (len > 0 && isspace(val[len-1]))
+                                               val[--len] = '\0';
+                                       dbg("removed %zi trailing whitespace chars from '%s'", strlen(val)-len, val);
                                }
 
-                               if (match_key("SYSFS", rule, &pair->key, value))
+                               if (match_key("SYSFS", rule, &pair->key, val))
                                        goto try_parent;
                        }
                        dbg("all %i SYSFS keys matched", rule->sysfs.count);
                }
 
-               /* found matching physical device  */
+               /* found matching device  */
                break;
 try_parent:
                dbg("try parent sysfs device");
-               parent_device = sysfs_get_device_parent(parent_device);
-               if (parent_device == NULL)
+               dev_parent = sysfs_device_get_parent(dev_parent);
+               if (dev_parent == NULL)
                        goto exit;
-               dbg("look at sysfs_device->path='%s'", parent_device->path);
-               dbg("look at sysfs_device->bus_id='%s'", parent_device->bus_id);
+               dbg("looking at dev_parent->devpath='%s'", dev_parent->devpath);
+               dbg("looking at dev_parent->bus_kernel_name='%s'", dev_parent->kernel_name);
        }
 
        /* execute external program */
@@ -853,8 +810,8 @@ try_parent:
                char result[PATH_SIZE];
 
                strlcpy(program, key_val(rule, &rule->program), sizeof(program));
-               apply_format(udev, program, sizeof(program), class_dev, sysfs_device);
-               if (run_program(program, udev->subsystem, result, sizeof(result), NULL, (udev_log_priority >= LOG_INFO)) != 0) {
+               apply_format(udev, program, sizeof(program));
+               if (run_program(program, udev->dev->subsystem, result, sizeof(result), NULL, (udev_log_priority >= LOG_INFO)) != 0) {
                        dbg("PROGRAM is false");
                        udev->program_result[0] = '\0';
                        if (rule->program.operation != KEY_OP_NOMATCH)
@@ -886,18 +843,18 @@ try_parent:
                int rc = -1;
 
                strlcpy(import, key_val(rule, &rule->import), sizeof(import));
-               apply_format(udev, import, sizeof(import), class_dev, sysfs_device);
+               apply_format(udev, import, sizeof(import));
                dbg("check for IMPORT import='%s'", import);
                if (rule->import_type == IMPORT_PROGRAM) {
                        rc = import_program_into_env(udev, import);
                } else if (rule->import_type == IMPORT_FILE) {
                        dbg("import file import='%s'", import);
                        rc = import_file_into_env(udev, import);
-               } else if (rule->import_type == IMPORT_PARENT && class_dev) {
+               } else if (rule->import_type == IMPORT_PARENT) {
                        dbg("import parent import='%s'", import);
-                       rc = import_parent_into_env(udev, class_dev, import);
+                       rc = import_parent_into_env(udev, import);
                }
-               if (rc) {
+               if (rc != 0) {
                        dbg("IMPORT failed");
                        if (rule->import.operation != KEY_OP_NOMATCH)
                                goto exit;
@@ -926,35 +883,13 @@ exit:
        return -1;
 }
 
-int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct sysfs_class_device *class_dev)
+int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev)
 {
-       struct sysfs_class_device *class_dev_parent;
-       struct sysfs_device *sysfs_device = NULL;
        struct udev_rule *rule;
        int name_set = 0;
 
-       dbg("class_dev->name='%s'", class_dev->name);
-
-       /* Figure out where the "device"-symlink is at.  For char devices this will
-        * always be in the class_dev->path.  On block devices, only the main block
-        * device will have the device symlink in it's path. All partition devices
-        * need to look at the symlink in its parent directory.
-        */
-       class_dev_parent = sysfs_get_classdev_parent(class_dev);
-       if (class_dev_parent != NULL) {
-               dbg("given class device has a parent, use this instead");
-               sysfs_device = sysfs_get_classdev_device(class_dev_parent);
-       } else {
-               sysfs_device = sysfs_get_classdev_device(class_dev);
-       }
-
-       if (sysfs_device) {
-               dbg("found devices device: path='%s', bus_id='%s', bus='%s'",
-                   sysfs_device->path, sysfs_device->bus_id, sysfs_device->bus);
-               strlcpy(udev->bus_id, sysfs_device->bus_id, sizeof(udev->bus_id));
-       }
-
-       dbg("udev->kernel_name='%s'", udev->kernel_name);
+       dbg("udev->dev->devpath='%s'", udev->dev->devpath);
+       dbg("udev->dev->kernel_name='%s'", udev->dev->kernel_name);
 
        /* look for a matching rule to apply */
        udev_rules_iter_init(rules);
@@ -969,10 +904,10 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s
                }
 
                dbg("process rule");
-               if (match_rule(udev, rule, class_dev, sysfs_device) == 0) {
+               if (match_rule(udev, rule) == 0) {
                        /* apply options */
                        if (rule->ignore_device) {
-                               info("rule applied, '%s' is ignored", udev->kernel_name);
+                               info("rule applied, '%s' is ignored", udev->dev->kernel_name);
                                udev->ignore_device = 1;
                                return 0;
                        }
@@ -981,7 +916,8 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s
                                dbg("remove event should be ignored");
                        }
                        /* apply all_partitions option only at a main block device */
-                       if (rule->partitions && udev->type == DEV_BLOCK && udev->kernel_number[0] == '\0') {
+                       if (rule->partitions &&
+                           strcmp(udev->dev->subsystem, "block") == 0 && udev->dev->kernel_number[0] == '\0') {
                                udev->partitions = rule->partitions;
                                dbg("creation of partition nodes requested");
                        }
@@ -991,21 +927,21 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s
                                if (rule->mode_operation == KEY_OP_ASSIGN_FINAL)
                                        udev->mode_final = 1;
                                udev->mode = rule->mode;
-                               dbg("applied mode=%#o to '%s'", rule->mode, udev->kernel_name);
+                               dbg("applied mode=%#o to '%s'", rule->mode, udev->dev->kernel_name);
                        }
                        if (!udev->owner_final && rule->owner.operation != KEY_OP_UNSET) {
                                if (rule->owner.operation == KEY_OP_ASSIGN_FINAL)
                                        udev->owner_final = 1;
                                strlcpy(udev->owner, key_val(rule, &rule->owner), sizeof(udev->owner));
-                               apply_format(udev, udev->owner, sizeof(udev->owner), class_dev, sysfs_device);
-                               dbg("applied owner='%s' to '%s'", udev->owner, udev->kernel_name);
+                               apply_format(udev, udev->owner, sizeof(udev->owner));
+                               dbg("applied owner='%s' to '%s'", udev->owner, udev->dev->kernel_name);
                        }
                        if (!udev->group_final && rule->group.operation != KEY_OP_UNSET) {
                                if (rule->group.operation == KEY_OP_ASSIGN_FINAL)
                                        udev->group_final = 1;
                                strlcpy(udev->group, key_val(rule, &rule->group), sizeof(udev->group));
-                               apply_format(udev, udev->group, sizeof(udev->group), class_dev, sysfs_device);
-                               dbg("applied group='%s' to '%s'", udev->group, udev->kernel_name);
+                               apply_format(udev, udev->group, sizeof(udev->group));
+                               dbg("applied group='%s' to '%s'", udev->group, udev->dev->kernel_name);
                        }
 
                        /* collect symlinks */
@@ -1021,7 +957,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s
                                        name_list_cleanup(&udev->symlink_list);
                                }
                                strlcpy(temp, key_val(rule, &rule->symlink), sizeof(temp));
-                               apply_format(udev, temp, sizeof(temp), class_dev, sysfs_device);
+                               apply_format(udev, temp, sizeof(temp));
                                count = replace_untrusted_chars(temp);
                                if (count)
                                        info("%i untrusted character(s) replaced" , count);
@@ -1052,13 +988,13 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s
                                int count;
                                name_set = 1;
                                strlcpy(udev->name, key_val(rule, &rule->name), sizeof(udev->name));
-                               apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device);
+                               apply_format(udev, udev->name, sizeof(udev->name));
                                count = replace_untrusted_chars(udev->name);
                                if (count)
                                        info("%i untrusted character(s) replaced", count);
 
-                               info("rule applied, '%s' becomes '%s'", udev->kernel_name, udev->name);
-                               if (udev->type != DEV_NET)
+                               info("rule applied, '%s' becomes '%s'", udev->dev->kernel_name, udev->name);
+                               if (strcmp(udev->dev->subsystem, "net") != 0)
                                        dbg("name, '%s' is going to have owner='%s', group='%s', mode=%#o partitions=%i",
                                            udev->name, udev->owner, udev->group, udev->mode, udev->partitions);
                        }
@@ -1073,7 +1009,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s
                                        name_list_cleanup(&udev->run_list);
                                }
                                strlcpy(program, key_val(rule, &rule->run), sizeof(program));
-                               apply_format(udev, program, sizeof(program), class_dev, sysfs_device);
+                               apply_format(udev, program, sizeof(program));
                                dbg("add run '%s'", program);
                                name_list_add(&udev->run_list, program, 0);
                        }
@@ -1091,7 +1027,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s
        }
 
        if (!name_set) {
-               strlcpy(udev->name, udev->kernel_name, sizeof(udev->name));
+               strlcpy(udev->name, udev->dev->kernel_name, sizeof(udev->name));
                info("no node name set, will use kernel name '%s'", udev->name);
        }
 
@@ -1104,20 +1040,11 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s
        return 0;
 }
 
-int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev,
-                      struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_dev)
+int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev)
 {
        struct udev_rule *rule;
 
-       if (class_dev && !sysfs_dev)
-               sysfs_dev = sysfs_get_classdev_device(class_dev);
-       if (sysfs_dev) {
-               dbg("found devices device: path='%s', bus_id='%s', bus='%s'",
-                   sysfs_dev->path, sysfs_dev->bus_id, sysfs_dev->bus);
-               strlcpy(udev->bus_id, sysfs_dev->bus_id, sizeof(udev->bus_id));
-       }
-
-       dbg("udev->kernel_name='%s'", udev->kernel_name);
+       dbg("udev->kernel_name='%s'", udev->dev->kernel_name);
 
        /* look for a matching rule to apply */
        udev_rules_iter_init(rules);
@@ -1133,9 +1060,9 @@ int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev,
                        continue;
                }
 
-               if (match_rule(udev, rule, class_dev, sysfs_dev) == 0) {
+               if (match_rule(udev, rule) == 0) {
                        if (rule->ignore_device) {
-                               info("rule applied, '%s' is ignored", udev->kernel_name);
+                               info("rule applied, '%s' is ignored", udev->dev->kernel_name);
                                udev->ignore_device = 1;
                                return 0;
                        }
@@ -1148,7 +1075,7 @@ int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev,
                                        name_list_cleanup(&udev->run_list);
                                }
                                strlcpy(program, key_val(rule, &rule->run), sizeof(program));
-                               apply_format(udev, program, sizeof(program), class_dev, sysfs_dev);
+                               apply_format(udev, program, sizeof(program));
                                dbg("add run '%s'", program);
                                name_list_add(&udev->run_list, program, 0);
                                if (rule->run.operation == KEY_OP_ASSIGN_FINAL)
index 6d9d306dedc60e42b0b4ebb54bd5ec8a761f4e3d..125babf1c529bb3bb02dd7de5a940b45a1d037b7 100644 (file)
@@ -22,7 +22,6 @@
 #ifndef UDEV_RULES_H
 #define UDEV_RULES_H
 
-#include "libsysfs/sysfs/libsysfs.h"
 #include "udev.h"
 #include "list.h"
 
@@ -104,18 +103,15 @@ struct udev_rules {
 };
 
 extern int udev_rules_init(struct udev_rules *rules, int resolve_names);
-extern void udev_rules_close(struct udev_rules *rules);
+extern void udev_rules_cleanup(struct udev_rules *rules);
 
-extern void udev_apply_format(struct udevice *udev, char *string, size_t maxsize,
-                             struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device);
+extern void udev_apply_format(struct udevice *udev, char *string, size_t maxsize);
 
 extern void udev_rules_iter_init(struct udev_rules *rules);
 extern struct udev_rule *udev_rules_iter_next(struct udev_rules *rules);
 extern struct udev_rule *udev_rules_iter_label(struct udev_rules *rules, const char *label);
 
-extern int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev,
-                              struct sysfs_class_device *class_dev);
-extern int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev,
-                             struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_dev);
+extern int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev);
+extern int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev);
 
 #endif
index 7fa21afa8c17264fc14f5cac7d773b06a4d77bdd..4fcd6db08ee362bec4233683df6143956baa1364 100644 (file)
 #include <sys/stat.h>
 #include <errno.h>
 
-#include "udev_libc_wrapper.h"
 #include "udev.h"
-#include "udev_utils.h"
-#include "logging.h"
 #include "udev_rules.h"
 
 
@@ -626,7 +623,7 @@ int udev_rules_init(struct udev_rules *rules, int resolve_names)
        return retval;
 }
 
-void udev_rules_close(struct udev_rules *rules)
+void udev_rules_cleanup(struct udev_rules *rules)
 {
        if (rules->buf) {
                free(rules->buf);
index 298c75566ca525230acfd0b669c7ee36381d96e1..94c213d297aca46c0d3927709db2789119bb57fc 100644 (file)
@@ -32,7 +32,6 @@
 
 #include "udev.h"
 #include "udev_selinux.h"
-#include "logging.h"
 
 static security_context_t prev_scontext = NULL;
 
diff --git a/udev_sysfs.c b/udev_sysfs.c
new file mode 100644 (file)
index 0000000..19fd614
--- /dev/null
@@ -0,0 +1,345 @@
+/*
+ * udev_sysfs.c - sysfs access
+ *
+ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
+ *
+ *     This program is free software; you can redistribute it and/or modify it
+ *     under the terms of the GNU General Public License as published by the
+ *     Free Software Foundation version 2 of the License.
+ * 
+ *     This program 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
+ *     General Public License for more details.
+ * 
+ *     You should have received a copy of the GNU General Public License along
+ *     with this program; if not, write to the Free Software Foundation, Inc.,
+ *     675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include "udev.h"
+
+char sysfs_path[PATH_SIZE];
+
+/* device cache */
+static LIST_HEAD(dev_list);
+
+/* attribute value cache */
+static LIST_HEAD(attr_list);
+struct sysfs_attr {
+       struct list_head node;
+       char path[PATH_SIZE];
+       char value[NAME_SIZE];
+};
+
+int sysfs_init(void)
+{
+       const char *env;
+
+       env = getenv("SYSFS_PATH");
+       if (env) {
+               strlcpy(sysfs_path, env, sizeof(sysfs_path));
+               remove_trailing_chars(sysfs_path, '/');
+       } else
+               strlcpy(sysfs_path, "/sys", sizeof(sysfs_path));
+       dbg("sysfs_path='%s'", sysfs_path);
+
+       INIT_LIST_HEAD(&dev_list);
+       INIT_LIST_HEAD(&attr_list);
+       return 0;
+}
+
+void sysfs_cleanup(void)
+{
+       struct sysfs_attr *attr_loop;
+       struct sysfs_attr *attr_temp;
+       struct sysfs_device *dev_loop;
+       struct sysfs_device *dev_temp;
+
+       list_for_each_entry_safe(attr_loop, attr_temp, &attr_list, node) {
+               list_del(&attr_loop->node);
+               free(attr_loop);
+       }
+
+       list_for_each_entry_safe(dev_loop, dev_temp, &dev_list, node) {
+               list_del(&dev_loop->node);
+               free(dev_loop);
+       }
+}
+
+void sysfs_device_set_values(struct sysfs_device *dev, const char *devpath, const char *subsystem)
+{
+       char *pos;
+
+       strlcpy(dev->devpath, devpath, sizeof(dev->devpath));
+       if (subsystem != NULL)
+               strlcpy(dev->subsystem, subsystem, sizeof(dev->subsystem));
+
+       /* set kernel name */
+       pos = strrchr(dev->devpath, '/');
+       if (pos == NULL)
+               return;
+
+       strlcpy(dev->kernel_name, &pos[1], sizeof(dev->kernel_name));
+       dbg("kernel_name='%s'", dev->kernel_name);
+
+       /* some devices have '!' in their name, change that to '/' */
+       pos = dev->kernel_name;
+       while (pos[0] != '\0') {
+               if (pos[0] == '!')
+                       pos[0] = '/';
+               pos++;
+       }
+
+       /* get kernel number */
+       pos = &dev->kernel_name[strlen(dev->kernel_name)];
+       while (isdigit(pos[-1]))
+               pos--;
+       strlcpy(dev->kernel_number, pos, sizeof(dev->kernel_number));
+       dbg("kernel_number='%s'", dev->kernel_number);
+}
+
+struct sysfs_device *sysfs_device_get(const char *devpath)
+{
+       char path[PATH_SIZE];
+       char devpath_real[PATH_SIZE];
+       struct sysfs_device *dev;
+       struct sysfs_device *dev_loop;
+       struct stat statbuf;
+       char link_path[PATH_SIZE];
+       char link_target[PATH_SIZE];
+       int len;
+       char *pos;
+
+       dbg("open '%s'", devpath);
+       strlcpy(devpath_real, devpath, sizeof(devpath_real));
+       remove_trailing_chars(devpath_real, '/');
+
+       strlcpy(path, sysfs_path, sizeof(path));
+       strlcat(path, devpath_real, sizeof(path));
+       if (lstat(path, &statbuf) != 0) {
+               dbg("stat '%s' failed: %s", devpath, strerror(errno));
+               return NULL;
+       }
+
+       /* if we got a link, resolve it to the real device */
+       if (S_ISLNK(statbuf.st_mode)) {
+               int i;
+               int back;
+
+               len = readlink(path, link_target, sizeof(link_target));
+               if (len <= 0)
+                       return NULL;
+               link_target[len] = '\0';
+               dbg("devpath link '%s' points to '%s'", path, link_target);
+
+               for (back = 0; strncmp(&link_target[back * 3], "../", 3) == 0; back++)
+                       ;
+               dbg("base '%s', tail '%s', back %i", devpath_real, &link_target[back * 3], back);
+               for (i = 0; i <= back; i++) {
+                       pos = strrchr(devpath_real, '/');
+                       if (pos == NULL)
+                               return NULL;
+                       pos[0] = '\0';
+               }
+               dbg("after moving back '%s'", devpath_real);
+               strlcat(devpath_real, "/", sizeof(devpath_real));
+               strlcat(devpath_real, &link_target[back * 3], sizeof(devpath_real));
+       }
+
+       /* look for device in cache */
+       list_for_each_entry(dev_loop, &dev_list, node) {
+               if (strcmp(dev_loop->devpath, devpath_real) == 0) {
+                       dbg("found in cache '%s'", dev_loop->devpath);
+                       return dev_loop;
+               }
+       }
+
+       /* new device */
+       dbg("'%s'", devpath_real);
+       dev = malloc(sizeof(struct sysfs_device));
+       if (dev == NULL)
+               return NULL;
+       memset(dev, 0x00, sizeof(struct sysfs_device));
+
+       sysfs_device_set_values(dev, devpath_real, NULL);
+
+       /* get subsystem */
+       if (strncmp(dev->devpath, "/class/", 7) == 0) {
+               strlcpy(dev->subsystem, &dev->devpath[7], sizeof(dev->subsystem));
+               pos = strchr(dev->subsystem, '/');
+               if (pos != NULL)
+                       pos[0] = '\0';
+               else
+                       dev->subsystem[0] = '\0';
+       } else if (strncmp(devpath, "/block/", 7) == 0) {
+               strlcpy(dev->subsystem, "block", sizeof(dev->subsystem));
+       } else if (strncmp(devpath, "/devices/", 9) == 0) {
+               /* get subsystem from bus name */
+               strlcpy(link_path, sysfs_path, sizeof(link_path));
+               strlcat(link_path, dev->devpath, sizeof(link_path));
+               strlcat(link_path, "/bus", sizeof(link_path));
+               len = readlink(link_path, link_target, sizeof(link_target));
+               if (len > 0) {
+                       link_target[len] = '\0';
+                       dbg("bus link '%s' points to '%s'", link_path, link_target);
+                       pos = strrchr(link_target, '/');
+                       if (pos != NULL)
+                               strlcpy(dev->subsystem, &pos[1], sizeof(dev->subsystem));
+               }
+
+               /* get driver name */
+               strlcpy(link_path, sysfs_path, sizeof(link_path));
+               strlcat(link_path, dev->devpath, sizeof(link_path));
+               strlcat(link_path, "/driver", sizeof(link_path));
+               len = readlink(link_path, link_target, sizeof(link_target));
+               if (len > 0) {
+                       link_target[len] = '\0';
+                       dbg("driver link '%s' points to '%s'", link_path, link_target);
+                       pos = strrchr(link_target, '/');
+                       if (pos != NULL)
+                               strlcpy(dev->driver, &pos[1], sizeof(dev->driver));
+               }
+       } else if (strncmp(devpath, "/bus/", 5) == 0 && strstr(devpath, "/drivers/")) {
+               strlcpy(dev->subsystem, "drivers", sizeof(dev->subsystem));
+       } else if (strncmp(devpath, "/module/", 8) == 0) {
+               strlcpy(dev->subsystem, "module", sizeof(dev->subsystem));
+       }
+
+       dbg("add to cache 'devpath=%s', subsystem='%s', driver='%s'", dev->devpath, dev->subsystem, dev->driver);
+       list_add(&dev->node, &dev_list);
+
+       return dev;
+}
+
+struct sysfs_device *sysfs_device_get_parent(struct sysfs_device *dev)
+{
+       char parent_devpath[PATH_SIZE];
+       char device_link[PATH_SIZE];
+       char device_link_target[PATH_SIZE];
+       char *pos;
+       int i;
+       int len;
+       int back;
+
+       /* requesting a parent is only valid for devices */
+       if ((strncmp(dev->devpath, "/devices/", 9) != 0) &&
+           (strncmp(dev->devpath, "/class/", 7) != 0) &&
+           (strncmp(dev->devpath, "/block/", 7) != 0))
+               return NULL;
+
+       strlcpy(parent_devpath, dev->devpath, sizeof(parent_devpath));
+       dbg("'%s'", parent_devpath);
+
+       /* strip last element */
+       pos = strrchr(parent_devpath, '/');
+       if (pos == NULL || pos == parent_devpath)
+               return NULL;
+       pos[0] = '\0';
+
+       /* are we at the top level */
+       if (strcmp(parent_devpath, "/devices") == 0) {
+               dbg("/devices top level");
+               return NULL;
+       }
+
+       /* at the top level we may follow the "device" link */
+       if (strcmp(parent_devpath, "/block") == 0) {
+               dbg("/block top level, look for device link");
+               goto device_link;
+       }
+
+       if (strncmp(parent_devpath, "/class", 6) == 0) {
+               pos = strrchr(parent_devpath, '/');
+               if (pos == &parent_devpath[6] || pos == parent_devpath) {
+                       dbg("class top level, look for device link");
+                       goto device_link;
+               }
+       }
+       return sysfs_device_get(parent_devpath);
+
+device_link:
+       strlcpy(device_link, sysfs_path, sizeof(device_link));
+       strlcat(device_link, dev->devpath, sizeof(device_link));
+       strlcat(device_link, "/device", sizeof(device_link));
+       len = readlink(device_link, device_link_target, sizeof(device_link_target));
+       if (len < 0)
+               return NULL;
+       device_link_target[len] = '\0';
+       dbg("device link '%s' points to '%s'", device_link, device_link_target);
+
+       for (back = 0; strncmp(&device_link_target[back * 3], "../", 3) == 0; back++)
+               ;
+       strlcpy(parent_devpath, dev->devpath, sizeof(parent_devpath));
+       dbg("base='%s', tail='%s', back=%i", parent_devpath, &device_link_target[back * 3], back);
+       for (i = 0; i < back; i++) {
+               pos = strrchr(parent_devpath, '/');
+               if (pos == NULL)
+                       return NULL;
+               pos[0] = '\0';
+       }
+       dbg("after moving back '%s'", parent_devpath);
+       strlcat(parent_devpath, "/", sizeof(parent_devpath));
+       strlcat(parent_devpath, &device_link_target[back * 3], sizeof(parent_devpath));
+       return sysfs_device_get(parent_devpath);
+}
+
+char *sysfs_attr_get_value(const char *devpath, const char *attr_name)
+{
+       char path_full[PATH_SIZE];
+       const char *path;
+       char value[NAME_SIZE];
+       struct sysfs_attr *attr_loop;
+       struct sysfs_attr *attr;
+       int fd;
+       ssize_t size;
+       size_t sysfs_len;
+
+       sysfs_len = strlcpy(path_full, sysfs_path, sizeof(path_full));
+       path = &path_full[sysfs_len];
+       strlcat(path_full, devpath, sizeof(path_full));
+       strlcat(path_full, "/", sizeof(path_full));
+       strlcat(path_full, attr_name, sizeof(path_full));
+
+       /* look for attribute in cache */
+       list_for_each_entry(attr_loop, &attr_list, node) {
+               if (strcmp(attr_loop->path, path) == 0) {
+                       dbg("found in cache '%s'", attr_loop->path);
+                       return attr_loop->value;
+               }
+       }
+
+       /* read attribute value */
+       fd = open(path_full, O_RDONLY);
+       if (fd < 0)
+               return NULL;
+       size = read(fd, value, sizeof(value));
+       close(fd);
+       if (size < 0)
+               return NULL;
+       if (size == sizeof(value))
+               return NULL;
+       value[size] = '\0';
+       remove_trailing_chars(value, '\n');
+
+       /* store attribute in cache */
+       attr = malloc(sizeof(struct sysfs_attr));
+       if (attr == NULL)
+               return NULL;
+       strlcpy(attr->path, path, sizeof(attr->path));
+       strlcpy(attr->value, value, sizeof(attr->value));
+       dbg("add to cache '%s' '%s'", attr->path, attr->value);
+       list_add(&attr->node, &attr_list);
+
+       return attr->value;
+}
index 581ba9e80afb0972a31b38107e216883b95fb97b..a37c4dfe7492f2927b0f7d1660e791ec32ba5533 100644 (file)
 #include <syslog.h>
 #include <sys/utsname.h>
 
-#include "udev_libc_wrapper.h"
 #include "udev.h"
-#include "logging.h"
-#include "udev_utils.h"
-#include "list.h"
 
 
 int log_priority(const char *priority)
diff --git a/udev_utils.h b/udev_utils.h
deleted file mode 100644 (file)
index a28ba00..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * udev_utils.c - generic stuff used by udev
- *
- * Copyright (C) 2004-2005 Kay Sievers <kay.sievers@vrfy.org>
- *
- *     This program is free software; you can redistribute it and/or modify it
- *     under the terms of the GNU General Public License as published by the
- *     Free Software Foundation version 2 of the License.
- * 
- *     This program 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
- *     General Public License for more details.
- * 
- *     You should have received a copy of the GNU General Public License along
- *     with this program; if not, write to the Free Software Foundation, Inc.,
- *     675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef _UDEV_COMMON_H_
-#define _UDEV_COMMON_H_
-
-#include "udev.h"
-#include "list.h"
-
-#define UDEV_MAX(a,b) ((a) > (b) ? (a) : (b))
-
-/* pipes */
-#define READ_END               0
-#define WRITE_END              1
-
-struct name_entry {
-       struct list_head node;
-       char name[PATH_SIZE];
-};
-
-/* udev_utils.c */
-extern int log_priority(const char *priority);
-extern int name_list_add(struct list_head *name_list, const char *name, int sort);
-extern int name_list_key_add(struct list_head *name_list, const char *key, const char *value);
-extern void name_list_cleanup(struct list_head *name_list);
-extern int add_matching_files(struct list_head *name_list, const char *dirname, const char *suffix);
-
-/* udev_utils_string.c */
-extern int strcmp_pattern(const char *p, const char *s);
-extern int string_is_true(const char *str);
-extern void remove_trailing_chars(char *path, char c);
-extern int utf8_encoded_valid_unichar(const char *str);
-extern int replace_untrusted_chars(char *str);
-
-/* udev_utils_file.c */
-extern int create_path(const char *path);
-extern int delete_path(const char *path);
-extern int file_map(const char *filename, char **buf, size_t *bufsize);
-extern void file_unmap(void *buf, size_t bufsize);
-extern int unlink_secure(const char *filename);
-extern size_t buf_get_line(const char *buf, size_t buflen, size_t cur);
-
-/* udev_utils_run.c */
-extern int pass_env_to_socket(const char *name, const char *devpath, const char *action);
-extern int run_program(const char *command, const char *subsystem,
-                      char *result, size_t ressize, size_t *reslen, int log);
-
-#endif
index cd9c244f0f3d1b799f58063032ba2da959c6e3b5..acaffdc9181cfb9d1ea22a1da1ace59ae314faec 100644 (file)
 #include <sys/stat.h>
 #include <sys/mman.h>
 
-#include "udev_libc_wrapper.h"
 #include "udev.h"
-#include "logging.h"
-#include "udev_utils.h"
-#include "list.h"
 
 int create_path(const char *path)
 {
index e1e775ebe6f2a5f03964aba8d5db86375a24d4bd..b6020b0ab6baea9f1f0d22e24385c3d213aad13f 100644 (file)
 #include <sys/wait.h>
 #include <sys/select.h>
 
-#include "udev_libc_wrapper.h"
 #include "udev.h"
-#include "logging.h"
-#include "udev_utils.h"
-#include "list.h"
 
 
 int pass_env_to_socket(const char *sockname, const char *devpath, const char *action)
index 37db8dbc8524683a937009aa0fd41c620642f69d..36ef8bef7e8d156b5d8729c0ad952a951421bce0 100644 (file)
 #include <syslog.h>
 #include <sys/utsname.h>
 
-#include "udev_libc_wrapper.h"
 #include "udev.h"
-#include "logging.h"
-#include "udev_utils.h"
-#include "list.h"
 
 /* compare string with pattern (like fnmatch(), supports * ? [0-9] [!A-Z]) */
 int strcmp_pattern(const char *p, const char *s)
index bd6563531d3fd687f1cd94c6673cb3072620fd23..6d91adc1c4eff994416ce89dbda88ba4253d9c31 100644 (file)
 #include <linux/stddef.h>
 
 #include "udev.h"
-#include "udev_version.h"
 #include "udevd.h"
-#include "udev_utils.h"
-#include "logging.h"
 
 /* global variables */
 static int sock = -1;
diff --git a/udevd.c b/udevd.c
index ff61c656c872c3d834efef79f6be1604136f9953..f64a4252bbbb5ea018e53a88abc7fd509d52020e 100644 (file)
--- a/udevd.c
+++ b/udevd.c
 #include <linux/types.h>
 #include <linux/netlink.h>
 
-#include "list.h"
-#include "udev_libc_wrapper.h"
 #include "udev.h"
-#include "udev_version.h"
 #include "udev_rules.h"
-#include "udev_utils.h"
 #include "udevd.h"
-#include "logging.h"
 
-struct udev_rules rules;
+static struct udev_rules rules;
 static int udevd_sock;
 static int uevent_netlink_sock;
 static int inotify_fd;
@@ -94,8 +89,7 @@ static void asmlinkage udev_event_sig_handler(int signum)
 static int udev_event_process(struct uevent_msg *msg)
 {
        struct sigaction act;
-       struct udevice udev;
-       struct name_entry *name_loop;
+       struct udevice *udev;
        int i;
        int retval;
 
@@ -109,27 +103,34 @@ static int udev_event_process(struct uevent_msg *msg)
        /* trigger timeout to prevent hanging processes */
        alarm(UDEV_ALARM_TIMEOUT);
 
-       /* reconstruct env from message */
+       /* reconstruct event environment from message */
        for (i = 0; msg->envp[i]; i++)
                putenv(msg->envp[i]);
 
-       udev_init_device(&udev, msg->devpath, msg->subsystem, msg->action);
-       retval = udev_process_event(&rules, &udev);
+       udev = udev_device_init();
+       if (udev == NULL)
+               return -1;
+       strlcpy(udev->action, msg->action, sizeof(udev->action));
+       sysfs_device_set_values(udev->dev, msg->devpath, msg->subsystem);
+       udev->devt = msg->devt;
+
+       retval = udev_device_event(&rules, udev);
 
        /* run programs collected by RUN-key*/
-       if (!retval) {
-               list_for_each_entry(name_loop, &udev.run_list, node) {
+       if (retval == 0) {
+               struct name_entry *name_loop;
+
+               list_for_each_entry(name_loop, &udev->run_list, node) {
                        if (strncmp(name_loop->name, "socket:", strlen("socket:")) == 0)
                                pass_env_to_socket(&name_loop->name[strlen("socket:")], msg->devpath, msg->action);
                        else
-                               if (run_program(name_loop->name, udev.subsystem, NULL, 0, NULL,
+                               if (run_program(name_loop->name, udev->dev->subsystem, NULL, 0, NULL,
                                                (udev_log_priority >= LOG_INFO)))
                                        retval = -1;
                }
        }
 
-       udev_cleanup_device(&udev);
-
+       udev_device_cleanup(udev);
        return retval;
 }
 
@@ -819,7 +820,7 @@ int main(int argc, char *argv[], char *envp[])
        if (fd < 0)
                err("fatal, could not open /dev/null: %s", strerror(errno));
 
-       udev_init_config();
+       udev_config_init();
        dbg("version %s", UDEV_VERSION);
 
        if (getuid() != 0) {
@@ -859,6 +860,7 @@ int main(int argc, char *argv[], char *envp[])
        }
 
        /* parse the rules and keep it in memory */
+       sysfs_init();
        udev_rules_init(&rules, 1);
 
        if (daemonize) {
@@ -1020,7 +1022,7 @@ int main(int argc, char *argv[], char *envp[])
                /* rules changed, set by inotify or a signal*/
                if (reload_config) {
                        reload_config = 0;
-                       udev_rules_close(&rules);
+                       udev_rules_cleanup(&rules);
                        udev_rules_init(&rules, 1);
                }
 
@@ -1038,7 +1040,8 @@ int main(int argc, char *argv[], char *envp[])
        }
 
 exit:
-       udev_rules_close(&rules);
+       udev_rules_cleanup(&rules);
+       sysfs_cleanup();
 
        if (signal_pipe[READ_END] > 0)
                close(signal_pipe[READ_END]);
diff --git a/udevd.h b/udevd.h
index afbc3a31b14e6a0e95e8ac88517e5b6eb399a646..c0a32e97eddac17739ce551595007d2bf9199f88 100644 (file)
--- a/udevd.h
+++ b/udevd.h
@@ -32,7 +32,7 @@
 #define EVENT_QUEUE_DIR                        ".udev/queue"
 #define EVENT_FAILED_DIR               ".udev/failed"
 
-/* maximum limit of runnig childs */
+/* maximum limit of forked childs */
 #define UDEVD_MAX_CHILDS               64
 /* start to throttle forking if maximum number of running childs in our session is reached */
 #define UDEVD_MAX_CHILDS_RUNNING       16
index 8ff09da3d1504d7e212ea09a6a7954e72f844de0..f8d0b6125af7680df269f10b07ec7bcec899e82f 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
+#include <stddef.h>
 #include <ctype.h>
 #include <stdarg.h>
 #include <unistd.h>
+#include <dirent.h>
 #include <errno.h>
 
-#include "libsysfs/sysfs/libsysfs.h"
-#include "udev_libc_wrapper.h"
 #include "udev.h"
-#include "udev_utils.h"
-#include "udev_version.h"
-#include "logging.h"
 
 
 #ifdef USE_LOG
@@ -48,125 +45,98 @@ void log_message (int priority, const char *format, ...)
 }
 #endif
 
-static void print_all_attributes(struct dlist *attr_list)
+static void print_all_attributes(const char *devpath)
 {
-       struct sysfs_attribute *attr;
-       char value[VALUE_SIZE];
-       size_t len;
-
-       dlist_for_each_data(attr_list, attr, struct sysfs_attribute) {
-               if (attr->value == NULL)
-                       continue;
-               len = strlcpy(value, attr->value, sizeof(value));
-               if (len >= sizeof(value)) {
-                       dbg("attribute value of '%s' too long, skip", attr->name);
-                       continue;
-               }
+       char path[PATH_SIZE];
+       DIR *dir;
+       struct dirent *dent;
+
+       strlcpy(path, sysfs_path, sizeof(path));
+       strlcat(path, devpath, sizeof(path));
+
+       dir = opendir(path);
+       if (dir != NULL) {
+               for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
+                       char *attr_value;
+                       char value[NAME_SIZE];
+                       size_t len;
+
+                       attr_value = sysfs_attr_get_value(devpath, dent->d_name);
+                       if (attr_value == NULL)
+                               continue;
+                       len = strlcpy(value, attr_value, sizeof(value));
+                       dbg("attr '%s'='%s'(%zi)", dent->d_name, value, len);
+
+                       /* remove trailing newlines */
+                       while (len && value[len-1] == '\n')
+                               value[--len] = '\0';
+
+                       /* skip nonprintable attributes */
+                       while (len && isprint(value[len-1]))
+                               len--;
+                       if (len) {
+                               dbg("attribute value of '%s' non-printable, skip", dent->d_name);
+                               continue;
+                       }
 
-               /* remove trailing newlines */
-               while (len && value[len-1] == '\n')
-                       value[--len] = '\0';
-               /* skip nonprintable attributes */
-               while (len && isprint(value[len-1]))
-                       len--;
-               if (len) {
-                       dbg("attribute value of '%s' non-printable, skip", attr->name);
-                       continue;
+                       replace_untrusted_chars(value);
+                       printf("    SYSFS{%s}==\"%s\"\n", dent->d_name, value);
                }
-               replace_untrusted_chars(value);
-               printf("    SYSFS{%s}==\"%s\"\n", attr->name, value);
        }
        printf("\n");
 }
 
-static void print_record(struct udevice *udev)
+static int print_device_chain(const char *devpath)
 {
-       struct name_entry *name_loop;
+       struct sysfs_device *dev;
 
-       printf("P: %s\n", udev->devpath);
-       printf("N: %s\n", udev->name);
-       list_for_each_entry(name_loop, &udev->symlink_list, node)
-               printf("S: %s\n", name_loop->name);
-       list_for_each_entry(name_loop, &udev->env_list, node)
-               printf("E: %s\n", name_loop->name);
-}
-
-static int print_device_chain(const char *path)
-{
-       struct sysfs_class_device *class_dev;
-       struct sysfs_class_device *class_dev_parent;
-       struct sysfs_attribute *attr;
-       struct sysfs_device *sysfs_dev;
-       struct dlist *attr_list;
-       int retval = 0;
-
-       /*  get the class dev */
-       class_dev = sysfs_open_class_device_path(path);
-       if (class_dev == NULL) {
-               fprintf(stderr, "couldn't get the class device\n");
-               return -1;
-       }
-
-       printf("\nudevinfo starts with the device the node belongs to and then walks up the\n"
+       printf("\n"
+              "udevinfo starts with the device the node belongs to and then walks up the\n"
               "device chain, to print for every device found, all possibly useful attributes\n"
               "in the udev key format.\n"
               "Only attributes within one device section may be used together in one rule,\n"
               "to match the device for which the node will be created.\n"
               "\n");
 
-       /* look for the 'dev' file */
-       attr = sysfs_get_classdev_attr(class_dev, "dev");
-       if (attr != NULL)
-               printf("device '%s' has major:minor %s", class_dev->path, attr->value);
-
-       /* open sysfs class device directory and print all attributes */
-       printf("  looking at class device '%s':\n", class_dev->path);
-       printf("    KERNEL==\"%s\"\n", class_dev->name);
-       printf("    SUBSYSTEM==\"%s\"\n", class_dev->classname);
+       dev = sysfs_device_get(devpath);
+       if (dev == NULL)
+               return -1;
 
-       attr_list = sysfs_get_classdev_attributes(class_dev);
-       if (attr_list == NULL) {
-               fprintf(stderr, "couldn't open class device directory\n");
-               retval = -1;
-               goto exit;
-       }
-       print_all_attributes(attr_list);
-
-       /* get the device link (if parent exists look here) */
-       class_dev_parent = sysfs_get_classdev_parent(class_dev);
-       if (class_dev_parent != NULL)
-               sysfs_dev = sysfs_get_classdev_device(class_dev_parent);
-       else 
-               sysfs_dev = sysfs_get_classdev_device(class_dev);
-       
-       if (sysfs_dev != NULL)
-               printf("follow the \"device\"-link to the physical device:\n");
-
-       /* look the device chain upwards */
-       while (sysfs_dev != NULL) {
-               printf("  looking at the device chain at '%s':\n", sysfs_dev->path);
-               printf("    BUS==\"%s\"\n", sysfs_dev->bus);
-               printf("    ID==\"%s\"\n", sysfs_dev->bus_id);
-               printf("    DRIVER==\"%s\"\n", sysfs_dev->driver_name);
-
-               attr_list = sysfs_get_device_attributes(sysfs_dev);
-               if (attr_list != NULL)
-                       print_all_attributes(attr_list);
-               else
-                       printf("\n");
+       printf("  looking at device '%s':\n", dev->devpath);
+       printf("    KERNEL==\"%s\"\n", dev->kernel_name);
+       printf("    SUBSYSTEM==\"%s\"\n", dev->subsystem);
+       print_all_attributes(dev->devpath);
 
-               sysfs_dev = sysfs_get_device_parent(sysfs_dev);
-               if (sysfs_dev == NULL)
+       /* walk up the chain of devices */
+       while (1) {
+               dev = sysfs_device_get_parent(dev);
+               if (dev == NULL)
                        break;
+               printf("  looking at device '%s':\n", dev->devpath);
+               printf("    ID==\"%s\"\n", dev->kernel_name);
+               printf("    BUS==\"%s\"\n", dev->subsystem);
+               printf("    DRIVER==\"%s\"\n", dev->driver);
+
+               print_all_attributes(dev->devpath);
        }
 
-exit:
-       sysfs_close_class_device(class_dev);
-       return retval;
+       return 0;
+}
+
+static void print_record(struct udevice *udev)
+{
+       struct name_entry *name_loop;
+
+       printf("P: %s\n", udev->dev->devpath);
+       printf("N: %s\n", udev->name);
+       list_for_each_entry(name_loop, &udev->symlink_list, node)
+               printf("S: %s\n", name_loop->name);
+       list_for_each_entry(name_loop, &udev->env_list, node)
+               printf("E: %s\n", name_loop->name);
 }
 
 static void export_name_devpath(struct udevice *udev) {
-       printf("%s=%s/%s\n", udev->devpath, udev_root, udev->name);
+       printf("%s=%s/%s\n", udev->dev->devpath, udev_root, udev->name);
 }
 
 static void export_record(struct udevice *udev) {
@@ -180,12 +150,14 @@ static void export_db(void fnct(struct udevice *udev)) {
 
        udev_db_get_all_entries(&name_list);
        list_for_each_entry(name_loop, &name_list, node) {
-               struct udevice udev_db;
+               struct udevice *udev_db;
 
-               udev_init_device(&udev_db, NULL, NULL, NULL);
-               if (udev_db_get_device(&udev_db, name_loop->name) == 0)
-                       fnct(&udev_db);
-               udev_cleanup_device(&udev_db);
+               udev_db = udev_device_init();
+               if (udev_db == NULL)
+                       continue;
+               if (udev_db_get_device(udev_db, name_loop->name) == 0)
+                       fnct(udev_db);
+               udev_device_cleanup(udev_db);
        }
        name_list_cleanup(&name_list);
 }
@@ -215,7 +187,7 @@ int main(int argc, char *argv[], char *envp[])
 {
        static const char short_options[] = "aden:p:q:rVh";
        int option;
-       struct udevice udev;
+       struct udevice *udev;
        int root = 0;
 
        enum action_type {
@@ -239,12 +211,18 @@ int main(int argc, char *argv[], char *envp[])
        char temp[PATH_SIZE];
        struct name_entry *name_loop;
        char *pos;
-       int retval = 0;
+       int rc = 0;
 
        logging_init("udevinfo");
 
-       udev_init_config();
-       udev_init_device(&udev, NULL, NULL, NULL);
+       udev_config_init();
+       sysfs_init();
+
+       udev = udev_device_init();
+       if (udev == NULL) {
+               rc = 1;
+               goto exit;
+       }
 
        /* get command line options */
        while (1) {
@@ -260,7 +238,11 @@ int main(int argc, char *argv[], char *envp[])
                        break;
                case 'p':
                        dbg("udev path: %s\n", optarg);
-                       strlcpy(path, optarg, sizeof(path));
+                       /* remove sysfs mountpoint if not given */
+                       if (strncmp(optarg, sysfs_path, strlen(sysfs_path)) == 0)
+                               strlcpy(path, &optarg[strlen(sysfs_path)], sizeof(path));
+                       else
+                               strlcpy(path, optarg, sizeof(path));
                        break;
                case 'q':
                        dbg("udev query: %s\n", optarg);
@@ -286,7 +268,7 @@ int main(int argc, char *argv[], char *envp[])
                                break;
                        }
                        fprintf(stderr, "unknown query type\n");
-                       retval = 2;
+                       rc = 2;
                        goto exit;
                case 'r':
                        if (action == ACTION_NONE)
@@ -331,10 +313,9 @@ int main(int argc, char *argv[], char *envp[])
                                        pos = path;
                                }
                        }
-                       retval = udev_db_get_device(&udev, pos);
-                       if (retval != 0) {
+                       if (udev_db_get_device(udev, pos) != 0) {
                                fprintf(stderr, "no record for '%s' in database\n", pos);
-                               retval = 3;
+                               rc = 3;
                                goto exit;
                        }
                } else if (name[0] != '\0') {
@@ -348,46 +329,45 @@ int main(int argc, char *argv[], char *envp[])
                        } else
                                pos = name;
 
-                       retval = udev_db_lookup_name(pos, devpath, sizeof(devpath));
-                       if (retval != 0) {
+                       if (udev_db_lookup_name(pos, devpath, sizeof(devpath)) != 0) {
                                fprintf(stderr, "no record for '%s' in database\n", pos);
-                               retval = 3;
+                               rc = 3;
                                goto exit;
                        }
-                       udev_db_get_device(&udev, devpath);
+                       udev_db_get_device(udev, devpath);
                } else {
                        fprintf(stderr, "query needs device path(-p) or node name(-n) specified\n");
-                       retval = 4;
+                       rc = 4;
                        goto exit;
                }
 
                switch(query) {
                case QUERY_NAME:
                        if (root)
-                               printf("%s/%s\n", udev_root, udev.name);
+                               printf("%s/%s\n", udev_root, udev->name);
                        else
-                               printf("%s\n", udev.name);
+                               printf("%s\n", udev->name);
                        break;
                case QUERY_SYMLINK:
-                       if (list_empty(&udev.symlink_list))
+                       if (list_empty(&udev->symlink_list))
                                goto exit;
                        if (root)
-                               list_for_each_entry(name_loop, &udev.symlink_list, node)
+                               list_for_each_entry(name_loop, &udev->symlink_list, node)
                                        printf("%s/%s ", udev_root, name_loop->name);
                        else
-                               list_for_each_entry(name_loop, &udev.symlink_list, node)
+                               list_for_each_entry(name_loop, &udev->symlink_list, node)
                                        printf("%s ", name_loop->name);
                        printf("\n");
                        break;
                case QUERY_PATH:
-                       printf("%s\n", udev.devpath);
+                       printf("%s\n", udev->dev->devpath);
                        goto exit;
                case QUERY_ENV:
-                       list_for_each_entry(name_loop, &udev.env_list, node)
+                       list_for_each_entry(name_loop, &udev->env_list, node)
                                printf("%s\n", name_loop->name);
                        break;
                case QUERY_ALL:
-                       print_record(&udev);
+                       print_record(udev);
                        break;
                default:
                        print_help();
@@ -397,29 +377,23 @@ int main(int argc, char *argv[], char *envp[])
        case ACTION_ATTRIBUTE_WALK:
                if (path[0] == '\0') {
                        fprintf(stderr, "attribute walk on device chain needs path(-p) specified\n");
-                       retval = 4;
+                       rc = 4;
                        goto exit;
-               } else {
-                       if (strncmp(path, sysfs_path, strlen(sysfs_path)) != 0) {
-                               /* prepend sysfs mountpoint if not given */
-                               snprintf(temp, sizeof(temp), "%s%s", sysfs_path, path);
-                               temp[sizeof(temp)-1] = '\0';
-                               strlcpy(path, temp, sizeof(temp));
-                       }
+               } else
                        print_device_chain(path);
-               }
                break;
        case ACTION_ROOT:
                printf("%s\n", udev_root);
                break;
        default:
                print_help();
-               retval = 1;
+               rc = 1;
                break;
        }
 
 exit:
-       udev_cleanup_device(&udev);
+       udev_device_cleanup(udev);
+       sysfs_cleanup();
        logging_close();
-       return retval;
+       return rc;
 }
index 7d3f0aa538499c224502907b9fc5e411c98dd306..80c49753f57a8052841bf4053e4c4f32d307c4ba 100644 (file)
@@ -34,8 +34,6 @@
 
 #include "udev.h"
 #include "udevd.h"
-#include "udev_utils.h"
-#include "udev_libc_wrapper.h"
 
 static int uevent_netlink_sock;
 static int udev_monitor_sock;
index b67df9720b0e81b97ff811046e3a60881b947a70..1b9860baca5ecfbf6537958a4a0edc27265a4722 100644 (file)
@@ -33,9 +33,7 @@
 #include <linux/stddef.h>
 
 #include "udev.h"
-#include "udev_version.h"
 #include "udevd.h"
-#include "logging.h"
 
 /* global variables */
 static int sock = -1;
@@ -67,7 +65,7 @@ int main(int argc, char *argv[], char *envp[])
 
        logging_init("udevsend");
 #ifdef USE_LOG
-       udev_init_config();
+       udev_config_init();
 #endif
        dbg("version %s", UDEV_VERSION);
 
index a9959c5d6b85cb631106addf567d0af81c242747..8c414f1acb345374b0b98f7153960d7a683fc0d4 100644 (file)
 #include <sys/stat.h>
 #include <sys/types.h>
 
-#include "libsysfs/sysfs/libsysfs.h"
-#include "udev_libc_wrapper.h"
 #include "udev.h"
-#include "udev_version.h"
-#include "logging.h"
-#include "udev_utils.h"
 #include "udev_rules.h"
-#include "list.h"
 
 static const char *udev_run_str;
 static const char *udev_log_str;
@@ -68,11 +62,10 @@ void log_message(int priority, const char *format, ...)
 struct device {
        struct list_head node;
        char path[PATH_SIZE];
-       char subsys[NAME_SIZE];
 };
 
 /* sort files in lexical order */
-static int device_list_insert(const char *path, char *subsystem, struct list_head *device_list)
+static int device_list_insert(const char *path, struct list_head *device_list)
 {
        struct device *loop_device;
        struct device *new_device;
@@ -93,9 +86,8 @@ static int device_list_insert(const char *path, char *subsystem, struct list_hea
        }
 
        strlcpy(new_device->path, devpath, sizeof(new_device->path));
-       strlcpy(new_device->subsys, subsystem, sizeof(new_device->subsys));
        list_add_tail(&new_device->node, &loop_device->node);
-       dbg("add '%s' from subsys '%s'", new_device->path, new_device->subsys);
+       dbg("add '%s'" , new_device->path);
        return 0;
 }
 
@@ -112,64 +104,68 @@ static char *first_list[] = {
        NULL,
 };
 
-static int add_device(const char *devpath, const char *subsystem)
+static int add_device(const char *devpath)
 {
-       struct udevice udev;
-       struct sysfs_class_device *class_dev;
-       char path[PATH_SIZE];
+       struct sysfs_device *dev;
+       struct udevice *udev;
 
        /* clear and set environment for next event */
        clearenv();
        setenv("ACTION", "add", 1);
-       setenv("DEVPATH", devpath, 1);
-       setenv("SUBSYSTEM", subsystem, 1);
        setenv("UDEV_START", "1", 1);
        if (udev_log_str)
                setenv("UDEV_LOG", udev_log_str, 1);
        if (udev_run_str)
                setenv("UDEV_RUN", udev_run_str, 1);
-       dbg("add '%s'", devpath);
 
-       snprintf(path, sizeof(path), "%s%s", sysfs_path, devpath);
-       path[sizeof(path)-1] = '\0';
-       class_dev = sysfs_open_class_device_path(path);
-       if (class_dev == NULL) {
-               dbg("sysfs_open_class_device_path failed");
+       dev = sysfs_device_get(devpath);
+       if (dev == NULL)
                return -1;
-       }
 
-       udev_init_device(&udev, &class_dev->path[strlen(sysfs_path)], subsystem, "add");
-       udev.devt = get_devt(class_dev);
-       if (!udev.devt && udev.type != DEV_NET) {
-               dbg("sysfs_open_class_device_path failed");
+       udev = udev_device_init();
+       if (udev == NULL)
                return -1;
+
+       /* override built-in sysfs device */
+       udev->dev = dev;
+       strcpy(udev->action, "add");
+       udev->devt = udev_device_get_devt(udev);
+
+       if (strcmp(udev->dev->subsystem, "net") != 0) {
+               udev->devt = udev_device_get_devt(udev);
+               if (major(udev->devt) == 0)
+                       return -1;
        }
-       udev_rules_get_name(&rules, &udev, class_dev);
-       if (udev.ignore_device) {
+
+       dbg("add '%s'", udev->dev->devpath);
+       setenv("DEVPATH", udev->dev->devpath, 1);
+       setenv("SUBSYSTEM", udev->dev->subsystem, 1);
+
+       udev_rules_get_name(&rules, udev);
+       if (udev->ignore_device) {
                dbg("device event will be ignored");
                goto exit;
        }
-       if (udev.name[0] == '\0') {
+       if (udev->name[0] == '\0') {
                dbg("device node creation supressed");
                goto run;
        }
 
-       udev_add_device(&udev, class_dev);
+       udev_add_device(udev);
 run:
-       if (udev_run && !list_empty(&udev.run_list)) {
+       if (udev_run && !list_empty(&udev->run_list)) {
                struct name_entry *name_loop;
 
                dbg("executing run list");
-               list_for_each_entry(name_loop, &udev.run_list, node) {
+               list_for_each_entry(name_loop, &udev->run_list, node) {
                        if (strncmp(name_loop->name, "socket:", strlen("socket:")) == 0)
-                               pass_env_to_socket(&name_loop->name[strlen("socket:")], devpath, "add");
+                               pass_env_to_socket(&name_loop->name[strlen("socket:")], udev->dev->devpath, "add");
                        else
-                               run_program(name_loop->name, udev.subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO));
+                               run_program(name_loop->name, udev->dev->subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO));
                }
        }
 exit:
-       sysfs_close_class_device(class_dev);
-       udev_cleanup_device(&udev);
+       udev_device_cleanup(udev);
 
        return 0;
 }
@@ -184,7 +180,7 @@ static void exec_list(struct list_head *device_list)
        list_for_each_entry_safe(loop_device, tmp_device, device_list, node) {
                for (i = 0; first_list[i] != NULL; i++) {
                        if (strncmp(loop_device->path, first_list[i], strlen(first_list[i])) == 0) {
-                               add_device(loop_device->path, loop_device->subsys);
+                               add_device(loop_device->path);
                                list_del(&loop_device->node);
                                free(loop_device);
                                break;
@@ -204,14 +200,14 @@ static void exec_list(struct list_head *device_list)
                if (found)
                        continue;
 
-               add_device(loop_device->path, loop_device->subsys);
+               add_device(loop_device->path);
                list_del(&loop_device->node);
                free(loop_device);
        }
 
        /* handle the rest of the devices left over, if any */
        list_for_each_entry_safe(loop_device, tmp_device, device_list, node) {
-               add_device(loop_device->path, loop_device->subsys);
+               add_device(loop_device->path);
                list_del(&loop_device->node);
                free(loop_device);
        }
@@ -253,7 +249,7 @@ static void udev_scan_block(struct list_head *device_list)
                        snprintf(dirname, sizeof(dirname), "%s/%s", base, dent->d_name);
                        dirname[sizeof(dirname)-1] = '\0';
                        if (has_devt(dirname))
-                               device_list_insert(dirname, "block", device_list);
+                               device_list_insert(dirname, device_list);
                        else
                                continue;
 
@@ -270,7 +266,7 @@ static void udev_scan_block(struct list_head *device_list)
                                        dirname2[sizeof(dirname2)-1] = '\0';
 
                                        if (has_devt(dirname2))
-                                               device_list_insert(dirname2, "block", device_list);
+                                               device_list_insert(dirname2, device_list);
                                }
                                closedir(dir2);
                        }
@@ -313,7 +309,7 @@ static void udev_scan_class(struct list_head *device_list)
                                        dirname2[sizeof(dirname2)-1] = '\0';
 
                                        if (has_devt(dirname2) || strcmp(dent->d_name, "net") == 0)
-                                               device_list_insert(dirname2, dent->d_name, device_list);
+                                               device_list_insert(dirname2, device_list);
                                }
                                closedir(dir2);
                        }
@@ -339,7 +335,7 @@ int main(int argc, char *argv[], char *envp[])
        struct sigaction act;
 
        logging_init("udevstart");
-       udev_init_config();
+       udev_config_init();
        dbg("version %s", UDEV_VERSION);
 
        udev_run_str = getenv("UDEV_RUN");
@@ -361,13 +357,15 @@ int main(int argc, char *argv[], char *envp[])
        /* trigger timeout to prevent hanging processes */
        alarm(UDEV_ALARM_TIMEOUT);
 
+       sysfs_init();
        udev_rules_init(&rules, 1);
 
        udev_scan_class(&device_list);
        udev_scan_block(&device_list);
        exec_list(&device_list);
 
-       udev_rules_close(&rules);
+       udev_rules_cleanup(&rules);
+       sysfs_cleanup();
        logging_close();
        return 0;
 }
index e547811a8b58e35c71bad5c254ed2b6174a4c75d..ea0ea5923878c4e161a7dfd44e75710f7c734ca9 100644 (file)
@@ -10,8 +10,8 @@
 .SH "NAME"
 udevtest \- simulate a udev run and print the action to the console
 .SH "SYNOPSIS"
-.HP 31
-\fBudevtest \fR\fB\fIdevice\-path\fR\fR\fB \fR\fB\fIsubsystem\fR\fR
+.HP 21
+\fBudevtest \fR\fB\fIdevice\-path\fR\fR
 .SH "DESCRIPTION"
 .PP
 udevtest simulates a udev run for the given device and prints out the name of the node udev would have created, or the name of the network interface, that would have been renamend.
index 1be3fa951578dd70021fefa2b655f1c625e0dce7..22fd3735c2f96a9b8e208b18434edf188fc2c5f7 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
+#include <stddef.h>
+#include <unistd.h>
 #include <errno.h>
 #include <ctype.h>
 #include <signal.h>
 #include <syslog.h>
 
-#include "libsysfs/sysfs/libsysfs.h"
 #include "udev.h"
-#include "udev_utils.h"
-#include "udev_version.h"
 #include "udev_rules.h"
-#include "logging.h"
 
 
 #ifdef USE_LOG
@@ -53,28 +51,28 @@ void log_message (int priority, const char *format, ...)
 int main(int argc, char *argv[], char *envp[])
 {
        struct udev_rules rules;
-       struct sysfs_class_device *class_dev;
        char *devpath;
-       char path[PATH_SIZE];
        char temp[PATH_SIZE];
-       struct udevice udev;
-       char *subsystem = NULL;
+       struct udevice *udev;
+       struct sysfs_device *dev;
+       int retval;
+       int rc = 0;
 
        info("version %s", UDEV_VERSION);
 
        /* initialize our configuration */
-       udev_init_config();
+       udev_config_init();
        if (udev_log_priority < LOG_INFO)
                udev_log_priority = LOG_INFO;
 
-       if (argc != 3) {
-               info("Usage: udevtest <devpath> <subsystem>");
+       if (argc != 2) {
+               info("Usage: udevtest <devpath>");
                return 1;
        }
 
        /* remove sysfs_path if given */
        if (strncmp(argv[1], sysfs_path, strlen(sysfs_path)) == 0)
-               devpath = &argv[1][strlen(sysfs_path)] ;
+               devpath = &argv[1][strlen(sysfs_path)];
        else
                if (argv[1][0] != '/') {
                        /* prepend '/' if missing */
@@ -84,39 +82,46 @@ int main(int argc, char *argv[], char *envp[])
                } else
                        devpath = argv[1];
 
-       subsystem = argv[2];
-       setenv("DEVPATH", devpath, 1);
-       setenv("SUBSYSTEM", subsystem, 1);
-       setenv("ACTION", "add", 1);
-       info("looking at device '%s' from subsystem '%s'", devpath, subsystem);
-
-       /* initialize the naming deamon */
+       sysfs_init();
        udev_rules_init(&rules, 0);
 
-       /* fill in values and test_run flag*/
-       udev_init_device(&udev, devpath, subsystem, "add");
+       dev = sysfs_device_get(devpath);
+       if (dev == NULL) {
+               info("unable to open '%s'", devpath);
+               rc = 2;
+               goto exit;
+       }
 
-       /* open the device */
-       snprintf(path, sizeof(path), "%s%s", sysfs_path, udev.devpath);
-       path[sizeof(path)-1] = '\0';
-       class_dev = sysfs_open_class_device_path(path);
-       if (class_dev == NULL) {
-               info("sysfs_open_class_device_path failed");
-               return 1;
+       udev = udev_device_init();
+       if (udev == NULL) {
+               info("can't open device");
+               rc = 3;
+               goto exit;
        }
-       info("opened class_dev->name='%s'", class_dev->name);
 
-       if (udev.type == DEV_BLOCK || udev.type == DEV_CLASS)
-               udev.devt = get_devt(class_dev);
+       /* override built-in sysfs device */
+       udev->dev = dev;
+       strcpy(udev->action, "add");
+       udev->devt = udev_device_get_devt(udev);
 
        /* simulate node creation with test flag */
-       udev.test_run = 1;
-       if (udev.type == DEV_NET || udev.devt) {
-               udev_rules_get_name(&rules, &udev, class_dev);
-               udev_add_device(&udev, class_dev);
-       } else
-               info("only char and block devices with a dev-file are supported by this test program");
-       sysfs_close_class_device(class_dev);
-
-       return 0;
+       udev->test_run = 1;
+
+       setenv("DEVPATH", udev->dev->devpath, 1);
+       setenv("SUBSYSTEM", udev->dev->subsystem, 1);
+       setenv("ACTION", "add", 1);
+
+       info("looking at device '%s' from subsystem '%s'", udev->dev->devpath, udev->dev->subsystem);
+       retval = udev_device_event(&rules, udev);
+       if (retval == 0) {
+               struct name_entry *name_loop;
+
+               list_for_each_entry(name_loop, &udev->run_list, node)
+                       info("run: '%s'", name_loop->name);
+       }
+
+exit:
+       udev_rules_cleanup(&rules);
+       sysfs_cleanup();
+       return rc;
 }