diff --git a/include/usage.h b/include/usage.h index e571d2ba3..036cf9db7 100644 --- a/include/usage.h +++ b/include/usage.h @@ -2824,9 +2824,21 @@ "-rw------- 1 andersen andersen 0 Apr 25 17:10 /tmp/temp.mWiLjM\n" #define modprobe_trivial_usage \ - "[-knqrsv] MODULE [symbol=value...]" + IF_MODPROBE_SMALL("[-qfwrsv] MODULE [symbol=value...]") \ + IF_NOT_MODPROBE_SMALL("[-" \ + IF_FEATURE_2_4_MODULES("k")"nqrsv" \ + IF_FEATURE_MODPROBE_BLACKLIST("b")"] MODULE [symbol=value...]") #define modprobe_full_usage "\n\n" \ "Options:" \ + IF_MODPROBE_SMALL( \ + "\n -q Quiet" \ + "\n -f Force" \ + "\n -w Wait for unload" \ + "\n -r Remove module (stacks) or do autoclean" \ + "\n -s Report via syslog instead of stderr" \ + "\n -v Verbose" \ + ) \ + IF_NOT_MODPROBE_SMALL( \ IF_FEATURE_2_4_MODULES( \ "\n -k Make module autoclean-able" \ ) \ @@ -2837,7 +2849,8 @@ "\n -v Verbose" \ IF_FEATURE_MODPROBE_BLACKLIST( \ "\n -b Apply blacklist to module names too" \ - ) + ) \ + ) #define modprobe_notes_usage \ "modprobe can (un)load a stack of modules, passing each module options (when\n" \ diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c index bc80723fa..e2359d042 100644 --- a/modutils/modprobe-small.c +++ b/modutils/modprobe-small.c @@ -44,11 +44,13 @@ struct globals { char *module_load_options; smallint dep_bb_seen; smallint wrote_dep_bb_ok; - int module_count; + unsigned module_count; int module_found_idx; - int stringbuf_idx; - char stringbuf[32 * 1024]; /* some modules have lots of stuff */ + unsigned stringbuf_idx; + unsigned stringbuf_size; + char *stringbuf; /* some modules have lots of stuff */ /* for example, drivers/media/video/saa7134/saa7134.ko */ + /* therefore having a fixed biggish buffer is not wise */ }; #define G (*ptr_to_globals) #define modinfo (G.modinfo ) @@ -58,16 +60,29 @@ struct globals { #define module_found_idx (G.module_found_idx ) #define module_load_options (G.module_load_options) #define stringbuf_idx (G.stringbuf_idx ) +#define stringbuf_size (G.stringbuf_size ) #define stringbuf (G.stringbuf ) #define INIT_G() do { \ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ } while (0) +static void append(const char *s) +{ + unsigned len = strlen(s); + if (stringbuf_idx + len + 15 > stringbuf_size) { + stringbuf_size = stringbuf_idx + len + 127; + dbg2_error_msg("grow stringbuf to %u", stringbuf_size); + stringbuf = xrealloc(stringbuf, stringbuf_size); + } + memcpy(stringbuf + stringbuf_idx, s, len); + stringbuf_idx += len; +} static void appendc(char c) { - if (stringbuf_idx < sizeof(stringbuf)) - stringbuf[stringbuf_idx++] = c; + /* We appendc() only after append(), + 15 trick in append() + * makes it unnecessary to check for overflow here */ + stringbuf[stringbuf_idx++] = c; } static void bksp(void) @@ -76,15 +91,6 @@ static void bksp(void) stringbuf_idx--; } -static void append(const char *s) -{ - size_t len = strlen(s); - if (stringbuf_idx + len < sizeof(stringbuf)) { - memcpy(stringbuf + stringbuf_idx, s, len); - stringbuf_idx += len; - } -} - static void reset_stringbuf(void) { stringbuf_idx = 0; @@ -92,7 +98,7 @@ static void reset_stringbuf(void) static char* copy_stringbuf(void) { - char *copy = xmalloc(stringbuf_idx); + char *copy = xzalloc(stringbuf_idx + 1); /* terminating NUL */ return memcpy(copy, stringbuf, stringbuf_idx); } @@ -216,7 +222,6 @@ static void parse_module(module_info *info, const char *pathname) pos = (ptr - module_image); } bksp(); /* remove last ' ' */ - appendc('\0'); info->aliases = copy_stringbuf(); replace(info->aliases, '-', '_'); @@ -229,7 +234,6 @@ static void parse_module(module_info *info, const char *pathname) dbg2_error_msg("dep:'%s'", ptr); append(ptr); } - appendc('\0'); info->deps = copy_stringbuf(); free(module_image);