Sophie

Sophie

distrib > Mandriva > 2007.0 > x86_64 > media > main-testing-src > by-pkgid > 6420fb1965140a49881a9e5d13f8d582 > files > 9

udev-098-7mdv2007.0.src.rpm

--- udev-098/udevstart.c.coldplug	2006-08-22 19:32:25.000000000 -0400
+++ udev-098/udevstart.c	2006-09-17 09:05:48.000000000 -0400
@@ -132,17 +132,23 @@
 	udev->dev = dev;
 	strcpy(udev->action, "add");
 
+    if (strncmp(udev->dev->devpath, "/devices/", 9) == 0) {
+	udev_rules_get_run(&rules, udev);
+    } else {
 	if (strcmp(udev->dev->subsystem, "net") != 0) {
+	  if (strcmp(udev->dev->subsystem, "input") != 0 || sysfs_attr_get_value(devpath, "dev")) {
 		udev->devt = udev_device_get_devt(udev);
 		if (major(udev->devt) == 0)
 			return -1;
+	  }
 	}
+	udev_rules_get_name(&rules, udev);
+    }
 
 	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;
@@ -217,12 +223,12 @@
 	}
 }
 
-static int has_devt(const char *path)
+static int has_sysfs_key(const char *path, const char *key)
 {
 	char filename[PATH_SIZE];
 	struct stat statbuf;
 
-	snprintf(filename, sizeof(filename), "%s/dev", path);
+	snprintf(filename, sizeof(filename), "%s/%s", path, key);
 	filename[sizeof(filename)-1] = '\0';
 
 	if (stat(filename, &statbuf) == 0)
@@ -231,6 +237,11 @@
 	return 0;
 }
 
+static int has_devt(const char *path)
+{
+	return has_sysfs_key(path, "dev");
+}
+
 static void udev_scan_block(struct list_head *device_list)
 {
 	char base[PATH_SIZE];
@@ -312,7 +323,8 @@
 					snprintf(dirname2, sizeof(dirname2), "%s/%s", dirname, dent2->d_name);
 					dirname2[sizeof(dirname2)-1] = '\0';
 
-					if (has_devt(dirname2) || strcmp(dent->d_name, "net") == 0)
+					if (has_devt(dirname2) || strcmp(dent->d_name, "net") == 0 ||
+					    (strcmp(dent->d_name, "input") == 0 && has_sysfs_key(dirname2, "modalias")))
 						device_list_insert(dirname2, device_list);
 				}
 				closedir(dir2);
@@ -322,6 +334,43 @@
 	}
 }
 
+static void udev_scan_bus(struct list_head *device_list, char *bus, const char *sysfs_key)
+{
+	char base[PATH_SIZE];
+	DIR *dir;
+	struct dirent *dent;
+
+	snprintf(base, sizeof(base), "%s/bus/%s/devices", sysfs_path, bus);
+	base[sizeof(base)-1] = '\0';
+
+	dir = opendir(base);
+	if (dir != NULL) {
+		for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
+			char linkname[PATH_SIZE];
+			char dirname_short[PATH_SIZE];
+			char *dirname = NULL;
+
+			if (dent->d_name[0] == '.')
+				continue;
+
+			snprintf(linkname, sizeof(linkname), "%s/%s", base, dent->d_name);
+			linkname[sizeof(linkname)-1] = '\0';
+
+			if (has_sysfs_key(linkname, sysfs_key)) {
+				int ret = readlink(linkname, dirname_short, PATH_SIZE);
+				if (ret > 8) {
+					dirname_short[ret] = '\0';
+					/* replace ../../.. with /sys */
+					dirname = dirname_short + 4;
+					memcpy(dirname, "/sys", 4);
+					device_list_insert(dirname, device_list);
+				}
+			}
+		}
+		closedir(dir);
+	}
+}
+
 static void asmlinkage sig_handler(int signum)
 {
 	switch (signum) {
@@ -367,6 +416,9 @@
 
 	udev_scan_class(&device_list);
 	udev_scan_block(&device_list);
+ 	udev_scan_bus(&device_list, "pci", "modalias");
+ 	udev_scan_bus(&device_list, "scsi", "type");
+	udev_scan_bus(&device_list, "usb", "modalias");
 	exec_list(&device_list);
 
 	udev_rules_cleanup(&rules);