Magellan Linux

Contents of /trunk/mkinitrd-magellan/klibc/usr/utils/insmod.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (show annotations) (download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File MIME type: text/plain
File size: 3398 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd

1 /* insmod.c: insert a module into the kernel.
2 Copyright (C) 2001 Rusty Russell.
3 Copyright (C) 2002 Rusty Russell, IBM Corporation.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 #include <stdio.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <fcntl.h>
24 #include <sys/mman.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <unistd.h>
28 #include <errno.h>
29
30 #define streq(a,b) (strcmp((a),(b)) == 0)
31
32 /* This really needs to be in a header file... */
33 extern long init_module(void *, unsigned long, const char *);
34
35 static void print_usage(const char *progname)
36 {
37 fprintf(stderr, "Usage: %s filename [args]\n", progname);
38 exit(1);
39 }
40
41 /* We use error numbers in a loose translation... */
42 static const char *moderror(int err)
43 {
44 switch (err) {
45 case ENOEXEC:
46 return "Invalid module format";
47 case ENOENT:
48 return "Unknown symbol in module";
49 case ESRCH:
50 return "Module has wrong symbol version";
51 case EINVAL:
52 return "Invalid parameters";
53 default:
54 return strerror(err);
55 }
56 }
57
58 static void *grab_file(const char *filename, unsigned long *size)
59 {
60 unsigned int max = 16384;
61 int ret, fd;
62 void *buffer = malloc(max);
63
64 if (streq(filename, "-"))
65 fd = dup(STDIN_FILENO);
66 else
67 fd = open(filename, O_RDONLY, 0);
68
69 if (fd < 0)
70 return NULL;
71
72 *size = 0;
73 while ((ret = read(fd, buffer + *size, max - *size)) > 0) {
74 *size += ret;
75 if (*size == max)
76 buffer = realloc(buffer, max *= 2);
77 }
78 if (ret < 0) {
79 free(buffer);
80 buffer = NULL;
81 }
82 close(fd);
83 return buffer;
84 }
85
86 int main(int argc, char *argv[])
87 {
88 int i;
89 long int ret;
90 unsigned long len;
91 void *file;
92 char *filename, *options = strdup("");
93 char *progname = argv[0];
94
95 if (argv[1] && (streq(argv[1], "--version") || streq(argv[1], "-V"))) {
96 puts("klibc insmod");
97 exit(0);
98 }
99
100 /* Ignore old options, for backwards compat. */
101 while (argv[1] && (streq(argv[1], "-p")
102 || streq(argv[1], "-s")
103 || streq(argv[1], "-f"))) {
104 argv++;
105 argc--;
106 }
107
108 filename = argv[1];
109 if (!filename)
110 print_usage(progname);
111
112 /* Rest is options */
113 for (i = 2; i < argc; i++) {
114 options = realloc(options,
115 strlen(options) + 2 + strlen(argv[i]) + 2);
116 /* Spaces handled by "" pairs, but no way of escaping
117 quotes */
118 if (strchr(argv[i], ' '))
119 strcat(options, "\"");
120 strcat(options, argv[i]);
121 if (strchr(argv[i], ' '))
122 strcat(options, "\"");
123 strcat(options, " ");
124 }
125
126 file = grab_file(filename, &len);
127 if (!file) {
128 fprintf(stderr, "insmod: can't read '%s': %s\n",
129 filename, strerror(errno));
130 exit(1);
131 }
132
133 ret = init_module(file, len, options);
134 if (ret != 0) {
135 fprintf(stderr, "insmod: error inserting '%s': %li %s\n",
136 filename, ret, moderror(errno));
137 exit(1);
138 }
139 exit(0);
140 }