kmodloader: fix possible segfaults
[project/ubox.git] / kmodloader.c
1 /*
2  * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
3  * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License version 2.1
7  * as published by the Free Software Foundation
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14
15 #define _GNU_SOURCE
16 #include <sys/syscall.h>
17 #include <sys/mman.h>
18 #include <sys/utsname.h>
19
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <sys/syscall.h>
23 #include <sys/types.h>
24 #include <values.h>
25 #include <errno.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <libgen.h>
31 #include <glob.h>
32 #include <elf.h>
33
34 #include <libubox/avl.h>
35 #include <libubox/avl-cmp.h>
36 #include <libubox/utils.h>
37 #include <libubox/ulog.h>
38
39 #define DEF_MOD_PATH "/modules/%s/"
40
41 enum {
42         SCANNED,
43         PROBE,
44         LOADED,
45 };
46
47 struct module {
48         char *name;
49         char *depends;
50         char *opts;
51
52         int size;
53         int usage;
54         int state;
55         int error;
56         int refcnt;                     /* number of references from module_node.m */
57 };
58
59 struct module_node {
60         struct avl_node avl;
61         struct module *m;
62         bool is_alias;
63 };
64
65 static struct avl_tree modules;
66
67 static char **module_folders = NULL;
68
69 static void free_module(struct module *m);
70
71 static int init_module_folders(void)
72 {
73         int n = 0;
74         struct stat st;
75         struct utsname ver;
76         char *s, *e, *p, path[256], ldpath[256];
77
78         e = ldpath;
79         s = getenv("LD_LIBRARY_PATH");
80
81         if (s)
82                 e += snprintf(ldpath, sizeof(ldpath), "%s:", s);
83
84         e += snprintf(e, sizeof(ldpath) - (e - ldpath), "/lib");
85
86         uname(&ver);
87
88         for (s = p = ldpath; p <= e; p++) {
89                 if (*p != ':' && *p != '\0')
90                         continue;
91
92                 *p = 0;
93                 snprintf(path, sizeof(path), "%s" DEF_MOD_PATH, s, ver.release);
94
95                 if (!stat(path, &st) && S_ISDIR(st.st_mode)) {
96                         module_folders = realloc(module_folders, sizeof(p) * (n + 2));
97
98                         if (!module_folders)
99                                 return -1;
100
101                         module_folders[n++] = strdup(path);
102                 }
103
104                 s = p + 1;
105         }
106
107         if (!module_folders)
108                 return -1;
109
110         module_folders[n] = NULL;
111         return 0;
112 }
113
114 static struct module *find_module(const char *name)
115 {
116         struct module_node *mn;
117         mn = avl_find_element(&modules, name, mn, avl);
118         if (mn)
119                 return mn->m;
120         else
121                 return NULL;
122 }
123
124 static void free_modules(void)
125 {
126         struct module_node *mn, *tmp;
127
128         avl_remove_all_elements(&modules, mn, avl, tmp) {
129                 struct module *m = mn->m;
130
131                 m->refcnt -= 1;
132                 if (m->refcnt == 0)
133                         free_module(m);
134                 free(mn);
135         }
136 }
137
138 static char* get_module_path(char *name)
139 {
140         char **p;
141         static char path[256];
142         struct stat s;
143
144         if (!stat(name, &s) && S_ISREG(s.st_mode))
145                 return name;
146
147         for (p = module_folders; *p; p++) {
148                 snprintf(path, sizeof(path), "%s%s.ko", *p, name);
149                 if (!stat(path, &s) && S_ISREG(s.st_mode))
150                         return path;
151         }
152
153         return NULL;
154 }
155
156 static char* get_module_name(char *path)
157 {
158         static char name[33];
159         char *t;
160
161         strncpy(name, basename(path), sizeof(name) - 1);
162
163         t = strstr(name, ".ko");
164         if (t)
165                 *t = '\0';
166
167         return name;
168 }
169
170 static int elf64_find_section(char *map, const char *section, unsigned int *offset, unsigned int *size)
171 {
172         const char *secnames;
173         Elf64_Ehdr *e;
174         Elf64_Shdr *sh;
175         int i;
176
177         e = (Elf64_Ehdr *) map;
178         sh = (Elf64_Shdr *) (map + e->e_shoff);
179
180         secnames = map + sh[e->e_shstrndx].sh_offset;
181         for (i = 0; i < e->e_shnum; i++) {
182                 if (!strcmp(section, secnames + sh[i].sh_name)) {
183                         *size = sh[i].sh_size;
184                         *offset = sh[i].sh_offset;
185                         return 0;
186                 }
187         }
188
189         return -1;
190 }
191
192 static int elf32_find_section(char *map, const char *section, unsigned int *offset, unsigned int *size)
193 {
194         const char *secnames;
195         Elf32_Ehdr *e;
196         Elf32_Shdr *sh;
197         int i;
198
199         e = (Elf32_Ehdr *) map;
200         sh = (Elf32_Shdr *) (map + e->e_shoff);
201
202         secnames = map + sh[e->e_shstrndx].sh_offset;
203         for (i = 0; i < e->e_shnum; i++) {
204                 if (!strcmp(section, secnames + sh[i].sh_name)) {
205                         *size = sh[i].sh_size;
206                         *offset = sh[i].sh_offset;
207                         return 0;
208                 }
209         }
210
211         return -1;
212 }
213
214 static int elf_find_section(char *map, const char *section, unsigned int *offset, unsigned int *size)
215 {
216         int clazz = map[EI_CLASS];
217         int endian = map[EI_DATA];
218
219 #if __BYTE_ORDER == __LITTLE_ENDIAN
220         if (endian != ELFDATA2LSB)
221 #elif __BYTE_ORDER == __BIG_ENDIAN
222         if (endian != ELFDATA2MSB)
223 #else
224 #error "unsupported endian"
225 #endif
226         {
227                 ULOG_ERR("invalid endianess: %d\n", endian);
228                 return -1;
229         }
230
231         if (clazz == ELFCLASS32)
232                 return elf32_find_section(map, section, offset, size);
233         else if (clazz == ELFCLASS64)
234                 return elf64_find_section(map, section, offset, size);
235
236         ULOG_ERR("unknown elf format %d\n", clazz);
237
238         return -1;
239 }
240
241 static struct module_node *
242 alloc_module_node(const char *name, struct module *m, bool is_alias)
243 {
244         struct module_node *mn;
245         char *_name;
246
247         mn = calloc_a(sizeof(*mn),
248                 &_name, strlen(name) + 1);
249         if (mn) {
250                 mn->avl.key = strcpy(_name, name);
251                 mn->m = m;
252                 mn->is_alias = is_alias;
253                 avl_insert(&modules, &mn->avl);
254                 m->refcnt += 1;
255         }
256         return mn;
257 }
258
259 static struct module *
260 alloc_module(const char *name, const char * const *aliases, int naliases, const char *depends, int size)
261 {
262         struct module *m;
263         char *_name, *_dep;
264         int i;
265
266         m = calloc_a(sizeof(*m),
267                 &_name, strlen(name) + 1,
268                 &_dep, depends ? strlen(depends) + 2 : 0);
269         if (!m)
270                 return NULL;
271
272         m->name = strcpy(_name, name);
273         m->opts = 0;
274
275         if (depends) {
276                 m->depends = strcpy(_dep, depends);
277                 while (*_dep) {
278                         if (*_dep == ',')
279                                 *_dep = '\0';
280                         _dep++;
281                 }
282         }
283         m->size = size;
284
285         m->refcnt = 0;
286         alloc_module_node(m->name, m, false);
287         for (i = 0; i < naliases; i++)
288                 alloc_module_node(aliases[i], m, true);
289
290         return m;
291 }
292
293 static void free_module(struct module *m)
294 {
295         if (m->opts)
296                 free(m->opts);
297         free(m);
298 }
299
300 static int scan_loaded_modules(void)
301 {
302         size_t buf_len = 0;
303         char *buf = NULL;
304         FILE *fp;
305
306         fp = fopen("/proc/modules", "r");
307         if (!fp) {
308                 ULOG_ERR("failed to open /proc/modules\n");
309                 return -1;
310         }
311
312         while (getline(&buf, &buf_len, fp) > 0) {
313                 struct module m;
314                 struct module *n;
315
316                 m.name = strtok(buf, " ");
317                 m.size = atoi(strtok(NULL, " "));
318                 m.usage = atoi(strtok(NULL, " "));
319                 m.depends = strtok(NULL, " ");
320
321                 if (!m.name || !m.depends)
322                         continue;
323
324                 n = find_module(m.name);
325                 if (!n) {
326                         /* possibly a module outside /lib/modules/<ver>/ */
327                         n = alloc_module(m.name, NULL, 0, m.depends, m.size);
328                 }
329                 n->usage = m.usage;
330                 n->state = LOADED;
331         }
332         free(buf);
333         fclose(fp);
334
335         return 0;
336 }
337
338 static struct module* get_module_info(const char *module, const char *name)
339 {
340         int fd = open(module, O_RDONLY);
341         unsigned int offset, size;
342         char *map = MAP_FAILED, *strings, *dep = NULL;
343         const char *aliases[32] = { 0 };
344         int naliases = 0;
345         struct module *m = NULL;
346         struct stat s;
347
348         if (fd < 0) {
349                 ULOG_ERR("failed to open %s\n", module);
350                 goto out;
351         }
352
353         if (fstat(fd, &s) == -1) {
354                 ULOG_ERR("failed to stat %s\n", module);
355                 goto out;
356         }
357
358         map = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
359         if (map == MAP_FAILED) {
360                 ULOG_ERR("failed to mmap %s\n", module);
361                 goto out;
362         }
363
364         if (elf_find_section(map, ".modinfo", &offset, &size)) {
365                 ULOG_ERR("failed to load the .modinfo section from %s\n", module);
366                 goto out;
367         }
368
369         strings = map + offset;
370         while (true) {
371                 char *sep;
372                 int len;
373
374                 while (!strings[0])
375                         strings++;
376                 if (strings >= map + offset + size)
377                         break;
378                 sep = strstr(strings, "=");
379                 if (!sep)
380                         break;
381                 len = sep - strings;
382                 sep++;
383                 if (!strncmp(strings, "depends=", len + 1))
384                         dep = sep;
385                 else if (!strncmp(strings, "alias=", len + 1)) {
386                         if (naliases < ARRAY_SIZE(aliases))
387                                 aliases[naliases++] = sep;
388                         else
389                                 ULOG_WARN("module %s has more than %d aliases: truncated",
390                                                 name, ARRAY_SIZE(aliases));
391                 }
392                 strings = &sep[strlen(sep)];
393         }
394
395         m = alloc_module(name, aliases, naliases, dep, s.st_size);
396
397         if (m)
398                 m->state = SCANNED;
399
400 out:
401         if (map != MAP_FAILED)
402                 munmap(map, s.st_size);
403
404         if (fd >= 0)
405                 close(fd);
406
407         return m;
408 }
409
410 static int scan_module_folder(const char *dir)
411 {
412         int gl_flags = GLOB_NOESCAPE | GLOB_MARK;
413         struct utsname ver;
414         char *path;
415         glob_t gl;
416         int j;
417
418         uname(&ver);
419         path = alloca(strlen(dir) + sizeof("*.ko") + 1);
420         sprintf(path, "%s*.ko", dir);
421
422         if (glob(path, gl_flags, NULL, &gl) < 0)
423                 return -1;
424
425         for (j = 0; j < gl.gl_pathc; j++) {
426                 char *name = get_module_name(gl.gl_pathv[j]);
427                 struct module *m;
428
429                 if (!name)
430                         continue;
431
432                 m = find_module(name);
433                 if (!m)
434                         get_module_info(gl.gl_pathv[j], name);
435         }
436
437         globfree(&gl);
438
439         return 0;
440 }
441
442 static int scan_module_folders(void)
443 {
444         int rv = 0;
445         char **p;
446
447         if (init_module_folders())
448                 return -1;
449
450         for (p = module_folders; *p; p++)
451                 rv |= scan_module_folder(*p);
452
453         return rv;
454 }
455
456 static int print_modinfo(char *module)
457 {
458         int fd = open(module, O_RDONLY);
459         unsigned int offset, size;
460         struct stat s;
461         char *map = MAP_FAILED, *strings;
462         int rv = -1;
463
464         if (fd < 0) {
465                 ULOG_ERR("failed to open %s\n", module);
466                 goto out;
467         }
468
469         if (fstat(fd, &s) == -1) {
470                 ULOG_ERR("failed to stat %s\n", module);
471                 goto out;
472         }
473
474         map = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
475         if (map == MAP_FAILED) {
476                 ULOG_ERR("failed to mmap %s\n", module);
477                 goto out;
478         }
479
480         if (elf_find_section(map, ".modinfo", &offset, &size)) {
481                 ULOG_ERR("failed to load the .modinfo section from %s\n", module);
482                 goto out;
483         }
484
485         strings = map + offset;
486         printf("module:\t\t%s\n", module);
487         while (true) {
488                 char *dup = NULL;
489                 char *sep;
490
491                 while (!strings[0])
492                         strings++;
493                 if (strings >= map + offset + size)
494                         break;
495                 sep = strstr(strings, "=");
496                 if (!sep)
497                         break;
498                 dup = strndup(strings, sep - strings);
499                 sep++;
500                 if (strncmp(strings, "parm", 4)) {
501                         if (strlen(dup) < 7)
502                                 printf("%s:\t\t%s\n",  dup, sep);
503                         else
504                                 printf("%s:\t%s\n",  dup, sep);
505                 }
506                 strings = &sep[strlen(sep)];
507                 if (dup)
508                         free(dup);
509         }
510
511         rv = 0;
512
513 out:
514         if (map != MAP_FAILED)
515                 munmap(map, s.st_size);
516
517         if (fd >= 0)
518                 close(fd);
519
520         return rv;
521 }
522
523 static int deps_available(struct module *m, int verbose)
524 {
525         char *dep;
526         int err = 0;
527
528         if (!m->depends || !strcmp(m->depends, "-") || !strcmp(m->depends, ""))
529                 return 0;
530
531         dep = m->depends;
532
533         while (*dep) {
534                 m = find_module(dep);
535
536                 if (verbose && !m)
537                         ULOG_ERR("missing dependency %s\n", dep);
538                 if (verbose && m && (m->state != LOADED))
539                         ULOG_ERR("dependency not loaded %s\n", dep);
540                 if (!m || (m->state != LOADED))
541                         err++;
542                 dep += strlen(dep) + 1;
543         }
544
545         return err;
546 }
547
548 static int insert_module(char *path, const char *options)
549 {
550         void *data = 0;
551         struct stat s;
552         int fd, ret = -1;
553
554         if (stat(path, &s)) {
555                 ULOG_ERR("missing module %s\n", path);
556                 return ret;
557         }
558
559         fd = open(path, O_RDONLY);
560         if (fd < 0) {
561                 ULOG_ERR("cannot open %s\n", path);
562                 return ret;
563         }
564
565         data = malloc(s.st_size);
566         if (!data)
567                 goto out;
568
569         if (read(fd, data, s.st_size) == s.st_size) {
570                 ret = syscall(__NR_init_module, data, (unsigned long) s.st_size, options);
571                 if (errno == EEXIST)
572                         ret = 0;
573         }
574         else
575                 ULOG_ERR("failed to read full module %s\n", path);
576
577 out:
578         close(fd);
579         free(data);
580
581         return ret;
582 }
583
584 static void load_moddeps(struct module *_m)
585 {
586         char *dep;
587         struct module *m;
588
589         if (!strcmp(_m->depends, "-") || !strcmp(_m->depends, ""))
590                 return;
591
592         dep = _m->depends;
593
594         while (*dep) {
595                 m = find_module(dep);
596
597                 if (!m)
598                         ULOG_ERR("failed to find dependency %s\n", dep);
599                 if (m && (m->state != LOADED)) {
600                         m->state = PROBE;
601                         load_moddeps(m);
602                 }
603
604                 dep = dep + strlen(dep) + 1;
605         }
606 }
607
608 static int iterations = 0;
609 static int load_modprobe(void)
610 {
611         int loaded, todo;
612         struct module_node *mn;
613         struct module *m;
614
615         avl_for_each_element(&modules, mn, avl) {
616                 if (mn->is_alias)
617                         continue;
618                 m = mn->m;
619                 if (m->state == PROBE)
620                         load_moddeps(m);
621         }
622
623         do {
624                 loaded = 0;
625                 todo = 0;
626                 avl_for_each_element(&modules, mn, avl) {
627                         if (mn->is_alias)
628                                 continue;
629                         m = mn->m;
630                         if ((m->state == PROBE) && (!deps_available(m, 0))) {
631                                 if (!insert_module(get_module_path(m->name), (m->opts) ? (m->opts) : (""))) {
632                                         m->state = LOADED;
633                                         m->error = 0;
634                                         loaded++;
635                                         continue;
636                                 }
637                                 m->error = 1;
638                         }
639
640                         if ((m->state == PROBE) || m->error)
641                                 todo++;
642                 }
643                 iterations++;
644         } while (loaded);
645
646         return todo;
647 }
648
649 static int print_insmod_usage(void)
650 {
651         ULOG_INFO("Usage:\n\tinsmod filename [args]\n");
652
653         return -1;
654 }
655
656 static int print_modprobe_usage(void)
657 {
658         ULOG_INFO("Usage:\n\tmodprobe [-q] filename\n");
659
660         return -1;
661 }
662
663 static int print_usage(char *arg)
664 {
665         ULOG_INFO("Usage:\n\t%s module\n", arg);
666
667         return -1;
668 }
669
670 static int main_insmod(int argc, char **argv)
671 {
672         char *name, *cur, *options;
673         int i, ret, len;
674
675         if (argc < 2)
676                 return print_insmod_usage();
677
678         name = get_module_name(argv[1]);
679         if (!name) {
680                 ULOG_ERR("cannot find module - %s\n", argv[1]);
681                 return -1;
682         }
683
684         if (scan_loaded_modules())
685                 return -1;
686
687         if (find_module(name)) {
688                 ULOG_ERR("module is already loaded - %s\n", name);
689                 return -1;
690
691         }
692
693         free_modules();
694
695         for (len = 0, i = 2; i < argc; i++)
696                 len += strlen(argv[i]) + 1;
697
698         options = malloc(len);
699         if (!options) {
700                 ret = -1;
701                 goto err;
702         }
703
704         options[0] = 0;
705         cur = options;
706         for (i = 2; i < argc; i++) {
707                 if (options[0]) {
708                         *cur = ' ';
709                         cur++;
710                 }
711                 cur += sprintf(cur, "%s", argv[i]);
712         }
713
714         if (init_module_folders()) {
715                 fprintf(stderr, "Failed to find the folder holding the modules\n");
716                 ret = -1;
717                 goto err;
718         }
719
720         if (get_module_path(argv[1])) {
721                 name = argv[1];
722         } else if (!get_module_path(name)) {
723                 fprintf(stderr, "Failed to find %s. Maybe it is a built in module ?\n", name);
724                 ret = -1;
725                 goto err;
726         }
727
728         ret = insert_module(get_module_path(name), options);
729         if (ret)
730                 ULOG_ERR("failed to insert %s\n", get_module_path(name));
731
732 err:
733         free(options);
734         return ret;
735 }
736
737 static int main_rmmod(int argc, char **argv)
738 {
739         struct module *m;
740         char *name;
741         int ret;
742
743         if (argc != 2)
744                 return print_usage("rmmod");
745
746         if (scan_loaded_modules())
747                 return -1;
748
749         name = get_module_name(argv[1]);
750         m = find_module(name);
751         if (!m) {
752                 ULOG_ERR("module is not loaded\n");
753                 return -1;
754         }
755         ret = syscall(__NR_delete_module, m->name, 0);
756
757         if (ret)
758                 ULOG_ERR("unloading the module failed\n");
759
760         free_modules();
761
762         return ret;
763 }
764
765 static int main_lsmod(int argc, char **argv)
766 {
767         struct module_node *mn;
768         struct module *m;
769         char *dep;
770
771         if (scan_loaded_modules())
772                 return -1;
773
774         avl_for_each_element(&modules, mn, avl) {
775                 if (mn->is_alias)
776                         continue;
777                 m = mn->m;
778                 if (m->state == LOADED) {
779                         printf("%-20s%8d%3d ",
780                                 m->name, m->size, m->usage);
781                         if (m->depends && strcmp(m->depends, "-") && strcmp(m->depends, "")) {
782                                 dep = m->depends;
783                                 while (*dep) {
784                                         printf("%s", dep);
785                                         dep = dep + strlen(dep) + 1;
786                                         if (*dep)
787                                                 printf(",");
788                                 }
789                         }
790                         printf("\n");
791                 }
792         }
793
794         free_modules();
795
796         return 0;
797 }
798
799 static int main_modinfo(int argc, char **argv)
800 {
801         struct module *m;
802         char *name;
803
804         if (argc != 2)
805                 return print_usage("modinfo");
806
807         if (scan_module_folders())
808                 return -1;
809
810         name = get_module_name(argv[1]);
811         m = find_module(name);
812         if (!m) {
813                 ULOG_ERR("cannot find module - %s\n", argv[1]);
814                 return -1;
815         }
816
817         name = get_module_path(m->name);
818         if (!name) {
819                 ULOG_ERR("cannot find path of module - %s\n", m->name);
820                 return -1;
821         }
822
823         print_modinfo(name);
824
825         return 0;
826 }
827
828 static int main_modprobe(int argc, char **argv)
829 {
830         struct module_node *mn;
831         struct module *m;
832         char *name;
833         char *mod = NULL;
834         int opt;
835         bool quiet = false;
836
837         while ((opt = getopt(argc, argv, "q")) != -1 ) {
838                 switch (opt) {
839                         case 'q': /* shhhh! */
840                                 quiet = true;
841                                 break;
842                         default: /* '?' */
843                                 return print_modprobe_usage();
844                                 break;
845                         }
846         }
847
848         if (optind >= argc)
849                 return print_modprobe_usage(); /* expected module after options */
850
851         mod = argv[optind];
852
853         if (scan_module_folders())
854                 return -1;
855
856         if (scan_loaded_modules())
857                 return -1;
858
859         name = get_module_name(mod);
860         m = find_module(name);
861         if (m && m->state == LOADED) {
862                 if (!quiet)
863                         ULOG_ERR("%s is already loaded\n", name);
864                 return 0;
865         } else if (!m) {
866                 if (!quiet)
867                         ULOG_ERR("failed to find a module named %s\n", name);
868                 return -1;
869         } else {
870                 int fail;
871
872                 m->state = PROBE;
873
874                 fail = load_modprobe();
875
876                 if (fail) {
877                         ULOG_ERR("%d module%s could not be probed\n",
878                                  fail, (fail == 1) ? ("") : ("s"));
879
880                         avl_for_each_element(&modules, mn, avl) {
881                                 if (mn->is_alias)
882                                         continue;
883                                 m = mn->m;
884                                 if ((m->state == PROBE) || m->error)
885                                         ULOG_ERR("- %s\n", m->name);
886                         }
887                 }
888         }
889
890         free_modules();
891
892         return 0;
893 }
894
895 static int main_loader(int argc, char **argv)
896 {
897         int gl_flags = GLOB_NOESCAPE | GLOB_MARK;
898         char *dir = "/etc/modules.d/";
899         struct module_node *mn;
900         struct module *m;
901         glob_t gl;
902         char *path;
903         int fail, j;
904
905         if (argc > 1)
906                 dir = argv[1];
907
908         path = malloc(strlen(dir) + 2);
909         if (!path)
910                 return -1;
911
912         strcpy(path, dir);
913         strcat(path, "*");
914
915         if (scan_module_folders()) {
916                 free (path);
917                 return -1;
918         }
919
920         if (scan_loaded_modules()) {
921                 free (path);
922                 return -1;
923         }
924
925         ULOG_INFO("loading kernel modules from %s\n", path);
926
927         if (glob(path, gl_flags, NULL, &gl) < 0)
928                 goto out;
929
930         for (j = 0; j < gl.gl_pathc; j++) {
931                 FILE *fp = fopen(gl.gl_pathv[j], "r");
932                 size_t mod_len = 0;
933                 char *mod = NULL;
934
935                 if (!fp) {
936                         ULOG_ERR("failed to open %s\n", gl.gl_pathv[j]);
937                         continue;
938                 }
939
940                 while (getline(&mod, &mod_len, fp) > 0) {
941                         char *nl = strchr(mod, '\n');
942                         struct module *m;
943                         char *opts;
944
945                         if (nl)
946                                 *nl = '\0';
947
948                         opts = strchr(mod, ' ');
949                         if (opts)
950                                 *opts++ = '\0';
951
952                         m = find_module(get_module_name(mod));
953                         if (!m || (m->state == LOADED))
954                                 continue;
955
956                         if (opts)
957                                 m->opts = strdup(opts);
958                         m->state = PROBE;
959                         if (basename(gl.gl_pathv[j])[0] - '0' <= 9)
960                                 load_modprobe();
961
962                 }
963                 free(mod);
964                 fclose(fp);
965         }
966
967         fail = load_modprobe();
968
969         if (fail) {
970                 ULOG_ERR("%d module%s could not be probed\n",
971                          fail, (fail == 1) ? ("") : ("s"));
972
973                 avl_for_each_element(&modules, mn, avl) {
974                         if (mn->is_alias)
975                                 continue;
976                         m = mn->m;
977                         if ((m->state == PROBE) || (m->error))
978                                 ULOG_ERR("- %s - %d\n", m->name, deps_available(m, 1));
979                 }
980         } else {
981                 ULOG_INFO("done loading kernel modules from %s\n", path);
982         }
983
984 out:
985         globfree(&gl);
986         free(path);
987
988         return 0;
989 }
990
991 static inline char weight(char c)
992 {
993         return c == '_' ? '-' : c;
994 }
995
996 static int avl_modcmp(const void *k1, const void *k2, void *ptr)
997 {
998         const char *s1 = k1;
999         const char *s2 = k2;
1000
1001         while (*s1 && (weight(*s1) == weight(*s2)))
1002         {
1003                 s1++;
1004                 s2++;
1005         }
1006
1007         return (unsigned char)weight(*s1) - (unsigned char)weight(*s2);
1008 }
1009
1010 int main(int argc, char **argv)
1011 {
1012         char *exec = basename(*argv);
1013
1014         avl_init(&modules, avl_modcmp, false, NULL);
1015         if (!strcmp(exec, "insmod"))
1016                 return main_insmod(argc, argv);
1017
1018         if (!strcmp(exec, "rmmod"))
1019                 return main_rmmod(argc, argv);
1020
1021         if (!strcmp(exec, "lsmod"))
1022                 return main_lsmod(argc, argv);
1023
1024         if (!strcmp(exec, "modinfo"))
1025                 return main_modinfo(argc, argv);
1026
1027         if (!strcmp(exec, "modprobe"))
1028                 return main_modprobe(argc, argv);
1029
1030         ulog_open(ULOG_KMSG, LOG_USER, "kmodloader");
1031         return main_loader(argc, argv);
1032 }