OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / user / module-init-tools / depmod.c
1 /* New simplified depmod without backwards compat stuff and not
2    requiring ksyms.
3
4    (C) 2002 Rusty Russell IBM Corporation
5  */
6 #include <stdarg.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <getopt.h>
10 #include <string.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <elf.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <fcntl.h>
17 #include <dirent.h>
18 #include <sys/utsname.h>
19 #include <sys/mman.h>
20
21 #include "zlibsupport.h"
22 #include "depmod.h"
23 #include "moduleops.h"
24 #include "tables.h"
25
26 #include "testing.h"
27
28 #ifndef MODULE_DIR
29 #define MODULE_DIR "/lib/modules/"
30 #endif
31
32 static int verbose;
33 static unsigned int skipchars;
34
35 void fatal(const char *fmt, ...)
36 {
37         va_list arglist;
38
39         fprintf(stderr, "FATAL: ");
40
41         va_start(arglist, fmt);
42         vfprintf(stderr, fmt, arglist);
43         va_end(arglist);
44
45         exit(1);
46 }
47
48 void warn(const char *fmt, ...)
49 {
50         va_list arglist;
51
52         fprintf(stderr, "WARNING: ");
53
54         va_start(arglist, fmt);
55         vfprintf(stderr, fmt, arglist);
56         va_end(arglist);
57 }
58
59 void *do_nofail(void *ptr, const char *file, int line, const char *expr)
60 {
61         if (!ptr) {
62                 fatal("Memory allocation failure %s line %d: %s.\n",
63                       file, line, expr);
64         }
65         return ptr;
66 }
67
68 #define SYMBOL_HASH_SIZE 1024
69 struct symbol
70 {
71         struct symbol *next;
72         struct module *owner;
73         char name[0];
74 };
75
76 static struct symbol *symbolhash[SYMBOL_HASH_SIZE];
77
78 /* This is based on the hash agorithm from gdbm, via tdb */
79 static inline unsigned int tdb_hash(const char *name)
80 {
81         unsigned value; /* Used to compute the hash value.  */
82         unsigned   i;   /* Used to cycle through random values. */
83
84         /* Set the initial value from the key size. */
85         for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++)
86                 value = (value + (((unsigned char *)name)[i] << (i*5 % 24)));
87
88         return (1103515243 * value + 12345);
89 }
90
91 void add_symbol(const char *name, struct module *owner)
92 {
93         unsigned int hash;
94         struct symbol *new = NOFAIL(malloc(sizeof *new + strlen(name) + 1));
95
96         new->owner = owner;
97         strcpy(new->name, name);
98
99         hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
100         new->next = symbolhash[hash];
101         symbolhash[hash] = new;
102 }
103
104 static int print_unknown;
105
106 struct module *find_symbol(const char *name, const char *modname, int weak)
107 {
108         struct symbol *s;
109
110         /* For our purposes, .foo matches foo.  PPC64 needs this. */
111         if (name[0] == '.')
112                 name++;
113
114         for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s=s->next) {
115                 if (streq(s->name, name))
116                         return s->owner;
117         }
118
119         if (print_unknown && !weak)
120                 warn("%s needs unknown symbol %s\n", modname, name);
121
122         return NULL;
123 }
124
125 void add_dep(struct module *mod, struct module *depends_on)
126 {
127         unsigned int i;
128
129         for (i = 0; i < mod->num_deps; i++)
130                 if (mod->deps[i] == depends_on)
131                         return;
132
133         mod->deps = NOFAIL(realloc(mod->deps, sizeof(mod->deps[0])*(mod->num_deps+1)));
134         mod->deps[mod->num_deps++] = depends_on;
135 }
136
137 static void load_system_map(const char *filename)
138 {
139         FILE *system_map;
140         char line[10240];
141
142         system_map = fopen(filename, "r");
143         if (!system_map)
144                 fatal("Could not open '%s': %s\n", filename, strerror(errno));
145
146         /* eg. c0294200 R __ksymtab_devfs_alloc_devnum */
147         while (fgets(line, sizeof(line)-1, system_map)) {
148                 char *ptr;
149
150                 /* Snip \n */
151                 ptr = strchr(line, '\n');
152                 *ptr = '\0';
153
154                 ptr = strchr(line, ' ');
155                 if (!ptr || !(ptr = strchr(ptr + 1, ' ')))
156                         continue;
157
158                 /* Covers gpl-only and normal symbols. */
159                 if (strncmp(ptr+1, "__ksymtab_", strlen("__ksymtab_")) == 0)
160                         add_symbol(ptr+1+strlen("__ksymtab_"), NULL);
161         }
162
163         /* __this_module is magic inserted by kernel loader. */
164         add_symbol("__this_module", NULL);
165         /* On S390, this is faked up too */
166         add_symbol("_GLOBAL_OFFSET_TABLE_", NULL);
167 }
168
169 static struct option options[] = { { "all", 0, NULL, 'a' },
170                                    { "quick", 0, NULL, 'A' },
171                                    { "basedir", 1, NULL, 'b' },
172                                    { "errsyms", 0, NULL, 'e' },
173                                    { "filesyms", 1, NULL, 'F' },
174                                    { "help", 0, NULL, 'h' },
175                                    { "show", 0, NULL, 'n' },
176                                    { "dry-run", 0, NULL, 'n' },
177                                    { "quiet", 0, NULL, 'q' },
178                                    { "root", 0, NULL, 'r' },
179                                    { "unresolved-error", 0, NULL, 'u' },
180                                    { "verbose", 0, NULL, 'v' },
181                                    { "version", 0, NULL, 'V' },
182                                    /* Obsolete, but we need to parse it. */
183                                    { "config", 1, NULL, 'C' },
184                                    { NULL, 0, NULL, 0 } };
185
186 /* Version number or module name?  Don't assume extension. */
187 static int is_version_number(const char *version)
188 {
189         unsigned int dummy;
190
191         return (sscanf(version, "%u.%u.%u", &dummy, &dummy, &dummy) == 3);
192 }
193
194 static int old_module_version(const char *version)
195 {
196         /* Expect three part version. */
197         unsigned int major, sub, minor;
198
199         sscanf(version, "%u.%u.%u", &major, &sub, &minor);
200
201         if (major > 2) return 0;
202         if (major < 2) return 1;
203
204         /* 2.x */
205         if (sub > 5) return 0;
206         if (sub < 5) return 1;
207
208         /* 2.5.x */
209         if (minor >= 48) return 0;
210         return 1;
211 }
212
213 static void exec_old_depmod(char *argv[])
214 {
215         char *sep;
216         char pathname[strlen(argv[0])+1];
217         char oldname[strlen("depmod") + strlen(argv[0]) + sizeof(".old")];
218
219         memset(pathname, 0, strlen(argv[0])+1);
220         sep = strrchr(argv[0], '/');
221         if (sep)
222                 memcpy(pathname, argv[0], sep - argv[0]+1);
223         sprintf(oldname, "%s%s.old", pathname, "depmod");
224
225         /* Recursion detection: we need an env var since we can't
226            change argv[0] (as older modutils uses it to determine
227            behavior). */
228         if (getenv("MODULE_RECURSE"))
229                 return;
230         setenv("MODULE_RECURSE", "y", 0);
231
232         execvp(oldname, argv);
233         fprintf(stderr,
234                 "Version requires old depmod, but couldn't run %s: %s\n",
235                 oldname, strerror(errno));
236         exit(2);
237 }
238
239 static void print_usage(const char *name)
240 {
241         fprintf(stderr,
242         "%s " VERSION " -- part of " PACKAGE "\n"
243         "%s -[aA] [-n -e -v -q -V -r -u]\n"
244         "      [-b basedirectory] [forced_version]\n"
245         "depmod [-n -e -v -q -r -u] [-F kernelsyms] module1.o module2.o ...\n"
246         "If no arguments (except options) are given, \"depmod -a\" is assumed\n"
247         "\n"
248         "depmod will output a dependancy list suitable for the modprobe utility.\n"
249         "\n"
250         "\n"
251         "Options:\n"
252         "\t-a, --all            Probe all modules\n"
253         "\t-n, --show           Write the dependency file on stdout only\n"
254         "\t-V, --version        Print the release version\n"
255         "\t-h, --help           Print this usage message\n"
256         "\n"
257         "The following options are useful for people managing distributions:\n"
258         "\t-b basedirectory\n"
259         "\t    --basedir basedirectory    Use an image of a module tree.\n"
260         "\t-F kernelsyms\n"
261         "\t    --filesyms kernelsyms      Use the file instead of the\n"
262         "\t                               current kernel symbols.\n",
263         "depmod", "depmod");
264 }
265
266 static int ends_in(const char *name, const char *ext)
267 {
268         unsigned int namelen, extlen;
269
270         /* Grab lengths */
271         namelen = strlen(name);
272         extlen = strlen(ext);
273
274         if (namelen < extlen) return 0;
275
276         if (streq(name + namelen - extlen, ext))
277                 return 1;
278         return 0;
279 }
280
281 /* "\177ELF" <byte> where byte = 001 for 32-bit, 002 for 64 */
282 int needconv(const char *elfhdr)
283 {
284         union { short s; char c[2]; } endian_test;
285
286         endian_test.s = 1;
287         if (endian_test.c[1] == 1) return elfhdr[EI_DATA] != ELFDATA2MSB;
288         if (endian_test.c[0] == 1) return elfhdr[EI_DATA] != ELFDATA2LSB;
289         else
290                 abort();
291 }
292
293 static struct module *grab_module(const char *dirname, const char *filename)
294 {
295         struct module *new;
296
297         new = NOFAIL(malloc(sizeof(*new)
298                             + strlen(dirname?:"") + 1 + strlen(filename) + 1));
299         if (dirname)
300                 sprintf(new->pathname, "%s/%s", dirname, filename);
301         else
302                 strcpy(new->pathname, filename);
303
304         INIT_LIST_HEAD(&new->dep_list);
305
306         new->data = grab_file(new->pathname, &new->len);
307         if (!new->data) {
308                 warn("Can't read module %s: %s\n",
309                      new->pathname, strerror(errno));
310                 goto fail_data;
311         }
312
313         /* "\177ELF" <byte> where byte = 001 for 32-bit, 002 for 64 */
314         if (memcmp(new->data, ELFMAG, SELFMAG) != 0) {
315                 warn("Module %s is not an elf object\n", new->pathname);
316                 goto fail;
317         }
318
319         switch (((char *)new->data)[EI_CLASS]) {
320         case ELFCLASS32:
321                 new->ops = &mod_ops32;
322                 break;
323         case ELFCLASS64:
324                 new->ops = &mod_ops64;
325                 break;
326         default:
327                 warn("Module %s has elf unknown identifier %i\n",
328                      new->pathname, ((char *)new->data)[EI_CLASS]);
329                 goto fail;
330         }
331         new->conv = needconv(new->data);
332         return new;
333
334 fail:
335         release_file(new->data, new->len);
336 fail_data:
337         free(new);
338         return NULL;
339 }
340
341 struct module_traverse
342 {
343         struct module_traverse *prev;
344         struct module *mod;
345 };
346
347 static int in_loop(struct module *mod, const struct module_traverse *traverse)
348 {
349         const struct module_traverse *i;
350
351         for (i = traverse; i; i = i->prev) {
352                 if (i->mod == mod)
353                         return 1;
354         }
355         return 0;
356 }
357
358 static char *basename(const char *name)
359 {
360         const char *base = strrchr(name, '/');
361         if (base) return (char *)base + 1;
362         return (char *)name;
363 }
364
365 /* Assume we are doing all the modules, so only report each loop once. */
366 static void report_loop(const struct module *mod,
367                         const struct module_traverse *traverse)
368 {
369         const struct module_traverse *i;
370
371         /* Check that start is least alphabetically.  eg.  a depends
372            on b depends on a will get reported for a, not b.  */
373         for (i = traverse->prev; i->prev; i = i->prev) {
374                 if (strcmp(mod->pathname, i->mod->pathname) > 0)
375                         return;
376         }
377
378         /* Is start in the loop?  If not, don't report now. eg. a
379            depends on b which depends on c which depends on b.  Don't
380            report when generating depends for a. */
381         if (mod != i->mod)
382                 return;
383
384         warn("Loop detected: %s ", mod->pathname);
385         for (i = traverse->prev; i->prev; i = i->prev)
386                 fprintf(stderr, "needs %s ", basename(i->mod->pathname));
387         fprintf(stderr, "which needs %s again!\n", basename(mod->pathname));
388 }
389
390 /* This is damn slow, but loops actually happen, and we don't want to
391    just exit() and leave the user without any modules. */
392 static int has_dep_loop(struct module *module, struct module_traverse *prev)
393 {
394         unsigned int i;
395         struct module_traverse traverse = { .prev = prev, .mod = module };
396
397         if (in_loop(module, prev)) {
398                 report_loop(module, &traverse);
399                 return 1;
400         }
401
402         for (i = 0; i < module->num_deps; i++)
403                 if (has_dep_loop(module->deps[i], &traverse))
404                         return 1;
405         return 0;
406 }
407
408 /* Uniquifies and orders a dependency list. */
409 static void order_dep_list(struct module *start, struct module *mod)
410 {
411         unsigned int i;
412
413         for (i = 0; i < mod->num_deps; i++) {
414                 /* If it was previously depended on, move it to the
415                    tail.  ie. if a needs b and c, and c needs b, we
416                    must order b after c. */
417                 list_del(&mod->deps[i]->dep_list);
418                 list_add_tail(&mod->deps[i]->dep_list, &start->dep_list);
419                 order_dep_list(start, mod->deps[i]);
420         }
421 }
422
423 static void del_module(struct module **modules, struct module *delme)
424 {
425         struct module **i;
426
427         /* Find pointer to it. */ 
428         for (i = modules; *i != delme; i = &(*i)->next);
429
430         *i = delme->next;
431 }
432
433 static void output_deps(struct module *modules,
434                         FILE *out)
435 {
436         struct module *i;
437
438         for (i = modules; i; i = i->next)
439                 i->ops->calculate_deps(i, verbose);
440
441         /* Strip out loops. */
442  again:
443         for (i = modules; i; i = i->next) {
444                 if (has_dep_loop(i, NULL)) {
445                         warn("Module %s ignored, due to loop\n",
446                              i->pathname + skipchars);
447                         del_module(&modules, i);
448                         goto again;
449                 }
450         }
451
452         /* Now dump them out. */
453         for (i = modules; i; i = i->next) {
454                 struct list_head *j, *tmp;
455                 order_dep_list(i, i);
456
457                 fprintf(out, "%s:", i->pathname + skipchars);
458                 list_for_each_safe(j, tmp, &i->dep_list) {
459                         struct module *dep
460                                 = list_entry(j, struct module, dep_list);
461                         fprintf(out, " %s", dep->pathname + skipchars);
462                         list_del_init(j);
463                 }
464                 fprintf(out, "\n");
465         }
466 }
467
468 static int smells_like_module(const char *name)
469 {
470         return ends_in(name,".ko") || ends_in(name, ".ko.gz");
471 }
472
473 typedef struct module *(*do_module_t)(const char *dirname,
474                                       const char *filename,
475                                       struct module *next);
476
477 static int is_update(const char *dirname)
478 {
479         char *p;
480
481         p = strstr(dirname, "updates");
482         if (!p)
483                 return 0;
484         return (p[strlen("updates")] == '/' || p[strlen("updates")] == '\0');
485 }
486
487 /* Grab everything not under updates/ directories. */
488 static struct module *do_normal_module(const char *dirname,
489                                        const char *filename,
490                                        struct module *list)
491 {
492         struct module *new;
493
494         if (is_update(dirname))
495                 return list;
496         new = grab_module(dirname, filename);
497         if (!new)
498                 return list;
499         new->next = list;
500         return new;
501 }
502
503 /* Grab everything under updates/ directories, override existing module. */
504 static struct module *do_update_module(const char *dirname,
505                                        const char *filename,
506                                        struct module *list)
507 {
508         struct module *new, **i;
509
510         if (!is_update(dirname))
511                 return list;
512
513         new = grab_module(dirname, filename);
514         if (!new)
515                 return list;
516
517         /* Find module of same name, and replace it. */
518         for (i = &list; *i; i = &(*i)->next) {
519                 if (streq(basename((*i)->pathname), filename)) {
520                         new->next = (*i)->next;
521                         *i = new;
522                         return list;
523                 }
524         }
525
526         /* Update of non-existent module.  Just prepend. */
527         new->next = list;
528         return new;
529 }
530
531 static struct module *grab_dir(const char *dirname,
532                                DIR *dir,
533                                struct module *next,
534                                do_module_t do_mod)
535 {
536         struct dirent *dirent;
537
538         while ((dirent = readdir(dir)) != NULL) {
539                 if (smells_like_module(dirent->d_name))
540                         next = do_mod(dirname, dirent->d_name, next);
541                 else if (!streq(dirent->d_name, ".")
542                          && !streq(dirent->d_name, "..")) {
543                         DIR *sub;
544                         char dummy; /* readlink with 0 len always fails */
545                         char subdir[strlen(dirname) + 1
546                                    + strlen(dirent->d_name) + 1];
547                         sprintf(subdir, "%s/%s", dirname, dirent->d_name);
548                         /* Don't follow links, eg. build/ */
549                         if (readlink(subdir, &dummy, 1) < 0) {
550                                 sub = opendir(subdir);
551                                 if (sub) {
552                                         next = grab_dir(subdir, sub, next,
553                                                         do_mod);
554                                         closedir(sub);
555                                 }
556                         }
557                 }
558         }
559         return next;
560 }
561
562
563 /* RH-ism: updates/ dir overrides other modules. */
564 static struct module *grab_basedir(const char *dirname)
565 {
566         DIR *dir;
567         struct module *list;
568         char updatedir[strlen(dirname) + sizeof("/updates")];
569
570         dir = opendir(dirname);
571         if (!dir) {
572                 warn("Couldn't open directory %s: %s\n",
573                      dirname, strerror(errno));
574                 return NULL;
575         }
576         list = grab_dir(dirname, dir, NULL, do_normal_module);
577         closedir(dir);
578
579         sprintf(updatedir, "%s/updates", dirname);
580         dir = opendir(updatedir);
581         if (dir) {
582                 list = grab_dir(updatedir, dir, list, do_update_module);
583                 closedir(dir);
584         }
585         return list;
586 }
587
588 static void parse_modules(struct module *list)
589 {
590         struct module *i;
591
592         for (i = list; i; i = i->next) {
593                 i->ops->load_symbols(i);
594                 i->ops->fetch_tables(i);
595         }
596 }
597
598 /* Convert filename to the module name.  Works if filename == modname, too. */
599 static void filename2modname(char *modname, const char *filename)
600 {
601         const char *afterslash;
602         unsigned int i;
603
604         afterslash = strrchr(filename, '/');
605         if (!afterslash)
606                 afterslash = filename;
607         else
608                 afterslash++;
609
610         /* Convert to underscores, stop at first . */
611         for (i = 0; afterslash[i] && afterslash[i] != '.'; i++) {
612                 if (afterslash[i] == '-')
613                         modname[i] = '_';
614                 else
615                         modname[i] = afterslash[i];
616         }
617         modname[i] = '\0';
618 }
619
620 /* Simply dump hash table. */
621 static void output_symbols(struct module *unused, FILE *out)
622 {
623         unsigned int i;
624
625         fprintf(out, "# Aliases for symbols, used by symbol_request().\n");
626         for (i = 0; i < SYMBOL_HASH_SIZE; i++) {
627                 struct symbol *s;
628
629                 for (s = symbolhash[i]; s; s = s->next) {
630                         if (s->owner) {
631                                 char modname[strlen(s->owner->pathname)+1];
632                                 filename2modname(modname, s->owner->pathname);
633                                 fprintf(out, "alias symbol:%s %s\n",
634                                         s->name, modname);
635                         }
636                 }
637         }
638 }
639
640 static const char *next_string(const char *string, unsigned long *secsize)
641 {
642         /* Skip non-zero chars */
643         while (string[0]) {
644                 string++;
645                 if ((*secsize)-- <= 1)
646                         return NULL;
647         }
648
649         /* Skip any zero padding. */
650         while (!string[0]) {
651                 string++;
652                 if ((*secsize)-- <= 1)
653                         return NULL;
654         }
655         return string;
656 }
657
658 static void output_aliases(struct module *modules, FILE *out)
659 {
660         struct module *i;
661         const char *p;
662         unsigned long size;
663
664         fprintf(out, "# Aliases extracted from modules themselves.\n");
665         for (i = modules; i; i = i->next) {
666                 char modname[strlen(i->pathname)+1];
667
668                 filename2modname(modname, i->pathname);
669
670                 /* Grab from old-style .modalias section. */
671                 for (p = i->ops->get_aliases(i, &size);
672                      p;
673                      p = next_string(p, &size))
674                         fprintf(out, "alias %s %s\n", p, modname);
675
676                 /* Grab form new-style .modinfo section. */
677                 for (p = i->ops->get_modinfo(i, &size);
678                      p;
679                      p = next_string(p, &size)) {
680                         if (strncmp(p, "alias=", strlen("alias=")) == 0)
681                                 fprintf(out, "alias %s %s\n",
682                                         p + strlen("alias="), modname);
683                 }
684         }
685 }
686
687 struct depfile {
688         char *name;
689         void (*func)(struct module *, FILE *);
690 };
691
692 static struct depfile depfiles[] = {
693         { "modules.dep", output_deps }, /* This is what we check for '-A'. */
694         { "modules.pcimap", output_pci_table },
695         { "modules.usbmap", output_usb_table },
696         { "modules.ccwmap", output_ccw_table },
697         { "modules.ieee1394map", output_ieee1394_table },
698         { "modules.isapnpmap", output_isapnp_table },
699         { "modules.inputmap", output_input_table },
700         { "modules.ofmap", output_of_table },
701         { "modules.seriomap", output_serio_table },
702         { "modules.alias", output_aliases },
703         { "modules.symbols", output_symbols },
704 };
705
706 /* If we can't figure it out, it's safe to say "true". */
707 static int any_modules_newer(const char *dirname, time_t mtime)
708 {
709         DIR *dir;
710         struct dirent *dirent;
711
712         dir = opendir(dirname);
713         if (!dir)
714                 return 1;
715
716         while ((dirent = readdir(dir)) != NULL) {
717                 struct stat st;
718                 char file[strlen(dirname) + 1 + strlen(dirent->d_name) + 1];
719
720                 if (streq(dirent->d_name, ".") || streq(dirent->d_name, ".."))
721                         continue;
722
723                 sprintf(file, "%s/%s", dirname, dirent->d_name);
724                 if (lstat(file, &st) != 0)
725                         return 1;
726
727                 if (smells_like_module(dirent->d_name)) {
728                         if (st.st_mtime > mtime)
729                                 return 1;
730                 } else if (S_ISDIR(st.st_mode)) {
731                         if (any_modules_newer(file, mtime))
732                                 return 1;
733                 }
734         }
735         closedir(dir);
736         return 0;
737 }
738
739 static int depfile_out_of_date(const char *dirname)
740 {
741         struct stat st;
742         char depfile[strlen(dirname) + 1 + strlen(depfiles[0].name) + 1];
743
744         sprintf(depfile, "%s/%s", dirname, depfiles[0].name);
745
746         if (stat(depfile, &st) != 0)
747                 return 1;
748
749         return any_modules_newer(dirname, st.st_mtime);
750 }
751
752 int main(int argc, char *argv[])
753 {
754         int opt, all = 0, maybe_all = 0, doing_stdout = 0;
755         char *basedir = "", *dirname, *version, *badopt = NULL,
756                 *system_map = NULL;
757         struct module *list = NULL;
758         int i;
759
760         /* Don't print out any errors just yet, we might want to exec
761            backwards compat version. */
762         opterr = 0;
763         while ((opt = getopt_long(argc, argv, "ab:ArehnqruvVF:C:", options, NULL))
764                != -1) {
765                 switch (opt) {
766                 case 'a':
767                         all = 1;
768                         break;
769                 case 'b':
770                         basedir = optarg;
771                         skipchars = strlen(basedir);
772                         break;
773                 case 'A':
774                         maybe_all = 1;
775                         break;
776                 case 'F':
777                         system_map = optarg;
778                         break;
779                 case 'e':
780                         print_unknown = 1;
781                         break;
782                 case 'v':
783                         verbose = 1;
784                         break;
785                 case 'u':
786                 case 'q':
787                 case 'r':
788                 case 'C':
789                         /* Ignored. */
790                         break;
791                 case 'h':
792                         print_usage(argv[0]);
793                         exit(0);
794                         break;
795                 case 'n':
796                         doing_stdout = 1;
797                         break;
798                 case 'V':
799                         printf("%s %s\n", PACKAGE, VERSION);
800                         exit(0);
801                 default:
802                         badopt = argv[optind-1];
803                 }
804         }
805
806         /* We can't print unknowns without a System.map */
807         if (!system_map)
808                 print_unknown = 0;
809         else
810                 load_system_map(system_map);
811
812         /* They can specify the version naked on the command line */
813         if (optind < argc && is_version_number(argv[optind])) {
814                 version = strdup(argv[optind]);
815                 optind++;
816         } else {
817                 struct utsname buf;
818                 uname(&buf);
819                 version = strdup(buf.release);
820         }
821
822         /* Run old version if required. */
823         if (old_module_version(version))
824                 exec_old_depmod(argv);
825
826         if (badopt) {
827                 fprintf(stderr, "%s: malformed/unrecognized option '%s'\n",
828                         argv[0], badopt);
829                 print_usage(argv[0]);
830                 exit(1);
831         }
832
833         /* Depmod -a by default if no names. */
834         if (optind == argc)
835                 all = 1;
836
837         dirname = NOFAIL(malloc(strlen(basedir)
838                          + strlen(MODULE_DIR)
839                          + strlen(version) + 1));
840         sprintf(dirname, "%s%s%s", basedir, MODULE_DIR, version);
841
842         if (maybe_all) {
843                 if (!doing_stdout && !depfile_out_of_date(dirname))
844                         exit(0);
845                 all = 1;
846         }
847
848         if (!all) {
849                 /* Do command line args. */
850                 for (opt = optind; opt < argc; opt++) {
851                         struct module *new = grab_module(NULL, argv[opt]);
852                         if (new) {
853                                 new->next = list;
854                                 list = new;
855                         }
856                 }
857         } else {
858                 list = grab_basedir(dirname);
859         }
860         parse_modules(list);
861
862         for (i = 0; i < sizeof(depfiles)/sizeof(depfiles[0]); i++) {
863                 FILE *out;
864                 struct depfile *d = &depfiles[i];
865                 char depname[strlen(dirname) + 1 + strlen(d->name) + 1];
866                 char tmpname[strlen(dirname) + 1 + strlen(d->name) +
867                                                 strlen(".temp") + 1];
868
869                 sprintf(depname, "%s/%s", dirname, d->name);
870                 sprintf(tmpname, "%s/%s.temp", dirname, d->name);
871                 if (!doing_stdout) {
872                         out = fopen(tmpname, "w");
873                         if (!out)
874                                 fatal("Could not open %s for writing: %s\n",
875                                         tmpname, strerror(errno));
876                 } else
877                         out = stdout;
878                 d->func(list, out);
879                 if (!doing_stdout) {
880                         fclose(out);
881                         if (rename(tmpname, depname) < 0)
882                                 fatal("Could not rename %s into %s: %s\n",
883                                         tmpname, depname, strerror(errno));
884                 }
885         }
886
887         free(dirname);
888         free(version);
889         
890         return 0;
891 }