linux-hotplug.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] The Ubuntu Collection
@ 2005-12-07 17:12 Scott James Remnant
  2005-12-07 22:37 ` Kay Sievers
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Scott James Remnant @ 2005-12-07 17:12 UTC (permalink / raw)
  To: linux-hotplug


[-- Attachment #1.1: Type: text/plain, Size: 3907 bytes --]

Attached are the current set of Ubuntu patches to udev, as of 077.  The
rest of this e-mail is a brief description of each one, and why we have
it.


01-lib-udev.patch
    This arranges for the various extras programs to be installed
    directly into /lib/udev/ rather than into /sbin/.  Pretty sweet and
    obvious.

02-no-sepol.patch
    The libsepol dependency seems to only exist on RedHat, with the
    versions of the SELinux libraries we have in Ubuntu, there wasn't
    any need for it.  Removing it saved us from having to security audit
    libsepol as part of our main promotion procedure.

10-udev-conf.patch
    We've given up trying to support people who want their udev_root and
    udev_rules to be in different places; with initramfs, changing this
    would mean regenerating the initramfs as well.  We decided to just
    drop mention of the two options as a safety catch against pedocide.

40-udevplug.patch
    This adds an extra tool to udev called "udevplug", it's basically a
    binary that handles tickling uevents and waiting for udevd to finish
    processing them.  The command-line options let you choose exactly
    what to tickle (or just everything), and do things like filter by
    sysfs attributes.  (manpage included)

50-result-whitespace.patch
    In a few places udev calls the replace_untrusted_chars() function on
    things like program output; it treats \t, \r, \n, and other
    whitespace characters (other than space itself) as illegal and
    replaces them with an underscore.  This patch slightly alters that
    behaviour, it leaves them as untrusted, but instead replaces those
    of whitespace-ilk with an ordinary space, instead of an underscore. 
    We use this because various helpers output a newline-separated list
    of modules, and we wanted to pass that $result straight to modprobe.

55-run-program.patch
    This reduces the severity of the "exec of program failed" error IF
    the reason the program couldn't be run was because it didn't exist
    yet.  With /dev/.udev/failed, helpers not existing yet isn't
    serious, it just means they need to be retried later and there's no
    point screaming too loudly about it.

60-firmware-hunt.patch
    This modifies the firmware_helper extra to also look in
    /lib/firmware/$KERNEL_VERSION which is where we put firmware that
    comes with our kernel images.

80-extras-dvb_device_name.patch
    This adds a dvb_device_name helper that's pretty much equivalent to
    the shell code passed around between the distros, just rather faster
    and usable in busybox environments.  As with all our extras,
    includes a manpage.

80-extras-ide_media.patch
    Adds an ide_media helper that looks up the media type under /proc,
    again somewhat similar to the shell code but this also will wait for
    the node to appear under /proc, avoiding a race condition.

80-extras-pnp_modules.patch
    Another binary helper replacing shell code, outputs a list of
    module aliases for a pnp device.

80-extras-storage_enum.patch
    An odd one, we use this in the installer to make the
    devfs-like /dev/discs, /dev/cdroms and /dev/floppy directories which
    the debian-installer we use still requires.  We didn't use the
    existing devfs scripts because they don't cope well with everything
    getting plugged at once, this is reasonably safe against that and
    ensures that each gets a unique number.

80-extras-usb_device_name.patch
    Back to the binary helpers again, this one is for the usb_device
    subsystem and again just replaces equivalent shell code other
    distros use.

80-extras-vio_type.patch
    Binary helper to look up the type of a vio device under /proc, and
    like ide_media wait for the node to appear to avoid races.


Scott
-- 
Scott James Remnant
scott@ubuntu.com

[-- Attachment #1.2: 01-lib-udev.patch --]
[-- Type: text/x-patch, Size: 4053 bytes --]

diff -ruNp udev-076~/extras/ata_id/Makefile udev-076/extras/ata_id/Makefile
--- udev-076~/extras/ata_id/Makefile	2005-11-22 16:34:55.000000000 +0000
+++ udev-076/extras/ata_id/Makefile	2005-11-22 18:37:55.757581520 +0000
@@ -48,11 +48,11 @@ clean:
 .PHONY: clean
 
 install-bin: all
-	$(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG)
+	$(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(libudevdir)/$(PROG)
 .PHONY: install-bin
 
 uninstall-bin:
-	- rm $(DESTDIR)$(sbindir)/$(PROG)
+	- rm $(DESTDIR)$(libudevdir)/$(PROG)
 .PHONY: uninstall-bin
 
 install-man:
diff -ruNp udev-076~/extras/cdrom_id/Makefile udev-076/extras/cdrom_id/Makefile
--- udev-076~/extras/cdrom_id/Makefile	2005-11-22 16:34:55.000000000 +0000
+++ udev-076/extras/cdrom_id/Makefile	2005-11-22 18:37:55.758581368 +0000
@@ -48,11 +48,11 @@ clean:
 .PHONY: clean
 
 install-bin: all
-	$(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG)
+	$(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(libudevdir)/$(PROG)
 .PHONY: install-bin
 
 uninstall-bin:
-	- rm $(DESTDIR)$(sbindir)/$(PROG)
+	- rm $(DESTDIR)$(libudevdir)/$(PROG)
 .PHONY: uninstall-bin
 
 install-man:
diff -ruNp udev-076~/extras/dasd_id/Makefile udev-076/extras/dasd_id/Makefile
--- udev-076~/extras/dasd_id/Makefile	2005-11-22 16:34:55.000000000 +0000
+++ udev-076/extras/dasd_id/Makefile	2005-11-22 18:37:55.759581216 +0000
@@ -48,11 +48,11 @@ clean:
 .PHONY: clean
 
 install-bin: all
-	$(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG)
+	$(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(libudevdir)/$(PROG)
 .PHONY: install-bin
 
 uninstall-bin:
-	- rm $(DESTDIR)$(sbindir)/$(PROG)
+	- rm $(DESTDIR)$(libudevdir)/$(PROG)
 .PHONY: uninstall-bin
 
 install-man:
diff -ruNp udev-076~/extras/edd_id/Makefile udev-076/extras/edd_id/Makefile
--- udev-076~/extras/edd_id/Makefile	2005-11-22 16:34:55.000000000 +0000
+++ udev-076/extras/edd_id/Makefile	2005-11-22 18:37:55.761580912 +0000
@@ -48,11 +48,11 @@ clean:
 .PHONY: clean
 
 install-bin: all
-	$(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG)
+	$(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(libudevdir)/$(PROG)
 .PHONY: install-bin
 
 uninstall-bin:
-	- rm $(DESTDIR)$(sbindir)/$(PROG)
+	- rm $(DESTDIR)$(libudevdir)/$(PROG)
 .PHONY: uninstall-bin
 
 install-man:
diff -ruNp udev-076~/extras/scsi_id/Makefile udev-076/extras/scsi_id/Makefile
--- udev-076~/extras/scsi_id/Makefile	2005-11-22 16:34:55.000000000 +0000
+++ udev-076/extras/scsi_id/Makefile	2005-11-22 18:37:55.766580152 +0000
@@ -67,11 +67,11 @@ clean:
 .PHONY: clean
 
 install-bin: all
-	$(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG)
+	$(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(libudevdir)/$(PROG)
 .PHONY: install-bin
 
 uninstall-bin:
-	- rm $(DESTDIR)$(sbindir)/$(PROG)
+	- rm $(DESTDIR)$(libudevdir)/$(PROG)
 .PHONY: uninstall-bin
 
 install-man:
diff -ruNp udev-076~/extras/usb_id/Makefile udev-076/extras/usb_id/Makefile
--- udev-076~/extras/usb_id/Makefile	2005-11-22 16:34:55.000000000 +0000
+++ udev-076/extras/usb_id/Makefile	2005-11-22 18:37:55.768579848 +0000
@@ -48,11 +48,11 @@ clean:
 .PHONY: clean
 
 install-bin: all
-	$(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG)
+	$(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(libudevdir)/$(PROG)
 .PHONY: install-bin
 
 uninstall-bin:
-	- rm $(DESTDIR)$(sbindir)/$(PROG)
+	- rm $(DESTDIR)$(libudevdir)/$(PROG)
 .PHONY: uninstall-bin
 
 install-man:
diff -ruNp udev-076~/extras/volume_id/Makefile udev-076/extras/volume_id/Makefile
--- udev-076~/extras/volume_id/Makefile	2005-11-22 16:34:55.000000000 +0000
+++ udev-076/extras/volume_id/Makefile	2005-11-22 18:37:55.769579696 +0000
@@ -51,11 +51,11 @@ clean:
 .PHONY: clean
 
 install-bin: all
-	$(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG)
+	$(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(libudevdir)/$(PROG)
 .PHONY: install-bin
 
 uninstall-bin:
-	- rm $(DESTDIR)$(sbindir)/$(PROG)
+	- rm $(DESTDIR)$(libudevdir)/$(PROG)
 .PHONY: uninstall-bin
 
 install-man:

[-- Attachment #1.3: 02-no-sepol.patch --]
[-- Type: text/x-patch, Size: 363 bytes --]

diff -ruNp udev-077~/Makefile udev-077/Makefile
--- udev-077~/Makefile	2005-12-04 02:01:48.000000000 +0000
+++ udev-077/Makefile	2005-12-05 17:11:23.464207250 +0000
@@ -178,7 +178,7 @@ endif
 
 ifeq ($(strip $(USE_SELINUX)),true)
 	UDEV_OBJS += udev_selinux.o
-	LIB_OBJS += -lselinux -lsepol
+	LIB_OBJS += -lselinux
 	CFLAGS += -DUSE_SELINUX
 endif
 

[-- Attachment #1.4: 10-udev-conf.patch --]
[-- Type: text/x-patch, Size: 631 bytes --]

diff -ruNp udev-076~/etc/udev/udev.conf.in udev-076/etc/udev/udev.conf.in
--- udev-076~/etc/udev/udev.conf.in	2005-11-22 16:34:55.000000000 +0000
+++ udev-076/etc/udev/udev.conf.in	2005-11-24 18:39:19.946473488 +0000
@@ -1,11 +1,5 @@
 # udev.conf
 
-# Where in the filesystem to place the device nodes.
-udev_root="@udevdir@"
-
-# The name and location of the udev rules file(s).
-udev_rules="@configdir@/rules.d"
-
 # The initial syslog(3) priority: "err", "info", "debug" or its
 # numerical equivalent. For runtime debugging, the daemons internal
 # state can be changed with: "udevcontrol log_priority=<value>".

[-- Attachment #1.5: 40-udevplug.patch --]
[-- Type: text/x-patch, Size: 19551 bytes --]

diff -ruNp udev-077~/Makefile udev-077/Makefile
--- udev-077~/Makefile	2005-12-05 17:12:17.295571500 +0000
+++ udev-077/Makefile	2005-12-05 17:12:28.260256750 +0000
@@ -54,7 +54,8 @@ PROGRAMS = \
 	udevmonitor			\
 	udevinfo			\
 	udevtest			\
-	udevstart
+	udevstart			\
+	udevplug
 
 HEADERS = \
 	udev.h				\
@@ -88,9 +89,11 @@ MAN_PAGES = \
 	udevsend.8			\
 	udevtest.8			\
 	udevinfo.8			\
-	udevstart.8
+	udevstart.8			\
+	udevplug.8
 
 SYSFS_OBJS = \
+	libsysfs/sysfs_bus.o		\
 	libsysfs/sysfs_class.o		\
 	libsysfs/sysfs_device.o		\
 	libsysfs/sysfs_dir.o		\
@@ -303,6 +306,7 @@ install-man:
 	$(INSTALL_DATA) -D udevd.8 $(DESTDIR)$(mandir)/man8/udevd.8
 	$(INSTALL_DATA) -D udevsend.8 $(DESTDIR)$(mandir)/man8/udevsend.8
 	$(INSTALL_DATA) -D udevmonitor.8 $(DESTDIR)$(mandir)/man8/udevmonitor.8
+	$(INSTALL_DATA) -D udevplug.8 $(DESTDIR)$(mandir)/man8/udevplug.8
 	- ln -f -s udevd.8 $(DESTDIR)$(mandir)/man8/udevcontrol.8
 	@extras="$(EXTRAS)"; for target in $$extras; do \
 		echo $$target; \
@@ -319,6 +323,7 @@ uninstall-man:
 	- rm -f $(DESTDIR)$(mandir)/man8/udevmonitor.8
 	- rm -f $(DESTDIR)$(mandir)/man8/udevsend.8
 	- rm -f $(DESTDIR)$(mandir)/man8/udevcontrol.8
+	- rm -f $(DESTDIR)$(mandir)/man8/udevplug.8
 	@extras="$(EXTRAS)"; for target in $$extras; do \
 		echo $$target; \
 		$(MAKE) -C $$target $@ || exit 1; \
@@ -335,6 +340,7 @@ install-bin:
 	$(INSTALL_PROGRAM) -D udevinfo $(DESTDIR)$(usrbindir)/udevinfo
 	$(INSTALL_PROGRAM) -D udevtest $(DESTDIR)$(usrbindir)/udevtest
 	$(INSTALL_PROGRAM) -D udevstart $(DESTDIR)$(sbindir)/udevstart
+	$(INSTALL_PROGRAM) -D udevplug $(DESTDIR)$(sbindir)/udevplug
 	@extras="$(EXTRAS)"; for target in $$extras; do \
 		echo $$target; \
 		$(MAKE) -C $$target $@ || exit 1; \
@@ -355,6 +361,7 @@ uninstall-bin:
 	- rm -f $(DESTDIR)$(usrsbindir)/udevmonitor
 	- rm -f $(usrbindir)/udevinfo
 	- rm -f $(DESTDIR)$(DESTDIR)$(usrbindir)/udevtest
+	- rm -f $(DESTDIR)$(sbindir)/udevplug
 ifndef DESTDIR
 	- killall udevd
 	- rm -rf /dev/.udev
diff -ruNp udev-077~/udevplug.8 udev-077/udevplug.8
--- udev-077~/udevplug.8	1970-01-01 01:00:00.000000000 +0100
+++ udev-077/udevplug.8	2005-12-05 17:12:28.260256750 +0000
@@ -0,0 +1,83 @@
+.TH "UDEVPLUG" "8" "November 2005" "udev" "udevplug"
+.SH NAME
+udevplug \- device cold-plugging tool
+.SH SYNOPSIS
+.B udevplug
+[\fB-I\fR\fIattr\fR=\fIvalue\fR]... [\fB-X\fR\fIattr\fR=\fIvalue\fR]...
+[\fB-b\fR] [\fB-c\fR] [\fB-B\fR\fIbus\fR]... [\fB-C\fR\fIclass\fR]...
+[\fB-F\fR] [\fB-v\fR] [\fIdevpath\fR]...
+
+.B udevplug -W
+.\"
+.SH DESCRIPTION
+.B udevplug
+is a tool to ease the cold-plugging of system devices.  It examines sysfs
+for devices already present on the system, for which the events may have
+been missed, and writes to the uevent attribute to cause the kernel to
+replay the event.  It does not process the events themselves,
+.BR udevd (8)
+should be run before calling this tool to do that.
+
+Both before and after requesting the events, it waits for the
+.BR udevd (8)
+event queue to be empty.  This provides some synchrony and prevents most
+but not all, race conditions.
+.\"
+.SH USAGE
+When called without any arguments
+.B udevplug
+replays the events for all currently connected devices on the system.  Options
+can be given to alter this list, limiting it to devices on a particular bus,
+in a particular class or those with or without specified attributes.
+
+Any non-option arguments given should be paths to individual devices that
+need to be replayed, instead of all connected devices.
+.SH OPTIONS
+All options are accumulative and may be specified multiple times.
+.TP
+.BI -I attr\fR=\fIvalue
+only events for those devices for which the \fIattr\fR attribute matches
+\fIvalue\fR are replayed.  \fIvalue\fR may include wildcards and globbing,
+as with the
+.BR udev (8)
+configuration file format.
+.TP
+.BI -X attr\fR=\fIvalue
+only events for those devices for which the \fIattr\fR attribute DOES NOT
+MATCH \fIvalue\fR are replayed.  \fIvalue\fR may include wildcards and
+globbing, as with the
+.BR udev (8)
+configuration file format.
+.TP
+.BI -b
+events for all block devices are replayed.
+.TP
+.BI -c
+events for all class devices are replayed.
+.TP
+.BI -B bus
+only events for those devices on the \fIbus\fR bus are replayed.
+.TP
+.BI -C class
+only events for those devices in the \fIclass\fR class are replayed.
+.TP
+.BI -F
+causes events for devices that have previously failed to be replayed.  When
+combined with the \fB-B\fR or \fB-C\fR options it acts as a union, rather
+than an exclusion, e.g. all \fIpci\fR devices and anything previously failed
+will be replayed.
+.TP
+.BI -v
+prints the sysfs path of each device being plugged.
+.TP
+.BI -W
+causes udev to simply wait for the 
+.BR udevd (8)
+queue to empty, exiting immediately if there is nothing in the queue.  This
+can not be used in combination with other arguments.
+.RE
+.SH SEE ALSO
+.BR udev (8)
+.BR udevd (8)
+.SH AUTHORS
+Scott James Remnant <scott@ubuntu.com>
diff -ruNp udev-077~/udevplug.c udev-077/udevplug.c
--- udev-077~/udevplug.c	1970-01-01 01:00:00.000000000 +0100
+++ udev-077/udevplug.c	2005-12-05 17:12:28.268257250 +0000
@@ -0,0 +1,600 @@
+/*
+ * udevplug.c - device cold-plugging tool
+ *
+ * Copyright © 2005 Canonical Ltd.
+ * Author: Scott James Remnant <scott@ubuntu.com>
+ *
+ *	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.,
+ *	51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "libsysfs/sysfs/libsysfs.h"
+#include "list.h"
+#include "udev.h"
+#include "udevd.h"
+#include "udev_utils.h"
+#include "udev_version.h"
+#include "udev_libc_wrapper.h"
+
+#include "logging.h"
+
+
+/* print the nodes we visit */
+static int verbose = 0;
+
+
+#ifdef USE_LOG
+void log_message(int priority, const char *format, ...)
+{
+	va_list args;
+
+	if (priority > udev_log_priority)
+		return;
+
+	va_start(args, format);
+	vsyslog(priority, format, args);
+	va_end(args);
+}
+#endif
+
+
+struct device {
+	struct list_head node;
+	struct sysfs_device *dev;
+};
+
+struct filter {
+	struct list_head node;
+	char name[NAME_SIZE];
+	char value[VALUE_SIZE];
+	int include;
+};
+
+/* insert the devpaths in lexical order */
+static int device_list_insert(struct sysfs_device *device, struct list_head *device_list)
+{
+	struct device *loop_device;
+	struct device *new_device;
+
+	dbg("insert: '%s'", device->path);
+
+	list_for_each_entry(loop_device, device_list, node) {
+		if (strcmp(loop_device->dev->path, device->path) > 0)
+			break;
+	}
+
+	new_device = malloc(sizeof(struct device));
+	if (new_device == NULL) {
+		dbg("error malloc");
+		return -ENOMEM;
+	}
+
+	new_device->dev = device;
+	list_add_tail(&new_device->node, &loop_device->node);
+	return 0;
+}
+
+/* append the filter to the list */
+static int filter_list_insert(int include, const char *filter, struct list_head *filter_list)
+{
+	struct filter *new_filter;
+	const char *ptr;
+
+	dbg("insert: '%s'", filter);
+
+	new_filter = malloc(sizeof(struct filter));
+	if (!new_filter) {
+		dbg("error malloc");
+		return -ENOMEM;
+	}
+	new_filter->include = include;
+
+	ptr = strchr(filter, '=');
+	if (ptr) {
+		if ((size_t)(ptr + 1 - filter) > sizeof(new_filter->name)) {
+			err("attribute name too long in filter %s", filter);
+			free(new_filter);
+			return 1;
+		}
+		memcpy(new_filter->name, filter, ptr - filter);
+		new_filter->name[ptr - filter] = '\0';
+
+		strlcpy(new_filter->value, ptr + 1, sizeof(new_filter->value));
+	} else {
+		strlcpy(new_filter->name, filter, sizeof(new_filter->name));
+		strlcpy(new_filter->value, "?*", sizeof(new_filter->value));
+	}
+
+	list_add_tail(&new_filter->node, filter_list);
+	dbg("add %s filter '%s' value '%s'",
+	    new_filter->include ? "include" : "exclude",
+	    new_filter->name, new_filter->value);
+	return 0;
+}
+
+/* touch up a device to load the uevent */
+static int tickle(struct sysfs_device *device)
+{
+	static const char message[] = "poke";
+	char uevent[PATH_SIZE];
+	int fd;
+
+	strlcpy(uevent, device->path, sizeof(uevent));
+	strlcat(uevent, "/uevent", sizeof(uevent));
+
+	dbg("uevent: '%s'", uevent);
+
+	if (verbose)
+		printf("%s\n", device->path);
+
+	fd = open(uevent, O_WRONLY);
+	if (fd < 0) {
+		err("unable to open uevent '%s': %s", uevent,
+		    strerror(errno));
+		return 1;
+	}
+
+	write(fd, message, sizeof(message));
+
+	close(fd);
+	return 0;
+}
+
+/* filter the device list and run any left */
+static void exec_list(struct list_head *device_list, struct list_head *filter_list)
+{
+	struct filter *loop_filter;
+	struct device *loop_device;
+
+	list_for_each_entry(loop_device, device_list, node) {
+		struct sysfs_device *device = loop_device->dev;
+
+		list_for_each_entry(loop_filter, filter_list, node) {
+			struct sysfs_attribute *attr;
+			char value[256];
+			int i;
+
+			attr = sysfs_get_device_attr(device, loop_filter->name);
+			if (!attr) {
+				if (loop_filter->include)
+					goto next;
+
+				continue;
+			}
+
+			i = strlcpy(value, attr->value, sizeof(value));
+			while (i > 0 && isspace(value[i-1]))
+				value[--i] = '\0';
+
+			if (strcmp_pattern(loop_filter->value, value) == 0) {
+				dbg("device '%s' attr '%s' matched filter '%s' <-> '%s'",
+				    device->path, attr->name, value, loop_filter->value);
+
+				if (!loop_filter->include)
+					goto next;
+			} else {
+				if (loop_filter->include)
+					goto next;
+			}
+		}
+
+		tickle(device);
+
+	next:
+		;
+	}
+}
+
+
+/* add a single device by path */
+static int add_device(const char *path, struct list_head *device_list)
+{
+	struct sysfs_device *device;
+
+	dbg("add: '%s'", path);
+
+	device = sysfs_open_device_path(path);
+	if (!device) {
+		err("unable to open device '%s'", path);
+		return 1;
+	}
+
+	device_list_insert(device, device_list);
+	return 0;
+}
+
+/* test whether something is probably a device */
+static int has_uevent(const char *path)
+{
+	struct stat statbuf;
+	char uevent[PATH_SIZE];
+
+	strlcpy(uevent, path, sizeof(uevent));
+	strlcat(uevent, "/uevent", sizeof(uevent));
+
+	if (lstat(uevent, &statbuf)) {
+		if (errno != ENOENT)
+			err("error checking for uevent '%s': %s", uevent,
+			    strerror(errno));
+
+		return 0;
+	}
+
+	return 1;
+}
+
+static int recurse_subtree(const char *path, struct list_head *device_list, int follow_links);
+
+/* visit an entry, adding the device and recursing the subtree beneath it */
+static int visit_entry(const char *path, struct list_head *device_list, int follow_links)
+{
+	char subpath[PATH_SIZE];
+	struct stat statbuf;
+
+	if (lstat(path, &statbuf)) {
+		err("error stat '%s': %s", path, strerror(errno));
+		return 1;
+	}
+
+	strlcpy(subpath, path, sizeof(subpath));
+	if (S_ISLNK(statbuf.st_mode) && follow_links) {
+		char linkpath[PATH_SIZE];
+		char *lptr;
+		int len;
+
+		len = readlink(path, linkpath, sizeof(linkpath));
+		if (len <= 0) {
+			err("unable to readlink '%s': %s", path, strerror(errno));
+			return 1;
+		}
+		linkpath[len] = '\0';
+		dbg("link is '%s'", linkpath);
+
+		lptr = linkpath;
+		for (;;) {
+			char *ptr;
+
+			ptr = strrchr(subpath, '/');
+			if (ptr)
+				*ptr = '\0';
+			else
+				subpath[0] = '\0';
+
+			if (!*lptr || strncmp(lptr, "../", 3))
+				break;
+			lptr += 3;
+		}
+		strlcat(subpath, "/", sizeof(subpath));
+		strlcat(subpath, lptr, sizeof(subpath));
+		dbg("link points to '%s'", subpath);
+
+		follow_links = 0;
+
+	} else if (S_ISDIR(statbuf.st_mode)) {
+		dbg("subdir '%s'", subpath);
+		if (follow_links)
+			follow_links--;
+
+	} else {
+		return 1;
+	}
+
+	if (has_uevent(subpath))
+		add_device(subpath, device_list);
+
+	return recurse_subtree(subpath, device_list, follow_links);
+}
+
+/* recurse a tree adding anything that looks like a device */
+static int recurse_subtree(const char *path, struct list_head *device_list, int follow_links)
+{
+	struct dirent *dent;
+	DIR *dp;
+
+	dbg("tree: '%s'", path);
+	dp = opendir(path);
+	if (!dp) {
+		info("unable to open tree: '%s': %s", path, strerror(errno));
+		return 1;
+	}
+
+	while ((dent = readdir(dp))) {
+		char subpath[PATH_SIZE];
+
+		if (dent->d_name[0] == '.')
+			continue;
+
+		snprintf(subpath, sizeof(subpath), "%s/%s", path, dent->d_name);
+		visit_entry(subpath, device_list, follow_links);
+	}
+
+	closedir(dp);
+
+	return 0;
+}
+
+/* recurse a tree adding anything that looks like a device */
+static int recurse_tree(const char *path, struct list_head *device_list)
+{
+	char tmppath[PATH_SIZE];
+	const char *syspath;
+
+	if (strncmp(path, sysfs_path, strlen(sysfs_path)) != 0) {
+		strlcpy(tmppath, sysfs_path, sizeof(tmppath));
+		if (path[0] != '/')
+			strlcat(tmppath, "/", sizeof(tmppath));
+		strlcat(tmppath, path, sizeof(tmppath));
+		syspath = tmppath;
+	} else {
+		syspath = path;
+	}
+
+	dbg("recurse: '%s'", syspath);
+	return visit_entry(syspath, device_list, 1);
+}
+
+
+/* scan the given bus for all devices */
+static int scan_bus(const char *name, struct list_head *device_list)
+{
+	char path[PATH_SIZE];
+
+	strlcpy(path, sysfs_path, sizeof(path));
+	strlcat(path, "/bus/", sizeof(path));
+	strlcat(path, name, sizeof(path));
+	strlcat(path, "/devices", sizeof(path));
+
+	return recurse_subtree(path, device_list, 1);
+}
+
+/* scan the given class for all devices */
+static int scan_class(const char *name, struct list_head *device_list)
+{
+	char path[PATH_SIZE];
+
+	strlcpy(path, sysfs_path, sizeof(path));
+	strlcat(path, "/class/", sizeof(path));
+	strlcat(path, name, sizeof(path));
+
+	return recurse_subtree(path, device_list, 1);
+}
+
+/* scan all of the class devices */
+static int scan_class_tree(struct list_head *device_list)
+{
+	char path[PATH_SIZE];
+
+	strlcpy(path, sysfs_path, sizeof(path));
+	strlcat(path, "/class", sizeof(path));
+
+	return recurse_subtree(path, device_list, 2);
+}
+
+/* scan all of the block devices */
+static int scan_block_tree(struct list_head *device_list)
+{
+	char path[PATH_SIZE];
+
+	strlcpy(path, sysfs_path, sizeof(path));
+	strlcat(path, "/block", sizeof(path));
+
+	return recurse_subtree(path, device_list, 2);
+}
+
+/* scan all of the separated devices */
+static int scan_device_tree(struct list_head *device_list)
+{
+	char path[PATH_SIZE];
+
+	strlcpy(path, sysfs_path, sizeof(path));
+	strlcat(path, "/devices", sizeof(path));
+
+	return recurse_subtree(path, device_list, 0);
+}
+
+/* scan the failed queue for symlinks and queue them */
+static int scan_failed(struct list_head *device_list)
+{
+	char failed[PATH_SIZE];
+
+	strlcpy(failed, udev_root, sizeof(failed));
+	strlcat(failed, "/", sizeof(failed));
+	strlcat(failed, EVENT_FAILED_DIR, sizeof(failed));
+
+	dbg("directory: '%s'", failed);
+	return recurse_subtree(failed, device_list, 1);
+}
+
+
+/* make the queue directory after waiting for it to go away
+ * (provides some kind of synchrony to the process) */
+static int make_queue(void)
+{
+	char queue[PATH_SIZE];
+	int first = 1;
+
+	strlcpy(queue, udev_root, sizeof(queue));
+	strlcat(queue, "/", sizeof(queue));
+	strlcat(queue, EVENT_QUEUE_DIR, sizeof(queue));
+
+	dbg("directory: '%s'", queue);
+
+	if (create_path(queue)) {
+		err("unable to create %s: %s", queue, strerror(errno));
+		return 1;
+	}
+
+	while (mkdir(queue, 0755)) {
+		if (errno != EEXIST) {
+			err("unable to create %s: %s", queue, strerror(errno));
+			return 1;
+		}
+
+		if (first) {
+			dbg("waiting for queue to become empty first");
+			first = 0;
+		}
+
+		usleep(10000);
+	}
+
+	return 0;
+}
+
+/* wait for the queue directory to go away */
+static void wait_for_queue(void)
+{
+	struct stat statbuf;
+	char queue[PATH_SIZE];
+
+	strlcpy(queue, udev_root, sizeof(queue));
+	strlcat(queue, "/", sizeof(queue));
+	strlcat(queue, EVENT_QUEUE_DIR, sizeof(queue));
+
+	dbg("directory: '%s'", queue);
+
+	for (;;) {
+		if (stat(queue, &statbuf)) {
+			if (errno != ENOENT)
+				err("unable to stat %s: %s", queue,
+				    strerror(errno));
+			break;
+		}
+
+		usleep(10000);
+	}
+}
+
+
+static void asmlinkage sig_handler(int signum)
+{
+	switch (signum) {
+	case SIGALRM:
+		exit(1);
+	case SIGINT:
+	case SIGTERM:
+		exit(20 + signum);
+	}
+}
+
+int main(int argc, char *argv[])
+{
+	LIST_HEAD(device_list);
+	LIST_HEAD(filter_list);
+	struct sigaction act;
+	int args = 0, wait_only = 0, ret = 0;
+	int i;
+
+	logging_init("udevplug");
+	udev_init_config();
+	dbg("version %s", UDEV_VERSION);
+
+	/* set signal handlers */
+	memset(&act, 0, sizeof(act));
+	act.sa_handler = (void (*) (int))sig_handler;
+	sigemptyset (&act.sa_mask);
+	act.sa_flags = 0;
+	sigaction(SIGALRM, &act, NULL);
+	sigaction(SIGINT, &act, NULL);
+	sigaction(SIGTERM, &act, NULL);
+
+	/* trigger timeout to prevent hanging processes */
+	alarm(UDEV_ALARM_TIMEOUT);
+
+	for (i = 1; i < argc; i++) {
+		char *arg = argv[i];
+
+		args++;
+		if (strcmp(arg, "-W") == 0) {
+			wait_only = 1;
+
+		} else if (strcmp(arg, "-F") == 0) {
+			scan_failed(&device_list);
+
+		} else if (strcmp(arg, "-c") == 0) {
+			scan_class_tree(&device_list);
+
+		} else if (strcmp(arg, "-b") == 0) {
+			scan_block_tree(&device_list);
+
+		} else if (strcmp(arg, "-v") == 0) {
+			args--;
+			verbose = 1;
+
+		} else if (arg[0] == '-') {
+			char *varg;
+
+			if (arg[2] != '\0') {
+				varg = &arg[2];
+			} else if (++i < argc) {
+				varg = argv[i];
+			} else {
+				args--;
+				continue;
+			}
+
+			switch (arg[1]) {
+			case 'I':
+				filter_list_insert(1, varg, &filter_list);
+				break;
+			case 'X':
+				filter_list_insert(0, varg, &filter_list);
+				break;
+			case 'B':
+				scan_bus(varg, &device_list);
+				break;
+			case 'C':
+				scan_class(varg, &device_list);
+				break;
+			}
+
+		} else {
+			recurse_tree(arg, &device_list);
+		}
+	}
+
+	if (!args) {
+		scan_class_tree(&device_list);
+		scan_block_tree(&device_list);
+		scan_device_tree(&device_list);
+	}
+
+	if (wait_only) {
+		wait_for_queue();
+		goto exit;
+	} else if (list_empty(&device_list))
+		goto exit;
+
+	make_queue();
+	exec_list(&device_list, &filter_list);
+	wait_for_queue();
+
+exit:
+	logging_close();
+	return ret;
+}

[-- Attachment #1.6: 50-result-whitespace.patch --]
[-- Type: text/x-patch, Size: 765 bytes --]

diff -ruNp udev-075~/udev_utils_string.c udev-075/udev_utils_string.c
--- udev-075~/udev_utils_string.c	2005-11-10 01:20:25.000000000 +0000
+++ udev-075/udev_utils_string.c	2005-11-22 17:32:33.305884816 +0000
@@ -245,10 +245,17 @@ int replace_untrusted_chars(char *str)
 		if ((str[i] >= '0' && str[i] <= '9') ||
 		    (str[i] >= 'A' && str[i] <= 'Z') ||
 		    (str[i] >= 'a' && str[i] <= 'z') ||
-		    strchr(" #$%+-./:=?@_", str[i])) {
+		    strchr("#$%+-./:=?@_", str[i])) {
 			i++;
 			continue;
 		}
+		/* whitespace replaced with ordinary space */
+		if (isspace(str[i])) {
+			str[i] = ' ';
+			i++;
+			replaced++;
+			continue;
+		}
 		/* valid utf8 is accepted */
 		len = utf8_encoded_valid_unichar(&str[i]);
 		if (len > 1) {

[-- Attachment #1.7: 55-run-program.patch --]
[-- Type: text/x-patch, Size: 743 bytes --]

diff -ruNp udev-077~/udev_utils_run.c udev-077/udev_utils_run.c
--- udev-077~/udev_utils_run.c	2005-12-04 02:01:48.000000000 +0000
+++ udev-077/udev_utils_run.c	2005-12-05 17:13:09.030804750 +0000
@@ -160,8 +160,13 @@ int run_program(const char *command, con
 			dup2(errpipe[WRITE_END], STDERR_FILENO);
 		execv(argv[0], argv);
 
-		/* we should never reach this */
-		err("exec of program '%s' failed", argv[0]);
+		if ((errno == ENOENT) || (errno = ENOTDIR)) {
+			/* will probably turn up later */
+			info("program '%s' not found", argv[0]);
+		} else {
+			/* bigger problems */
+			err("exec of program '%s' failed", argv[0]);
+		}
 		_exit(1);
 	case -1:
 		err("fork of '%s' failed: %s", argv[0], strerror(errno));

[-- Attachment #1.8: 60-firmware-hunt.patch --]
[-- Type: text/x-patch, Size: 3200 bytes --]

diff -ruNp udev-076~/extras/firmware/firmware_helper.c udev-076/extras/firmware/firmware_helper.c
--- udev-076~/extras/firmware/firmware_helper.c	2005-11-22 16:34:55.000000000 +0000
+++ udev-076/extras/firmware/firmware_helper.c	2005-11-23 14:16:31.533149568 +0000
@@ -16,11 +16,11 @@
 #include <syslog.h>
 #include <unistd.h>
 #include <sys/stat.h>
+#include <sys/utsname.h>
 
 #include "../../udev_utils.h"
 #include "../../logging.h"
 
-#define FIRMWARE_PATH			"/lib/firmware"
 #define PATH_SIZE			256
 
 #ifdef USE_LOG
@@ -74,10 +74,12 @@ int main(int argc, char **argv) {
 	char *devpath, *firmware, *action, *driver;
 	char fw_path[PATH_SIZE];
 	char data_path[PATH_SIZE];
+	struct utsname utsbuf;
 	int fw_fd;
 	char *fw_buffer;
 	size_t fw_buffer_size;
 	size_t count;
+	int i, loaded = 0;
 	int rc = 0;
 
 	logging_init("firmware_helper");
@@ -93,42 +95,67 @@ int main(int argc, char **argv) {
 		exit(1);
 	}
 
+	if (uname(&utsbuf)) {
+		err("unable to get kernel version");
+		exit(1);
+	}
+
 	dbg("try to load firmware '%s' for '%s'", firmware, devpath);
 	set_loading(devpath, 1);
 
-	snprintf(fw_path, sizeof(fw_path), "%s/%s", FIRMWARE_PATH, firmware);
-	fw_path[sizeof(fw_path)-1] = '\0';
-	if (file_map(fw_path, &fw_buffer, &fw_buffer_size) != 0 || fw_buffer_size == 0) {
-		err("could not load firmware '%s' for '%s'", fw_path, devpath);
-		fw_buffer = NULL;
-		goto out_err;
-	}
-
-	snprintf(data_path, sizeof(data_path), "/sys/%s/data", devpath);
-	data_path[sizeof(data_path)-1] = '\0';
-	fw_fd = open(data_path, O_RDWR);
-	if (fw_fd < 0) {
-		rc = errno;
-		goto out_err;
-	}
+	for (i = 0; i < 2; i++) {
+		switch (i) {
+		case 0: /* /lib/firmware/$VERSION/$FIRMWARE */
+			snprintf(fw_path, sizeof(fw_path),
+				 "/lib/firmware/%s/%s", utsbuf.release,
+				 firmware);
+			break;
+		case 1: /* /lib/firmware/$FIRMWARE */
+			snprintf(fw_path, sizeof(fw_path),
+				 "/lib/firmware/%s", firmware);
+			break;
+		}
+		fw_path[sizeof(fw_path)-1] = '\0';
 
-	count = 0;
-	while (count < fw_buffer_size) {
-		ssize_t c;
+		dbg("looking for firmware at '%s'", fw_path);
+		if (file_map(fw_path, &fw_buffer, &fw_buffer_size) != 0 || fw_buffer_size == 0) {
+			fw_buffer = NULL;
+			continue;
+		}
 
-		c = write(fw_fd, fw_buffer+count, fw_buffer_size-count);
-		if (c <= 0) {
+		dbg("firmware found");
+		snprintf(data_path, sizeof(data_path), "/sys/%s/data", devpath);
+		data_path[sizeof(data_path)-1] = '\0';
+		fw_fd = open(data_path, O_RDWR);
+		if (fw_fd < 0) {
 			rc = errno;
-			close(fw_fd);
 			goto out_err;
 		}
-		count += c;
+
+		count = 0;
+		while (count < fw_buffer_size) {
+			ssize_t c;
+
+			c = write(fw_fd, fw_buffer+count, fw_buffer_size-count);
+			if (c <= 0) {
+				rc = errno;
+				close(fw_fd);
+				goto out_err;
+			}
+			count += c;
+		}
+
+		close(fw_fd);
+		file_unmap(fw_buffer, fw_buffer_size);
+		loaded = 1;
 	}
 
-	close(fw_fd);
-	file_unmap(fw_buffer, fw_buffer_size);
+	if (!loaded)
+		goto out_err;
+
 	set_loading(devpath, 0);
 	info("loaded '%s' for device '%s'", fw_path, devpath);
+
 	logging_close();
 	return 0;
 

[-- Attachment #1.9: 80-extras-dvb_device_name.patch --]
[-- Type: text/x-patch, Size: 5763 bytes --]

diff -ruNp udev-076~/extras/dvb_device_name/Makefile udev-076/extras/dvb_device_name/Makefile
--- udev-076~/extras/dvb_device_name/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ udev-076/extras/dvb_device_name/Makefile	2005-11-24 19:24:32.674076208 +0000
@@ -0,0 +1,66 @@
+# Copyright © 2005 Canonical Ltd.
+# Author: Scott James Remnant <scott@ubuntu.com>
+#
+# Released under the GNU General Public License, version 2.
+
+PROG = dvb_device_name
+OBJ =
+HEADERS =
+GEN_HEADERS =
+MAN_PAGES =
+
+prefix =
+etcdir =	${prefix}/etc
+sbindir =	${prefix}/sbin
+usrbindir =	${prefix}/usr/bin
+usrsbindir =	${prefix}/usr/sbin
+libudevdir =	${prefix}/lib/udev
+mandir =	${prefix}/usr/share/man
+configdir =	${etcdir}/udev/
+
+INSTALL = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_DATA  = ${INSTALL} -m 644
+INSTALL_SCRIPT = ${INSTALL_PROGRAM}
+
+all: $(PROG) $(MAN_PAGES)
+.PHONY: all
+.DEFAULT: all
+
+%.o: %.c $(GEN_HEADERS)
+	$(QUIET) $(CC) -c $(CFLAGS) $< -o $@
+
+$(PROG): %: $(HEADERS) %.o $(OBJS)
+	$(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS)
+ifneq ($(strip $(STRIPCMD)),)
+	$(QUIET) $(STRIPCMD) $@
+endif
+
+# man pages
+%.8: %.xml
+	xmlto man $?
+.PRECIOUS: %.8
+
+clean:
+	rm -f $(PROG) $(OBJS) $(GEN_HEADERS)
+.PHONY: clean
+
+install-bin: all
+	$(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(libudevdir)/$(PROG)
+.PHONY: install-bin
+
+uninstall-bin:
+	- rm $(DESTDIR)$(libudevdir)/$(PROG)
+.PHONY: uninstall-bin
+
+install-man:
+	$(INSTALL_DATA) -D $(PROG).8 $(DESTDIR)$(mandir)/man8/$(PROG).8
+.PHONY: uninstall-man
+
+uninstall-man:
+	-rm -f $(DESTDIR)$(mandir)/man8/$(PROG).8
+.PHONY: uninstall-man
+
+install-config:
+	@echo "no config file to install"
+.PHONY: install-config
diff -ruNp udev-076~/extras/dvb_device_name/dvb_device_name.8 udev-076/extras/dvb_device_name/dvb_device_name.8
--- udev-076~/extras/dvb_device_name/dvb_device_name.8	1970-01-01 01:00:00.000000000 +0100
+++ udev-076/extras/dvb_device_name/dvb_device_name.8	2005-11-24 19:24:32.674076208 +0000
@@ -0,0 +1,28 @@
+.TH DVB_DEVICE_NAME 8 "November 2005" "" "Linux Administrator's Manual"
+.SH NAME
+dvb_device_name \- udev callout to split kernel name for dvb devices
+.SH SYNOPSIS
+.BI dvb_device_name
+[\fI--export\fP] \fIdevicename\fP
+.SH DESCRIPTION
+.B dvb_device_name
+is normally called from a udev rule to split the kernel-assigned name for a
+device in the dvb_device subsystem into bus and device numbers.  Udev can use
+this information to construct a name under /dev/dvb for the real device
+node.
+.SH USAGE
+.B dvb_device_name
+splits the kernel-assigned name specified on the command-line and prints the
+information chosen by the options.
+.SH OPTIONS
+The following command-line switches are supported to specify what
+dvb_device_name should print:
+.TP
+.BI --export
+print bus and device numbers as DVB_ADAPTER and DVB_DEV environment variables,
+for use with an IMPORT{program} rule.
+.RE
+.SH SEE ALSO
+.BR udev (8)
+.SH AUTHORS
+Scott James Remnant <scott@ubuntu.com>
diff -ruNp udev-076~/extras/dvb_device_name/dvb_device_name.c udev-076/extras/dvb_device_name/dvb_device_name.c
--- udev-076~/extras/dvb_device_name/dvb_device_name.c	1970-01-01 01:00:00.000000000 +0100
+++ udev-076/extras/dvb_device_name/dvb_device_name.c	2005-11-24 20:03:03.648916750 +0000
@@ -0,0 +1,103 @@
+/*
+ * dvb_device_name - splits kernel name for dvb_device subsystem
+ *
+ * Copyright © 2005 Canonical Ltd.
+ * Author: Scott James Remnant <scott@ubuntu.com>
+ *
+ *	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.,
+ *	51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../../logging.h"
+#include "../../udev_utils.h"
+
+#ifdef USE_LOG
+void log_message(int priority, const char *format, ...)
+{
+	va_list args;
+	static int udev_log = -1;
+
+	if (udev_log == -1) {
+		const char *value;
+
+		value = getenv("UDEV_LOG");
+		if (value)
+			udev_log = log_priority(value);
+		else
+			udev_log = LOG_ERR;
+	}
+
+	if (priority > udev_log)
+		return;
+
+	va_start(args, format);
+	vsyslog(priority, format, args);
+	va_end(args);
+}
+#endif
+
+int main(int argc, char *argv[])
+{
+	const char *name = NULL, *ptr;
+	int export = 0, ret = 0;
+	int i, bus, dev;
+
+	logging_init("dvb_device_name");
+
+	for (i = 1; i < argc; i++) {
+		if (strcmp (argv[i], "--export") == 0) {
+			export = 1;
+		} else {
+			name = argv[i];
+		}
+	}
+
+	if (!name) {
+		err("no device name specified");
+		ret = 1;
+		goto exit;
+	}
+
+	if (strncmp(name, "dvb", 3) != 0) {
+		info("device not dvb_device");
+		ret = 1;
+		goto exit;
+	}
+
+	ptr = strchr(name, '.');
+	if (!ptr) {
+		err("device name contains no device");
+		ret = 1;
+		goto exit;
+	}
+
+	name += 6;
+	bus = atoi(name);
+	dev = atoi(ptr + 1);
+
+	if (export) {
+		printf("DVB_ADAPTER=%d\n", bus);
+		printf("DVB_DEV=%d\n", dev);
+	} else {
+		printf("%d.%d\n", bus, dev);
+	}
+
+exit:
+	logging_close();
+	return ret;
+}

[-- Attachment #1.10: 80-extras-ide_media.patch --]
[-- Type: text/x-patch, Size: 6728 bytes --]

diff -ruNp udev-076~/extras/ide_media/Makefile udev-076/extras/ide_media/Makefile
--- udev-076~/extras/ide_media/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ udev-076/extras/ide_media/Makefile	2005-11-24 20:14:02.598098500 +0000
@@ -0,0 +1,66 @@
+# Copyright © 2005 Canonical Ltd.
+# Author: Scott James Remnant <scott@ubuntu.com>
+#
+# Released under the GNU General Public License, version 2.
+
+PROG = ide_media
+OBJ =
+HEADERS =
+GEN_HEADERS =
+MAN_PAGES =
+
+prefix =
+etcdir =	${prefix}/etc
+sbindir =	${prefix}/sbin
+usrbindir =	${prefix}/usr/bin
+usrsbindir =	${prefix}/usr/sbin
+libudevdir =	${prefix}/lib/udev
+mandir =	${prefix}/usr/share/man
+configdir =	${etcdir}/udev/
+
+INSTALL = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_DATA  = ${INSTALL} -m 644
+INSTALL_SCRIPT = ${INSTALL_PROGRAM}
+
+all: $(PROG) $(MAN_PAGES)
+.PHONY: all
+.DEFAULT: all
+
+%.o: %.c $(GEN_HEADERS)
+	$(QUIET) $(CC) -c $(CFLAGS) $< -o $@
+
+$(PROG): %: $(HEADERS) %.o $(OBJS)
+	$(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS)
+ifneq ($(strip $(STRIPCMD)),)
+	$(QUIET) $(STRIPCMD) $@
+endif
+
+# man pages
+%.8: %.xml
+	xmlto man $?
+.PRECIOUS: %.8
+
+clean:
+	rm -f $(PROG) $(OBJS) $(GEN_HEADERS)
+.PHONY: clean
+
+install-bin: all
+	$(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(libudevdir)/$(PROG)
+.PHONY: install-bin
+
+uninstall-bin:
+	- rm $(DESTDIR)$(libudevdir)/$(PROG)
+.PHONY: uninstall-bin
+
+install-man:
+	$(INSTALL_DATA) -D $(PROG).8 $(DESTDIR)$(mandir)/man8/$(PROG).8
+.PHONY: uninstall-man
+
+uninstall-man:
+	-rm -f $(DESTDIR)$(mandir)/man8/$(PROG).8
+.PHONY: uninstall-man
+
+install-config:
+	@echo "no config file to install"
+.PHONY: install-config
diff -ruNp udev-076~/extras/ide_media/ide_media.8 udev-076/extras/ide_media/ide_media.8
--- udev-076~/extras/ide_media/ide_media.8	1970-01-01 01:00:00.000000000 +0100
+++ udev-076/extras/ide_media/ide_media.8	2005-11-24 20:14:02.598098500 +0000
@@ -0,0 +1,29 @@
+.TH IDE_MEDIA 8 "November 2005" "" "Linux Administrator's Manual"
+.SH NAME
+ide_media \- udev callout to identify media of IDE device
+.SH SYNOPSIS
+.BI ide_media
+[\fI--export\fP] \fIdevpath\fP
+.SH DESCRIPTION
+.B ide_media
+is normally called from a udev rule to identify the media type of an IDE
+device.  Udev can use this information to assign appropriate permissions to
+the device or load an appropriate module.
+.SH USAGE
+.B ide_media
+takes a path under /sys, if not given it uses the value of the
+.I DEVPATH
+environment variable instead.  It then prints the information chosen by the
+options.
+.SH OPTIONS
+The following command-line switches are supported to specify what
+ide_media should print:
+.TP
+.BI --export
+print media type as IDE_MEDIA environment variable for use with an
+IMPORT{program} rule.
+.RE
+.SH SEE ALSO
+.BR udev (8)
+.SH AUTHORS
+Scott James Remnant <scott@ubuntu.com>
diff -ruNp udev-076~/extras/ide_media/ide_media.c udev-076/extras/ide_media/ide_media.c
--- udev-076~/extras/ide_media/ide_media.c	1970-01-01 01:00:00.000000000 +0100
+++ udev-076/extras/ide_media/ide_media.c	2005-11-24 20:55:08.466927750 +0000
@@ -0,0 +1,155 @@
+/*
+ * ide_media - identify media type of an IDE device
+ *
+ * Copyright © 2005 Canonical Ltd.
+ * Author: Scott James Remnant <scott@ubuntu.com>
+ *
+ *	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.,
+ *	51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include "../../logging.h"
+#include "../../udev_utils.h"
+#include "../../udev_libc_wrapper.h"
+
+#ifdef USE_LOG
+void log_message(int priority, const char *format, ...)
+{
+	va_list args;
+	static int udev_log = -1;
+
+	if (udev_log == -1) {
+		const char *value;
+
+		value = getenv("UDEV_LOG");
+		if (value)
+			udev_log = log_priority(value);
+		else
+			udev_log = LOG_ERR;
+	}
+
+	if (priority > udev_log)
+		return;
+
+	va_start(args, format);
+	vsyslog(priority, format, args);
+	va_end(args);
+}
+#endif
+
+int main(int argc, char *argv[])
+{
+	struct stat buf;
+	const char *devpath = NULL, *name, *ptr;
+	char filename[PATH_SIZE], media[256];
+	int ret = 0, export = 0;
+	int host, drive, dev;
+	int i, fd, len;
+
+	logging_init("ide_media");
+
+	for (i = 1; i < argc; i++) {
+		if (strcmp(argv[i], "--export") == 0) {
+			export = 1;
+		} else {
+			devpath = argv[i];
+		}
+	}
+
+	if (!devpath) {
+		devpath = getenv("DEVPATH");
+		if (!devpath) {
+			err("no devpath specified and DEVPATH not set");
+			ret = 1;
+			goto exit;
+		}
+	}
+
+	name = strstr(devpath, "/ide");
+	if (name)
+		name = strchr(name + 1, '/');
+	if (!name) {
+		info("devpath is not ide device");
+		ret = 1;
+		goto exit;
+	}
+
+	ptr = strchr(name, '.');
+	if (!ptr) {
+		err("device name contains no drive");
+		ret = 1;
+		goto exit;
+	}
+
+	name += 1;
+	host = atoi(name);
+	drive = atoi(ptr + 1);
+
+	/* evil, evil, evil */
+	dev = drive + host * 2 + 10;
+
+	snprintf(filename, sizeof(filename), "/proc/ide/ide%d/hd%x/media", host, dev);
+	filename[sizeof(filename)-1] = '\0';
+
+	/* hang around for /proc to catch up */
+	for (i = 100; i; i--) {
+		if (stat(filename, &buf) == 0)
+			break;
+
+		usleep(30000);
+	}
+
+	fd = open(filename, O_RDONLY);
+	if (!fd) {
+		err("unable to open '%s'", filename);
+		ret = 1;
+		goto exit;
+	}
+
+	len = read(fd, media, sizeof(media));
+	if (len <= 0) {
+		err("unable to read from '%s'", filename);
+		ret = 1;
+		goto close;
+	}
+
+	media[len] = '\0';
+	if (media[len-1] == '\n')
+		media[len-1] = '\0';
+
+	if (export) {
+		printf("IDE_HOST=%d\n", host);
+		printf("IDE_DRIVE=%d\n", drive);
+		printf("IDE_DEVICE=hd%x\n", dev);
+		printf("IDE_MEDIA=%s\n", media);
+	} else {
+		printf("%s\n", media);
+	}
+
+close:
+	close(fd);
+exit:
+	logging_close();
+	return ret;
+}

[-- Attachment #1.11: 80-extras-pnp_modules.patch --]
[-- Type: text/x-patch, Size: 5695 bytes --]

diff -ruNp udev-076~/extras/pnp_modules/Makefile udev-076/extras/pnp_modules/Makefile
--- udev-076~/extras/pnp_modules/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ udev-076/extras/pnp_modules/Makefile	2005-12-01 01:15:52.315553750 +0000
@@ -0,0 +1,66 @@
+# Copyright © 2005 Canonical Ltd.
+# Author: Scott James Remnant <scott@ubuntu.com>
+#
+# Released under the GNU General Public License, version 2.
+
+PROG = pnp_modules
+OBJ =
+HEADERS =
+GEN_HEADERS =
+MAN_PAGES =
+
+prefix =
+etcdir =	${prefix}/etc
+sbindir =	${prefix}/sbin
+usrbindir =	${prefix}/usr/bin
+usrsbindir =	${prefix}/usr/sbin
+libudevdir =	${prefix}/lib/udev
+mandir =	${prefix}/usr/share/man
+configdir =	${etcdir}/udev/
+
+INSTALL = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_DATA  = ${INSTALL} -m 644
+INSTALL_SCRIPT = ${INSTALL_PROGRAM}
+
+all: $(PROG) $(MAN_PAGES)
+.PHONY: all
+.DEFAULT: all
+
+%.o: %.c $(GEN_HEADERS)
+	$(QUIET) $(CC) -c $(CFLAGS) $< -o $@
+
+$(PROG): %: $(HEADERS) %.o $(OBJS)
+	$(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS)
+ifneq ($(strip $(STRIPCMD)),)
+	$(QUIET) $(STRIPCMD) $@
+endif
+
+# man pages
+%.8: %.xml
+	xmlto man $?
+.PRECIOUS: %.8
+
+clean:
+	rm -f $(PROG) $(OBJS) $(GEN_HEADERS)
+.PHONY: clean
+
+install-bin: all
+	$(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(libudevdir)/$(PROG)
+.PHONY: install-bin
+
+uninstall-bin:
+	- rm $(DESTDIR)$(libudevdir)/$(PROG)
+.PHONY: uninstall-bin
+
+install-man:
+	$(INSTALL_DATA) -D $(PROG).8 $(DESTDIR)$(mandir)/man8/$(PROG).8
+.PHONY: uninstall-man
+
+uninstall-man:
+	-rm -f $(DESTDIR)$(mandir)/man8/$(PROG).8
+.PHONY: uninstall-man
+
+install-config:
+	@echo "no config file to install"
+.PHONY: install-config
diff -ruNp udev-076~/extras/pnp_modules/pnp_modules.8 udev-076/extras/pnp_modules/pnp_modules.8
--- udev-076~/extras/pnp_modules/pnp_modules.8	1970-01-01 01:00:00.000000000 +0100
+++ udev-076/extras/pnp_modules/pnp_modules.8	2005-12-01 01:15:52.315553750 +0000
@@ -0,0 +1,22 @@
+.TH PNP_MODULES 8 "November 2005" "" "Linux Administrator's Manual"
+.SH NAME
+pnp_modules \- udev callout to list modules for PNP devices
+.SH SYNOPSIS
+.BI pnp_modules
+\fIdevpath\fP
+.SH DESCRIPTION
+.B ide_media
+is normally called from a udev PROGRAM rule to list aliases that can be
+used to load modules for PNP devices.
+.SH USAGE
+.B pnp_modules
+takes a single argument which should be a path under /sys, if not given
+it uses the value of the
+.I DEVPATH
+environment variable instead.  Outputs a list of modprobe aliases that
+can be used to load modules, e.g. with a RUN rule.
+.RE
+.SH SEE ALSO
+.BR udev (8)
+.SH AUTHORS
+Scott James Remnant <scott@ubuntu.com>
diff -ruNp udev-076~/extras/pnp_modules/pnp_modules.c udev-076/extras/pnp_modules/pnp_modules.c
--- udev-076~/extras/pnp_modules/pnp_modules.c	1970-01-01 01:00:00.000000000 +0100
+++ udev-076/extras/pnp_modules/pnp_modules.c	2005-12-01 13:21:32.696657500 +0000
@@ -0,0 +1,111 @@
+/*
+ * pnp_modules - list modules for PNP devices
+ *
+ * Copyright © 2005 Canonical Ltd.
+ * Author: Scott James Remnant <scott@ubuntu.com>
+ *
+ *	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.,
+ *	51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include "../../logging.h"
+#include "../../udev_utils.h"
+#include "../../udev_libc_wrapper.h"
+
+#ifdef USE_LOG
+void log_message(int priority, const char *format, ...)
+{
+	va_list args;
+	static int udev_log = -1;
+
+	if (udev_log == -1) {
+		const char *value;
+
+		value = getenv("UDEV_LOG");
+		if (value)
+			udev_log = log_priority(value);
+		else
+			udev_log = LOG_ERR;
+	}
+
+	if (priority > udev_log)
+		return;
+
+	va_start(args, format);
+	vsyslog(priority, format, args);
+	va_end(args);
+}
+#endif
+
+int main(int argc, char *argv[])
+{
+	struct stat statbuf;
+	const char *devpath;
+	char filename[PATH_SIZE], line[256];
+	FILE *fp;
+	int ret = 0;
+
+	logging_init("pnp_modules");
+	udev_init_config();
+
+	if (argc > 1) {
+		devpath = argv[1];
+	} else {
+		devpath = getenv("DEVPATH");
+		if (!devpath) {
+			err("no devpath specified and DEVPATH not set");
+			ret = 1;
+			goto exit;
+		}
+	}
+
+	strlcpy(filename, sysfs_path, sizeof(filename));
+	strlcat(filename, devpath, sizeof(filename));
+
+	if (stat(filename, &statbuf) != 0) {
+		err("stat of '%s' failed", filename);
+		ret = 1;
+		goto exit;
+	}
+
+	strlcat(filename, "/", sizeof(filename));
+	strlcat(filename, "id", sizeof(filename));
+
+	fp = fopen(filename, "r");
+	if (!fp) {
+		err("can't open '%s': %s", filename, strerror(errno));
+		ret = 1;
+		goto exit;
+	}
+
+	while (fgets(line, sizeof(line), fp)) {
+		remove_trailing_chars(line, '\n');
+		printf("pnp:d%s\n", line);
+	}
+
+	fclose(fp);
+exit:
+	logging_close();
+	return ret;
+}

[-- Attachment #1.12: 80-extras-storage_enum.patch --]
[-- Type: text/x-patch, Size: 2335 bytes --]

--- udev-077~/extras/storage_enum.sh	1970-01-01 01:00:00.000000000 +0100
+++ udev-077/extras/storage_enum.sh	2005-12-06 19:49:08.656949250 +0000
@@ -0,0 +1,93 @@
+#!/bin/sh -e
+# storage_enum - enumerated storage devices
+#
+# Copyright © 2005 Canonical Ltd.
+# Author: Scott James Remnant <scott@ubuntu.com>
+#
+#	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.,
+#	51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+
+
+# Figure out what type of device we've been called for
+devname="$1"
+case "$devname" in
+    fd[0-9]*)
+        type=floppy
+	;;
+
+    sd[a-z])
+        type=disk
+	;;
+
+    sd[a-z][0-9]*)
+        type=partition
+        name=part${devname##sd[a-z]}
+	disk=${devname%%[0-9]*}
+	;;
+
+    sr[0-9]*)
+        type=cdrom
+	;;
+
+    hd[a-z])
+        type=$(/lib/udev/ide_media $PHYSDEVPATH)
+	;;
+
+    hd[a-z][0-9]*)
+        type=partition
+	name=part${devname##hd[a-z]}
+	disk=${devname%%[0-9]*}
+	;;
+
+    *)
+	exit 1
+	;;
+esac
+
+
+# Handle partitions, which don't need enumerating
+if [ "$type" = "partition" ]; then
+    subdir=$(sed -n -e "/^$disk /s/.* //p" /dev/.names)
+    echo "discs/$subdir/$name"
+    exit 0
+fi
+
+
+# Get the next number atomically, the only way we reliably can
+while ! mkdir /dev/.$type.lock 2>/dev/null; do
+    sleep 1
+done
+if [ -e /dev/.$type.next ]; then
+    enum=$(cat /dev/.$type.next)
+else
+    enum=0
+fi
+echo $(($enum + 1)) > /dev/.$type.next
+rmdir /dev/.$type.lock
+
+
+# Figure out the symlink name
+case "$type" in
+    disk)
+	echo "$devname disc$enum" >> /dev/.names
+	echo "discs/disc$enum/disc"
+	;;
+
+    cdrom)
+	echo "cdroms/cdrom$enum"
+	;;
+
+    floppy)
+	echo "floppy/$enum"
+	;;
+esac

[-- Attachment #1.13: 80-extras-usb_device_name.patch --]
[-- Type: text/x-patch, Size: 5769 bytes --]

diff -ruNp udev-076~/extras/usb_device_name/Makefile udev-076/extras/usb_device_name/Makefile
--- udev-076~/extras/usb_device_name/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ udev-076/extras/usb_device_name/Makefile	2005-11-24 19:24:32.682074992 +0000
@@ -0,0 +1,66 @@
+# Copyright © 2005 Canonical Ltd.
+# Author: Scott James Remnant <scott@ubuntu.com>
+#
+# Released under the GNU General Public License, version 2.
+
+PROG = usb_device_name
+OBJ =
+HEADERS =
+GEN_HEADERS =
+MAN_PAGES =
+
+prefix =
+etcdir =	${prefix}/etc
+sbindir =	${prefix}/sbin
+usrbindir =	${prefix}/usr/bin
+usrsbindir =	${prefix}/usr/sbin
+libudevdir =	${prefix}/lib/udev
+mandir =	${prefix}/usr/share/man
+configdir =	${etcdir}/udev/
+
+INSTALL = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_DATA  = ${INSTALL} -m 644
+INSTALL_SCRIPT = ${INSTALL_PROGRAM}
+
+all: $(PROG) $(MAN_PAGES)
+.PHONY: all
+.DEFAULT: all
+
+%.o: %.c $(GEN_HEADERS)
+	$(QUIET) $(CC) -c $(CFLAGS) $< -o $@
+
+$(PROG): %: $(HEADERS) %.o $(OBJS)
+	$(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS)
+ifneq ($(strip $(STRIPCMD)),)
+	$(QUIET) $(STRIPCMD) $@
+endif
+
+# man pages
+%.8: %.xml
+	xmlto man $?
+.PRECIOUS: %.8
+
+clean:
+	rm -f $(PROG) $(OBJS) $(GEN_HEADERS)
+.PHONY: clean
+
+install-bin: all
+	$(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(libudevdir)/$(PROG)
+.PHONY: install-bin
+
+uninstall-bin:
+	- rm $(DESTDIR)$(libudevdir)/$(PROG)
+.PHONY: uninstall-bin
+
+install-man:
+	$(INSTALL_DATA) -D $(PROG).8 $(DESTDIR)$(mandir)/man8/$(PROG).8
+.PHONY: uninstall-man
+
+uninstall-man:
+	-rm -f $(DESTDIR)$(mandir)/man8/$(PROG).8
+.PHONY: uninstall-man
+
+install-config:
+	@echo "no config file to install"
+.PHONY: install-config
diff -ruNp udev-076~/extras/usb_device_name/usb_device_name.8 udev-076/extras/usb_device_name/usb_device_name.8
--- udev-076~/extras/usb_device_name/usb_device_name.8	1970-01-01 01:00:00.000000000 +0100
+++ udev-076/extras/usb_device_name/usb_device_name.8	2005-11-24 19:24:32.683074840 +0000
@@ -0,0 +1,28 @@
+.TH USB_DEVICE_NAME 8 "November 2005" "" "Linux Administrator's Manual"
+.SH NAME
+usb_device_name \- udev callout to split kernel name for usb devices
+.SH SYNOPSIS
+.BI usb_device_name
+[\fI--export\fP] \fIdevicename\fP
+.SH DESCRIPTION
+.B usb_device_name
+is normally called from a udev rule to split the kernel-assigned name for a
+device in the usb_device subsystem into bus and device numbers.  Udev can use
+this information to construct a name under /dev/bus/usb for the real device
+node.
+.SH USAGE
+.B usb_device_name
+splits the kernel-assigned name specified on the command-line and prints the
+information chosen by the options.
+.SH OPTIONS
+The following command-line switches are supported to specify what
+usb_device_name should print:
+.TP
+.BI --export
+print bus and device numbers as USB_BUS and USB_DEV environment variables,
+for use with an IMPORT{program} rule.
+.RE
+.SH SEE ALSO
+.BR udev (8)
+.SH AUTHORS
+Scott James Remnant <scott@ubuntu.com>
diff -ruNp udev-076~/extras/usb_device_name/usb_device_name.c udev-076/extras/usb_device_name/usb_device_name.c
--- udev-076~/extras/usb_device_name/usb_device_name.c	1970-01-01 01:00:00.000000000 +0100
+++ udev-076/extras/usb_device_name/usb_device_name.c	2005-11-24 20:02:54.252329500 +0000
@@ -0,0 +1,103 @@
+/*
+ * usb_device_name - splits kernel name for usb_device subsystem
+ *
+ * Copyright © 2005 Canonical Ltd.
+ * Author: Scott James Remnant <scott@ubuntu.com>
+ *
+ *	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.,
+ *	51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../../logging.h"
+#include "../../udev_utils.h"
+
+#ifdef USE_LOG
+void log_message(int priority, const char *format, ...)
+{
+	va_list args;
+	static int udev_log = -1;
+
+	if (udev_log == -1) {
+		const char *value;
+
+		value = getenv("UDEV_LOG");
+		if (value)
+			udev_log = log_priority(value);
+		else
+			udev_log = LOG_ERR;
+	}
+
+	if (priority > udev_log)
+		return;
+
+	va_start(args, format);
+	vsyslog(priority, format, args);
+	va_end(args);
+}
+#endif
+
+int main(int argc, char *argv[])
+{
+	const char *name = NULL, *ptr;
+	int export = 0, ret = 0;
+	int i, bus, dev;
+
+	logging_init("usb_device_name");
+
+	for (i = 1; i < argc; i++) {
+		if (strcmp(argv[i], "--export") == 0) {
+			export = 1;
+		} else {
+			name = argv[i];
+		}
+	}
+
+	if (!name) {
+		err("no device name specified");
+		ret = 1;
+		goto exit;
+	}
+
+	if (strncmp(name, "usbdev", 6) != 0) {
+		info("device not usb_device");
+		ret = 1;
+		goto exit;
+	}
+
+	ptr = strchr(name, '.');
+	if (!ptr) {
+		err("device name contains no device");
+		ret = 1;
+		goto exit;
+	}
+
+	name += 6;
+	bus = atoi(name);
+	dev = atoi(ptr + 1);
+
+	if (export) {
+		printf("USB_BUS=%03d\n", bus);
+		printf("USB_DEV=%03d\n", dev);
+	} else {
+		printf("%03d.%03d\n", bus, dev);
+	}
+
+exit:
+	logging_close();
+	return ret;
+}

[-- Attachment #1.14: 80-extras-vio_type.patch --]
[-- Type: text/x-patch, Size: 6963 bytes --]

diff -ruNp udev-076~/extras/vio_type/Makefile udev-076/extras/vio_type/Makefile
--- udev-076~/extras/vio_type/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ udev-076/extras/vio_type/Makefile	2005-12-01 01:15:52.387558250 +0000
@@ -0,0 +1,66 @@
+# Copyright © 2005 Canonical Ltd.
+# Author: Scott James Remnant <scott@ubuntu.com>
+#
+# Released under the GNU General Public License, version 2.
+
+PROG = vio_type
+OBJ =
+HEADERS =
+GEN_HEADERS =
+MAN_PAGES =
+
+prefix =
+etcdir =	${prefix}/etc
+sbindir =	${prefix}/sbin
+usrbindir =	${prefix}/usr/bin
+usrsbindir =	${prefix}/usr/sbin
+libudevdir =	${prefix}/lib/udev
+mandir =	${prefix}/usr/share/man
+configdir =	${etcdir}/udev/
+
+INSTALL = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL}
+INSTALL_DATA  = ${INSTALL} -m 644
+INSTALL_SCRIPT = ${INSTALL_PROGRAM}
+
+all: $(PROG) $(MAN_PAGES)
+.PHONY: all
+.DEFAULT: all
+
+%.o: %.c $(GEN_HEADERS)
+	$(QUIET) $(CC) -c $(CFLAGS) $< -o $@
+
+$(PROG): %: $(HEADERS) %.o $(OBJS)
+	$(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS)
+ifneq ($(strip $(STRIPCMD)),)
+	$(QUIET) $(STRIPCMD) $@
+endif
+
+# man pages
+%.8: %.xml
+	xmlto man $?
+.PRECIOUS: %.8
+
+clean:
+	rm -f $(PROG) $(OBJS) $(GEN_HEADERS)
+.PHONY: clean
+
+install-bin: all
+	$(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(libudevdir)/$(PROG)
+.PHONY: install-bin
+
+uninstall-bin:
+	- rm $(DESTDIR)$(libudevdir)/$(PROG)
+.PHONY: uninstall-bin
+
+install-man:
+	$(INSTALL_DATA) -D $(PROG).8 $(DESTDIR)$(mandir)/man8/$(PROG).8
+.PHONY: uninstall-man
+
+uninstall-man:
+	-rm -f $(DESTDIR)$(mandir)/man8/$(PROG).8
+.PHONY: uninstall-man
+
+install-config:
+	@echo "no config file to install"
+.PHONY: install-config
diff -ruNp udev-076~/extras/vio_type/vio_type.8 udev-076/extras/vio_type/vio_type.8
--- udev-076~/extras/vio_type/vio_type.8	1970-01-01 01:00:00.000000000 +0100
+++ udev-076/extras/vio_type/vio_type.8	2005-12-01 01:15:52.387558250 +0000
@@ -0,0 +1,29 @@
+.TH VIO_TYPE 8 "November 2005" "" "Linux Administrator's Manual"
+.SH NAME
+vio_type \- udev callout to identify type of VIO device
+.SH SYNOPSIS
+.BI vio_type
+[\fI--export\fP] \fIdevpath\fP
+.SH DESCRIPTION
+.B vio_type
+is normally called from a udev rule to identify the type of a VIO
+device.  Udev can use this information to assign appropriate permissions to
+the device or load an appropriate module.
+.SH USAGE
+.B vio_type
+takes a path under /sys, if not given it uses the value of the
+.I DEVPATH
+environment variable instead.  It then prints the information chosen by the
+options.
+.SH OPTIONS
+The following command-line switches are supported to specify what
+vio_type should print:
+.TP
+.BI --export
+print device type as VIO_TYPE environment variable for use with an
+IMPORT{program} rule.
+.RE
+.SH SEE ALSO
+.BR udev (8)
+.SH AUTHORS
+Scott James Remnant <scott@ubuntu.com>
diff -ruNp udev-076~/extras/vio_type/vio_type.c udev-076/extras/vio_type/vio_type.c
--- udev-076~/extras/vio_type/vio_type.c	1970-01-01 01:00:00.000000000 +0100
+++ udev-076/extras/vio_type/vio_type.c	2005-12-01 01:15:52.387558250 +0000
@@ -0,0 +1,165 @@
+/*
+ * vio-type - identify type of a VIO device
+ *
+ * Copyright © 2005 Canonical Ltd.
+ * Author: Scott James Remnant <scott@ubuntu.com>
+ *
+ *	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.,
+ *	51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include "../../logging.h"
+#include "../../udev_utils.h"
+#include "../../udev_libc_wrapper.h"
+
+#ifdef USE_LOG
+void log_message(int priority, const char *format, ...)
+{
+	va_list args;
+	static int udev_log = -1;
+
+	if (udev_log == -1) {
+		const char *value;
+
+		value = getenv("UDEV_LOG");
+		if (value)
+			udev_log = log_priority(value);
+		else
+			udev_log = LOG_ERR;
+	}
+
+	if (priority > udev_log)
+		return;
+
+	va_start(args, format);
+	vsyslog(priority, format, args);
+	va_end(args);
+}
+#endif
+
+int main(int argc, char *argv[])
+{
+	struct stat buf;
+	const char *devpath = NULL;
+	char filename[PATH_SIZE], devspec[256], devtype[256];
+	int ret = 0, export = 0;
+	int i, fd, len;
+
+	logging_init("ide_media");
+
+	for (i = 1; i < argc; i++) {
+		if (strcmp(argv[i], "--export") == 0) {
+			export = 1;
+		} else {
+			devpath = argv[i];
+		}
+	}
+
+	if (!devpath) {
+		devpath = getenv("DEVPATH");
+		if (!devpath) {
+			err("no devpath specified and DEVPATH not set");
+			ret = 1;
+			goto exit;
+		}
+	}
+
+	strlcpy(filename, sysfs_path, sizeof(filename));
+	strlcat(filename, devpath, sizeof(filename));
+
+	if (stat(filename, &buf) != 0) {
+		err("stat of '%s' failed", filename);
+		ret = 1;
+		goto exit;
+	}
+
+	strlcat(filename, "/", sizeof(filename));
+	strlcat(filename, "devspec", sizeof(filename));
+
+	fd = open(filename, O_RDONLY);
+	if (!fd) {
+		err("unable to open '%s'", filename);
+		ret = 1;
+		goto exit;
+	}
+
+	len = read(fd, devspec, sizeof(devspec));
+	if (len <= 0) {
+		err("unable to read from '%s'", filename);
+		ret = 1;
+		goto close;
+	}
+
+	devspec[len] = '\0';
+	if (devspec[len-1] == '\n')
+		devspec[len-1] = '\0';
+
+	close(fd);
+
+
+	/* now we look in /proc */
+
+	strlcpy(filename, "/proc/device-tree", sizeof(filename));
+	strlcat(filename, devspec, sizeof(filename));
+	strlcat(filename, "/", sizeof(filename));
+	strlcat(filename, "device_type", sizeof(filename));
+
+	/* hang around for /proc to catch up */
+	for (i = 100; i; i--) {
+		if (stat(filename, &buf) == 0)
+			break;
+
+		usleep(30000);
+	}
+
+	fd = open(filename, O_RDONLY);
+	if (!fd) {
+		err("unable to open '%s'", filename);
+		ret = 1;
+		goto exit;
+	}
+
+	len = read(fd, devtype, sizeof(devtype));
+	if (len <= 0) {
+		err("unable to read from '%s'", filename);
+		ret = 1;
+		goto close;
+	}
+
+	devtype[len] = '\0';
+	if (devtype[len-1] == '\n')
+		devtype[len-1] = '\0';
+
+	if (export) {
+		printf("VIO_TYPE=%s\n", devtype);
+	} else {
+		printf("%s\n", devtype);
+	}
+
+close:
+	close(fd);
+exit:
+	logging_close();
+	return ret;
+}

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2005-12-08  1:50 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-12-07 17:12 [PATCH] The Ubuntu Collection Scott James Remnant
2005-12-07 22:37 ` Kay Sievers
2005-12-07 22:51 ` Marco d'Itri
2005-12-08  1:50 ` Scott James Remnant

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).