/* * 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 #include #include #include #include #include #include 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> 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>*>(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; }