blob: 7394f11401561cfbf9dd1fc690a9448a328dbdb2 [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>
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>
Mark Salyzyn8daa9af2014-04-28 14:07:23 -070024#include <sys/prctl.h>
Mark Salyzyn0175b072014-02-26 09:50:16 -080025#include <sys/socket.h>
26#include <sys/types.h>
27
Mark Salyzyn73160ac2015-08-20 10:01:44 -070028#include <string>
29
Elliott Hughes4f713192015-12-04 22:00:26 -080030#include <android-base/stringprintf.h>
Mark Salyzyndfc47e82014-03-24 10:26:47 -070031#include <cutils/sockets.h>
Mark Salyzyn0175b072014-02-26 09:50:16 -080032#include <private/android_filesystem_config.h>
Mark Salyzyn1114f182014-02-21 13:54:07 -080033#include <sysutils/SocketClient.h>
Mark Salyzyn0175b072014-02-26 09:50:16 -080034
35#include "CommandListener.h"
Mark Salyzyn1114f182014-02-21 13:54:07 -080036#include "LogCommand.h"
Mark Salyzyn083b0372015-12-04 10:59:45 -080037#include "LogUtils.h"
Mark Salyzyn0175b072014-02-26 09:50:16 -080038
39CommandListener::CommandListener(LogBuffer *buf, LogReader * /*reader*/,
Mark Salyzyn77187782015-05-12 15:21:31 -070040 LogListener * /*swl*/) :
Andreas Gamped75564f2015-07-27 11:04:37 -070041 FrameworkListener(getLogSocket()) {
Mark Salyzyn0175b072014-02-26 09:50:16 -080042 // registerCmd(new ShutdownCmd(buf, writer, swl));
43 registerCmd(new ClearCmd(buf));
44 registerCmd(new GetBufSizeCmd(buf));
Mark Salyzyndfa7a072014-02-11 12:29:31 -080045 registerCmd(new SetBufSizeCmd(buf));
Mark Salyzyn0175b072014-02-26 09:50:16 -080046 registerCmd(new GetBufSizeUsedCmd(buf));
Mark Salyzyn34facab2014-02-06 14:48:50 -080047 registerCmd(new GetStatisticsCmd(buf));
Mark Salyzyndfa7a072014-02-11 12:29:31 -080048 registerCmd(new SetPruneListCmd(buf));
49 registerCmd(new GetPruneListCmd(buf));
Mark Salyzyn11e55cb2015-03-10 16:45:17 -070050 registerCmd(new ReinitCmd());
Mark Salyzyn0175b072014-02-26 09:50:16 -080051}
52
Andreas Gamped75564f2015-07-27 11:04:37 -070053CommandListener::ShutdownCmd::ShutdownCmd(LogReader *reader,
Mark Salyzyn77187782015-05-12 15:21:31 -070054 LogListener *swl) :
55 LogCommand("shutdown"),
Mark Salyzyn77187782015-05-12 15:21:31 -070056 mReader(*reader),
57 mSwl(*swl) {
58}
Mark Salyzyn0175b072014-02-26 09:50:16 -080059
60int CommandListener::ShutdownCmd::runCommand(SocketClient * /*cli*/,
61 int /*argc*/,
62 char ** /*argv*/) {
63 mSwl.stopListener();
64 mReader.stopListener();
65 exit(0);
66}
67
Mark Salyzyn77187782015-05-12 15:21:31 -070068CommandListener::ClearCmd::ClearCmd(LogBuffer *buf) :
69 LogCommand("clear"),
70 mBuf(*buf) {
71}
Mark Salyzyn0175b072014-02-26 09:50:16 -080072
Mark Salyzyn8daa9af2014-04-28 14:07:23 -070073static void setname() {
Mark Salyzyne3aeeee2015-03-17 07:56:32 -070074 static bool name_set;
75 if (!name_set) {
76 prctl(PR_SET_NAME, "logd.control");
77 name_set = true;
78 }
Mark Salyzyn8daa9af2014-04-28 14:07:23 -070079}
80
Mark Salyzyn0175b072014-02-26 09:50:16 -080081int CommandListener::ClearCmd::runCommand(SocketClient *cli,
82 int argc, char **argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -070083 setname();
Mark Salyzyn1a240b42014-06-12 11:16:16 -070084 uid_t uid = cli->getUid();
85 if (clientHasLogCredentials(cli)) {
86 uid = AID_ROOT;
Mark Salyzyn0175b072014-02-26 09:50:16 -080087 }
88
89 if (argc < 2) {
90 cli->sendMsg("Missing Argument");
91 return 0;
92 }
93
94 int id = atoi(argv[1]);
Mark Salyzyn1114f182014-02-21 13:54:07 -080095 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) {
Mark Salyzyn0175b072014-02-26 09:50:16 -080096 cli->sendMsg("Range Error");
97 return 0;
98 }
99
Mark Salyzync5dc9702015-09-16 15:34:00 -0700100 cli->sendMsg(mBuf.clear((log_id_t) id, uid) ? "busy" : "success");
Mark Salyzyn0175b072014-02-26 09:50:16 -0800101 return 0;
102}
103
Mark Salyzyn77187782015-05-12 15:21:31 -0700104CommandListener::GetBufSizeCmd::GetBufSizeCmd(LogBuffer *buf) :
105 LogCommand("getLogSize"),
106 mBuf(*buf) {
107}
Mark Salyzyn0175b072014-02-26 09:50:16 -0800108
109int CommandListener::GetBufSizeCmd::runCommand(SocketClient *cli,
110 int argc, char **argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700111 setname();
Mark Salyzyn0175b072014-02-26 09:50:16 -0800112 if (argc < 2) {
113 cli->sendMsg("Missing Argument");
114 return 0;
115 }
116
117 int id = atoi(argv[1]);
Mark Salyzyn1114f182014-02-21 13:54:07 -0800118 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) {
Mark Salyzyn0175b072014-02-26 09:50:16 -0800119 cli->sendMsg("Range Error");
120 return 0;
121 }
122
123 unsigned long size = mBuf.getSize((log_id_t) id);
124 char buf[512];
125 snprintf(buf, sizeof(buf), "%lu", size);
126 cli->sendMsg(buf);
127 return 0;
128}
129
Mark Salyzyn77187782015-05-12 15:21:31 -0700130CommandListener::SetBufSizeCmd::SetBufSizeCmd(LogBuffer *buf) :
131 LogCommand("setLogSize"),
132 mBuf(*buf) {
133}
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800134
135int CommandListener::SetBufSizeCmd::runCommand(SocketClient *cli,
136 int argc, char **argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700137 setname();
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800138 if (!clientHasLogCredentials(cli)) {
139 cli->sendMsg("Permission Denied");
140 return 0;
141 }
142
143 if (argc < 3) {
144 cli->sendMsg("Missing Argument");
145 return 0;
146 }
147
148 int id = atoi(argv[1]);
149 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) {
150 cli->sendMsg("Range Error");
151 return 0;
152 }
153
154 unsigned long size = atol(argv[2]);
155 if (mBuf.setSize((log_id_t) id, size)) {
156 cli->sendMsg("Range Error");
157 return 0;
158 }
159
160 cli->sendMsg("success");
161 return 0;
162}
163
Mark Salyzyn77187782015-05-12 15:21:31 -0700164CommandListener::GetBufSizeUsedCmd::GetBufSizeUsedCmd(LogBuffer *buf) :
165 LogCommand("getLogSizeUsed"),
166 mBuf(*buf) {
167}
Mark Salyzyn0175b072014-02-26 09:50:16 -0800168
169int CommandListener::GetBufSizeUsedCmd::runCommand(SocketClient *cli,
170 int argc, char **argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700171 setname();
Mark Salyzyn0175b072014-02-26 09:50:16 -0800172 if (argc < 2) {
173 cli->sendMsg("Missing Argument");
174 return 0;
175 }
176
177 int id = atoi(argv[1]);
Mark Salyzyn1114f182014-02-21 13:54:07 -0800178 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) {
Mark Salyzyn0175b072014-02-26 09:50:16 -0800179 cli->sendMsg("Range Error");
180 return 0;
181 }
182
183 unsigned long size = mBuf.getSizeUsed((log_id_t) id);
184 char buf[512];
185 snprintf(buf, sizeof(buf), "%lu", size);
186 cli->sendMsg(buf);
187 return 0;
188}
Mark Salyzyn34facab2014-02-06 14:48:50 -0800189
Mark Salyzyn77187782015-05-12 15:21:31 -0700190CommandListener::GetStatisticsCmd::GetStatisticsCmd(LogBuffer *buf) :
191 LogCommand("getStatistics"),
192 mBuf(*buf) {
193}
Mark Salyzyn34facab2014-02-06 14:48:50 -0800194
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700195static std::string package_string(const std::string &str) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800196 // Calculate total buffer size prefix, count is the string length w/o nul
197 char fmt[32];
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700198 for(size_t l = str.length(), y = 0, x = 6; y != x; y = x, x = strlen(fmt) - 2) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800199 snprintf(fmt, sizeof(fmt), "%zu\n%%s\n\f", l + x);
200 }
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700201 return android::base::StringPrintf(fmt, str.c_str());
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800202}
203
Mark Salyzyn34facab2014-02-06 14:48:50 -0800204int CommandListener::GetStatisticsCmd::runCommand(SocketClient *cli,
205 int argc, char **argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700206 setname();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800207 uid_t uid = cli->getUid();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800208 if (clientHasLogCredentials(cli)) {
209 uid = AID_ROOT;
210 }
211
212 unsigned int logMask = -1;
Mark Salyzynee3b8382015-12-17 09:58:43 -0800213 pid_t pid = 0;
Mark Salyzyn34facab2014-02-06 14:48:50 -0800214 if (argc > 1) {
215 logMask = 0;
216 for (int i = 1; i < argc; ++i) {
Mark Salyzynee3b8382015-12-17 09:58:43 -0800217 static const char _pid[] = "pid=";
218 if (!strncmp(argv[i], _pid, sizeof(_pid) - 1)) {
219 pid = atol(argv[i] + sizeof(_pid) - 1);
220 if (pid == 0) {
221 cli->sendMsg("PID Error");
222 return 0;
223 }
224 continue;
225 }
226
Mark Salyzyn34facab2014-02-06 14:48:50 -0800227 int id = atoi(argv[i]);
228 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) {
229 cli->sendMsg("Range Error");
230 return 0;
231 }
232 logMask |= 1 << id;
233 }
234 }
235
Mark Salyzynee3b8382015-12-17 09:58:43 -0800236 cli->sendMsg(package_string(mBuf.formatStatistics(uid, pid,
237 logMask)).c_str());
Mark Salyzyn34facab2014-02-06 14:48:50 -0800238 return 0;
239}
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800240
Mark Salyzyn77187782015-05-12 15:21:31 -0700241CommandListener::GetPruneListCmd::GetPruneListCmd(LogBuffer *buf) :
242 LogCommand("getPruneList"),
243 mBuf(*buf) {
244}
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800245
246int CommandListener::GetPruneListCmd::runCommand(SocketClient *cli,
247 int /*argc*/, char ** /*argv*/) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700248 setname();
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700249 cli->sendMsg(package_string(mBuf.formatPrune()).c_str());
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800250 return 0;
251}
252
Mark Salyzyn77187782015-05-12 15:21:31 -0700253CommandListener::SetPruneListCmd::SetPruneListCmd(LogBuffer *buf) :
254 LogCommand("setPruneList"),
255 mBuf(*buf) {
256}
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800257
258int CommandListener::SetPruneListCmd::runCommand(SocketClient *cli,
259 int argc, char **argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700260 setname();
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800261 if (!clientHasLogCredentials(cli)) {
262 cli->sendMsg("Permission Denied");
263 return 0;
264 }
265
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700266 std::string str;
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800267 for (int i = 1; i < argc; ++i) {
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700268 if (str.length()) {
269 str += " ";
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800270 }
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700271 str += argv[i];
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800272 }
273
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700274 int ret = mBuf.initPrune(str.c_str());
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800275
276 if (ret) {
277 cli->sendMsg("Invalid");
278 return 0;
279 }
280
281 cli->sendMsg("success");
282
283 return 0;
284}
Mark Salyzyndfc47e82014-03-24 10:26:47 -0700285
Mark Salyzyn77187782015-05-12 15:21:31 -0700286CommandListener::ReinitCmd::ReinitCmd() : LogCommand("reinit") {
287}
Mark Salyzyn11e55cb2015-03-10 16:45:17 -0700288
289int CommandListener::ReinitCmd::runCommand(SocketClient *cli,
290 int /*argc*/, char ** /*argv*/) {
291 setname();
292
293 reinit_signal_handler(SIGHUP);
294
295 cli->sendMsg("success");
296
297 return 0;
298}
299
Mark Salyzyndfc47e82014-03-24 10:26:47 -0700300int CommandListener::getLogSocket() {
301 static const char socketName[] = "logd";
302 int sock = android_get_control_socket(socketName);
303
304 if (sock < 0) {
305 sock = socket_local_server(socketName,
306 ANDROID_SOCKET_NAMESPACE_RESERVED,
307 SOCK_STREAM);
308 }
309
310 return sock;
311}