- int fd;
- struct utsname un;
- struct dep_t *first = 0;
- struct dep_t *current = 0;
- char buffer[2048];
- char *filename;
- int continuation_line = 0;
- int k_version;
-
- if (uname(&un))
- bb_error_msg_and_die("can't determine kernel version");
-
- k_version = 0;
- if (un.release[0] == '2') {
- k_version = un.release[2] - '0';
- }
-
- filename = xasprintf("/lib/modules/%s/modules.dep", un.release);
- fd = open(filename, O_RDONLY);
- if (ENABLE_FEATURE_CLEAN_UP)
- free(filename);
- if (fd < 0) {
- /* Ok, that didn't work. Fall back to looking in /lib/modules */
- fd = open("/lib/modules/modules.dep", O_RDONLY);
- if (fd < 0) {
- return 0;
- }
- }
-
- while (reads(fd, buffer, sizeof(buffer))) {
- int l = strlen(buffer);
- char *p = 0;
-
- while (l > 0 && isspace(buffer[l-1])) {
- buffer[l-1] = 0;
- l--;
- }
-
- if (l == 0) {
- continuation_line = 0;
- continue;
- }
-
- /* Is this a new module dep description? */
- if (!continuation_line) {
- /* find the dep beginning */
- char *col = strchr(buffer, ':');
- char *dot = col;
-
- if (col) {
- /* This line is a dep description */
- char *mods;
- char *modpath;
- char *mod;
-
- /* Find the beginning of the module file name */
- *col = 0;
- mods = strrchr(buffer, '/');
-
- if (!mods)
- mods = buffer; /* no path for this module */
- else
- mods++; /* there was a path for this module... */
-
- /* find the path of the module */
- modpath = strchr(buffer, '/'); /* ... and this is the path */
- if (!modpath)
- modpath = buffer; /* module with no path */
- /* find the end of the module name in the file name */
- if (ENABLE_FEATURE_2_6_MODULES &&
- (k_version > 4) && (*(col-3) == '.') &&
- (*(col-2) == 'k') && (*(col-1) == 'o'))
- dot = col - 3;
- else
- if ((*(col-2) == '.') && (*(col-1) == 'o'))
- dot = col - 2;
-
- mod = xstrndup(mods, dot - mods);
-
- /* enqueue new module */
- if (!current) {
- first = current = xmalloc(sizeof(struct dep_t));
- } else {
- current->m_next = xmalloc(sizeof(struct dep_t));
- current = current->m_next;
- }
- current->m_name = mod;
- current->m_path = xstrdup(modpath);
- current->m_options = NULL;
- current->m_isalias = 0;
- current->m_depcnt = 0;
- current->m_deparr = 0;
- current->m_next = 0;
-
- p = col + 1;
- } else
- /* this line is not a dep description */
- p = 0;
- } else
- /* It's a dep description continuation */
- p = buffer;
-
- while (p && *p && isblank(*p))
- p++;
-
- /* p points to the first dependable module; if NULL, no dependable module */
- if (p && *p) {
- char *end = &buffer[l-1];
- char *deps;
- char *dep;
- char *next;
- int ext = 0;
-
- while (isblank(*end) || (*end == '\\'))
- end--;
-
- do {
- /* search the end of the dependency */
- next = strchr(p, ' ');
- if (next) {
- *next = 0;
- next--;
- } else
- next = end;
-
- /* find the beginning of the module file name */
- deps = strrchr(p, '/');
-
- if (!deps || (deps < p)) {
- deps = p;
-
- while (isblank(*deps))
- deps++;
- } else
- deps++;
-
- /* find the end of the module name in the file name */
- if (ENABLE_FEATURE_2_6_MODULES
- && (k_version > 4) && (*(next-2) == '.')
- && (*(next-1) == 'k') && (*next == 'o'))
- ext = 3;
- else
- if ((*(next-1) == '.') && (*next == 'o'))
- ext = 2;
-
- /* Cope with blank lines */
- if ((next-deps-ext+1) <= 0)
- continue;
- dep = xstrndup(deps, next - deps - ext + 1);
-
- /* Add the new dependable module name */
- current->m_depcnt++;
- current->m_deparr = xrealloc(current->m_deparr,
- sizeof(char *) * current->m_depcnt);
- current->m_deparr[current->m_depcnt - 1] = dep;
-
- p = next + 2;
- } while (next < end);
- }
-
- /* is there other dependable module(s) ? */
- if (buffer[l-1] == '\\')
- continuation_line = 1;
- else
- continuation_line = 0;
- }
- close(fd);
-
- /*
- * First parse system-specific options and aliases
- * as they take precedence over the kernel ones.
- * >=2.6: we only care about modprobe.conf
- * <=2.4: we care about modules.conf and conf.modules
- */
- if (ENABLE_FEATURE_2_6_MODULES
- && (fd = open("/etc/modprobe.conf", O_RDONLY)) < 0)
- if (ENABLE_FEATURE_2_4_MODULES
- && (fd = open("/etc/modules.conf", O_RDONLY)) < 0)
- if (ENABLE_FEATURE_2_4_MODULES)
- fd = open("/etc/conf.modules", O_RDONLY);
-
- if (fd >= 0) {
- include_conf(&first, ¤t, buffer, sizeof(buffer), fd);
- close(fd);
- }
-
- /* Only 2.6 has a modules.alias file */
- if (ENABLE_FEATURE_2_6_MODULES) {
- /* Parse kernel-declared aliases */
- filename = xasprintf("/lib/modules/%s/modules.alias", un.release);
- fd = open(filename, O_RDONLY);
- if (fd < 0) {
- /* Ok, that didn't work. Fall back to looking in /lib/modules */
- fd = open("/lib/modules/modules.alias", O_RDONLY);
- }
- if (ENABLE_FEATURE_CLEAN_UP)
- free(filename);
-
- if (fd >= 0) {
- include_conf(&first, ¤t, buffer, sizeof(buffer), fd);
- close(fd);
- }
- }
-
- return first;