1/*****************************************************************************\
2*  _  _       _          _              ___                                   *
3* | || | ___ | |_  _ __ | | _  _  __ _ |_  )                                  *
4* | __ |/ _ \|  _|| '_ \| || || |/ _` | / /                                   *
5* |_||_|\___/ \__|| .__/|_| \_,_|\__, |/___|                                  *
6*                 |_|            |___/                                        *
7\*****************************************************************************/
8
9#define _GNU_SOURCE
10
11#include <fcntl.h>
12#include <stdio.h>
13#include <unistd.h>
14#include <stdlib.h>
15#include <string.h>
16#include <errno.h>
17#include <dirent.h>
18#include <ctype.h>
19#include <fnmatch.h>
20#include <sys/types.h>
21#include <sys/wait.h>
22#include <sys/stat.h>
23#include <sys/mman.h>
24#include <sys/utsname.h>
25#include <linux/types.h>
26#include <linux/input.h>
27
28#include "../hotplug2.h"
29#include "../mem_utils.h"
30#include "../parser_utils.h"
31#include "../filemap_utils.h"
32
33int execute(char **argv) {
34	pid_t p;
35
36	p = fork();
37	switch (p) {
38		case -1:
39			return -1;
40		case 0:
41			execvp(argv[0], argv);
42			exit(1);
43			break;
44		default:
45			waitpid(p, NULL, 0);
46			break;
47	}
48	return 0;
49}
50
51int main(int argc, char *argv[]) {
52	struct utsname unamebuf;
53	struct filemap_t aliasmap;
54	char *line, *nline, *nptr;
55	char *token;
56	char *filename;
57
58	char *cur_alias, *match_alias, *module;
59
60	if (argc < 2) {
61		fprintf(stderr, "Usage: hotplug2-modwrap [options for modprobe] <alias>\n");
62	}
63
64	match_alias = strdup(argv[argc - 1]);
65
66	if (uname(&unamebuf)) {
67		ERROR("uname", "Unable to perform uname: %s.", strerror(errno));
68		return 1;
69	}
70
71	/* We use this one */
72	argv[0] = getenv("MODPROBE_COMMAND");
73	if (argv[0] == NULL)
74		argv[0] = "/sbin/modprobe";
75
76	/* "/lib/modules/" + "/" + "\0" */
77	filename = xmalloc(15 + strlen(unamebuf.release) + strlen("modules.alias"));
78	strcpy(filename, "/lib/modules/");
79	strcat(filename, unamebuf.release);
80	strcat(filename, "/modules.alias");
81
82	if (map_file(filename, &aliasmap)) {
83		ERROR("map_file", "Unable to map file: `%s'.", filename);
84		free(filename);
85		free(match_alias);
86		return 1;
87	}
88
89	nptr = aliasmap.map;
90	while ((line = dup_line(nptr, &nptr)) != NULL) {
91		nline = line;
92
93		token = dup_token(nline, &nline, isspace);
94		if (!token || strcmp(token, "alias")) {
95			free(token);
96			free(line);
97			continue;
98		}
99		free(token);
100
101		cur_alias = dup_token(nline, &nline, isspace);
102		if (!cur_alias) {
103			free(line);
104			continue;
105		}
106
107		module = dup_token(nline, &nline, isspace);
108		if (!module) {
109			free(line);
110			free(cur_alias);
111			continue;
112		}
113
114		if (!fnmatch(cur_alias, match_alias, 0)) {
115			argv[argc - 1] = module;
116			if (execute(argv)) {
117				ERROR("execute", "Unable to execute: `%s'.", argv[0]);
118			}
119		}
120
121		free(cur_alias);
122		free(module);
123		free(line);
124	}
125
126	free(filename);
127	free(match_alias);
128	unmap_file(&aliasmap);
129
130	return 0;
131}
132