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