?? modprobe.c
字號:
int removing, struct module_options **options, struct module_command **commands){ FILE *cfile; char *line; char *result = NULL; unsigned int linenum = 0; cfile = fopen(filename, "r"); if (!cfile) { if (mustload) fatal("Failed to open config file %s: %s\n", filename, strerror(errno)); return NULL; } while ((line = getline_wrapped(cfile, &linenum)) != NULL) { char *ptr = line; char *cmd, *modname; if (dump_only) printf("%s\n", line); cmd = strsep_skipspace(&ptr, "\t "); if (cmd == NULL || cmd[0] == '#' || cmd[0] == '\0') continue; if (strcmp(cmd, "alias") == 0) { char *wildcard = underscores(strsep_skipspace(&ptr, "\t ")); char *realname = underscores(strsep_skipspace(&ptr, "\t ")); if (!wildcard || !realname) grammar(cmd, filename, linenum); else if (fnmatch(wildcard,name,0) == 0) result = NOFAIL(strdup(realname)); } else if (strcmp(cmd, "include") == 0) { char *newresult, *newfilename; newfilename = strsep_skipspace(&ptr, "\t "); if (!newfilename) grammar(cmd, filename, linenum); else { newresult = read_config(newfilename, 1, name, dump_only, removing, options, commands); /* Files included override aliases, etc that was already set ... */ if (newresult) result = newresult; } } else if (strcmp(cmd, "options") == 0) { modname = strsep_skipspace(&ptr, "\t "); if (!modname || !ptr) grammar(cmd, filename, linenum); else { ptr += strspn(ptr, "\t "); *options = add_options(underscores(modname), ptr, *options); } } else if (strcmp(cmd, "install") == 0) { modname = strsep_skipspace(&ptr, "\t "); if (!modname || !ptr) grammar(cmd, filename, linenum); else if (!removing) { ptr += strspn(ptr, "\t "); *commands = add_command(underscores(modname), ptr, *commands); } } else if (strcmp(cmd, "remove") == 0) { modname = strsep_skipspace(&ptr, "\t "); if (!modname || !ptr) grammar(cmd, filename, linenum); else if (removing) { ptr += strspn(ptr, "\t "); *commands = add_command(underscores(modname), ptr, *commands); } } else grammar(cmd, filename, linenum); free(line); } fclose(cfile); return result;}static void add_to_env_var(const char *option){ const char *oldenv; if ((oldenv = getenv("MODPROBE_OPTIONS")) != NULL) { char *newenv; asprintf(&newenv, "%s %s", oldenv, option); setenv("MODPROBE_OPTIONS", newenv, 1); } else setenv("MODPROBE_OPTIONS", option, 1);}/* Prepend options from environment. */static char **merge_args(char *args, char *argv[], int *argc){ char *arg, *argstring; char **newargs = NULL; unsigned int i, num_env = 0; if (!args) return argv; argstring = NOFAIL(strdup(args)); for (arg = strtok(argstring, " "); arg; arg = strtok(NULL, " ")) { num_env++; newargs = NOFAIL(realloc(newargs, sizeof(newargs[0]) * (num_env + *argc + 1))); newargs[num_env] = arg; } /* Append commandline args */ newargs[0] = argv[0]; for (i = 1; i <= *argc; i++) newargs[num_env+i] = argv[i]; *argc += num_env; return newargs;}static char *gather_options(char *argv[]){ char *optstring = NOFAIL(strdup("")); /* Rest is module options */ while (*argv) { if (strchr(*argv, ' ')) { /* Spaces handled by "" pairs, but no way of escaping quotes */ char protected_option[strlen(optstring) + 3]; sprintf(protected_option, "\"%s\"", *argv); optstring = append_option(optstring, protected_option); } else optstring = append_option(optstring, *argv); argv++; } return optstring;}static struct option options[] = { { "verbose", 0, NULL, 'v' }, { "version", 0, NULL, 'V' }, { "config", 1, NULL, 'C' }, { "name", 1, NULL, 'o' }, { "remove", 0, NULL, 'r' }, { "showconfig", 0, NULL, 'c' }, { "autoclean", 0, NULL, 'k' }, { "quiet", 0, NULL, 'q' }, { "show", 0, NULL, 'n' }, { "dry-run", 0, NULL, 'n' }, { "syslog", 0, NULL, 's' }, { "type", 1, NULL, 't' }, { "list", 0, NULL, 'l' }, { "all", 0, NULL, 'a' }, { "ignore-install", 0, NULL, 'i' }, { "ignore-remove", 0, NULL, 'i' }, { "force", 0, NULL, 'f' }, { "force-vermagic", 0, NULL, 1 }, { "force-modversion", 0, NULL, 2 }, { "set-version", 1, NULL, 'S' }, { "show-depends", 0, NULL, 'D' }, { "first-time", 0, NULL, 3 }, { NULL, 0, NULL, 0 } };#define DEFAULT_CONFIG "/etc/modprobe.conf"#define MODPROBE_DEVFSD_CONF "/etc/modprobe.devfs"/* This is a horrible hack to allow devfsd, which calls modprobe with -C /etc/modules.conf or /etc/modules.devfs, to work. FIXME. *//* Modern devfsd or variants should use -q explicitly in 2.6. */static int is_devfs_call(char *argv[]){ unsigned int i; /* Look for "/dev" arg */ for (i = 1; argv[i]; i++) { if (strncmp(argv[i], "/dev/", 5) == 0) return 1; } return 0;}int main(int argc, char *argv[]){ struct utsname buf; struct stat statbuf; int opt; int dump_only = 0; int dry_run = 0; int remove = 0; int verbose = 0; int unknown_silent = 0; int list_only = 0; int all = 0; int ignore_commands = 0; int strip_vermagic = 0; int strip_modversion = 0; int ignore_proc = 0; int first_time = 0; unsigned int i, num_modules; char *type = NULL; const char *config = NULL, *command = NULL; char *dirname, *optstring; char *modname, *newname = NULL; char *aliasfilename, *symfilename; errfn_t error = fatal; /* Prepend options from environment. */ argv = merge_args(getenv("MODPROBE_OPTIONS"), argv, &argc); /* --set-version overrides version, and disables backwards compat. */ for (opt = 1; opt < argc; opt++) if (strncmp(argv[opt],"--set-version",strlen("--set-version")) == 0) break; if (opt == argc) try_old_version("modprobe", argv); uname(&buf); while ((opt = getopt_long(argc, argv, "vVC:o:rknqQsclt:aif", options, NULL)) != -1){ switch (opt) { case 'v': add_to_env_var("-v"); verbose = 1; break; case 'V': puts(PACKAGE " version " VERSION); exit(0); case 'S': strncpy(buf.release, optarg, sizeof(buf.release)); buf.release[sizeof(buf.release)-1] = '\0'; break; case 'C': if (is_devfs_call(argv)) { if (streq("/etc/modules.devfs", optarg)) { config = MODPROBE_DEVFSD_CONF; add_to_env_var("-C"); add_to_env_var(config); /* Fall thru to -q */ } else if (streq("/etc/modules.conf", optarg)) /* Ignore config, fall thru to -q */ ; else { /* False alarm. Treat as normal. */ config = optarg; add_to_env_var("-C"); add_to_env_var(config); break; } } else { config = optarg; add_to_env_var("-C"); add_to_env_var(config); break; } case 'q': unknown_silent = 1; add_to_env_var("-q"); break; case 'D': dry_run = 1; ignore_proc = 1; verbose = 1; add_to_env_var("-D"); break; case 'o': newname = optarg; break; case 'r': remove = 1; break; case 'c': dump_only = 1; break; case 't': type = optarg; break; case 'l': list_only = 1; break; case 'a': all = 1; error = warn; break; case 'k': /* FIXME: This should actually do something */ break; case 'n': dry_run = 1; break; case 's': add_to_env_var("-s"); log = 1; break; case 'i': ignore_commands = 1; break; case 'f': strip_vermagic = 1; strip_modversion = 1; break; case 1: strip_vermagic = 1; break; case 2: strip_modversion = 1; break; case 3: first_time = 1; break; default: print_usage(argv[0]); } } /* If stderr not open, go to syslog */ if (log || fstat(STDERR_FILENO, &statbuf) != 0) { openlog("modprobe", LOG_CONS, LOG_DAEMON); log = 1; } if (argc < optind + 1 && !dump_only && !list_only && !remove) print_usage(argv[0]); dirname = NOFAIL(malloc(strlen(buf.release) + sizeof(MODULE_DIR) + 1)); sprintf(dirname, "%s/%s", MODULE_DIR, buf.release); aliasfilename = NOFAIL(malloc(strlen(dirname) + sizeof("/modules.alias"))); sprintf(aliasfilename, "%s/modules.alias", dirname); symfilename = NOFAIL(malloc(strlen(dirname) + sizeof("/modules.symbols"))); sprintf(symfilename, "%s/modules.symbols", dirname); /* Old-style -t xxx wildcard? Only with -l. */ if (list_only) { if (optind+1 < argc) fatal("Can't have multiple wildcards\n"); /* fprintf(stderr, "man find\n"); return 1; */ return do_wildcard(dirname, type, argv[optind]?:"*"); } if (type) fatal("-t only supported with -l"); if (dump_only) { struct module_command *commands = NULL; struct module_options *modoptions = NULL; read_config(config ?: DEFAULT_CONFIG, config ? 1 : 0, "", 1, 0, &modoptions, &commands); read_config(aliasfilename, 0, "", 1, 0,&modoptions, &commands); read_config(symfilename, 0, "", 1, 0, &modoptions, &commands); exit(0); } if (remove || all) { num_modules = argc - optind; optstring = NOFAIL(strdup("")); /* -r only allows certain restricted options */ if (newname) fatal("Can't specify replacement name with -%c\n", remove ? 'r' : 'a'); } else { num_modules = 1; optstring = gather_options(argv+optind+1); } /* num_modules is always 1 except for -r or -a. */ for (i = 0; i < num_modules; i++) { struct module_command *commands = NULL; struct module_options *modoptions = NULL; LIST_HEAD(list); char *modulearg = argv[optind + i]; /* Convert name we are looking for */ underscores(modulearg); /* Returns the resolved alias, options */ modname = read_config(config ?: DEFAULT_CONFIG, config ? 1 : 0, modulearg, 0, remove, &modoptions, &commands); /* No luck? Try symbol names, if starts with symbol:. */ if (!modname && strncmp(modulearg, "symbol:", strlen("symbol:") == 0)) modname = read_config(symfilename, 0, modulearg, 0, remove, &modoptions, &commands); /* If we have an alias, gather any options associated with it (needs to happen after parsing complete). */ if (modname) { got_modname: optstring = add_extra_options(modulearg, optstring, modoptions); read_depends(dirname, modname, &list); } else { read_depends(dirname, modulearg, &list); /* We don't allow canned aliases to override real modules, so we delay lookup until now. */ if (list_empty(&list) && (modname = read_config(aliasfilename, 0, modulearg, 0, remove, &modoptions, &commands))) goto got_modname; modname = strdup(modulearg); } if (list_empty(&list)) { /* The dependencies have to be real modules, but handle case where the first is completely bogus. */ command = find_command(modname, commands); if (command && !ignore_commands) { do_command(modname, command, verbose, dry_run, fatal, remove ? "remove":"install"); continue; } if (unknown_silent) exit(1); error("Module %s not found.\n", modname); continue; } if (remove) rmmod(&list, first_time, error, dry_run, verbose, commands, ignore_commands, 0); else insmod(&list, NOFAIL(strdup(optstring)), newname, first_time, error, dry_run, verbose, modoptions, commands, ignore_commands, ignore_proc, strip_vermagic, strip_modversion); free(modname); } free(dirname); free(symfilename); free(optstring); if (log) closelog(); return 0;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -