1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h>
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h>
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h>
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <malloc.h>
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h>
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h>
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/stat.h>
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h>
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern int init_module(void *, unsigned long, const char *);
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void *read_file(const char *filename, ssize_t *_size)
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int ret, fd;
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct stat sb;
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	ssize_t size;
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	void *buffer = NULL;
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* open the file */
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	fd = open(filename, O_RDONLY);
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (fd < 0)
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return NULL;
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* find out how big it is */
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (fstat(fd, &sb) < 0)
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		goto bail;
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	size = sb.st_size;
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* allocate memory for it to be read into */
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	buffer = malloc(size);
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (!buffer)
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		goto bail;
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* slurp it into our buffer */
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	ret = read(fd, buffer, size);
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (ret != size)
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		goto bail;
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* let the caller know how big it is */
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	*_size = size;
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbail:
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	close(fd);
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return buffer;
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define min(x,y) ((x) < (y) ? (x) : (y))
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint insmod_main(int argc, char **argv)
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	void *file;
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	ssize_t size = 0;
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char opts[1024];
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int ret;
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* make sure we've got an argument */
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (argc < 2) {
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		fprintf(stderr, "usage: insmod <module.o>\n");
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return -1;
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* read the file into memory */
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	file = read_file(argv[1], &size);
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (!file) {
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		fprintf(stderr, "insmod: can't open '%s'\n", argv[1]);
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return -1;
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	opts[0] = '\0';
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (argc > 2) {
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		int i, len;
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		char *end = opts + sizeof(opts) - 1;
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		char *ptr = opts;
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (i = 2; (i < argc) && (ptr < end); i++) {
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			len = min(strlen(argv[i]), end - ptr);
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			memcpy(ptr, argv[i], len);
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			ptr += len;
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			*ptr++ = ' ';
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*(ptr - 1) = '\0';
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* pass it to the kernel */
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	ret = init_module(file, size, opts);
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (ret != 0) {
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		fprintf(stderr,
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                "insmod: init_module '%s' failed (%s)\n",
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                argv[1], strerror(errno));
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* free the file buffer */
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	free(file);
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return ret;
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
98