char *name;
char *depends;
char *opts;
- char **aliases;
- int naliases;
int size;
int usage;
if (!stat(path, &st) && S_ISDIR(st.st_mode)) {
module_folders = realloc(module_folders, sizeof(p) * (n + 2));
- if (!module_folders)
+ if (!module_folders) {
+ ULOG_ERR("out of memory\n");
return -1;
+ }
module_folders[n++] = strdup(path);
}
static char* get_module_name(char *path)
{
- static char name[32];
+ static char name[33];
char *t;
- strncpy(name, basename(path), sizeof(name));
+ strncpy(name, basename(path), sizeof(name) - 1);
t = strstr(name, ".ko");
if (t)
static int elf_find_section(char *map, const char *section, unsigned int *offset, unsigned int *size)
{
int clazz = map[EI_CLASS];
+ int endian = map[EI_DATA];
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ if (endian != ELFDATA2LSB)
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ if (endian != ELFDATA2MSB)
+#else
+#error "unsupported endian"
+#endif
+ {
+ ULOG_ERR("invalid endianess: %d\n", endian);
+ return -1;
+ }
if (clazz == ELFCLASS32)
return elf32_find_section(map, section, offset, size);
{
struct module *m;
char *_name, *_dep;
- char **_aliases;
- int i, len_aliases;
+ int i;
- len_aliases = naliases * sizeof(aliases[0]);
- for (i = 0; i < naliases; i++)
- len_aliases += strlen(aliases[i]) + 1;
m = calloc_a(sizeof(*m),
&_name, strlen(name) + 1,
- &_dep, depends ? strlen(depends) + 2 : 0,
- &_aliases, len_aliases);
+ &_dep, depends ? strlen(depends) + 2 : 0);
if (!m)
return NULL;
}
}
m->size = size;
- m->naliases = naliases;
- if (naliases == 0)
- m->aliases = NULL;
- else {
- char *ptr = (char *)_aliases + naliases * sizeof(_aliases[0]);
- int len;
-
- i = 0;
- do {
- len = strlen(aliases[i]) + 1;
- memcpy(ptr, aliases[i], len);
- _aliases[i] = ptr;
- ptr += len;
- i++;
- } while (i < naliases);
- m->aliases = _aliases;
- }
m->refcnt = 0;
alloc_module_node(m->name, m, false);
- for (i = 0; i < m->naliases; i++)
- alloc_module_node(m->aliases[i], m, true);
+ for (i = 0; i < naliases; i++)
+ alloc_module_node(aliases[i], m, true);
return m;
}
int fd = open(module, O_RDONLY);
unsigned int offset, size;
char *map = MAP_FAILED, *strings, *dep = NULL;
- const char *aliases[32];
+ const char **aliases = NULL;
int naliases = 0;
struct module *m = NULL;
struct stat s;
if (!strncmp(strings, "depends=", len + 1))
dep = sep;
else if (!strncmp(strings, "alias=", len + 1)) {
- if (naliases < ARRAY_SIZE(aliases))
- aliases[naliases++] = sep;
- else
- ULOG_WARN("module %s has more than %d aliases: truncated",
- name, ARRAY_SIZE(aliases));
+ aliases = realloc(aliases, sizeof(sep) * (naliases + 1));
+ if (!aliases) {
+ ULOG_ERR("out of memory\n");
+ goto out;
+ }
+
+ aliases[naliases++] = sep;
}
strings = &sep[strlen(sep)];
}
if (fd >= 0)
close(fd);
+ free(aliases);
+
return m;
}
struct utsname ver;
char *path;
glob_t gl;
- int j;
+ int j, rv = 0;
uname(&ver);
path = alloca(strlen(dir) + sizeof("*.ko") + 1);
continue;
m = find_module(name);
- if (!m)
- get_module_info(gl.gl_pathv[j], name);
+ if (!m) {
+ if (!get_module_info(gl.gl_pathv[j], name))
+ rv |= -1;
+ }
}
globfree(&gl);
- return 0;
+ return rv;
}
static int scan_module_folders(void)
}
data = malloc(s.st_size);
+ if (!data) {
+ ULOG_ERR("out of memory\n");
+ goto out;
+ }
+
if (read(fd, data, s.st_size) == s.st_size) {
ret = syscall(__NR_init_module, data, (unsigned long) s.st_size, options);
if (errno == EEXIST)
else
ULOG_ERR("failed to read full module %s\n", path);
+out:
close(fd);
free(data);
len += strlen(argv[i]) + 1;
options = malloc(len);
+ if (!options) {
+ ULOG_ERR("out of memory\n");
+ ret = -1;
+ goto err;
+ }
+
options[0] = 0;
cur = options;
for (i = 2; i < argc; i++) {
if (init_module_folders()) {
fprintf(stderr, "Failed to find the folder holding the modules\n");
- return -1;
+ ret = -1;
+ goto err;
}
if (get_module_path(argv[1])) {
name = argv[1];
} else if (!get_module_path(name)) {
fprintf(stderr, "Failed to find %s. Maybe it is a built in module ?\n", name);
- return -1;
+ ret = -1;
+ goto err;
}
ret = insert_module(get_module_path(name), options);
- free(options);
-
if (ret)
ULOG_ERR("failed to insert %s\n", get_module_path(name));
+err:
+ free(options);
return ret;
}
if (m && m->state == LOADED) {
if (!quiet)
ULOG_ERR("%s is already loaded\n", name);
- return -1;
+ return 0;
} else if (!m) {
if (!quiet)
ULOG_ERR("failed to find a module named %s\n", name);
dir = argv[1];
path = malloc(strlen(dir) + 2);
+ if (!path) {
+ ULOG_ERR("out of memory\n");
+ return -1;
+ }
+
strcpy(path, dir);
strcat(path, "*");
return 0;
}
+static inline char weight(char c)
+{
+ return c == '_' ? '-' : c;
+}
+
static int avl_modcmp(const void *k1, const void *k2, void *ptr)
{
const char *s1 = k1;
const char *s2 = k2;
- while (*s1 && ((*s1 == *s2) ||
- ((*s1 == '_') && (*s2 == '-')) ||
- ((*s1 == '-') && (*s2 == '_'))))
+ while (*s1 && (weight(*s1) == weight(*s2)))
{
s1++;
s2++;
}
- return *(const unsigned char *)s1 - *(const unsigned char *)s2;
+ return (unsigned char)weight(*s1) - (unsigned char)weight(*s2);
}
int main(int argc, char **argv)