blob: 06c0ab5fe9f2cd0ce6f900dce9bf55eea5b00969 [file] [log] [blame]
Mark Salyzyn0175b072014-02-26 09:50:16 -08001/*
Mark Salyzyn1114f182014-02-21 13:54:07 -08002 * Copyright (C) 2012-2014 The Android Open Source Project
Mark Salyzyn0175b072014-02-26 09:50:16 -08003 *
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>
Mark Salyzyn61e9ce62016-09-12 14:51:54 -070018#include <ctype.h>
Mark Salyzyn0175b072014-02-26 09:50:16 -080019#include <dirent.h>
20#include <errno.h>
21#include <fcntl.h>
22#include <netinet/in.h>
Mark Salyzyn0175b072014-02-26 09:50:16 -080023#include <stdlib.h>
Mark Salyzyn501c3732017-03-10 14:31:54 -080024#include <string.h>
Mark Salyzyn8daa9af2014-04-28 14:07:23 -070025#include <sys/prctl.h>
Mark Salyzyn0175b072014-02-26 09:50:16 -080026#include <sys/socket.h>
27#include <sys/types.h>
28
Mark Salyzyn73160ac2015-08-20 10:01:44 -070029#include <string>
30
Elliott Hughes4f713192015-12-04 22:00:26 -080031#include <android-base/stringprintf.h>
Mark Salyzyndfc47e82014-03-24 10:26:47 -070032#include <cutils/sockets.h>
Mark Salyzyn0175b072014-02-26 09:50:16 -080033#include <private/android_filesystem_config.h>
Mark Salyzyn1114f182014-02-21 13:54:07 -080034#include <sysutils/SocketClient.h>
Mark Salyzyn0175b072014-02-26 09:50:16 -080035
36#include "CommandListener.h"
Mark Salyzyn1114f182014-02-21 13:54:07 -080037#include "LogCommand.h"
Mark Salyzyn083b0372015-12-04 10:59:45 -080038#include "LogUtils.h"
Mark Salyzyn0175b072014-02-26 09:50:16 -080039
Mark Salyzyn501c3732017-03-10 14:31:54 -080040CommandListener::CommandListener(LogBuffer* buf, LogReader* /*reader*/,
41 LogListener* /*swl*/)
42 : FrameworkListener(getLogSocket()) {
Mark Salyzyn0175b072014-02-26 09:50:16 -080043 // registerCmd(new ShutdownCmd(buf, writer, swl));
44 registerCmd(new ClearCmd(buf));
45 registerCmd(new GetBufSizeCmd(buf));
Mark Salyzyndfa7a072014-02-11 12:29:31 -080046 registerCmd(new SetBufSizeCmd(buf));
Mark Salyzyn0175b072014-02-26 09:50:16 -080047 registerCmd(new GetBufSizeUsedCmd(buf));
Mark Salyzyn34facab2014-02-06 14:48:50 -080048 registerCmd(new GetStatisticsCmd(buf));
Mark Salyzyndfa7a072014-02-11 12:29:31 -080049 registerCmd(new SetPruneListCmd(buf));
50 registerCmd(new GetPruneListCmd(buf));
Mark Salyzyn61e9ce62016-09-12 14:51:54 -070051 registerCmd(new GetEventTagCmd(buf));
Mark Salyzyn11e55cb2015-03-10 16:45:17 -070052 registerCmd(new ReinitCmd());
Mark Salyzync8749d52016-09-08 13:16:59 -070053 registerCmd(new ExitCmd(this));
Mark Salyzyn0175b072014-02-26 09:50:16 -080054}
55
Mark Salyzyn501c3732017-03-10 14:31:54 -080056CommandListener::ShutdownCmd::ShutdownCmd(LogReader* reader, LogListener* swl)
57 : LogCommand("shutdown"), mReader(*reader), mSwl(*swl) {
Mark Salyzyn77187782015-05-12 15:21:31 -070058}
Mark Salyzyn0175b072014-02-26 09:50:16 -080059
Mark Salyzyn501c3732017-03-10 14:31:54 -080060int CommandListener::ShutdownCmd::runCommand(SocketClient* /*cli*/,
61 int /*argc*/, char** /*argv*/) {
Mark Salyzyn0175b072014-02-26 09:50:16 -080062 mSwl.stopListener();
63 mReader.stopListener();
64 exit(0);
65}
66
Mark Salyzyn501c3732017-03-10 14:31:54 -080067CommandListener::ClearCmd::ClearCmd(LogBuffer* buf)
68 : LogCommand("clear"), mBuf(*buf) {
Mark Salyzyn77187782015-05-12 15:21:31 -070069}
Mark Salyzyn0175b072014-02-26 09:50:16 -080070
Mark Salyzyn8daa9af2014-04-28 14:07:23 -070071static void setname() {
Mark Salyzyne3aeeee2015-03-17 07:56:32 -070072 static bool name_set;
73 if (!name_set) {
74 prctl(PR_SET_NAME, "logd.control");
75 name_set = true;
76 }
Mark Salyzyn8daa9af2014-04-28 14:07:23 -070077}
78
Mark Salyzyn501c3732017-03-10 14:31:54 -080079int CommandListener::ClearCmd::runCommand(SocketClient* cli, int argc,
80 char** argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -070081 setname();
Mark Salyzyn1a240b42014-06-12 11:16:16 -070082 uid_t uid = cli->getUid();
83 if (clientHasLogCredentials(cli)) {
84 uid = AID_ROOT;
Mark Salyzyn0175b072014-02-26 09:50:16 -080085 }
86
87 if (argc < 2) {
88 cli->sendMsg("Missing Argument");
89 return 0;
90 }
91
92 int id = atoi(argv[1]);
Mark Salyzyn1114f182014-02-21 13:54:07 -080093 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) {
Mark Salyzyn0175b072014-02-26 09:50:16 -080094 cli->sendMsg("Range Error");
95 return 0;
96 }
97
Mark Salyzyn501c3732017-03-10 14:31:54 -080098 cli->sendMsg(mBuf.clear((log_id_t)id, uid) ? "busy" : "success");
Mark Salyzyn0175b072014-02-26 09:50:16 -080099 return 0;
100}
101
Mark Salyzyn501c3732017-03-10 14:31:54 -0800102CommandListener::GetBufSizeCmd::GetBufSizeCmd(LogBuffer* buf)
103 : LogCommand("getLogSize"), mBuf(*buf) {
Mark Salyzyn77187782015-05-12 15:21:31 -0700104}
Mark Salyzyn0175b072014-02-26 09:50:16 -0800105
Mark Salyzyn501c3732017-03-10 14:31:54 -0800106int CommandListener::GetBufSizeCmd::runCommand(SocketClient* cli, int argc,
107 char** argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700108 setname();
Mark Salyzyn0175b072014-02-26 09:50:16 -0800109 if (argc < 2) {
110 cli->sendMsg("Missing Argument");
111 return 0;
112 }
113
114 int id = atoi(argv[1]);
Mark Salyzyn1114f182014-02-21 13:54:07 -0800115 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) {
Mark Salyzyn0175b072014-02-26 09:50:16 -0800116 cli->sendMsg("Range Error");
117 return 0;
118 }
119
Mark Salyzyn501c3732017-03-10 14:31:54 -0800120 unsigned long size = mBuf.getSize((log_id_t)id);
Mark Salyzyn0175b072014-02-26 09:50:16 -0800121 char buf[512];
122 snprintf(buf, sizeof(buf), "%lu", size);
123 cli->sendMsg(buf);
124 return 0;
125}
126
Mark Salyzyn501c3732017-03-10 14:31:54 -0800127CommandListener::SetBufSizeCmd::SetBufSizeCmd(LogBuffer* buf)
128 : LogCommand("setLogSize"), mBuf(*buf) {
Mark Salyzyn77187782015-05-12 15:21:31 -0700129}
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800130
Mark Salyzyn501c3732017-03-10 14:31:54 -0800131int CommandListener::SetBufSizeCmd::runCommand(SocketClient* cli, int argc,
132 char** argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700133 setname();
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800134 if (!clientHasLogCredentials(cli)) {
135 cli->sendMsg("Permission Denied");
136 return 0;
137 }
138
139 if (argc < 3) {
140 cli->sendMsg("Missing Argument");
141 return 0;
142 }
143
144 int id = atoi(argv[1]);
145 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) {
146 cli->sendMsg("Range Error");
147 return 0;
148 }
149
150 unsigned long size = atol(argv[2]);
Mark Salyzyn501c3732017-03-10 14:31:54 -0800151 if (mBuf.setSize((log_id_t)id, size)) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800152 cli->sendMsg("Range Error");
153 return 0;
154 }
155
156 cli->sendMsg("success");
157 return 0;
158}
159
Mark Salyzyn501c3732017-03-10 14:31:54 -0800160CommandListener::GetBufSizeUsedCmd::GetBufSizeUsedCmd(LogBuffer* buf)
161 : LogCommand("getLogSizeUsed"), mBuf(*buf) {
Mark Salyzyn77187782015-05-12 15:21:31 -0700162}
Mark Salyzyn0175b072014-02-26 09:50:16 -0800163
Mark Salyzyn501c3732017-03-10 14:31:54 -0800164int CommandListener::GetBufSizeUsedCmd::runCommand(SocketClient* cli, int argc,
165 char** argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700166 setname();
Mark Salyzyn0175b072014-02-26 09:50:16 -0800167 if (argc < 2) {
168 cli->sendMsg("Missing Argument");
169 return 0;
170 }
171
172 int id = atoi(argv[1]);
Mark Salyzyn1114f182014-02-21 13:54:07 -0800173 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) {
Mark Salyzyn0175b072014-02-26 09:50:16 -0800174 cli->sendMsg("Range Error");
175 return 0;
176 }
177
Mark Salyzyn501c3732017-03-10 14:31:54 -0800178 unsigned long size = mBuf.getSizeUsed((log_id_t)id);
Mark Salyzyn0175b072014-02-26 09:50:16 -0800179 char buf[512];
180 snprintf(buf, sizeof(buf), "%lu", size);
181 cli->sendMsg(buf);
182 return 0;
183}
Mark Salyzyn34facab2014-02-06 14:48:50 -0800184
Mark Salyzyn501c3732017-03-10 14:31:54 -0800185CommandListener::GetStatisticsCmd::GetStatisticsCmd(LogBuffer* buf)
186 : LogCommand("getStatistics"), mBuf(*buf) {
Mark Salyzyn77187782015-05-12 15:21:31 -0700187}
Mark Salyzyn34facab2014-02-06 14:48:50 -0800188
Mark Salyzyn501c3732017-03-10 14:31:54 -0800189static std::string package_string(const std::string& str) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800190 // Calculate total buffer size prefix, count is the string length w/o nul
191 char fmt[32];
Mark Salyzyn501c3732017-03-10 14:31:54 -0800192 for (size_t l = str.length(), y = 0, x = 6; y != x;
193 y = x, x = strlen(fmt) - 2) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800194 snprintf(fmt, sizeof(fmt), "%zu\n%%s\n\f", l + x);
195 }
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700196 return android::base::StringPrintf(fmt, str.c_str());
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800197}
198
Mark Salyzyn501c3732017-03-10 14:31:54 -0800199int CommandListener::GetStatisticsCmd::runCommand(SocketClient* cli, int argc,
200 char** argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700201 setname();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800202 uid_t uid = cli->getUid();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800203 if (clientHasLogCredentials(cli)) {
204 uid = AID_ROOT;
205 }
206
207 unsigned int logMask = -1;
Mark Salyzynee3b8382015-12-17 09:58:43 -0800208 pid_t pid = 0;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800209 if (argc > 1) {
210 logMask = 0;
211 for (int i = 1; i < argc; ++i) {
Mark Salyzynee3b8382015-12-17 09:58:43 -0800212 static const char _pid[] = "pid=";
213 if (!strncmp(argv[i], _pid, sizeof(_pid) - 1)) {
214 pid = atol(argv[i] + sizeof(_pid) - 1);
215 if (pid == 0) {
216 cli->sendMsg("PID Error");
217 return 0;
218 }
219 continue;
220 }
221
Mark Salyzyn34facab2014-02-06 14:48:50 -0800222 int id = atoi(argv[i]);
223 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) {
224 cli->sendMsg("Range Error");
225 return 0;
226 }
227 logMask |= 1 << id;
228 }
229 }
230
Mark Salyzyn501c3732017-03-10 14:31:54 -0800231 cli->sendMsg(
232 package_string(mBuf.formatStatistics(uid, pid, logMask)).c_str());
Mark Salyzyn34facab2014-02-06 14:48:50 -0800233 return 0;
234}
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800235
Mark Salyzyn501c3732017-03-10 14:31:54 -0800236CommandListener::GetPruneListCmd::GetPruneListCmd(LogBuffer* buf)
237 : LogCommand("getPruneList"), mBuf(*buf) {
Mark Salyzyn77187782015-05-12 15:21:31 -0700238}
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800239
Mark Salyzyn501c3732017-03-10 14:31:54 -0800240int CommandListener::GetPruneListCmd::runCommand(SocketClient* cli,
241 int /*argc*/, char** /*argv*/) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700242 setname();
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700243 cli->sendMsg(package_string(mBuf.formatPrune()).c_str());
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800244 return 0;
245}
246
Mark Salyzyn501c3732017-03-10 14:31:54 -0800247CommandListener::SetPruneListCmd::SetPruneListCmd(LogBuffer* buf)
248 : LogCommand("setPruneList"), mBuf(*buf) {
Mark Salyzyn77187782015-05-12 15:21:31 -0700249}
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800250
Mark Salyzyn501c3732017-03-10 14:31:54 -0800251int CommandListener::SetPruneListCmd::runCommand(SocketClient* cli, int argc,
252 char** argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700253 setname();
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800254 if (!clientHasLogCredentials(cli)) {
255 cli->sendMsg("Permission Denied");
256 return 0;
257 }
258
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700259 std::string str;
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800260 for (int i = 1; i < argc; ++i) {
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700261 if (str.length()) {
262 str += " ";
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800263 }
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700264 str += argv[i];
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800265 }
266
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700267 int ret = mBuf.initPrune(str.c_str());
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800268
269 if (ret) {
270 cli->sendMsg("Invalid");
271 return 0;
272 }
273
274 cli->sendMsg("success");
275
276 return 0;
277}
Mark Salyzyndfc47e82014-03-24 10:26:47 -0700278
Mark Salyzyn501c3732017-03-10 14:31:54 -0800279CommandListener::GetEventTagCmd::GetEventTagCmd(LogBuffer* buf)
280 : LogCommand("getEventTag"), mBuf(*buf) {
Mark Salyzyn61e9ce62016-09-12 14:51:54 -0700281}
282
Mark Salyzyn501c3732017-03-10 14:31:54 -0800283int CommandListener::GetEventTagCmd::runCommand(SocketClient* cli, int argc,
284 char** argv) {
Mark Salyzyn61e9ce62016-09-12 14:51:54 -0700285 setname();
286 uid_t uid = cli->getUid();
287 if (clientHasLogCredentials(cli)) {
288 uid = AID_ROOT;
289 }
290
Mark Salyzyn501c3732017-03-10 14:31:54 -0800291 const char* name = NULL;
292 const char* format = NULL;
293 const char* id = NULL;
Mark Salyzyn61e9ce62016-09-12 14:51:54 -0700294 for (int i = 1; i < argc; ++i) {
295 static const char _name[] = "name=";
296 if (!strncmp(argv[i], _name, strlen(_name))) {
297 name = argv[i] + strlen(_name);
298 continue;
299 }
300
301 static const char _format[] = "format=";
302 if (!strncmp(argv[i], _format, strlen(_format))) {
303 format = argv[i] + strlen(_format);
304 continue;
305 }
Mark Salyzyn407537f2017-02-21 16:19:08 -0800306
307 static const char _id[] = "id=";
308 if (!strncmp(argv[i], _id, strlen(_id))) {
309 id = argv[i] + strlen(_id);
310 continue;
311 }
312 }
313
314 if (id) {
315 if (format || name) {
316 cli->sendMsg("can not mix id= with either format= or name=");
317 return 0;
318 }
319 cli->sendMsg(package_string(mBuf.formatEntry(atoi(id), uid)).c_str());
320 return 0;
Mark Salyzyn61e9ce62016-09-12 14:51:54 -0700321 }
322
Mark Salyzyn501c3732017-03-10 14:31:54 -0800323 cli->sendMsg(
324 package_string(mBuf.formatGetEventTag(uid, name, format)).c_str());
Mark Salyzyn61e9ce62016-09-12 14:51:54 -0700325
326 return 0;
327}
328
Mark Salyzyn77187782015-05-12 15:21:31 -0700329CommandListener::ReinitCmd::ReinitCmd() : LogCommand("reinit") {
330}
Mark Salyzyn11e55cb2015-03-10 16:45:17 -0700331
Mark Salyzyn501c3732017-03-10 14:31:54 -0800332int CommandListener::ReinitCmd::runCommand(SocketClient* cli, int /*argc*/,
333 char** /*argv*/) {
Mark Salyzyn11e55cb2015-03-10 16:45:17 -0700334 setname();
335
336 reinit_signal_handler(SIGHUP);
337
338 cli->sendMsg("success");
339
340 return 0;
341}
342
Mark Salyzyn501c3732017-03-10 14:31:54 -0800343CommandListener::ExitCmd::ExitCmd(CommandListener* parent)
344 : LogCommand("EXIT"), mParent(*parent) {
Mark Salyzync8749d52016-09-08 13:16:59 -0700345}
346
Mark Salyzyn501c3732017-03-10 14:31:54 -0800347int CommandListener::ExitCmd::runCommand(SocketClient* cli, int /*argc*/,
348 char** /*argv*/) {
Mark Salyzync8749d52016-09-08 13:16:59 -0700349 setname();
350
351 cli->sendMsg("success");
352 release(cli);
353
354 return 0;
355}
356
Mark Salyzyndfc47e82014-03-24 10:26:47 -0700357int CommandListener::getLogSocket() {
358 static const char socketName[] = "logd";
359 int sock = android_get_control_socket(socketName);
360
361 if (sock < 0) {
Mark Salyzyn501c3732017-03-10 14:31:54 -0800362 sock = socket_local_server(
363 socketName, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
Mark Salyzyndfc47e82014-03-24 10:26:47 -0700364 }
365
366 return sock;
367}