1 // 2 // Copyright (C) 2017 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include <getopt.h> 18 #include <sys/system_properties.h> 19 20 #include <iostream> 21 #include <string> 22 #include <vector> 23 24 #include <android-base/properties.h> 25 #include <property_info_parser/property_info_parser.h> 26 27 using android::base::GetProperty; 28 using android::properties::PropertyInfoAreaFile; 29 30 PropertyInfoAreaFile property_info_file; 31 32 enum class ResultType { 33 Value, 34 Context, 35 Type, 36 }; 37 38 void PrintAllProperties(ResultType result_type) { 39 std::vector<std::pair<std::string, std::string>> properties; 40 __system_property_foreach( 41 [](const prop_info* pi, void* cookie) { 42 __system_property_read_callback( 43 pi, 44 [](void* cookie, const char* name, const char* value, unsigned) { 45 auto properties = 46 reinterpret_cast<std::vector<std::pair<std::string, std::string>>*>(cookie); 47 properties->emplace_back(name, value); 48 }, 49 cookie); 50 }, 51 &properties); 52 53 std::sort(properties.begin(), properties.end()); 54 55 if (result_type != ResultType::Value) { 56 for (auto& [name, value] : properties) { 57 const char* context = nullptr; 58 const char* type = nullptr; 59 property_info_file->GetPropertyInfo(name.c_str(), &context, &type); 60 if (result_type == ResultType::Context) { 61 value = context; 62 } else { 63 value = type; 64 } 65 } 66 } 67 68 for (const auto& [name, value] : properties) { 69 std::cout << "[" << name << "]: [" << value << "]" << std::endl; 70 } 71 } 72 73 void PrintProperty(const char* name, const char* default_value, ResultType result_type) { 74 switch (result_type) { 75 case ResultType::Value: 76 std::cout << GetProperty(name, default_value) << std::endl; 77 break; 78 case ResultType::Context: { 79 const char* context = nullptr; 80 property_info_file->GetPropertyInfo(name, &context, nullptr); 81 std::cout << context << std::endl; 82 break; 83 } 84 case ResultType::Type: { 85 const char* type = nullptr; 86 property_info_file->GetPropertyInfo(name, nullptr, &type); 87 std::cout << type << std::endl; 88 break; 89 } 90 } 91 } 92 93 extern "C" int getprop_main(int argc, char** argv) { 94 auto result_type = ResultType::Value; 95 96 while (true) { 97 static const struct option long_options[] = { 98 {"help", no_argument, nullptr, 'h'}, 99 {nullptr, 0, nullptr, 0}, 100 }; 101 102 int arg = getopt_long(argc, argv, "TZ", long_options, nullptr); 103 104 if (arg == -1) { 105 break; 106 } 107 108 switch (arg) { 109 case 'h': 110 std::cout << "usage: getprop [-TZ] [NAME [DEFAULT]]\n" 111 "\n" 112 "Gets an Android system property, or lists them all.\n" 113 "\n" 114 "-T\tShow property types instead of values\n" 115 "-Z\tShow property contexts instead of values\n" 116 << std::endl; 117 return 0; 118 case 'T': 119 if (result_type != ResultType::Value) { 120 std::cerr << "Only one of -T or -Z may be specified" << std::endl; 121 return -1; 122 } 123 result_type = ResultType::Type; 124 break; 125 case 'Z': 126 if (result_type != ResultType::Value) { 127 std::cerr << "Only one of -T or -Z may be specified" << std::endl; 128 return -1; 129 } 130 result_type = ResultType::Context; 131 break; 132 case '?': 133 return -1; 134 default: 135 std::cerr << "getprop: getopt returned invalid result: " << arg << std::endl; 136 return -1; 137 } 138 } 139 140 if (result_type != ResultType::Value) { 141 property_info_file.LoadDefaultPath(); 142 if (!property_info_file) { 143 std::cerr << "Unable to load property info file" << std::endl; 144 return -1; 145 } 146 } 147 148 if (optind >= argc) { 149 PrintAllProperties(result_type); 150 return 0; 151 } 152 153 if (optind < argc - 2) { 154 std::cerr << "getprop: Max 2 arguments (see \"getprop --help\")" << std::endl; 155 return -1; 156 } 157 158 PrintProperty(argv[optind], (optind == argc - 1) ? "" : argv[optind + 1], result_type); 159 160 return 0; 161 } 162