1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <errno.h> 2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <ftw.h> 3e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <getopt.h> 4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/client.h> 5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/service.h> 6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <sys/stat.h> 7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <algorithm> 9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <vector> 10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/default_transport/client_channel_factory.h> 12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::default_transport::ClientChannelFactory; 14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace { 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoconstexpr long kClientTimeoutMs = 0; // Don't wait for non-existent services. 18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoconstexpr int kDumpBufferSize = 2 * 4096; // Two pages. 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 20e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass ControlClient : public android::pdx::ClientBase<ControlClient> { 21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko explicit ControlClient(const std::string& service_path, long timeout_ms); 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void Reload(); 25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::string Dump(); 26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko friend BASE; 29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 30e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ControlClient(const ControlClient&) = delete; 31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void operator=(const ControlClient&) = delete; 32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkobool option_verbose = false; 35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostatic struct option long_options[] = { 37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko {"reload", required_argument, 0, 0}, 38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko {"dump", required_argument, 0, 0}, 39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko {"verbose", no_argument, 0, 0}, 40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko {0, 0, 0, 0}, 41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#define printf_verbose(fmt, ... /*args*/) \ 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko do { \ 45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (option_verbose) \ 46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf(fmt, ##__VA_ARGS__); \ 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } while (0) 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid HexDump(const void* pointer, size_t length); 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoControlClient::ControlClient(const std::string& service_path, long timeout_ms) 52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : BASE{ClientChannelFactory::Create(service_path), timeout_ms} {} 53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid ControlClient::Reload() { 55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko android::pdx::Transaction trans{*this}; 56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = trans.Send<void>(android::pdx::opcodes::REPORT_SYSPROP_CHANGE, 57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko nullptr, 0, nullptr, 0); 58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) { 59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko fprintf(stderr, "Failed to send reload: %s\n", 60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.GetErrorMessage().c_str()); 61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::string ControlClient::Dump() { 65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko android::pdx::Transaction trans{*this}; 66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::vector<char> buffer(kDumpBufferSize); 67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = trans.Send<int>(android::pdx::opcodes::DUMP_STATE, nullptr, 0, 68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko buffer.data(), buffer.size()); 69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf_verbose("ControlClient::Dump: ret=%d\n", ReturnStatusOrError(status)); 71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!status) { 73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko fprintf(stderr, "Failed to send dump request: %s\n", 74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.GetErrorMessage().c_str()); 75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ""; 76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else if (status.get() > static_cast<ssize_t>(buffer.capacity())) { 77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko fprintf(stderr, "Service returned a larger size than requested: %d\n", 78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko status.get()); 79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ""; 80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (option_verbose) 83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko HexDump(buffer.data(), status.get()); 84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return std::string(buffer.data(), status.get()); 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint Usage(const std::string& command_name) { 89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf("Usage: %s [options]\n", command_name.c_str()); 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf("\t--verbose : Use verbose messages.\n"); 91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf( 92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "\t--reload <all | service path> : Ask service(s) to reload system " 93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "properties.\n"); 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf("\t--dump <all | service path> : Dump service(s) state.\n"); 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return -1; 96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkotypedef int (*CallbackType)(const char* path, const struct stat* sb, 99e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int type_flag, FTW* ftw_buffer); 100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint ReloadCommandCallback(const char* path, const struct stat* sb, 102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int type_flag, FTW* ftw_buffer); 103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint DumpCommandCallback(const char* path, const struct stat* sb, int type_flag, 104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko FTW* ftw_buffer); 105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid CallOnAllFiles(CallbackType callback, const std::string& base_path) { 107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int kMaxDepth = 32; 108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko nftw(base_path.c_str(), callback, kMaxDepth, FTW_PHYS); 109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint ReloadCommand(const std::string& service_path) { 112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf_verbose("ReloadCommand: service_path=%s\n", service_path.c_str()); 113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (service_path == "" || service_path == "all") { 115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko CallOnAllFiles(ReloadCommandCallback, 116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ClientChannelFactory::GetRootEndpointPath()); 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto client = ControlClient::Create(service_path, kClientTimeoutMs); 120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!client) { 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko fprintf(stderr, "Failed to open service at \"%s\".\n", 122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko service_path.c_str()); 123e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return -1; 124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 126e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko client->Reload(); 127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint DumpCommand(const std::string& service_path) { 132e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf_verbose("DumpCommand: service_path=%s\n", service_path.c_str()); 133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (service_path == "" || service_path == "all") { 135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko CallOnAllFiles(DumpCommandCallback, 136e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ClientChannelFactory::GetRootEndpointPath()); 137e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 138e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto client = ControlClient::Create(service_path, kClientTimeoutMs); 140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!client) { 141e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko fprintf(stderr, "Failed to open service at \"%s\".\n", 142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko service_path.c_str()); 143e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return -1; 144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::string response = client->Dump(); 147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!response.empty()) { 148e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf( 149e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "--------------------------------------------------------------------" 150e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko "---\n"); 151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf("%s:\n", service_path.c_str()); 152e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf("%s\n", response.c_str()); 153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 158e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint ReloadCommandCallback(const char* path, const struct stat*, int type_flag, 159e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko FTW*) { 160e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (type_flag == FTW_F) 161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ReloadCommand(path); 162e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 163e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 164e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 165e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint DumpCommandCallback(const char* path, const struct stat*, int type_flag, 166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko FTW*) { 167e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (type_flag == FTW_F) 168e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko DumpCommand(path); 169e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return 0; 170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkovoid HexDump(const void* pointer, size_t length) { 173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko uintptr_t address = reinterpret_cast<uintptr_t>(pointer); 174e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 175e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko for (size_t count = 0; count < length; count += 16, address += 16) { 176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf("0x%08lx: ", static_cast<unsigned long>(address)); 177e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko for (size_t i = 0; i < 16u; i++) { 179e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (i < std::min(length - count, static_cast<size_t>(16))) { 180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf("%02x ", *reinterpret_cast<const uint8_t*>(address + i)); 181e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 182e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf(" "); 183e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 184e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 185e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 186e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf("|"); 187e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko for (size_t i = 0; i < 16u; i++) { 189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (i < std::min(length - count, static_cast<size_t>(16))) { 190e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko char c = *reinterpret_cast<const char*>(address + i); 191e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (isalnum(c) || c == ' ') { 192e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf("%c", c); 193e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf("."); 195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 196e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 197e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf(" "); 198e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 199e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 200e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 201e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf("|\n"); 202e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 203e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 204e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 205e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // anonymous namespace 206e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 207e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoint main(int argc, char** argv) { 208e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int getopt_code; 209e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int option_index; 210e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::string option = ""; 211e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::string command = ""; 212e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::string command_argument = ""; 213e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 214e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Process command line options. 215e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko while ((getopt_code = 216e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko getopt_long(argc, argv, "", long_options, &option_index)) != -1) { 217e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko option = long_options[option_index].name; 218e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf_verbose("option=%s\n", option.c_str()); 219e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko switch (getopt_code) { 220e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case 0: 221e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (option == "verbose") { 222e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko option_verbose = true; 223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 224e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko command = option; 225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (optarg) 226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko command_argument = optarg; 227e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 228e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko break; 229e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 230e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 231e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 232e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko printf_verbose("command=%s command_argument=%s\n", command.c_str(), 233e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko command_argument.c_str()); 234e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 235e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (command == "") { 236e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return Usage(argv[0]); 237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else if (command == "reload") { 238e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReloadCommand(command_argument); 239e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else if (command == "dump") { 240e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return DumpCommand(command_argument); 241e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } else { 242e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return Usage(argv[0]); 243e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 244e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 245