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