CommandListener.cpp revision dfa7a07f5be656cfafdb4e75916bc9dcd9e592e7
1/* 2 * Copyright (C) 2012-2014 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 <arpa/inet.h> 18#include <dirent.h> 19#include <errno.h> 20#include <fcntl.h> 21#include <netinet/in.h> 22#include <string.h> 23#include <stdlib.h> 24#include <sys/socket.h> 25#include <sys/types.h> 26 27#include <private/android_filesystem_config.h> 28#include <sysutils/SocketClient.h> 29 30#include "CommandListener.h" 31#include "LogCommand.h" 32 33CommandListener::CommandListener(LogBuffer *buf, LogReader * /*reader*/, 34 LogListener * /*swl*/) 35 : FrameworkListener("logd") 36 , mBuf(*buf) { 37 // registerCmd(new ShutdownCmd(buf, writer, swl)); 38 registerCmd(new ClearCmd(buf)); 39 registerCmd(new GetBufSizeCmd(buf)); 40#ifdef USERDEBUG_BUILD 41 registerCmd(new SetBufSizeCmd(buf)); 42#endif 43 registerCmd(new GetBufSizeUsedCmd(buf)); 44 registerCmd(new GetStatisticsCmd(buf)); 45#ifdef USERDEBUG_BUILD 46 registerCmd(new SetPruneListCmd(buf)); 47 registerCmd(new GetPruneListCmd(buf)); 48#endif 49} 50 51CommandListener::ShutdownCmd::ShutdownCmd(LogBuffer *buf, LogReader *reader, 52 LogListener *swl) 53 : LogCommand("shutdown") 54 , mBuf(*buf) 55 , mReader(*reader) 56 , mSwl(*swl) 57{ } 58 59int CommandListener::ShutdownCmd::runCommand(SocketClient * /*cli*/, 60 int /*argc*/, 61 char ** /*argv*/) { 62 mSwl.stopListener(); 63 mReader.stopListener(); 64 exit(0); 65} 66 67CommandListener::ClearCmd::ClearCmd(LogBuffer *buf) 68 : LogCommand("clear") 69 , mBuf(*buf) 70{ } 71 72int CommandListener::ClearCmd::runCommand(SocketClient *cli, 73 int argc, char **argv) { 74 if (!clientHasLogCredentials(cli)) { 75 cli->sendMsg("Permission Denied"); 76 return 0; 77 } 78 79 if (argc < 2) { 80 cli->sendMsg("Missing Argument"); 81 return 0; 82 } 83 84 int id = atoi(argv[1]); 85 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) { 86 cli->sendMsg("Range Error"); 87 return 0; 88 } 89 90 mBuf.clear((log_id_t) id); 91 cli->sendMsg("success"); 92 return 0; 93} 94 95CommandListener::GetBufSizeCmd::GetBufSizeCmd(LogBuffer *buf) 96 : LogCommand("getLogSize") 97 , mBuf(*buf) 98{ } 99 100int CommandListener::GetBufSizeCmd::runCommand(SocketClient *cli, 101 int argc, char **argv) { 102 if (argc < 2) { 103 cli->sendMsg("Missing Argument"); 104 return 0; 105 } 106 107 int id = atoi(argv[1]); 108 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) { 109 cli->sendMsg("Range Error"); 110 return 0; 111 } 112 113 unsigned long size = mBuf.getSize((log_id_t) id); 114 char buf[512]; 115 snprintf(buf, sizeof(buf), "%lu", size); 116 cli->sendMsg(buf); 117 return 0; 118} 119 120#ifdef USERDEBUG_BUILD 121 122CommandListener::SetBufSizeCmd::SetBufSizeCmd(LogBuffer *buf) 123 : LogCommand("setLogSize") 124 , mBuf(*buf) 125{ } 126 127int CommandListener::SetBufSizeCmd::runCommand(SocketClient *cli, 128 int argc, char **argv) { 129 if (!clientHasLogCredentials(cli)) { 130 cli->sendMsg("Permission Denied"); 131 return 0; 132 } 133 134 if (argc < 3) { 135 cli->sendMsg("Missing Argument"); 136 return 0; 137 } 138 139 int id = atoi(argv[1]); 140 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) { 141 cli->sendMsg("Range Error"); 142 return 0; 143 } 144 145 unsigned long size = atol(argv[2]); 146 if (mBuf.setSize((log_id_t) id, size)) { 147 cli->sendMsg("Range Error"); 148 return 0; 149 } 150 151 cli->sendMsg("success"); 152 return 0; 153} 154 155#endif // USERDEBUG_BUILD 156 157CommandListener::GetBufSizeUsedCmd::GetBufSizeUsedCmd(LogBuffer *buf) 158 : LogCommand("getLogSizeUsed") 159 , mBuf(*buf) 160{ } 161 162int CommandListener::GetBufSizeUsedCmd::runCommand(SocketClient *cli, 163 int argc, char **argv) { 164 if (argc < 2) { 165 cli->sendMsg("Missing Argument"); 166 return 0; 167 } 168 169 int id = atoi(argv[1]); 170 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) { 171 cli->sendMsg("Range Error"); 172 return 0; 173 } 174 175 unsigned long size = mBuf.getSizeUsed((log_id_t) id); 176 char buf[512]; 177 snprintf(buf, sizeof(buf), "%lu", size); 178 cli->sendMsg(buf); 179 return 0; 180} 181 182CommandListener::GetStatisticsCmd::GetStatisticsCmd(LogBuffer *buf) 183 : LogCommand("getStatistics") 184 , mBuf(*buf) 185{ } 186 187static void package_string(char **strp) { 188 const char *a = *strp; 189 if (!a) { 190 a = ""; 191 } 192 193 // Calculate total buffer size prefix, count is the string length w/o nul 194 char fmt[32]; 195 for(size_t l = strlen(a), y = 0, x = 6; y != x; y = x, x = strlen(fmt) - 2) { 196 snprintf(fmt, sizeof(fmt), "%zu\n%%s\n\f", l + x); 197 } 198 199 char *b = *strp; 200 *strp = NULL; 201 asprintf(strp, fmt, a); 202 free(b); 203} 204 205int CommandListener::GetStatisticsCmd::runCommand(SocketClient *cli, 206 int argc, char **argv) { 207 uid_t uid = cli->getUid(); 208 gid_t gid = cli->getGid(); 209 if (clientHasLogCredentials(cli)) { 210 uid = AID_ROOT; 211 } 212 213 unsigned int logMask = -1; 214 if (argc > 1) { 215 logMask = 0; 216 for (int i = 1; i < argc; ++i) { 217 int id = atoi(argv[i]); 218 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) { 219 cli->sendMsg("Range Error"); 220 return 0; 221 } 222 logMask |= 1 << id; 223 } 224 } 225 226 char *buf = NULL; 227 228 mBuf.formatStatistics(&buf, uid, logMask); 229 if (!buf) { 230 cli->sendMsg("Failed"); 231 } else { 232 package_string(&buf); 233 cli->sendMsg(buf); 234 free(buf); 235 } 236 return 0; 237} 238 239#ifdef USERDEBUG_BUILD 240 241CommandListener::GetPruneListCmd::GetPruneListCmd(LogBuffer *buf) 242 : LogCommand("getPruneList") 243 , mBuf(*buf) 244{ } 245 246int CommandListener::GetPruneListCmd::runCommand(SocketClient *cli, 247 int /*argc*/, char ** /*argv*/) { 248 char *buf = NULL; 249 mBuf.formatPrune(&buf); 250 if (!buf) { 251 cli->sendMsg("Failed"); 252 } else { 253 package_string(&buf); 254 cli->sendMsg(buf); 255 free(buf); 256 } 257 return 0; 258} 259 260CommandListener::SetPruneListCmd::SetPruneListCmd(LogBuffer *buf) 261 : LogCommand("setPruneList") 262 , mBuf(*buf) 263{ } 264 265int CommandListener::SetPruneListCmd::runCommand(SocketClient *cli, 266 int argc, char **argv) { 267 if (!clientHasLogCredentials(cli)) { 268 cli->sendMsg("Permission Denied"); 269 return 0; 270 } 271 272 char *cp = NULL; 273 for (int i = 1; i < argc; ++i) { 274 char *p = cp; 275 if (p) { 276 cp = NULL; 277 asprintf(&cp, "%s %s", p, argv[i]); 278 free(p); 279 } else { 280 asprintf(&cp, "%s", argv[i]); 281 } 282 } 283 284 int ret = mBuf.initPrune(cp); 285 free(cp); 286 287 if (ret) { 288 cli->sendMsg("Invalid"); 289 return 0; 290 } 291 292 cli->sendMsg("success"); 293 294 return 0; 295} 296 297#endif // USERDEBUG_BUILD 298