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