1 /*****************************************************************************\
3 * | || | ___ | |_ _ __ | | _ _ __ _ |_ ) *
4 * | __ |/ _ \| _|| '_ \| || || |/ _` | / / *
5 * |_||_|\___/ \__|| .__/|_| \_,_|\__, |/___| *
7 \*****************************************************************************/
20 #include <sys/types.h>
24 #include <sys/utsname.h>
25 #include <linux/types.h>
26 #include <linux/input.h>
28 #include "../hotplug2.h"
29 #include "../mem_utils.h"
30 #include "../parser_utils.h"
31 #include "../filemap_utils.h"
33 #define MODULES_PATH "/lib/modules/"
34 #define MODULES_ALIAS "modules.alias"
37 * A simple fork/exec wrapper
39 * @1 Complete argv, including app path
41 * Returns: -1 if error, children return value otherwise
43 int execute(char **argv
) {
52 execvp(argv
[0], argv
);
56 waitpid(p
, &status
, 0);
60 return WEXITSTATUS(status
);
63 int main(int argc
, char *argv
[]) {
64 struct utsname unamebuf
;
65 struct filemap_t aliasmap
;
66 char *line
, *nline
, *nptr
;
70 char *cur_alias
, *match_alias
, *module
;
73 fprintf(stderr
, "Usage: hotplug2-modwrap [options for modprobe] <alias>\n");
76 match_alias
= strdup(argv
[argc
- 1]);
79 * If we can't do uname, we're absolutely screwed and there's no
80 * sense thinking twice about anything.
82 if (uname(&unamebuf
)) {
83 ERROR("uname", "Unable to perform uname: %s.", strerror(errno
));
88 * We allow setting the modprobe command to an arbitrary value.
90 * The whole trick lies in executing modprobe with exactly the
91 * same argv as this app was executed, except we use a different
92 * argv[0] (application path) and argv[argc-1] (we substitute
93 * the given modalias by the matching module name)
95 argv
[0] = getenv("MODPROBE_COMMAND");
97 argv
[0] = "/sbin/modprobe";
100 * Compose a path, /lib/modules/`uname -r`/modules.alias
102 * "/lib/modules/" + "/" + "\0"
104 filename
= xmalloc(strlen(MODULES_PATH
) + strlen(unamebuf
.release
) + strlen(MODULES_ALIAS
));
105 strcpy(filename
, MODULES_PATH
);
106 strcat(filename
, unamebuf
.release
);
107 strcat(filename
, MODULES_ALIAS
);
109 if (map_file(filename
, &aliasmap
)) {
110 ERROR("map_file", "Unable to map file: `%s'.", filename
);
117 * Read all the aliases, match them against given parameter.
120 while ((line
= dup_line(nptr
, &nptr
)) != NULL
) {
124 * We want aliases only
126 token
= dup_token(nline
, &nline
, isspace
);
127 if (!token
|| strcmp(token
, "alias")) {
135 * It's an alias, so fetch it
137 cur_alias
= dup_token(nline
, &nline
, isspace
);
144 * And now we get the module name
146 module
= dup_token(nline
, &nline
, isspace
);
154 * If we match, we do the modalias->module name
155 * substitution as described above and execute.
157 if (!fnmatch(cur_alias
, match_alias
, 0)) {
158 argv
[argc
- 1] = module
;
160 ERROR("execute", "Error during exection of: `%s'.", argv
[0]);
170 * Perhaps we didn't match anything, so we might've been given
171 * a module name instead of a modalias. Try to modprobe it
174 if (strcmp(argv
[argc
- 1], match_alias
) == 0) {
176 ERROR("execute", "Error during exection of: `%s'.", argv
[0]);
182 unmap_file(&aliasmap
);