summaryrefslogtreecommitdiff
path: root/modutils/modprobe-small.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-07-09 15:30:57 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-07-09 15:30:57 +0000
commit24a131ea4d6697f388bf9ef87c84d11b37f95503 (patch)
tree86025dee495553a27e23b86b6a10cde67e5f8b6a /modutils/modprobe-small.c
parentf62ab2d77455ca42e1300e72b70d06e8a16db53b (diff)
downloadbusybox-w32-24a131ea4d6697f388bf9ef87c84d11b37f95503.tar.gz
busybox-w32-24a131ea4d6697f388bf9ef87c84d11b37f95503.tar.bz2
busybox-w32-24a131ea4d6697f388bf9ef87c84d11b37f95503.zip
modprobe-small: preparatory patch for modprobe.dep.bb creation patches,
Code size impact ~0.
Diffstat (limited to 'modutils/modprobe-small.c')
-rw-r--r--modutils/modprobe-small.c97
1 files changed, 54 insertions, 43 deletions
diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c
index 1096ba7ae..72209610a 100644
--- a/modutils/modprobe-small.c
+++ b/modutils/modprobe-small.c
@@ -14,14 +14,17 @@
14#include <sys/utsname.h> /* uname() */ 14#include <sys/utsname.h> /* uname() */
15#include <fnmatch.h> 15#include <fnmatch.h>
16 16
17extern int init_module(void *module, unsigned long len, const char *options);
18extern int delete_module(const char *module, unsigned flags);
19extern int query_module(const char *name, int which, void *buf, size_t bufsize, size_t *ret);
20
21
17#define dbg1_error_msg(...) ((void)0) 22#define dbg1_error_msg(...) ((void)0)
18#define dbg2_error_msg(...) ((void)0) 23#define dbg2_error_msg(...) ((void)0)
19//#define dbg1_error_msg(...) bb_error_msg(__VA_ARGS__) 24//#define dbg1_error_msg(...) bb_error_msg(__VA_ARGS__)
20//#define dbg2_error_msg(...) bb_error_msg(__VA_ARGS__) 25//#define dbg2_error_msg(...) bb_error_msg(__VA_ARGS__)
21 26
22extern int init_module(void *module, unsigned long len, const char *options); 27#define DEPFILE_BB CONFIG_DEFAULT_DEPMOD_FILE".bb"
23extern int delete_module(const char *module, unsigned flags);
24extern int query_module(const char *name, int which, void *buf, size_t bufsize, size_t *ret);
25 28
26enum { 29enum {
27 OPT_q = (1 << 0), /* be quiet */ 30 OPT_q = (1 << 0), /* be quiet */
@@ -63,6 +66,12 @@ static void appendc(char c)
63 stringbuf[stringbuf_idx++] = c; 66 stringbuf[stringbuf_idx++] = c;
64} 67}
65 68
69static void bksp(void)
70{
71 if (stringbuf_idx)
72 stringbuf_idx--;
73}
74
66static void append(const char *s) 75static void append(const char *s)
67{ 76{
68 size_t len = strlen(s); 77 size_t len = strlen(s);
@@ -115,6 +124,19 @@ static void replace(char *s, char what, char with)
115 } 124 }
116} 125}
117 126
127/* Take "word word", return malloced "word",NUL,"word",NUL,NUL */
128static char* str_2_list(const char *str)
129{
130 int len = strlen(str) + 1;
131 char *dst = xmalloc(len + 1);
132
133 dst[len] = '\0';
134 memcpy(dst, str, len);
135//TODO: protect against 2+ spaces: "word word"
136 replace(dst, ' ', '\0');
137 return dst;
138}
139
118#if ENABLE_FEATURE_MODPROBE_SMALL_ZIPPED 140#if ENABLE_FEATURE_MODPROBE_SMALL_ZIPPED
119static char *xmalloc_open_zipped_read_close(const char *fname, size_t *sizep) 141static char *xmalloc_open_zipped_read_close(const char *fname, size_t *sizep)
120{ 142{
@@ -187,13 +209,13 @@ static int load_module(const char *fname, const char *options)
187#endif 209#endif
188} 210}
189 211
190static char* parse_module(const char *pathname, const char *name) 212static char* parse_module(const char *pathname)
191{ 213{
192 char *module_image; 214 char *module_image;
193 char *ptr; 215 char *ptr;
194 size_t len; 216 size_t len;
195 size_t pos; 217 size_t pos;
196 dbg1_error_msg("parse_module('%s','%s')", pathname, name); 218 dbg1_error_msg("parse_module('%s')", pathname);
197 219
198 /* Read (possibly compressed) module */ 220 /* Read (possibly compressed) module */
199 len = 64 * 1024 * 1024; /* 64 Mb at most */ 221 len = 64 * 1024 * 1024; /* 64 Mb at most */
@@ -202,11 +224,7 @@ static char* parse_module(const char *pathname, const char *name)
202 reset_stringbuf(); 224 reset_stringbuf();
203 225
204 /* First desc line's format is 226 /* First desc line's format is
205 * "modname alias1 symbol:sym1 alias2 symbol:sym2 " (note trailing ' ') 227 * "alias1 symbol:sym1 alias2 symbol:sym2" */
206 */
207 append(name);
208 appendc(' ');
209 /* Aliases */
210 pos = 0; 228 pos = 0;
211 while (1) { 229 while (1) {
212 ptr = find_keyword(module_image + pos, len - pos, "alias="); 230 ptr = find_keyword(module_image + pos, len - pos, "alias=");
@@ -217,19 +235,20 @@ static char* parse_module(const char *pathname, const char *name)
217 /* DOCME: __ksymtab_gpl and __ksymtab_strings occur 235 /* DOCME: __ksymtab_gpl and __ksymtab_strings occur
218 * in many modules. What do they mean? */ 236 * in many modules. What do they mean? */
219 if (strcmp(ptr, "gpl") != 0 && strcmp(ptr, "strings") != 0) { 237 if (strcmp(ptr, "gpl") != 0 && strcmp(ptr, "strings") != 0) {
220 dbg2_error_msg("alias: 'symbol:%s'", ptr); 238 dbg2_error_msg("alias:'symbol:%s'", ptr);
221 append("symbol:"); 239 append("symbol:");
222 } 240 }
223 } else { 241 } else {
224 dbg2_error_msg("alias: '%s'", ptr); 242 dbg2_error_msg("alias:'%s'", ptr);
225 } 243 }
226 append(ptr); 244 append(ptr);
227 appendc(' '); 245 appendc(' ');
228 pos = (ptr - module_image); 246 pos = (ptr - module_image);
229 } 247 }
248 bksp(); /* remove last ' ' */
230 appendc('\0'); 249 appendc('\0');
231 250
232 /* Second line: "dependency1 depandency2 " (note trailing ' ') */ 251 /* Second line: "dependency1 depandency2" */
233 ptr = find_keyword(module_image, len, "depends="); 252 ptr = find_keyword(module_image, len, "depends=");
234 if (ptr && *ptr) { 253 if (ptr && *ptr) {
235 replace(ptr, ',', ' '); 254 replace(ptr, ',', ' ');
@@ -237,28 +256,31 @@ static char* parse_module(const char *pathname, const char *name)
237 dbg2_error_msg("dep:'%s'", ptr); 256 dbg2_error_msg("dep:'%s'", ptr);
238 append(ptr); 257 append(ptr);
239 } 258 }
240 appendc(' '); appendc('\0'); 259 appendc('\0');
241 260
242 free(module_image); 261 free(module_image);
243 return copy_stringbuf(); 262 return copy_stringbuf();
244} 263}
245 264
246static char* pathname_2_modname(const char *pathname) 265static int pathname_matches_modname(const char *pathname, const char *modname)
247{ 266{
248 const char *fname = bb_get_last_path_component_nostrip(pathname); 267 const char *fname = bb_get_last_path_component_nostrip(pathname);
249 const char *suffix = strrstr(fname, ".ko"); 268 const char *suffix = strrstr(fname, ".ko");
269//TODO: can do without malloc?
250 char *name = xstrndup(fname, suffix - fname); 270 char *name = xstrndup(fname, suffix - fname);
271 int r;
251 replace(name, '-', '_'); 272 replace(name, '-', '_');
252 return name; 273 r = (strcmp(name, modname) == 0);
274 free(name);
275 return r;
253} 276}
254 277
255static FAST_FUNC int fileAction(const char *pathname, 278static FAST_FUNC int fileAction(const char *pathname,
256 struct stat *sb UNUSED_PARAM, 279 struct stat *sb UNUSED_PARAM,
257 void *data, 280 void *modname_to_match,
258 int depth UNUSED_PARAM) 281 int depth UNUSED_PARAM)
259{ 282{
260 int cur; 283 int cur;
261 char *name;
262 const char *fname; 284 const char *fname;
263 285
264 pathname += 2; /* skip "./" */ 286 pathname += 2; /* skip "./" */
@@ -270,21 +292,20 @@ static FAST_FUNC int fileAction(const char *pathname,
270 292
271 cur = module_count++; 293 cur = module_count++;
272 modinfo = xrealloc_vector(modinfo, 12, cur); 294 modinfo = xrealloc_vector(modinfo, 12, cur);
295//TODO: use zeroing version of xrealloc_vector?
273 modinfo[cur].pathname = xstrdup(pathname); 296 modinfo[cur].pathname = xstrdup(pathname);
274 modinfo[cur].desc = NULL; 297 modinfo[cur].desc = NULL;
275 modinfo[cur+1].pathname = NULL; 298 modinfo[cur+1].pathname = NULL;
276 modinfo[cur+1].desc = NULL; 299 modinfo[cur+1].desc = NULL;
277 300
278 name = pathname_2_modname(fname); 301 if (!pathname_matches_modname(fname, modname_to_match)) {
279 if (strcmp(name, data) != 0) {
280 free(name);
281 dbg1_error_msg("'%s' module name doesn't match", pathname); 302 dbg1_error_msg("'%s' module name doesn't match", pathname);
282 return TRUE; /* module name doesn't match, continue search */ 303 return TRUE; /* module name doesn't match, continue search */
283 } 304 }
284 305
285 dbg1_error_msg("'%s' module name matches", pathname); 306 dbg1_error_msg("'%s' module name matches", pathname);
286 module_found_idx = cur; 307 module_found_idx = cur;
287 modinfo[cur].desc = parse_module(pathname, name); 308 modinfo[cur].desc = parse_module(pathname);
288 309
289 if (!(option_mask32 & OPT_r)) { 310 if (!(option_mask32 & OPT_r)) {
290 if (load_module(pathname, module_load_options) == 0) { 311 if (load_module(pathname, module_load_options) == 0) {
@@ -292,11 +313,9 @@ static FAST_FUNC int fileAction(const char *pathname,
292 * This can happen ONLY for "top-level" module load, 313 * This can happen ONLY for "top-level" module load,
293 * not a dep, because deps dont do dirscan. */ 314 * not a dep, because deps dont do dirscan. */
294 exit(EXIT_SUCCESS); 315 exit(EXIT_SUCCESS);
295 /*free(name);return RECURSE_RESULT_ABORT;*/
296 } 316 }
297 } 317 }
298 318
299 free(name);
300 return TRUE; 319 return TRUE;
301} 320}
302 321
@@ -308,16 +327,13 @@ static module_info* find_alias(const char *alias)
308 /* First try to find by name (cheaper) */ 327 /* First try to find by name (cheaper) */
309 i = 0; 328 i = 0;
310 while (modinfo[i].pathname) { 329 while (modinfo[i].pathname) {
311 char *name = pathname_2_modname(modinfo[i].pathname); 330 if (pathname_matches_modname(modinfo[i].pathname, alias)) {
312 if (strcmp(name, alias) == 0) {
313 dbg1_error_msg("found '%s' in module '%s'", 331 dbg1_error_msg("found '%s' in module '%s'",
314 alias, modinfo[i].pathname); 332 alias, modinfo[i].pathname);
315 if (!modinfo[i].desc) 333 if (!modinfo[i].desc)
316 modinfo[i].desc = parse_module(modinfo[i].pathname, name); 334 modinfo[i].desc = parse_module(modinfo[i].pathname);
317 free(name);
318 return &modinfo[i]; 335 return &modinfo[i];
319 } 336 }
320 free(name);
321 i++; 337 i++;
322 } 338 }
323 339
@@ -326,16 +342,13 @@ static module_info* find_alias(const char *alias)
326 while (modinfo[i].pathname) { 342 while (modinfo[i].pathname) {
327 char *desc, *s; 343 char *desc, *s;
328 if (!modinfo[i].desc) { 344 if (!modinfo[i].desc) {
329 char *name = pathname_2_modname(modinfo[i].pathname); 345 modinfo[i].desc = parse_module(modinfo[i].pathname);
330 modinfo[i].desc = parse_module(modinfo[i].pathname, name);
331 free(name);
332 } 346 }
333 /* "modname alias1 symbol:sym1 alias2 symbol:sym2 " */ 347 /* "alias1 symbol:sym1 alias2 symbol:sym2" */
334 desc = xstrdup(modinfo[i].desc); 348 desc = str_2_list(modinfo[i].desc);
335 /* Does matching substring exist? */ 349 /* Does matching substring exist? */
336 replace(desc, ' ', '\0');
337 for (s = desc; *s; s += strlen(s) + 1) { 350 for (s = desc; *s; s += strlen(s) + 1) {
338 /* aliases in module bodies can be defined with 351 /* Aliases in module bodies can be defined with
339 * shell patterns. Example: 352 * shell patterns. Example:
340 * "pci:v000010DEd000000D9sv*sd*bc*sc*i*". 353 * "pci:v000010DEd000000D9sv*sd*bc*sc*i*".
341 * Plain strcmp() won't catch that */ 354 * Plain strcmp() won't catch that */
@@ -463,10 +476,8 @@ static void process_module(char *name, const char *cmdline_options)
463 } 476 }
464 477
465 /* Second line of desc contains dependencies */ 478 /* Second line of desc contains dependencies */
466 deps = xstrdup(info->desc + strlen(info->desc) + 1); 479 deps = str_2_list(info->desc + strlen(info->desc) + 1);
467 480
468 /* Transform deps to string list */
469 replace(deps, ' ', '\0');
470 /* Iterate thru dependencies, trying to (un)load them */ 481 /* Iterate thru dependencies, trying to (un)load them */
471 for (s = deps; *s; s += strlen(s) + 1) { 482 for (s = deps; *s; s += strlen(s) + 1) {
472 //if (strcmp(name, s) != 0) // N.B. do loops exist? 483 //if (strcmp(name, s) != 0) // N.B. do loops exist?
@@ -481,12 +492,12 @@ static void process_module(char *name, const char *cmdline_options)
481 errno = 0; 492 errno = 0;
482 if (load_module(info->pathname, options) != 0) { 493 if (load_module(info->pathname, options) != 0) {
483 if (EEXIST != errno) { 494 if (EEXIST != errno) {
484 bb_error_msg("insert '%s' %s: %s", 495 bb_error_msg("'%s': %s",
485 info->pathname, options, 496 info->pathname,
486 moderror(errno)); 497 moderror(errno));
487 } else { 498 } else {
488 dbg1_error_msg("insert '%s' %s: %s", 499 dbg1_error_msg("'%s': %s",
489 info->pathname, options, 500 info->pathname,
490 moderror(errno)); 501 moderror(errno));
491 } 502 }
492 } 503 }