Loading toolbox/Android.bp +6 −1 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ cc_defaults { "toolbox.c", "getevent.c", "getprop.cpp", "modprobe.cpp", "setprop.cpp", "start.cpp", ], Loading @@ -33,11 +34,15 @@ cc_defaults { shared_libs: [ "libbase", ], static_libs: ["libpropertyinfoparser"], static_libs: [ "libmodprobe", "libpropertyinfoparser", ], symlinks: [ "getevent", "getprop", "modprobe", "setprop", "start", "stop", Loading toolbox/modprobe.cpp 0 → 100644 +201 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <ctype.h> #include <getopt.h> #include <stdlib.h> #include <iostream> #include <android-base/strings.h> #include <modprobe/modprobe.h> enum modprobe_mode { AddModulesMode, RemoveModulesMode, ListModulesMode, ShowDependenciesMode, }; static void print_usage(void) { std::cerr << "Usage:" << std::endl; std::cerr << std::endl; std::cerr << " modprobe [-alrqvsDb] [-d DIR] [MODULE]+" << std::endl; std::cerr << " modprobe [-alrqvsDb] [-d DIR] MODULE [symbol=value][...]" << std::endl; std::cerr << std::endl; std::cerr << "Options:" << std::endl; std::cerr << " -b: Apply blacklist to module names too" << std::endl; std::cerr << " -d: Load modules from DIR, option may be used multiple times" << std::endl; std::cerr << " -D: Print dependencies for modules only, do not load"; std::cerr << " -h: Print this help" << std::endl; std::cerr << " -l: List modules matching pattern" << std::endl; std::cerr << " -r: Remove MODULE (multiple modules may be specified)" << std::endl; std::cerr << " -q: Quiet" << std::endl; std::cerr << " -v: Verbose" << std::endl; std::cerr << std::endl; } #define check_mode() \ if (mode != AddModulesMode) { \ std::cerr << "Error, multiple mode flags specified" << std::endl; \ print_usage(); \ return EXIT_FAILURE; \ } extern "C" int modprobe_main(int argc, char** argv) { std::vector<std::string> modules; std::string module_parameters; std::vector<std::string> mod_dirs; modprobe_mode mode = AddModulesMode; bool blacklist = false; bool verbose = false; int rv = EXIT_SUCCESS; int opt; while ((opt = getopt(argc, argv, "abd:Dhlqrv")) != -1) { switch (opt) { case 'a': // toybox modprobe supported -a to load multiple modules, this // is supported here by default, ignore flag check_mode(); break; case 'b': blacklist = true; break; case 'd': mod_dirs.emplace_back(optarg); break; case 'D': check_mode(); mode = ShowDependenciesMode; break; case 'h': print_usage(); return EXIT_SUCCESS; case 'l': check_mode(); mode = ListModulesMode; break; case 'q': verbose = false; break; case 'r': check_mode(); mode = RemoveModulesMode; break; case 'v': verbose = true; break; default: std::cerr << "Unrecognized option: " << opt << std::endl; return EXIT_FAILURE; } } int parameter_count = 0; for (opt = optind; opt < argc; opt++) { if (!strchr(argv[opt], '=')) { modules.emplace_back(argv[opt]); } else { parameter_count++; if (module_parameters.empty()) { module_parameters = argv[opt]; } else { module_parameters = module_parameters + " " + argv[opt]; } } } if (verbose) { std::cout << "mode is " << mode << std::endl; std::cout << "verbose is " << verbose << std::endl; std::cout << "mod_dirs is: " << android::base::Join(mod_dirs, "") << std::endl; std::cout << "modules is: " << android::base::Join(modules, "") << std::endl; std::cout << "module parameters is: " << android::base::Join(module_parameters, "") << std::endl; } if (modules.empty()) { if (mode == ListModulesMode) { // emulate toybox modprobe list with no pattern (list all) modules.emplace_back("*"); } else { std::cerr << "No modules given." << std::endl; print_usage(); return EXIT_FAILURE; } } if (mod_dirs.empty()) { std::cerr << "No module configuration directories given." << std::endl; print_usage(); return EXIT_FAILURE; } if (parameter_count && modules.size() > 1) { std::cerr << "Only one module may be loaded when specifying module parameters." << std::endl; print_usage(); return EXIT_FAILURE; } Modprobe m(mod_dirs); m.EnableVerbose(verbose); if (blacklist) { m.EnableBlacklist(true); } for (const auto& module : modules) { switch (mode) { case AddModulesMode: if (!m.LoadWithAliases(module, true, module_parameters)) { std::cerr << "Failed to load module " << module; rv = EXIT_FAILURE; } break; case RemoveModulesMode: if (!m.Remove(module)) { std::cerr << "Failed to remove module " << module; rv = EXIT_FAILURE; } break; case ListModulesMode: { std::vector<std::string> list = m.ListModules(module); std::cout << android::base::Join(list, "\n") << std::endl; break; } case ShowDependenciesMode: { std::vector<std::string> pre_deps; std::vector<std::string> deps; std::vector<std::string> post_deps; if (!m.GetAllDependencies(module, &pre_deps, &deps, &post_deps)) { rv = EXIT_FAILURE; break; } std::cout << "Dependencies for " << module << ":" << std::endl; std::cout << "Soft pre-dependencies:" << std::endl; std::cout << android::base::Join(pre_deps, "\n") << std::endl; std::cout << "Hard dependencies:" << std::endl; std::cout << android::base::Join(deps, "\n") << std::endl; std::cout << "Soft post-dependencies:" << std::endl; std::cout << android::base::Join(post_deps, "\n") << std::endl; break; } default: std::cerr << "Bad mode"; rv = EXIT_FAILURE; } } return rv; } toolbox/tools.h +1 −0 Original line number Diff line number Diff line TOOL(getevent) TOOL(getprop) TOOL(modprobe) TOOL(setprop) TOOL(start) TOOL(stop) Loading Loading
toolbox/Android.bp +6 −1 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ cc_defaults { "toolbox.c", "getevent.c", "getprop.cpp", "modprobe.cpp", "setprop.cpp", "start.cpp", ], Loading @@ -33,11 +34,15 @@ cc_defaults { shared_libs: [ "libbase", ], static_libs: ["libpropertyinfoparser"], static_libs: [ "libmodprobe", "libpropertyinfoparser", ], symlinks: [ "getevent", "getprop", "modprobe", "setprop", "start", "stop", Loading
toolbox/modprobe.cpp 0 → 100644 +201 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <ctype.h> #include <getopt.h> #include <stdlib.h> #include <iostream> #include <android-base/strings.h> #include <modprobe/modprobe.h> enum modprobe_mode { AddModulesMode, RemoveModulesMode, ListModulesMode, ShowDependenciesMode, }; static void print_usage(void) { std::cerr << "Usage:" << std::endl; std::cerr << std::endl; std::cerr << " modprobe [-alrqvsDb] [-d DIR] [MODULE]+" << std::endl; std::cerr << " modprobe [-alrqvsDb] [-d DIR] MODULE [symbol=value][...]" << std::endl; std::cerr << std::endl; std::cerr << "Options:" << std::endl; std::cerr << " -b: Apply blacklist to module names too" << std::endl; std::cerr << " -d: Load modules from DIR, option may be used multiple times" << std::endl; std::cerr << " -D: Print dependencies for modules only, do not load"; std::cerr << " -h: Print this help" << std::endl; std::cerr << " -l: List modules matching pattern" << std::endl; std::cerr << " -r: Remove MODULE (multiple modules may be specified)" << std::endl; std::cerr << " -q: Quiet" << std::endl; std::cerr << " -v: Verbose" << std::endl; std::cerr << std::endl; } #define check_mode() \ if (mode != AddModulesMode) { \ std::cerr << "Error, multiple mode flags specified" << std::endl; \ print_usage(); \ return EXIT_FAILURE; \ } extern "C" int modprobe_main(int argc, char** argv) { std::vector<std::string> modules; std::string module_parameters; std::vector<std::string> mod_dirs; modprobe_mode mode = AddModulesMode; bool blacklist = false; bool verbose = false; int rv = EXIT_SUCCESS; int opt; while ((opt = getopt(argc, argv, "abd:Dhlqrv")) != -1) { switch (opt) { case 'a': // toybox modprobe supported -a to load multiple modules, this // is supported here by default, ignore flag check_mode(); break; case 'b': blacklist = true; break; case 'd': mod_dirs.emplace_back(optarg); break; case 'D': check_mode(); mode = ShowDependenciesMode; break; case 'h': print_usage(); return EXIT_SUCCESS; case 'l': check_mode(); mode = ListModulesMode; break; case 'q': verbose = false; break; case 'r': check_mode(); mode = RemoveModulesMode; break; case 'v': verbose = true; break; default: std::cerr << "Unrecognized option: " << opt << std::endl; return EXIT_FAILURE; } } int parameter_count = 0; for (opt = optind; opt < argc; opt++) { if (!strchr(argv[opt], '=')) { modules.emplace_back(argv[opt]); } else { parameter_count++; if (module_parameters.empty()) { module_parameters = argv[opt]; } else { module_parameters = module_parameters + " " + argv[opt]; } } } if (verbose) { std::cout << "mode is " << mode << std::endl; std::cout << "verbose is " << verbose << std::endl; std::cout << "mod_dirs is: " << android::base::Join(mod_dirs, "") << std::endl; std::cout << "modules is: " << android::base::Join(modules, "") << std::endl; std::cout << "module parameters is: " << android::base::Join(module_parameters, "") << std::endl; } if (modules.empty()) { if (mode == ListModulesMode) { // emulate toybox modprobe list with no pattern (list all) modules.emplace_back("*"); } else { std::cerr << "No modules given." << std::endl; print_usage(); return EXIT_FAILURE; } } if (mod_dirs.empty()) { std::cerr << "No module configuration directories given." << std::endl; print_usage(); return EXIT_FAILURE; } if (parameter_count && modules.size() > 1) { std::cerr << "Only one module may be loaded when specifying module parameters." << std::endl; print_usage(); return EXIT_FAILURE; } Modprobe m(mod_dirs); m.EnableVerbose(verbose); if (blacklist) { m.EnableBlacklist(true); } for (const auto& module : modules) { switch (mode) { case AddModulesMode: if (!m.LoadWithAliases(module, true, module_parameters)) { std::cerr << "Failed to load module " << module; rv = EXIT_FAILURE; } break; case RemoveModulesMode: if (!m.Remove(module)) { std::cerr << "Failed to remove module " << module; rv = EXIT_FAILURE; } break; case ListModulesMode: { std::vector<std::string> list = m.ListModules(module); std::cout << android::base::Join(list, "\n") << std::endl; break; } case ShowDependenciesMode: { std::vector<std::string> pre_deps; std::vector<std::string> deps; std::vector<std::string> post_deps; if (!m.GetAllDependencies(module, &pre_deps, &deps, &post_deps)) { rv = EXIT_FAILURE; break; } std::cout << "Dependencies for " << module << ":" << std::endl; std::cout << "Soft pre-dependencies:" << std::endl; std::cout << android::base::Join(pre_deps, "\n") << std::endl; std::cout << "Hard dependencies:" << std::endl; std::cout << android::base::Join(deps, "\n") << std::endl; std::cout << "Soft post-dependencies:" << std::endl; std::cout << android::base::Join(post_deps, "\n") << std::endl; break; } default: std::cerr << "Bad mode"; rv = EXIT_FAILURE; } } return rv; }
toolbox/tools.h +1 −0 Original line number Diff line number Diff line TOOL(getevent) TOOL(getprop) TOOL(modprobe) TOOL(setprop) TOOL(start) TOOL(stop) Loading