| // |
| // 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; |
| } |