blob: 489bea6e5b06d3a360f7b9efe60b19bac006cf6b [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*/) :
Andreas Gamped75564f2015-07-27 11:04:37 -070037 FrameworkListener(getLogSocket()) {
Mark Salyzyn0175b072014-02-26 09:50:16 -080038 // registerCmd(new ShutdownCmd(buf, writer, swl));
39 registerCmd(new ClearCmd(buf));
40 registerCmd(new GetBufSizeCmd(buf));
Mark Salyzyndfa7a072014-02-11 12:29:31 -080041 registerCmd(new SetBufSizeCmd(buf));
Mark Salyzyn0175b072014-02-26 09:50:16 -080042 registerCmd(new GetBufSizeUsedCmd(buf));
Mark Salyzyn34facab2014-02-06 14:48:50 -080043 registerCmd(new GetStatisticsCmd(buf));
Mark Salyzyndfa7a072014-02-11 12:29:31 -080044 registerCmd(new SetPruneListCmd(buf));
45 registerCmd(new GetPruneListCmd(buf));
Mark Salyzyn11e55cb2015-03-10 16:45:17 -070046 registerCmd(new ReinitCmd());
Mark Salyzyn0175b072014-02-26 09:50:16 -080047}
48
Andreas Gamped75564f2015-07-27 11:04:37 -070049CommandListener::ShutdownCmd::ShutdownCmd(LogReader *reader,
Mark Salyzyn77187782015-05-12 15:21:31 -070050 LogListener *swl) :
51 LogCommand("shutdown"),
Mark Salyzyn77187782015-05-12 15:21:31 -070052 mReader(*reader),
53 mSwl(*swl) {
54}
Mark Salyzyn0175b072014-02-26 09:50:16 -080055
56int CommandListener::ShutdownCmd::runCommand(SocketClient * /*cli*/,
57 int /*argc*/,
58 char ** /*argv*/) {
59 mSwl.stopListener();
60 mReader.stopListener();
61 exit(0);
62}
63
Mark Salyzyn77187782015-05-12 15:21:31 -070064CommandListener::ClearCmd::ClearCmd(LogBuffer *buf) :
65 LogCommand("clear"),
66 mBuf(*buf) {
67}
Mark Salyzyn0175b072014-02-26 09:50:16 -080068
Mark Salyzyn8daa9af2014-04-28 14:07:23 -070069static void setname() {
Mark Salyzyne3aeeee2015-03-17 07:56:32 -070070 static bool name_set;
71 if (!name_set) {
72 prctl(PR_SET_NAME, "logd.control");
73 name_set = true;
74 }
Mark Salyzyn8daa9af2014-04-28 14:07:23 -070075}
76
Mark Salyzyn0175b072014-02-26 09:50:16 -080077int CommandListener::ClearCmd::runCommand(SocketClient *cli,
78 int argc, char **argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -070079 setname();
Mark Salyzyn1a240b42014-06-12 11:16:16 -070080 uid_t uid = cli->getUid();
81 if (clientHasLogCredentials(cli)) {
82 uid = AID_ROOT;
Mark Salyzyn0175b072014-02-26 09:50:16 -080083 }
84
85 if (argc < 2) {
86 cli->sendMsg("Missing Argument");
87 return 0;
88 }
89
90 int id = atoi(argv[1]);
Mark Salyzyn1114f182014-02-21 13:54:07 -080091 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) {
Mark Salyzyn0175b072014-02-26 09:50:16 -080092 cli->sendMsg("Range Error");
93 return 0;
94 }
95
Mark Salyzyn1a240b42014-06-12 11:16:16 -070096 mBuf.clear((log_id_t) id, uid);
Mark Salyzyn0175b072014-02-26 09:50:16 -080097 cli->sendMsg("success");
98 return 0;
99}
100
Mark Salyzyn77187782015-05-12 15:21:31 -0700101CommandListener::GetBufSizeCmd::GetBufSizeCmd(LogBuffer *buf) :
102 LogCommand("getLogSize"),
103 mBuf(*buf) {
104}
Mark Salyzyn0175b072014-02-26 09:50:16 -0800105
106int CommandListener::GetBufSizeCmd::runCommand(SocketClient *cli,
107 int argc, 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
120 unsigned long size = mBuf.getSize((log_id_t) id);
121 char buf[512];
122 snprintf(buf, sizeof(buf), "%lu", size);
123 cli->sendMsg(buf);
124 return 0;
125}
126
Mark Salyzyn77187782015-05-12 15:21:31 -0700127CommandListener::SetBufSizeCmd::SetBufSizeCmd(LogBuffer *buf) :
128 LogCommand("setLogSize"),
129 mBuf(*buf) {
130}
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800131
132int CommandListener::SetBufSizeCmd::runCommand(SocketClient *cli,
133 int argc, char **argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700134 setname();
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800135 if (!clientHasLogCredentials(cli)) {
136 cli->sendMsg("Permission Denied");
137 return 0;
138 }
139
140 if (argc < 3) {
141 cli->sendMsg("Missing Argument");
142 return 0;
143 }
144
145 int id = atoi(argv[1]);
146 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) {
147 cli->sendMsg("Range Error");
148 return 0;
149 }
150
151 unsigned long size = atol(argv[2]);
152 if (mBuf.setSize((log_id_t) id, size)) {
153 cli->sendMsg("Range Error");
154 return 0;
155 }
156
157 cli->sendMsg("success");
158 return 0;
159}
160
Mark Salyzyn77187782015-05-12 15:21:31 -0700161CommandListener::GetBufSizeUsedCmd::GetBufSizeUsedCmd(LogBuffer *buf) :
162 LogCommand("getLogSizeUsed"),
163 mBuf(*buf) {
164}
Mark Salyzyn0175b072014-02-26 09:50:16 -0800165
166int CommandListener::GetBufSizeUsedCmd::runCommand(SocketClient *cli,
167 int argc, char **argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700168 setname();
Mark Salyzyn0175b072014-02-26 09:50:16 -0800169 if (argc < 2) {
170 cli->sendMsg("Missing Argument");
171 return 0;
172 }
173
174 int id = atoi(argv[1]);
Mark Salyzyn1114f182014-02-21 13:54:07 -0800175 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) {
Mark Salyzyn0175b072014-02-26 09:50:16 -0800176 cli->sendMsg("Range Error");
177 return 0;
178 }
179
180 unsigned long size = mBuf.getSizeUsed((log_id_t) id);
181 char buf[512];
182 snprintf(buf, sizeof(buf), "%lu", size);
183 cli->sendMsg(buf);
184 return 0;
185}
Mark Salyzyn34facab2014-02-06 14:48:50 -0800186
Mark Salyzyn77187782015-05-12 15:21:31 -0700187CommandListener::GetStatisticsCmd::GetStatisticsCmd(LogBuffer *buf) :
188 LogCommand("getStatistics"),
189 mBuf(*buf) {
190}
Mark Salyzyn34facab2014-02-06 14:48:50 -0800191
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800192static void package_string(char **strp) {
193 const char *a = *strp;
194 if (!a) {
195 a = "";
196 }
197
198 // Calculate total buffer size prefix, count is the string length w/o nul
199 char fmt[32];
200 for(size_t l = strlen(a), y = 0, x = 6; y != x; y = x, x = strlen(fmt) - 2) {
201 snprintf(fmt, sizeof(fmt), "%zu\n%%s\n\f", l + x);
202 }
203
204 char *b = *strp;
205 *strp = NULL;
206 asprintf(strp, fmt, a);
207 free(b);
208}
209
Mark Salyzyn34facab2014-02-06 14:48:50 -0800210int CommandListener::GetStatisticsCmd::runCommand(SocketClient *cli,
211 int argc, char **argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700212 setname();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800213 uid_t uid = cli->getUid();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800214 if (clientHasLogCredentials(cli)) {
215 uid = AID_ROOT;
216 }
217
218 unsigned int logMask = -1;
219 if (argc > 1) {
220 logMask = 0;
221 for (int i = 1; i < argc; ++i) {
222 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
231 char *buf = NULL;
232
233 mBuf.formatStatistics(&buf, uid, logMask);
234 if (!buf) {
235 cli->sendMsg("Failed");
236 } else {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800237 package_string(&buf);
Mark Salyzyn34facab2014-02-06 14:48:50 -0800238 cli->sendMsg(buf);
239 free(buf);
240 }
241 return 0;
242}
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800243
Mark Salyzyn77187782015-05-12 15:21:31 -0700244CommandListener::GetPruneListCmd::GetPruneListCmd(LogBuffer *buf) :
245 LogCommand("getPruneList"),
246 mBuf(*buf) {
247}
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800248
249int CommandListener::GetPruneListCmd::runCommand(SocketClient *cli,
250 int /*argc*/, char ** /*argv*/) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700251 setname();
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800252 char *buf = NULL;
253 mBuf.formatPrune(&buf);
254 if (!buf) {
255 cli->sendMsg("Failed");
256 } else {
257 package_string(&buf);
258 cli->sendMsg(buf);
259 free(buf);
260 }
261 return 0;
262}
263
Mark Salyzyn77187782015-05-12 15:21:31 -0700264CommandListener::SetPruneListCmd::SetPruneListCmd(LogBuffer *buf) :
265 LogCommand("setPruneList"),
266 mBuf(*buf) {
267}
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800268
269int CommandListener::SetPruneListCmd::runCommand(SocketClient *cli,
270 int argc, char **argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700271 setname();
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800272 if (!clientHasLogCredentials(cli)) {
273 cli->sendMsg("Permission Denied");
274 return 0;
275 }
276
277 char *cp = NULL;
278 for (int i = 1; i < argc; ++i) {
279 char *p = cp;
280 if (p) {
281 cp = NULL;
282 asprintf(&cp, "%s %s", p, argv[i]);
283 free(p);
284 } else {
285 asprintf(&cp, "%s", argv[i]);
286 }
287 }
288
289 int ret = mBuf.initPrune(cp);
290 free(cp);
291
292 if (ret) {
293 cli->sendMsg("Invalid");
294 return 0;
295 }
296
297 cli->sendMsg("success");
298
299 return 0;
300}
Mark Salyzyndfc47e82014-03-24 10:26:47 -0700301
Mark Salyzyn77187782015-05-12 15:21:31 -0700302CommandListener::ReinitCmd::ReinitCmd() : LogCommand("reinit") {
303}
Mark Salyzyn11e55cb2015-03-10 16:45:17 -0700304
305int CommandListener::ReinitCmd::runCommand(SocketClient *cli,
306 int /*argc*/, char ** /*argv*/) {
307 setname();
308
309 reinit_signal_handler(SIGHUP);
310
311 cli->sendMsg("success");
312
313 return 0;
314}
315
Mark Salyzyndfc47e82014-03-24 10:26:47 -0700316int CommandListener::getLogSocket() {
317 static const char socketName[] = "logd";
318 int sock = android_get_control_socket(socketName);
319
320 if (sock < 0) {
321 sock = socket_local_server(socketName,
322 ANDROID_SOCKET_NAMESPACE_RESERVED,
323 SOCK_STREAM);
324 }
325
326 return sock;
327}