~ubuntu-core-dev/module-init-tools/ubuntu

« back to all changes in this revision

Viewing changes to modinfo.c

  • Committer: Scott James Remnant
  • Date: 2009-07-16 15:24:17 UTC
  • mfrom: (152.1.38)
  • Revision ID: scott@netsplit.com-20090716152417-7ak1sklxb59cs4fz
MergeĀ 3.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
#include <sys/mman.h>
15
15
 
16
16
#include "util.h"
 
17
#include "logging.h"
 
18
#include "elfops.h"
17
19
#include "zlibsupport.h"
18
20
#include "testing.h"
19
21
 
37
39
        for (i = *list; i; i = i->next)
38
40
                if (strncmp(i->name, name, namelen) == 0)
39
41
                        return i;
40
 
        i = malloc(sizeof(*i) + namelen+1);
 
42
        i = NOFAIL(malloc(sizeof(*i) + namelen+1));
41
43
        strncpy((char *)(i + 1), name, namelen);
42
44
        ((char *)(i + 1))[namelen] = '\0';
43
45
        i->name = (char *)(i + 1);
48
50
        return i;
49
51
}
50
52
 
51
 
static void print_tag(const char *tag, const char *info, unsigned long size,
 
53
static void print_tag(const char *tag, struct string_table *tags,
52
54
                      const char *filename, char sep)
53
55
{
 
56
        int j;
54
57
        unsigned int taglen = strlen(tag);
55
58
 
56
59
        if (streq(tag, "filename")) {
58
61
                return;
59
62
        }
60
63
 
61
 
        for (; info; info = next_string(info, &size))
 
64
        for (j = 0; j < tags->cnt; j++) {
 
65
                const char *info = tags->str[j];
62
66
                if (strncmp(info, tag, taglen) == 0 && info[taglen] == '=')
63
67
                        printf("%s%c", info + taglen + 1, sep);
 
68
        }
64
69
}
65
70
 
66
 
static void print_all(const char *info, unsigned long size,
 
71
static void print_all(struct string_table *tags,
67
72
                      const char *filename, char sep)
68
73
{
 
74
        int j;
69
75
        struct param *i, *params = NULL;
70
76
 
71
77
        printf("%-16s%s%c", "filename:", filename, sep);
72
 
        for (; info; info = next_string(info, &size)) {
 
78
        for (j = 0; j < tags->cnt; j++) {
 
79
                const char *info = tags->str[j];
73
80
                char *eq, *colon;
74
81
 
75
82
                /* We expect this in parm and parmtype. */
177
184
        return (char *)end + 1;
178
185
}
179
186
 
180
 
static void *grab_module(const char *name, unsigned long *size, char**filename,
181
 
        const char *kernel, const char *basedir)
 
187
static struct elf_file *grab_module(const char *name,
 
188
                                    const char *kernel,
 
189
                                    const char *basedir)
182
190
{
183
191
        char *data;
 
192
        unsigned long size;
184
193
        struct utsname buf;
185
194
        char *depname, *p, *moddir;
 
195
        struct elf_file *module;
186
196
 
187
197
        if (strchr(name, '.') || strchr(name, '/')) {
188
 
                data = grab_file(name, size);
189
 
                if (data) {
190
 
                        *filename = strdup(name);
191
 
                        return data;
192
 
                } else {
193
 
                        fprintf(stderr, "modinfo: could not open %s: %s\n",
 
198
                module = grab_elf_file(name);
 
199
                if (!module)
 
200
                        error("modinfo: could not open %s: %s\n",
194
201
                                name, strerror(errno));
195
 
                        return NULL;
196
 
                }
 
202
                return module;
197
203
        }
198
204
 
199
 
        if (kernel) {
200
 
                if (strlen(basedir))
201
 
                        asprintf(&moddir, "%s/%s/%s",
202
 
                                basedir, MODULE_DIR, kernel);
203
 
                else
204
 
                        asprintf(&moddir, "%s/%s",
205
 
                                MODULE_DIR, kernel);
206
 
        } else {
 
205
        if (!kernel) {
207
206
                uname(&buf);
208
 
                if (strlen(basedir))
209
 
                        asprintf(&moddir, "%s/%s/%s",
210
 
                                basedir, MODULE_DIR, buf.release);
211
 
                else
212
 
                        asprintf(&moddir, "%s/%s",
213
 
                                MODULE_DIR, buf.release);
 
207
                kernel = buf.release;
214
208
        }
215
 
        asprintf(&depname, "%s/%s", moddir, "modules.dep");
 
209
        if (strlen(basedir))
 
210
                nofail_asprintf(&moddir, "%s/%s/%s", basedir, MODULE_DIR, kernel);
 
211
        else
 
212
                nofail_asprintf(&moddir, "%s/%s", MODULE_DIR, kernel);
216
213
 
217
214
        /* Search for it in modules.dep. */
218
 
        data = grab_file(depname, size);
 
215
        nofail_asprintf(&depname, "%s/%s", moddir, "modules.dep");
 
216
        data = grab_file(depname, &size);
219
217
        if (!data) {
220
 
                fprintf(stderr, "modinfo: could not open %s\n", depname);
 
218
                error("modinfo: could not open %s\n", depname);
221
219
                free(depname);
222
220
                return NULL;
223
221
        }
224
222
        free(depname);
225
223
 
226
 
        for (p = data; p < data + *size; p = next_line(p, data + *size)) {
227
 
                if (name_matches(p, data + *size, name)) {
 
224
        for (p = data; p < data + size; p = next_line(p, data + size)) {
 
225
                if (name_matches(p, data + size, name)) {
228
226
                        int namelen = strcspn(p, ":");
229
 
 
230
 
                        if ('/' == p[0]) { /* old style deps - absolute path */
231
 
                                *filename = malloc(namelen + strlen(basedir)+2);
232
 
                                if (strlen(basedir)) {
233
 
                                        sprintf(*filename, "%s/", basedir);
234
 
                                        memcpy(*filename+strlen(basedir)+1,p,
235
 
                                                namelen);
236
 
                                        (*filename)[namelen
237
 
                                                +strlen(basedir)+1] = '\0';
238
 
                                } else {
239
 
                                        memcpy(*filename,p,namelen);
240
 
                                        (*filename)[namelen] = '\0';
241
 
                                }
 
227
                        const char *dir;
 
228
                        char *filename;
 
229
 
 
230
                        if ('/' == p[0])
 
231
                                dir = basedir; /* old style deps - abs. path */
 
232
                        else
 
233
                                dir = moddir; /* new style - relative path */
 
234
 
 
235
                        if (strlen(dir)) {
 
236
                                nofail_asprintf(&filename, "%s/%s", dir, p);
 
237
                                filename[namelen + strlen(dir) + 1] = '\0';
242
238
                        } else {
243
 
                                *filename = malloc(namelen + strlen(moddir)+2);
244
 
                                sprintf(*filename, "%s/", moddir);
245
 
                                memcpy(*filename+strlen(moddir)+1, p,namelen);
246
 
                                (*filename)[namelen+strlen(moddir)+1] ='\0';
 
239
                                filename = strndup(p, namelen);
247
240
                        }
248
 
                        release_file(data, *size);
249
 
                        data = grab_file(*filename, size);
250
 
                        if (!data)
251
 
                                fprintf(stderr,
252
 
                                        "modinfo: could not open %s: %s\n",
 
241
                        release_file(data, size);
 
242
                        module = grab_elf_file(filename);
 
243
                        if (!module)
 
244
                                error("modinfo: could not open %s: %s\n",
253
245
                                        *filename, strerror(errno));
254
 
                        return data;
 
246
                        free(filename);
 
247
                        return module;
255
248
                }
256
249
        }
257
 
        release_file(data, *size);
258
 
        fprintf(stderr, "modinfo: could not find module %s\n", name);
 
250
        release_file(data, size);
 
251
        error("modinfo: could not find module %s\n", name);
259
252
        return NULL;
260
253
}
261
254
 
275
268
        const char *field = NULL;
276
269
        const char *kernel = NULL;
277
270
        char sep = '\n';
278
 
        unsigned long infosize = 0;
279
271
        int opt, ret = 0;
280
272
        char *basedir = "";
281
273
 
 
274
        logging = 0; /* send messages to stderr */
 
275
 
282
276
        if (native_endianness() == 0)
283
277
                abort();
284
278
 
305
299
        }
306
300
 
307
301
        for (opt = optind; opt < argc; opt++) {
308
 
                void *info, *mod;
309
 
                unsigned long modulesize;
310
 
                char *filename;
 
302
                struct string_table *tags;
 
303
                struct elf_file *mod;
311
304
 
312
 
                mod = grab_module(argv[opt], &modulesize, &filename,
313
 
                                  kernel, basedir);
 
305
                mod = grab_module(argv[opt], kernel, basedir);
314
306
                if (!mod) {
315
307
                        ret = 1;
316
308
                        continue;
317
309
                }
318
 
 
319
 
                info = get_section(mod, modulesize, ".modinfo", &infosize);
320
 
                if (!info) {
321
 
                        release_file(mod, modulesize);
322
 
                        free(filename);
 
310
                tags = mod->ops->load_strings(mod, ".modinfo", NULL, error);
 
311
                if (!tags) {
 
312
                        release_elf_file(mod);
323
313
                        continue;
324
314
                }
325
315
                if (field)
326
 
                        print_tag(field, info, infosize, filename, sep);
 
316
                        print_tag(field, tags, mod->pathname, sep);
327
317
                else
328
 
                        print_all(info, infosize, filename, sep);
329
 
                release_file(mod, modulesize);
330
 
                free(filename);
 
318
                        print_all(tags, mod->pathname, sep);
 
319
                strtbl_free(tags);
 
320
                release_elf_file(mod);
331
321
        }
332
322
        return ret;
333
323
}