| /* | |
| * Copyright (C) 2017 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 <getopt.h> | |
| #include <sys/system_properties.h> | |
| #include <iostream> | |
| #include <string> | |
| #include <vector> | |
| #include <android-base/properties.h> | |
| #include <property_info_parser/property_info_parser.h> | |
| using android::base::GetProperty; | |
| using android::properties::PropertyInfoAreaFile; | |
| PropertyInfoAreaFile property_info_file; | |
| enum class ResultType { | |
| Value, | |
| Context, | |
| Type, | |
| }; | |
| void PrintAllProperties(ResultType result_type) { | |
| std::vector<std::pair<std::string, std::string>> properties; | |
| __system_property_foreach( | |
| [](const prop_info* pi, void* cookie) { | |
| __system_property_read_callback( | |
| pi, | |
| [](void* cookie, const char* name, const char* value, unsigned) { | |
| auto properties = | |
| reinterpret_cast<std::vector<std::pair<std::string, std::string>>*>(cookie); | |
| properties->emplace_back(name, value); | |
| }, | |
| cookie); | |
| }, | |
| &properties); | |
| std::sort(properties.begin(), properties.end()); | |
| if (result_type != ResultType::Value) { | |
| for (auto& [name, value] : properties) { | |
| const char* context = nullptr; | |
| const char* type = nullptr; | |
| property_info_file->GetPropertyInfo(name.c_str(), &context, &type); | |
| if (result_type == ResultType::Context) { | |
| value = context; | |
| } else { | |
| value = type; | |
| } | |
| } | |
| } | |
| for (const auto& [name, value] : properties) { | |
| std::cout << "[" << name << "]: [" << value << "]" << std::endl; | |
| } | |
| } | |
| void PrintProperty(const char* name, const char* default_value, ResultType result_type) { | |
| switch (result_type) { | |
| case ResultType::Value: | |
| std::cout << GetProperty(name, default_value) << std::endl; | |
| break; | |
| case ResultType::Context: { | |
| const char* context = nullptr; | |
| property_info_file->GetPropertyInfo(name, &context, nullptr); | |
| std::cout << context << std::endl; | |
| break; | |
| } | |
| case ResultType::Type: { | |
| const char* type = nullptr; | |
| property_info_file->GetPropertyInfo(name, nullptr, &type); | |
| std::cout << type << std::endl; | |
| break; | |
| } | |
| } | |
| } | |
| extern "C" int getprop_main(int argc, char** argv) { | |
| auto result_type = ResultType::Value; | |
| while (true) { | |
| static const struct option long_options[] = { | |
| {"help", no_argument, nullptr, 'h'}, | |
| {nullptr, 0, nullptr, 0}, | |
| }; | |
| int arg = getopt_long(argc, argv, "TZ", long_options, nullptr); | |
| if (arg == -1) { | |
| break; | |
| } | |
| switch (arg) { | |
| case 'h': | |
| std::cout << "usage: getprop [-TZ] [NAME [DEFAULT]]\n" | |
| "\n" | |
| "Gets an Android system property, or lists them all.\n" | |
| "\n" | |
| "-T\tShow property types instead of values\n" | |
| "-Z\tShow property contexts instead of values\n" | |
| << std::endl; | |
| return 0; | |
| case 'T': | |
| if (result_type != ResultType::Value) { | |
| std::cerr << "Only one of -T or -Z may be specified" << std::endl; | |
| return -1; | |
| } | |
| result_type = ResultType::Type; | |
| break; | |
| case 'Z': | |
| if (result_type != ResultType::Value) { | |
| std::cerr << "Only one of -T or -Z may be specified" << std::endl; | |
| return -1; | |
| } | |
| result_type = ResultType::Context; | |
| break; | |
| case '?': | |
| return -1; | |
| default: | |
| std::cerr << "getprop: getopt returned invalid result: " << arg << std::endl; | |
| return -1; | |
| } | |
| } | |
| if (result_type != ResultType::Value) { | |
| property_info_file.LoadDefaultPath(); | |
| if (!property_info_file) { | |
| std::cerr << "Unable to load property info file" << std::endl; | |
| return -1; | |
| } | |
| } | |
| if (optind >= argc) { | |
| PrintAllProperties(result_type); | |
| return 0; | |
| } | |
| if (optind < argc - 2) { | |
| std::cerr << "getprop: Max 2 arguments (see \"getprop --help\")" << std::endl; | |
| return -1; | |
| } | |
| PrintProperty(argv[optind], (optind == argc - 1) ? "" : argv[optind + 1], result_type); | |
| return 0; | |
| } |