svn commit: trunk/busybox/util-linux

landley at busybox.net landley at busybox.net
Sat Dec 17 10:52:32 UTC 2005


Author: landley
Date: 2005-12-17 02:52:30 -0800 (Sat, 17 Dec 2005)
New Revision: 12945

Log:
Added /etc/mdev.conf support.  Adds about 1.9k to mdev.


Modified:
   trunk/busybox/util-linux/Config.in
   trunk/busybox/util-linux/mdev.c


Changeset:
Modified: trunk/busybox/util-linux/Config.in
===================================================================
--- trunk/busybox/util-linux/Config.in	2005-12-17 01:34:03 UTC (rev 12944)
+++ trunk/busybox/util-linux/Config.in	2005-12-17 10:52:30 UTC (rev 12945)
@@ -254,7 +254,7 @@
 	  have it handle hotplug events afterwards.  Device names are taken
 	  from sysfs.
 
-config CONFIG_FEATURE_MDEV_CONFIG
+config CONFIG_FEATURE_MDEV_CONF
 	bool "  Support /etc/mdev.conf"
 	default n
 	depends on CONFIG_MDEV

Modified: trunk/busybox/util-linux/mdev.c
===================================================================
--- trunk/busybox/util-linux/mdev.c	2005-12-17 01:34:03 UTC (rev 12944)
+++ trunk/busybox/util-linux/mdev.c	2005-12-17 10:52:30 UTC (rev 12945)
@@ -8,25 +8,31 @@
  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  */
 
+#include <ctype.h>
 #include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <string.h>
+#include <sys/mman.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include "busybox.h"
+#include "xregex.h"
 
-#define DEV_PATH	"/dev"
-#define DEV_MODE	0660
+#define DEV_PATH	"/tmp/dev"
 
 #include <busybox.h>
 
 /* mknod in /dev based on a path like "/sys/block/hda/hda1" */
-void make_device(char *path)
+static void make_device(char *path)
 {
-	char *device_name, *s;
+	char *device_name,*s;
 	int major,minor,type,len,fd;
+	int mode=0660;
+	uid_t uid=0;
+	gid_t gid=0;
 
 	RESERVE_CONFIG_BUFFER(temp,PATH_MAX);
 
@@ -44,8 +50,8 @@
 	device_name = strrchr(path, '/') + 1;
 	type = strncmp(path+5, "block/" ,6) ? S_IFCHR : S_IFBLK;
 	major = minor = 0;
-	for(s = temp; *s; s++) {
-		if(*s == ':') {
+	for (s = temp; *s; s++) {
+		if (*s == ':') {
 			major = minor;
 			minor = 0;
 		} else {
@@ -54,14 +60,115 @@
 		}
 	}
 
-/* Open config file here, look up permissions */	
+	/* If we have a config file, look up permissions for this device */
+	
+	if (ENABLE_FEATURE_MDEV_CONF) {
+		char *conf,*pos,*end;
 
+		/* mmap the config file */
+		if (-1!=(fd=open("/etc/mdev.conf",O_RDONLY))) {
+			len=lseek(fd,0,SEEK_END);
+			conf=mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0);
+			if (conf) {
+				int line=0;
+
+				/* Loop through lines in mmaped file*/
+				for (pos=conf;pos-conf<len;) {
+					int field;
+					char *end2;
+					
+					line++;
+					/* find end of this line */
+					for(end=pos;end-conf<len && *end!='\n';end++);
+
+					/* Three fields: regex, uid:gid, mode */
+					for (field=3;field;field--) {
+						/* Skip whitespace */
+						while (pos<end && isspace(*pos)) pos++;
+						if (pos==end || *pos=='#') break;
+						for (end2=pos;
+							end2<end && !isspace(*end2) && *end2!='#'; end2++);
+						switch(field) {
+							/* Regex to match this device */
+							case 3:
+							{
+								char *regex=strndupa(pos,end2-pos);
+								regex_t match;
+								regmatch_t off;
+								int result;
+
+								/* Is this it? */	
+								xregcomp(&match,regex,REG_EXTENDED);
+								result=regexec(&match,device_name,1,&off,0);
+								regfree(&match);
+								
+								/* If not this device, skip rest of line */
+								if(result || off.rm_so
+									|| off.rm_eo!=strlen(device_name))
+										goto end_line;
+
+								break;
+							}
+							/* uid:gid */
+							case 2:
+							{
+								char *s2;
+
+								/* Find : */
+								for(s=pos;s<end2 && *s!=':';s++);
+								if(s==end2) goto end_line;
+
+								/* Parse UID */
+								uid=strtoul(pos,&s2,10);
+								if(s!=s2) {
+									struct passwd *pass;
+									pass=getpwnam(strndupa(pos,s-pos));
+									if(!pass) goto end_line;
+									uid=pass->pw_uid;
+								}
+								s++;
+								/* parse GID */
+								gid=strtoul(s,&s2,10);
+								if(end2!=s2) {
+									struct group *grp;
+									grp=getgrnam(strndupa(s,end2-s));
+									if(!grp) goto end_line;
+									gid=grp->gr_gid;
+								}
+								break;
+							}
+							/* mode */
+							case 1:
+							{
+								mode=strtoul(pos,&pos,8);
+								if(pos!=end2) goto end_line;
+								goto found_device;
+							}
+						}
+						pos=end2;
+					}
+end_line:
+					/* Did everything parse happily? */
+					if (field && field!=3)
+							bb_error_msg_and_die("Bad line %d",line);
+
+					/* Next line */
+					pos=++end;
+				}
+found_device:
+				munmap(conf,len);
+			}
+			close(fd);
+		}
+	}
+
 	sprintf(temp, "%s/%s", DEV_PATH, device_name);
-	if(mknod(temp, DEV_MODE | type, makedev(major, minor)) && errno != EEXIST)
+	umask(0);
+	if (mknod(temp, mode | type, makedev(major, minor)) && errno != EEXIST)
 		bb_perror_msg_and_die("mknod %s failed", temp);
+
+	if (ENABLE_FEATURE_MDEV_CONF) chown(temp,uid,gid);
 	
-/* Perform shellout here */
-
 end:
 	RELEASE_CONFIG_BUFFER(temp);
 }
@@ -69,18 +176,18 @@
 /* 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. */
 
-void find_dev(char *path)
+static void find_dev(char *path)
 {
 	DIR *dir;
 	int len=strlen(path);
 
-	if(!(dir = opendir(path)))
+	if (!(dir = opendir(path)))
 		bb_perror_msg_and_die("No %s",path);
 
-	for(;;) {
+	for (;;) {
 		struct dirent *entry = readdir(dir);
 		
-		if(!entry) break;
+		if (!entry) break;
 
 		/* Skip "." and ".." (also skips hidden files, which is ok) */
 
@@ -103,7 +210,7 @@
 int mdev_main(int argc, char *argv[])
 {
 	if (argc > 1) {
-		if(argc == 2 && !strcmp(argv[1],"-s")) {
+		if (argc == 2 && !strcmp(argv[1],"-s")) {
 			RESERVE_CONFIG_BUFFER(temp,PATH_MAX);
 			strcpy(temp,"/sys/block");
 			find_dev(temp);




More information about the busybox-cvs mailing list