modprobe: optional "blacklist" command support (by Natanael Copa)

is_conf_command                                        -      56     +56
include_conf                                         898     917     +19
check_dep                                            348     356      +8
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 2/0 up/down: 83/0)               Total: 83 bytes

diff --git a/modutils/Config.in b/modutils/Config.in
index b2ef51a..c5e596d 100644
--- a/modutils/Config.in
+++ b/modutils/Config.in
@@ -117,6 +117,18 @@
 	  mismatch between module name and file name, along with bus-specific
 	  aliases (such as pci:... or usb:... aliases).
 
+config FEATURE_MODPROBE_BLACKLIST
+	bool
+	prompt "Blacklist support"
+	default n
+	depends on MODPROBE && FEATURE_2_6_MODULES
+	help
+	  Say 'y' here to enable support for the 'blacklist' command in 
+	  modprobe.conf. This prevents the alias resolver to resolve 
+	  blacklisted modules. This is useful if you want to prevent your 
+	  hardware autodetection scripts to load modules like evdev, frame 
+	  buffer drivers etc.
+
 comment "Options common to multiple modutils"
 	depends on INSMOD || RMMOD || MODPROBE || LSMOD
 
diff --git a/modutils/modprobe.c b/modutils/modprobe.c
index f6681a8..60dc926 100644
--- a/modutils/modprobe.c
+++ b/modutils/modprobe.c
@@ -29,7 +29,8 @@
 	struct mod_opt_t *  m_options;	        /* the module options */
 
 	int     m_isalias  : 1;                 /* the module is an alias */
-	int     m_reserved : 15;                /* stuffin' */
+	int     m_isblacklisted : 1;
+	int     m_reserved : 14;                /* stuffin' */
 
 	int     m_depcnt   : 16;                /* the number of dependable module(s) */
 	char ** m_deparr;                       /* the list of dependable module(s) */
@@ -230,6 +231,13 @@
 #define parse_command_string(src, dst)	(0)
 #endif /* ENABLE_FEATURE_MODPROBE_MULTIPLE_OPTIONS */
 
+static int is_conf_command(char *buffer, const char *command)
+{ 
+	int len = strlen(command);
+	return ((strstr(buffer, command) == buffer) &&
+			isspace(buffer[len])); 
+}
+
 /*
  * This function reads aliases and default module options from a configuration file
  * (/etc/modprobe.conf syntax). It supports includes (only files, no directories).
@@ -260,7 +268,7 @@
 		if (continuation_line)
 			continue;
 
-		if ((strncmp(buffer, "alias", 5) == 0) && isspace(buffer[5])) {
+		if (is_conf_command(buffer, "alias")) {
 			char *alias, *mod;
 
 			if (parse_tag_value(buffer + 6, &alias, &mod)) {
@@ -284,7 +292,7 @@
 				}
 				/*(*current)->m_next = NULL; - done by xzalloc */
 			}
-		} else if ((strncmp(buffer, "options", 7) == 0) && isspace(buffer[7])) {
+		} else if (is_conf_command(buffer, "options")) {
 			char *mod, *opt;
 
 			/* split the line in the module/alias name, and options */
@@ -307,7 +315,7 @@
 					}
 				}
 			}
-		} else if ((strncmp(buffer, "include", 7) == 0) && isspace(buffer[7])) {
+		} else if (is_conf_command(buffer, "include")) {
 			int fdi;
 			char *filename;
 
@@ -317,6 +325,18 @@
 				include_conf(first, current, buffer, buflen, fdi);
 				close(fdi);
 			}
+		} else if (ENABLE_FEATURE_MODPROBE_BLACKLIST && 
+				(is_conf_command(buffer, "blacklist"))) {
+			char *mod;
+			struct dep_t *dt;
+
+			mod = skip_whitespace(buffer + 10);
+			for (dt = *first; dt; dt = dt->m_next) {
+				if (dt->m_isalias && strcmp(dt->m_deparr[0], mod) == 0)
+					break;
+			}
+			if (dt)
+				dt->m_isblacklisted = 1;
 		}
 	} /* while (reads(...)) */
 }
@@ -728,7 +748,8 @@
 
 	// resolve alias names
 	while (dt->m_isalias) {
-		if (dt->m_depcnt == 1) {
+		if (dt->m_depcnt == 1 && !(ENABLE_FEATURE_MODPROBE_BLACKLIST &&
+				dt->m_isblacklisted)) {
 			struct dep_t *adt;
 
 			for (adt = depend; adt; adt = adt->m_next) {