blob: c45111aa5c47582c1397c35b87ad214aa6613f03 [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 Salyzyn0175b072014-02-26 09:50:16 -080037
38CommandListener::CommandListener(LogBuffer *buf, LogReader * /*reader*/,
Mark Salyzyn77187782015-05-12 15:21:31 -070039 LogListener * /*swl*/) :
Andreas Gamped75564f2015-07-27 11:04:37 -070040 FrameworkListener(getLogSocket()) {
Mark Salyzyn0175b072014-02-26 09:50:16 -080041 // registerCmd(new ShutdownCmd(buf, writer, swl));
42 registerCmd(new ClearCmd(buf));
43 registerCmd(new GetBufSizeCmd(buf));
Mark Salyzyndfa7a072014-02-11 12:29:31 -080044 registerCmd(new SetBufSizeCmd(buf));
Mark Salyzyn0175b072014-02-26 09:50:16 -080045 registerCmd(new GetBufSizeUsedCmd(buf));
Mark Salyzyn34facab2014-02-06 14:48:50 -080046 registerCmd(new GetStatisticsCmd(buf));
Mark Salyzyndfa7a072014-02-11 12:29:31 -080047 registerCmd(new SetPruneListCmd(buf));
48 registerCmd(new GetPruneListCmd(buf));
Mark Salyzyn11e55cb2015-03-10 16:45:17 -070049 registerCmd(new ReinitCmd());
Mark Salyzyn0175b072014-02-26 09:50:16 -080050}
51
Andreas Gamped75564f2015-07-27 11:04:37 -070052CommandListener::ShutdownCmd::ShutdownCmd(LogReader *reader,
Mark Salyzyn77187782015-05-12 15:21:31 -070053 LogListener *swl) :
54 LogCommand("shutdown"),
Mark Salyzyn77187782015-05-12 15:21:31 -070055 mReader(*reader),
56 mSwl(*swl) {
57}
Mark Salyzyn0175b072014-02-26 09:50:16 -080058
59int CommandListener::ShutdownCmd::runCommand(SocketClient * /*cli*/,
60 int /*argc*/,
61 char ** /*argv*/) {
62 mSwl.stopListener();
63 mReader.stopListener();
64 exit(0);
65}
66
Mark Salyzyn77187782015-05-12 15:21:31 -070067CommandListener::ClearCmd::ClearCmd(LogBuffer *buf) :
68 LogCommand("clear"),
69 mBuf(*buf) {
70}
Mark Salyzyn0175b072014-02-26 09:50:16 -080071
Mark Salyzyn8daa9af2014-04-28 14:07:23 -070072static void setname() {
Mark Salyzyne3aeeee2015-03-17 07:56:32 -070073 static bool name_set;
74 if (!name_set) {
75 prctl(PR_SET_NAME, "logd.control");
76 name_set = true;
77 }
Mark Salyzyn8daa9af2014-04-28 14:07:23 -070078}
79
Mark Salyzyn0175b072014-02-26 09:50:16 -080080int CommandListener::ClearCmd::runCommand(SocketClient *cli,
81 int argc, char **argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -070082 setname();
Mark Salyzyn1a240b42014-06-12 11:16:16 -070083 uid_t uid = cli->getUid();
84 if (clientHasLogCredentials(cli)) {
85 uid = AID_ROOT;
Mark Salyzyn0175b072014-02-26 09:50:16 -080086 }
87
88 if (argc < 2) {
89 cli->sendMsg("Missing Argument");
90 return 0;
91 }
92
93 int id = atoi(argv[1]);
Mark Salyzyn1114f182014-02-21 13:54:07 -080094 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) {
Mark Salyzyn0175b072014-02-26 09:50:16 -080095 cli->sendMsg("Range Error");
96 return 0;
97 }
98
Mark Salyzync5dc9702015-09-16 15:34:00 -070099 cli->sendMsg(mBuf.clear((log_id_t) id, uid) ? "busy" : "success");
Mark Salyzyn0175b072014-02-26 09:50:16 -0800100 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 Salyzyn73160ac2015-08-20 10:01:44 -0700194static std::string package_string(const std::string &str) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800195 // Calculate total buffer size prefix, count is the string length w/o nul
196 char fmt[32];
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700197 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 -0800198 snprintf(fmt, sizeof(fmt), "%zu\n%%s\n\f", l + x);
199 }
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700200 return android::base::StringPrintf(fmt, str.c_str());
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800201}
202
Mark Salyzyn34facab2014-02-06 14:48:50 -0800203int CommandListener::GetStatisticsCmd::runCommand(SocketClient *cli,
204 int argc, char **argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700205 setname();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800206 uid_t uid = cli->getUid();
Mark Salyzyn34facab2014-02-06 14:48:50 -0800207 if (clientHasLogCredentials(cli)) {
208 uid = AID_ROOT;
209 }
210
211 unsigned int logMask = -1;
212 if (argc > 1) {
213 logMask = 0;
214 for (int i = 1; i < argc; ++i) {
215 int id = atoi(argv[i]);
216 if ((id < LOG_ID_MIN) || (LOG_ID_MAX <= id)) {
217 cli->sendMsg("Range Error");
218 return 0;
219 }
220 logMask |= 1 << id;
221 }
222 }
223
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700224 cli->sendMsg(package_string(mBuf.formatStatistics(uid, logMask)).c_str());
Mark Salyzyn34facab2014-02-06 14:48:50 -0800225 return 0;
226}
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800227
Mark Salyzyn77187782015-05-12 15:21:31 -0700228CommandListener::GetPruneListCmd::GetPruneListCmd(LogBuffer *buf) :
229 LogCommand("getPruneList"),
230 mBuf(*buf) {
231}
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800232
233int CommandListener::GetPruneListCmd::runCommand(SocketClient *cli,
234 int /*argc*/, char ** /*argv*/) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700235 setname();
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700236 cli->sendMsg(package_string(mBuf.formatPrune()).c_str());
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800237 return 0;
238}
239
Mark Salyzyn77187782015-05-12 15:21:31 -0700240CommandListener::SetPruneListCmd::SetPruneListCmd(LogBuffer *buf) :
241 LogCommand("setPruneList"),
242 mBuf(*buf) {
243}
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800244
245int CommandListener::SetPruneListCmd::runCommand(SocketClient *cli,
246 int argc, char **argv) {
Mark Salyzyn8daa9af2014-04-28 14:07:23 -0700247 setname();
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800248 if (!clientHasLogCredentials(cli)) {
249 cli->sendMsg("Permission Denied");
250 return 0;
251 }
252
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700253 std::string str;
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800254 for (int i = 1; i < argc; ++i) {
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700255 if (str.length()) {
256 str += " ";
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800257 }
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700258 str += argv[i];
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800259 }
260
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700261 int ret = mBuf.initPrune(str.c_str());
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800262
263 if (ret) {
264 cli->sendMsg("Invalid");
265 return 0;
266 }
267
268 cli->sendMsg("success");
269
270 return 0;
271}
Mark Salyzyndfc47e82014-03-24 10:26:47 -0700272
Mark Salyzyn77187782015-05-12 15:21:31 -0700273CommandListener::ReinitCmd::ReinitCmd() : LogCommand("reinit") {
274}
Mark Salyzyn11e55cb2015-03-10 16:45:17 -0700275
276int CommandListener::ReinitCmd::runCommand(SocketClient *cli,
277 int /*argc*/, char ** /*argv*/) {
278 setname();
279
280 reinit_signal_handler(SIGHUP);
281
282 cli->sendMsg("success");
283
284 return 0;
285}
286
Mark Salyzyndfc47e82014-03-24 10:26:47 -0700287int CommandListener::getLogSocket() {
288 static const char socketName[] = "logd";
289 int sock = android_get_control_socket(socketName);
290
291 if (sock < 0) {
292 sock = socket_local_server(socketName,
293 ANDROID_SOCKET_NAMESPACE_RESERVED,
294 SOCK_STREAM);
295 }
296
297 return sock;
298}