Damned. I was too hurry (too much job in same time!). Thanks for noticing.
Heres the correction.


2007/6/13, Mike Frysinger <[EMAIL PROTECTED]>:

On Monday 11 June 2007, Renaud Cerrato wrote:
> Here's the patch correcting mdev, using recursive_action :
>
> We noticed that some devices were not attached to /dev/ using "mdev -s".
> Looking at the source code, the function which walk through the /sys/
tree
> make use of lstat, but the /sys tree can use symlink as seen here :
>
> $ ls -l /sys/class/misc/
> lrwxrwxrwx    1 root     root            0 Jan  1  1970 watchdog ->
> ../../devices/platform/at91sam9x_wdt/watchdog
>
> Doing so, the function can't walk through symbolic links. By replacing
> lstat by stat, the problem is corrected.
> To avoid infinite loop, we added a walking through depth limit to 2 (see

> udevstart.c).

almost ... you introduced a little memory corruption there and that's no
good ;)

(notice how make_dev() requires the string be writable and that there be
64
bytes to spare at the end)

but otherwise, recursive_action() is good stuff

try out current svn now please
-mike


diff -Nru busybox-1.4.1_original/util-linux/mdev.c busybox-1.4.1/util-linux/mdev.c
--- busybox-1.4.1_original/util-linux/mdev.c	2007-01-24 22:34:51.000000000 +0100
+++ busybox-1.4.1/util-linux/mdev.c	2007-06-13 11:30:59.643974472 +0200
@@ -14,6 +14,8 @@
 
 #define DEV_PATH	"/dev"
 
+#define MAX_DEPTH	3
+
 struct mdev_globals
 {
 	int root_major, root_minor;
@@ -194,41 +196,46 @@
 	if (delete) unlink(device_name);
 }
 
-/* Recursive search of /sys/block or /sys/class.  path must be a writeable
- * buffer of size PATH_MAX containing the directory string to start at. */
-
-static void find_dev(char *path)
+/* File action callback.
+ * 
+ */
+static int faction(const char *fileName, 
+			struct stat *statbuf, 
+			void* userData, int depth)
 {
-	DIR *dir;
-	size_t len = strlen(path);
-	struct dirent *entry;
-
-	dir = opendir(path);
-	if (dir == NULL)
-		return;
-
-	while ((entry = readdir(dir)) != NULL) {
-		struct stat st;
-
-		/* Skip "." and ".." (also skips hidden files, which is ok) */
-
-		if (entry->d_name[0] == '.')
-			continue;
-
-		// uClibc doesn't fill out entry->d_type reliably. so we use lstat().
+	char *pt;
+	
+	/* Remove path from fileName */
+	pt = strrchr(fileName,'/');
+	
+	if(!pt || strcmp(pt, DEV_PATH))
+		return FALSE;
+	
+	sprintf(userData,"%.*s",pt-fileName,fileName)
+	make_device(userData, 0);
 
-		snprintf(path+len, PATH_MAX-len, "/%s", entry->d_name);
-		if (!lstat(path, &st) && S_ISDIR(st.st_mode)) find_dev(path);
-		path[len] = 0;
-
-		/* If there's a dev entry, mknod it */
-
-		if (!strcmp(entry->d_name, "dev")) make_device(path, 0);
-	}
+	return TRUE;	
+}
 
-	closedir(dir);
+/* Directory callback.
+ * Should return SKIP to stop traversal.
+ */
+static int daction(const char *fileName, 
+			struct stat *statbuf, 
+			void* userData, int depth)
+{
+	/* Maximum depth */ 
+	if(depth>=MAX_DEPTH)
+		return SKIP;
+		
+	return TRUE;
 }
 
+/* Recursive search of /sys/block or /sys/class.  
+ * The recursive depth is limited to avoid 
+ * inifinite loop (circular symlinks)
+ * (see udevstart.c)
+ */
 int mdev_main(int argc, char *argv[])
 {
 	char *action;
@@ -245,10 +252,20 @@
 		xstat("/", &st);
 		bbg.root_major = major(st.st_dev);
 		bbg.root_minor = minor(st.st_dev);
-		strcpy(temp,"/sys/block");
-		find_dev(temp);
-		strcpy(temp,"/sys/class");
-		find_dev(temp);
+		recursive_action("/sys/block", 
+				TRUE, TRUE,	/* Recurse, follow links */
+				FALSE,		/* no depth first */
+				faction, 	/* file action callback */
+				daction, 	/* dir action callback */
+				temp, 0);
+
+		recursive_action("/sys/class", 
+				TRUE, TRUE,  	/* Recurse, follow links */
+				FALSE,		/* no depth first */
+				faction, 	/* file action callback */
+				daction, 	/* dir action callback */
+				temp, 0);
+
 
 	/* Hotplug */
 
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox

Reply via email to