blob: 5489cc945295181a845ed212597934e3c045ceb4 [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 Salyzyndfc47e82014-03-24 10:26:47 -070028#include <cutils/sockets.h>
Mark Salyzyn0175b072014-02-26 09:50:16 -080029#include <private/android_filesystem_config.h>
Mark Salyzyn1114f182014-02-21 13:54:07 -080030#include <sysutils/SocketClient.h>
Mark Salyzyn0175b072014-02-26 09:50:16 -080031
32#include "CommandListener.h"
Mark Salyzyn1114f182014-02-21 13:54:07 -080033#include "LogCommand.h"
Mark Salyzyn0175b072014-02-26 09:50:16 -080034
35CommandListener::CommandListener(LogBuffer *buf, LogReader * /*reader*/,
Mark Salyzyn77187782015-05-12 15:21:31 -070036 LogListener * /*swl*/) :
37 FrameworkListener(getLogSocket()),
38 mBuf(*buf) {
Mark Salyzyn0175b072014-02-26 09:50:16 -080039 // registerCmd(new ShutdownCmd(buf, writer, swl));
40 registerCmd(new ClearCmd(buf));
41 registerCmd(new GetBufSizeCmd(buf));
Mark Salyzyndfa7a072014-02-11 12:29:31 -080042 registerCmd(new SetBufSizeCmd(buf));
Mark Salyzyn0175b072014-02-26 09:50:16 -080043 registerCmd(new GetBufSizeUsedCmd(buf));
Mark Salyzyn34facab2014-02-06 14:48:50 -080044 registerCmd(new GetStatisticsCmd(buf));
Mark Salyzyndfa7a072014-02-11 12:29:31 -080045 registerCmd(new SetPruneListCmd(buf));
46 registerCmd(new GetPruneListCmd(buf));
Mark Salyzyn11e55cb2015-03-10 16:45:17 -070047 registerCmd(new ReinitCmd());
Mark Salyzyn0175b072014-02-26 09:50:16 -080048}
49
50CommandListener::ShutdownCmd::ShutdownCmd(LogBuffer *buf, LogReader *reader,
Mark Salyzyn77187782015-05-12 15:21:31 -070051 LogListener *swl) :
52 LogCommand("shutdown"),
53 mBuf(*buf),
54 mReader(*reader),
55 mSwl(*swl) {
56}
Mark Salyzyn0175b072014-02-26 09:50:16 -080057
58int CommandListener::ShutdownCmd::runCommand(SocketClient * /*cli*/,
59 int /*argc*/,
60 char ** /*argv*/) {
61 mSwl.stopListener();
62 mReader.stopListener();
63 exit(0);
64}
65
Mark Salyzyn77187782015-05-12 15:21:31 -070066CommandListener::ClearCmd::ClearCmd(LogBuffer *buf) :
67 LogCommand("clear"),
68 mBuf(*buf) {
69}
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 Salyzyn0175b072014-02-26 09:50:16 -080079int CommandListener::ClearCmd::runCommand(SocketClient *cli,
80 int argc, 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 Salyzyn1a240b42014-06-12 11:16:16 -070098 mBuf.clear((log_id_t) id, uid);
Mark Salyzyn0175b072014-02-26 09:50:16 -080099 cli->sendMsg("success");
100 return 0;
101}
102
Mark Salyzyn77187782015-05-12 15:21:31 -0700103CommandListener::GetBufSizeCmd::GetBufSizeCmd(LogBuffer *buf) :
104 LogCommand("getLogSize"),
105 mBuf(*buf) {
106}
Mark Salyzyn0175b072014-02-26 09:50:16 -0800107
108int CommandListener::GetBufSizeCmd::runCommand(SocketClient *cli,
109 int argc, char **argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700110 setname();
Mark Salyzyn0175b072014-02-26 09:50:16 -0800111 if (argc < 2) {
112 cli->sendMsg("Missing Argument");
113 return 0;
114 }
115
116 int id = atoi(argv[1]);
Mark Salyzyn1114f182014-02-21 13:54:07 -0800117 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) {
Mark Salyzyn0175b072014-02-26 09:50:16 -0800118 cli->sendMsg("Range Error");
119 return 0;
120 }
121
122 unsigned long size = mBuf.getSize((log_id_t) id);
123 char buf[512];
124 snprintf(buf, sizeof(buf), "%lu", size);
125 cli->sendMsg(buf);
126 return 0;
127}
128
Mark Salyzyn77187782015-05-12 15:21:31 -0700129CommandListener::SetBufSizeCmd::SetBufSizeCmd(LogBuffer *buf) :
130 LogCommand("setLogSize"),
131 mBuf(*buf) {
132}
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800133
134int CommandListener::SetBufSizeCmd::runCommand(SocketClient *cli,
135 int argc, char **argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700136 setname();
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800137 if (!clientHasLogCredentials(cli)) {
138 cli->sendMsg("Permission Denied");
139 return 0;
140 }
141
142 if (argc < 3) {
143 cli->sendMsg("Missing Argument");
144 return 0;
145 }
146
147 int id = atoi(argv[1]);
148 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) {
149 cli->sendMsg("Range Error");
150 return 0;
151 }
152
153 unsigned long size = atol(argv[2]);
154 if (mBuf.setSize((log_id_t) id, size)) {
155 cli->sendMsg("Range Error");
156 return 0;
157 }
158
159 cli->sendMsg("success");
160 return 0;
161}
162
Mark Salyzyn77187782015-05-12 15:21:31 -0700163CommandListener::GetBufSizeUsedCmd::GetBufSizeUsedCmd(LogBuffer *buf) :
164 LogCommand("getLogSizeUsed"),
165 mBuf(*buf) {
166}
Mark Salyzyn0175b072014-02-26 09:50:16 -0800167
168int CommandListener::GetBufSizeUsedCmd::runCommand(SocketClient *cli,
169 int argc, char **argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700170 setname();
Mark Salyzyn0175b072014-02-26 09:50:16 -0800171 if (argc < 2) {
172 cli->sendMsg("Missing Argument");
173 return 0;
174 }
175
176 int id = atoi(argv[1]);
Mark Salyzyn1114f182014-02-21 13:54:07 -0800177 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) {
Mark Salyzyn0175b072014-02-26 09:50:16 -0800178 cli->sendMsg("Range Error");
179 return 0;
180 }
181
182 unsigned long size = mBuf.getSizeUsed((log_id_t) id);
183 char buf[512];
184 snprintf(buf, sizeof(buf), "%lu", size);
185 cli->sendMsg(buf);
186 return 0;
187}
Mark Salyzyn34facab2014-02-06 14:48:50 -0800188
Mark Salyzyn77187782015-05-12 15:21:31 -0700189CommandListener::GetStatisticsCmd::GetStatisticsCmd(LogBuffer *buf) :
190 LogCommand("getStatistics"),
191 mBuf(*buf) {
192}
Mark Salyzyn34facab2014-02-06 14:48:50 -0800193
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800194static void package_string(char **strp) {
195 const char *a = *strp;
196 if (!a) {
197 a = "";
198 }
199
200 // Calculate total buffer size prefix, count is the string length w/o nul
201 char fmt[32];
202 for(size_t l = strlen(a), y = 0, x = 6; y != x; y = x, x = strlen(fmt) - 2) {
203 snprintf(fmt, sizeof(fmt), "%zu\n%%s\n\f", l + x);
204 }
205
206 char *b = *strp;
207 *strp = NULL;
208 asprintf(strp, fmt, a);
209 free(b);
210}
211
Mark Salyzyn34facab2014-02-06 14:48:50 -0800212int CommandListener::GetStatisticsCmd::runCommand(SocketClient *cli,
213 int argc, char **argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700214 setname();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800215 uid_t uid = cli->getUid();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800216 if (clientHasLogCredentials(cli)) {
217 uid = AID_ROOT;
218 }
219
220 unsigned int logMask = -1;
221 if (argc > 1) {
222 logMask = 0;
223 for (int i = 1; i < argc; ++i) {
224 int id = atoi(argv[i]);
225 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) {
226 cli->sendMsg("Range Error");
227 return 0;
228 }
229 logMask |= 1 << id;
230 }
231 }
232
233 char *buf = NULL;
234
235 mBuf.formatStatistics(&buf, uid, logMask);
236 if (!buf) {
237 cli->sendMsg("Failed");
238 } else {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800239 package_string(&buf);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800240 cli->sendMsg(buf);
241 free(buf);
242 }
243 return 0;
244}
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800245
Mark Salyzyn77187782015-05-12 15:21:31 -0700246CommandListener::GetPruneListCmd::GetPruneListCmd(LogBuffer *buf) :
247 LogCommand("getPruneList"),
248 mBuf(*buf) {
249}
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800250
251int CommandListener::GetPruneListCmd::runCommand(SocketClient *cli,
252 int /*argc*/, char ** /*argv*/) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700253 setname();
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800254 char *buf = NULL;
255 mBuf.formatPrune(&buf);
256 if (!buf) {
257 cli->sendMsg("Failed");
258 } else {
259 package_string(&buf);
260 cli->sendMsg(buf);
261 free(buf);
262 }
263 return 0;
264}
265
Mark Salyzyn77187782015-05-12 15:21:31 -0700266CommandListener::SetPruneListCmd::SetPruneListCmd(LogBuffer *buf) :
267 LogCommand("setPruneList"),
268 mBuf(*buf) {
269}
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800270
271int CommandListener::SetPruneListCmd::runCommand(SocketClient *cli,
272 int argc, char **argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700273 setname();
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800274 if (!clientHasLogCredentials(cli)) {
275 cli->sendMsg("Permission Denied");
276 return 0;
277 }
278
279 char *cp = NULL;
280 for (int i = 1; i < argc; ++i) {
281 char *p = cp;
282 if (p) {
283 cp = NULL;
284 asprintf(&cp, "%s %s", p, argv[i]);
285 free(p);
286 } else {
287 asprintf(&cp, "%s", argv[i]);
288 }
289 }
290
291 int ret = mBuf.initPrune(cp);
292 free(cp);
293
294 if (ret) {
295 cli->sendMsg("Invalid");
296 return 0;
297 }
298
299 cli->sendMsg("success");
300
301 return 0;
302}
Mark Salyzyndfc47e82014-03-24 10:26:47 -0700303
Mark Salyzyn77187782015-05-12 15:21:31 -0700304CommandListener::ReinitCmd::ReinitCmd() : LogCommand("reinit") {
305}
Mark Salyzyn11e55cb2015-03-10 16:45:17 -0700306
307int CommandListener::ReinitCmd::runCommand(SocketClient *cli,
308 int /*argc*/, char ** /*argv*/) {
309 setname();
310
311 reinit_signal_handler(SIGHUP);
312
313 cli->sendMsg("success");
314
315 return 0;
316}
317
Mark Salyzyndfc47e82014-03-24 10:26:47 -0700318int CommandListener::getLogSocket() {
319 static const char socketName[] = "logd";
320 int sock = android_get_control_socket(socketName);
321
322 if (sock < 0) {
323 sock = socket_local_server(socketName,
324 ANDROID_SOCKET_NAMESPACE_RESERVED,
325 SOCK_STREAM);
326 }
327
328 return sock;
329}