Home | History | Annotate | Download | only in toolbox
      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