destroy bug 679, use getopt_ulflags with new feature: usage option. Removed two strdup
diff --git a/libbb/getopt_ulflags.c b/libbb/getopt_ulflags.c
index f18ee2d..3e77bbf 100644
--- a/libbb/getopt_ulflags.c
+++ b/libbb/getopt_ulflags.c
@@ -182,6 +182,10 @@
  "-N"   A dash as the first char in a bb_opt_complementally group with
 	number 0-9 as one char is means check minimal arguments required.
 
+ "V-"   A option with dash before colon or end line indicate: call
+	bb_show_usage if this option give, for example verbose
+	usage option.
+
  "--"   A double dash between two options, or between an option and a group
 	of options, means that they are mutually exclusive.  Unlike
 	the "-" case above, an error will be forced if the options
@@ -387,6 +391,12 @@
 			requires |= on_off->switch_on;
 			continue;
 		}
+		if(c == '-' && (s[2] == ':' || s[2] == '\0')) {
+			flags |= on_off->switch_on;
+			on_off->incongruously |= on_off->switch_on;
+			s++;
+			continue;
+		}
 		if(c == *s) {
 			on_off->counter = va_arg (p, int *);
 			s++;
diff --git a/modutils/modprobe.c b/modutils/modprobe.c
index 844eb99..d04c7ff 100644
--- a/modutils/modprobe.c
+++ b/modutils/modprobe.c
@@ -55,7 +55,30 @@
 
 
 static struct dep_t *depend;
-static int autoclean, show_only, quiet, do_syslog, verbose;
+
+#define main_options "acdklnqrst:vVC:"
+#define INSERT_ALL     1        /* a */
+#define DUMP_CONF_EXIT 2        /* c */
+#define D_OPT_IGNORED  4        /* d */
+#define AUTOCLEAN_FLG  8        /* k */
+#define LIST_ALL       16       /* l */
+#define SHOW_ONLY      32       /* n */
+#define QUIET          64       /* q */
+#define REMOVE_OPT     128      /* r */
+#define DO_SYSLOG      256      /* s */
+#define RESTRICT_DIR   512      /* t */
+#define VERBOSE        1024     /* v */
+#define VERSION_ONLY   2048     /* V */
+#define CONFIG_FILE    4096     /* C */
+
+#define autoclean       (main_opts & AUTOCLEAN_FLG)
+#define show_only       (main_opts & SHOW_ONLY)
+#define quiet           (main_opts & QUIET)
+#define remove_opt      (main_opts & REMOVE_OPT)
+#define do_syslog       (main_opts & DO_SYSLOG)
+#define verbose         (main_opts & VERBOSE)
+
+static int main_opts;
 
 static int parse_tag_value ( char *buffer, char **ptag, char **pvalue )
 {
@@ -234,8 +257,8 @@
 	if( opt_status & ( ARG_IN_DQUOTES | ARG_IN_SQUOTES ) ) {
 		bb_error_msg_and_die( "unterminated (single or double) quote in options list: %s", src );
 	}
-	*tmp_str = '\0';
-	*dst = xrealloc( *dst, strlen( *dst ) );
+	*tmp_str++ = '\0';
+	*dst = xrealloc( *dst, (tmp_str - *dst ) );
 	return src;
 }
 #else
@@ -254,7 +277,7 @@
 	struct dep_t *first = 0;
 	struct dep_t *current = 0;
 	char buffer[2048];
-	char *filename = buffer;
+	char *filename;
 	int continuation_line = 0;
 	int k_version;
 
@@ -262,17 +285,11 @@
 	if ( uname ( &un ))
 		bb_error_msg_and_die("can't determine kernel version");
 
-	// check for buffer overflow in following code
-	if ( bb_strlen ( un.release ) > ( sizeof( buffer ) - 64 )) {
-		return 0;
-	}
 	if (un.release[0] == '2') {
 		k_version = un.release[2] - '0';
 	}
 
-	strcpy ( filename, "/lib/modules/" );
-	strcat ( filename, un.release );
-	strcat ( filename, "/modules.dep" );
+	filename = bb_xasprintf("/lib/modules/%s/modules.dep", un.release );
 
 	if (( fd = open ( filename, O_RDONLY )) < 0 ) {
 
@@ -281,12 +298,13 @@
 			return 0;
 		}
 	}
+	free(filename);
 
 	while ( reads ( fd, buffer, sizeof( buffer ))) {
 		int l = bb_strlen ( buffer );
 		char *p = 0;
 
-		while ( isspace ( buffer [l-1] )) {
+		while ( l > 0 && isspace ( buffer [l-1] )) {
 			buffer [l-1] = 0;
 			l--;
 		}
@@ -787,7 +805,7 @@
 static int mod_remove ( char *mod )
 {
 	int rc;
-	static struct mod_list_t rm_a_dummy = { "-a", 0, 0 };
+	static struct mod_list_t rm_a_dummy = { "-a", NULL, NULL, NULL, NULL };
 
 	struct mod_list_t *head = 0;
 	struct mod_list_t *tail = 0;
@@ -807,50 +825,17 @@
 
 extern int modprobe_main(int argc, char** argv)
 {
-	int	opt;
 	int rc = EXIT_SUCCESS;
-	int remove_opt = 0;
+	char *unused;
 
-	autoclean = show_only = quiet = do_syslog = verbose = 0;
-
-	while ((opt = getopt(argc, argv, "acdklnqrst:vVC:")) != -1) {
-		switch(opt) {
-			case 'c': // no config used
-			case 'l': // no pattern matching
+	bb_opt_complementally = "?V-:q-v:v-q";
+	main_opts = bb_getopt_ulflags(argc, argv, "acdklnqrst:vVC:",
+							&unused, &unused);
+	if((main_opts & (DUMP_CONF_EXIT | LIST_ALL)))
 				return EXIT_SUCCESS;
-				break;
-			case 'C': // no config used
-			case 't': // no pattern matching
+	if((main_opts & (RESTRICT_DIR | CONFIG_FILE)))
 				bb_error_msg_and_die("-t and -C not supported");
 
-			case 'a': // ignore
-			case 'd': // ignore
-				break;
-			case 'k':
-				autoclean++;
-				break;
-			case 'n':
-				show_only++;
-				break;
-			case 'q':
-				quiet++; verbose=0;
-				break;
-			case 'r':
-				remove_opt++;
-				break;
-			case 's':
-				do_syslog++;
-				break;
-			case 'v':
-				verbose++; quiet=0;
-				break;
-			case 'V':
-			default:
-				bb_show_usage();
-				break;
-		}
-	}
-
 	depend = build_dep ( );
 
 	if ( !depend )
@@ -859,7 +844,7 @@
 	if (remove_opt) {
 		do {
 			if (mod_remove ( optind < argc ?
-						bb_xstrdup (argv [optind]) : NULL )) {
+						argv [optind] : NULL )) {
 				bb_error_msg ("failed to remove module %s",
 						argv [optind] );
 				rc = EXIT_FAILURE;
@@ -869,7 +854,7 @@
 		if (optind >= argc)
 			bb_error_msg_and_die ( "No module or pattern provided\n" );
 
-		if ( mod_insert ( bb_xstrdup ( argv [optind] ), argc - optind - 1, argv + optind + 1 ))
+		if ( mod_insert ( argv [optind], argc - optind - 1, argv + optind + 1 ))
 			bb_error_msg_and_die ( "failed to load module %s", argv [optind] );
 	}