~mirabilos/klibc/master

« back to all changes in this revision

Viewing changes to usr/utils/insmod.c

  • Committer: H. Peter Anvin
  • Date: 2006-05-01 00:56:02 UTC
  • Revision ID: git-v1:5dea5e01daaaff0685016f23b5cb46240f28e792
[klibc] Reorganize the standalone klibc tree to match the in-kernel tree

Right now, it's harder than it should to apply and test patches using
the standalone klibc tree.  Reorganize the standalone tree to match
the in-kernel tree.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
31
#define streq(a,b) (strcmp((a),(b)) == 0)
 
32
 
 
33
/* This really needs to be in a header file... */
 
34
extern long init_module(void *, unsigned long, const char *);
 
35
 
 
36
static void print_usage(const char *progname)
 
37
{
 
38
        fprintf(stderr, "Usage: %s filename [args]\n", progname);
 
39
        exit(1);
 
40
}
 
41
 
 
42
/* We use error numbers in a loose translation... */
 
43
static const char *moderror(int err)
 
44
{
 
45
        switch (err) {
 
46
        case ENOEXEC:
 
47
                return "Invalid module format";
 
48
        case ENOENT:
 
49
                return "Unknown symbol in module";
 
50
        case ESRCH:
 
51
                return "Module has wrong symbol version";
 
52
        case EINVAL:
 
53
                return "Invalid parameters";
 
54
        default:
 
55
                return strerror(err);
 
56
        }
 
57
}
 
58
 
 
59
static void *grab_file(const char *filename, unsigned long *size)
 
60
{
 
61
        unsigned int max = 16384;
 
62
        int ret, fd;
 
63
        void *buffer = malloc(max);
 
64
 
 
65
        if (streq(filename, "-"))
 
66
                fd = dup(STDIN_FILENO);
 
67
        else
 
68
                fd = open(filename, O_RDONLY, 0);
 
69
 
 
70
        if (fd < 0)
 
71
                return NULL;
 
72
 
 
73
        *size = 0;
 
74
        while ((ret = read(fd, buffer + *size, max - *size)) > 0) {
 
75
                *size += ret;
 
76
                if (*size == max)
 
77
                        buffer = realloc(buffer, max *= 2);
 
78
        }
 
79
        if (ret < 0) {
 
80
                free(buffer);
 
81
                buffer = NULL;
 
82
        }
 
83
        close(fd);
 
84
        return buffer;
 
85
}
 
86
 
 
87
int main(int argc, char *argv[])
 
88
{
 
89
        int i;
 
90
        long int ret;
 
91
        unsigned long len;
 
92
        void *file;
 
93
        char *filename, *options = strdup("");
 
94
        char *progname = argv[0];
 
95
 
 
96
        if (argv[1] && (streq(argv[1], "--version") || streq(argv[1], "-V"))) {
 
97
                puts("klibc insmod");
 
98
                exit(0);
 
99
        }
 
100
 
 
101
        /* Ignore old options, for backwards compat. */
 
102
        while (argv[1] && (streq(argv[1], "-p")
 
103
                           || streq(argv[1], "-s")
 
104
                           || streq(argv[1], "-f"))) {
 
105
                argv++;
 
106
                argc--;
 
107
        }
 
108
 
 
109
        filename = argv[1];
 
110
        if (!filename)
 
111
                print_usage(progname);
 
112
 
 
113
        /* Rest is options */
 
114
        for (i = 2; i < argc; i++) {
 
115
                options = realloc(options,
 
116
                                  strlen(options) + 2 + strlen(argv[i]) + 2);
 
117
                /* Spaces handled by "" pairs, but no way of escaping
 
118
                   quotes */
 
119
                if (strchr(argv[i], ' '))
 
120
                        strcat(options, "\"");
 
121
                strcat(options, argv[i]);
 
122
                if (strchr(argv[i], ' '))
 
123
                        strcat(options, "\"");
 
124
                strcat(options, " ");
 
125
        }
 
126
 
 
127
        file = grab_file(filename, &len);
 
128
        if (!file) {
 
129
                fprintf(stderr, "insmod: can't read '%s': %s\n",
 
130
                        filename, strerror(errno));
 
131
                exit(1);
 
132
        }
 
133
 
 
134
        ret = init_module(file, len, options);
 
135
        if (ret != 0) {
 
136
                fprintf(stderr, "insmod: error inserting '%s': %li %s\n",
 
137
                        filename, ret, moderror(errno));
 
138
                exit(1);
 
139
        }
 
140
        exit(0);
 
141
}