From 3f1bce870bf682b704ca30d3a62ff75b1496c31b Mon Sep 17 00:00:00 2001 From: Tom Cherry Date: Wed, 5 Jun 2019 09:13:11 -0700 Subject: [PATCH] init: switch host_init_verifier to getopt() Test: host init verifier works Change-Id: Ia0fe5994079e6e182a64b14a15fdb36328080168 --- init/host_init_verifier.cpp | 65 +++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 10 deletions(-) diff --git a/init/host_init_verifier.cpp b/init/host_init_verifier.cpp index 1b4716fd1..9323aa043 100644 --- a/init/host_init_verifier.cpp +++ b/init/host_init_verifier.cpp @@ -15,11 +15,13 @@ // #include +#include #include #include #include #include +#include #include #include @@ -48,9 +50,9 @@ using android::base::ParseInt; using android::base::ReadFileToString; using android::base::Split; -static std::string passwd_file; +static std::vector passwd_files; -static std::vector> GetVendorPasswd() { +static std::vector> GetVendorPasswd(const std::string& passwd_file) { std::string passwd; if (!ReadFileToString(passwd_file, &passwd)) { return {}; @@ -72,6 +74,16 @@ static std::vector> GetVendorPasswd() { return result; } +static std::vector> GetVendorPasswd() { + std::vector> result; + for (const auto& passwd_file : passwd_files) { + auto individual_result = GetVendorPasswd(passwd_file); + std::move(individual_result.begin(), individual_result.end(), + std::back_insert_iterator(result)); + } + return result; +} + passwd* getpwnam(const char* login) { // NOLINT: implementing bad function. // This isn't thread safe, but that's okay for our purposes. static char static_name[32] = ""; @@ -126,17 +138,50 @@ static Result do_stub(const BuiltinArguments& args) { #include "generated_stub_builtin_function_map.h" +void PrintUsage() { + std::cout << "usage: host_init_verifier [-p FILE] \n" + "\n" + "Tests an init script for correctness\n" + "\n" + "-p FILE\tSearch this passwd file for users and groups\n" + << std::endl; +} + int main(int argc, char** argv) { android::base::InitLogging(argv, &android::base::StdioLogger); android::base::SetMinimumLogSeverity(android::base::ERROR); - if (argc != 2 && argc != 3) { - LOG(ERROR) << "Usage: " << argv[0] << " [passwd file]"; - return EXIT_FAILURE; + while (true) { + static const struct option long_options[] = { + {"help", no_argument, nullptr, 'h'}, + {nullptr, 0, nullptr, 0}, + }; + + int arg = getopt_long(argc, argv, "p:", long_options, nullptr); + + if (arg == -1) { + break; + } + + switch (arg) { + case 'h': + PrintUsage(); + return EXIT_FAILURE; + case 'p': + passwd_files.emplace_back(optarg); + break; + default: + std::cerr << "getprop: getopt returned invalid result: " << arg << std::endl; + return EXIT_FAILURE; + } } - if (argc == 3) { - passwd_file = argv[2]; + argc -= optind; + argv += optind; + + if (argc != 1) { + PrintUsage(); + return EXIT_FAILURE; } const BuiltinFunctionMap function_map; @@ -148,12 +193,12 @@ int main(int argc, char** argv) { parser.AddSectionParser("on", std::make_unique(&am, nullptr)); parser.AddSectionParser("import", std::make_unique()); - if (!parser.ParseConfigFileInsecure(argv[1])) { - LOG(ERROR) << "Failed to open init rc script '" << argv[1] << "'"; + if (!parser.ParseConfigFileInsecure(*argv)) { + LOG(ERROR) << "Failed to open init rc script '" << *argv << "'"; return EXIT_FAILURE; } if (parser.parse_error_count() > 0) { - LOG(ERROR) << "Failed to parse init script '" << argv[1] << "' with " + LOG(ERROR) << "Failed to parse init script '" << *argv << "' with " << parser.parse_error_count() << " errors"; return EXIT_FAILURE; }