blob: c71beb5476e36f9508943c71d2a9c5894e0408ad [file] [log] [blame]
Mark Salyzyndfa7a072014-02-11 12:29:31 -08001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
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
Mark Salyzyndfa7a072014-02-11 12:29:31 -080017#include <ctype.h>
18
Mark Salyzynb332f1c2015-08-19 13:53:20 -070019#include <base/stringprintf.h>
Mark Salyzyn932f7ac2015-08-28 08:02:59 -070020#include <cutils/properties.h>
Mark Salyzyndfa7a072014-02-11 12:29:31 -080021
22#include "LogWhiteBlackList.h"
23
24// White and Black list
25
Mark Salyzyn77187782015-05-12 15:21:31 -070026Prune::Prune(uid_t uid, pid_t pid) : mUid(uid), mPid(pid) {
27}
Mark Salyzyndfa7a072014-02-11 12:29:31 -080028
29int Prune::cmp(uid_t uid, pid_t pid) const {
30 if ((mUid == uid_all) || (mUid == uid)) {
31 if (mPid == pid_all) {
32 return 0;
33 }
34 return pid - mPid;
35 }
36 return uid - mUid;
37}
38
Mark Salyzyn73160ac2015-08-20 10:01:44 -070039std::string Prune::format() {
Mark Salyzyndfa7a072014-02-11 12:29:31 -080040 if (mUid != uid_all) {
Chih-Hung Hsieh634118e2014-09-12 16:02:28 -070041 if (mPid != pid_all) {
Mark Salyzyn73160ac2015-08-20 10:01:44 -070042 return android::base::StringPrintf("%u/%u", mUid, mPid);
Chih-Hung Hsieh634118e2014-09-12 16:02:28 -070043 }
Mark Salyzyn73160ac2015-08-20 10:01:44 -070044 return android::base::StringPrintf("%u", mUid);
Mark Salyzyndfa7a072014-02-11 12:29:31 -080045 }
Mark Salyzyn73160ac2015-08-20 10:01:44 -070046 if (mPid != pid_all) {
47 return android::base::StringPrintf("/%u", mPid);
48 }
49 // NB: mPid == pid_all can not happen if mUid == uid_all
50 return std::string("/");
Mark Salyzyndfa7a072014-02-11 12:29:31 -080051}
52
Mark Salyzyn932f7ac2015-08-28 08:02:59 -070053PruneList::PruneList() {
54 init(NULL);
Mark Salyzyndfa7a072014-02-11 12:29:31 -080055}
56
57PruneList::~PruneList() {
58 PruneCollection::iterator it;
59 for (it = mNice.begin(); it != mNice.end();) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -080060 it = mNice.erase(it);
61 }
62 for (it = mNaughty.begin(); it != mNaughty.end();) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -080063 it = mNaughty.erase(it);
64 }
65}
66
Mark Salyzyn73160ac2015-08-20 10:01:44 -070067int PruneList::init(const char *str) {
Mark Salyzyn1a01f962014-05-06 13:49:28 -070068 mWorstUidEnabled = true;
Mark Salyzyndfa7a072014-02-11 12:29:31 -080069 PruneCollection::iterator it;
70 for (it = mNice.begin(); it != mNice.end();) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -080071 it = mNice.erase(it);
72 }
73 for (it = mNaughty.begin(); it != mNaughty.end();) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -080074 it = mNaughty.erase(it);
75 }
76
Mark Salyzyn932f7ac2015-08-28 08:02:59 -070077 static const char _default[] = "default";
78 // default here means take ro.logd.filter, persist.logd.filter then
79 // internal default in that order.
80 if (str && !strcmp(str, _default)) {
81 str = NULL;
82 }
83 static const char _disable[] = "disable";
84 if (str && !strcmp(str, _disable)) {
85 str = "";
86 }
87
88 std::string filter;
89
90 if (str) {
91 filter = str;
92 } else {
93 char property[PROPERTY_VALUE_MAX];
94 property_get("ro.logd.filter", property, _default);
95 filter = property;
96 property_get("persist.logd.filter", property, filter.c_str());
97 // default here means take ro.logd.filter
98 if (strcmp(property, _default)) {
99 filter = property;
100 }
101 }
102
103 // default here means take internal default.
104 if (filter == _default) {
105 // See README.property for description of filter format
106 filter = "~!";
107 }
108 if (filter == _disable) {
109 filter = "";
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800110 }
111
112 mWorstUidEnabled = false;
113
Mark Salyzyn932f7ac2015-08-28 08:02:59 -0700114 for(str = filter.c_str(); *str; ++str) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800115 if (isspace(*str)) {
116 continue;
117 }
118
119 PruneCollection *list;
120 if ((*str == '~') || (*str == '!')) { // ~ supported, ! undocumented
121 ++str;
122 // special case, translates to worst UID at priority in blacklist
123 if (*str == '!') {
124 mWorstUidEnabled = true;
125 ++str;
126 if (!*str) {
127 break;
128 }
129 if (!isspace(*str)) {
130 return 1;
131 }
132 continue;
133 }
134 if (!*str) {
135 return 1;
136 }
137 list = &mNaughty;
138 } else {
139 list = &mNice;
140 }
141
142 uid_t uid = Prune::uid_all;
143 if (isdigit(*str)) {
144 uid = 0;
145 do {
146 uid = uid * 10 + *str++ - '0';
147 } while (isdigit(*str));
148 }
149
150 pid_t pid = Prune::pid_all;
151 if (*str == '/') {
152 ++str;
153 if (isdigit(*str)) {
154 pid = 0;
155 do {
156 pid = pid * 10 + *str++ - '0';
157 } while (isdigit(*str));
158 }
159 }
160
161 if ((uid == Prune::uid_all) && (pid == Prune::pid_all)) {
162 return 1;
163 }
164
165 if (*str && !isspace(*str)) {
166 return 1;
167 }
168
169 // insert sequentially into list
170 PruneCollection::iterator it = list->begin();
171 while (it != list->end()) {
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700172 Prune &p = *it;
173 int m = uid - p.mUid;
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800174 if (m == 0) {
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700175 if (p.mPid == p.pid_all) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800176 break;
177 }
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700178 if ((pid == p.pid_all) && (p.mPid != p.pid_all)) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800179 it = list->erase(it);
180 continue;
181 }
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700182 m = pid - p.mPid;
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800183 }
Mark Salyzyn22e287d2014-03-21 13:12:16 -0700184 if (m <= 0) {
185 if (m < 0) {
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700186 list->insert(it, Prune(uid,pid));
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800187 }
188 break;
189 }
190 ++it;
191 }
192 if (it == list->end()) {
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700193 list->push_back(Prune(uid,pid));
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800194 }
195 if (!*str) {
196 break;
197 }
198 }
199
200 return 0;
201}
202
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700203std::string PruneList::format() {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800204 static const char nice_format[] = " %s";
205 const char *fmt = nice_format + 1;
206
Mark Salyzynb332f1c2015-08-19 13:53:20 -0700207 std::string string;
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800208
209 if (mWorstUidEnabled) {
Mark Salyzynb332f1c2015-08-19 13:53:20 -0700210 string = "~!";
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800211 fmt = nice_format;
212 }
213
214 PruneCollection::iterator it;
215
216 for (it = mNice.begin(); it != mNice.end(); ++it) {
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700217 string += android::base::StringPrintf(fmt, (*it).format().c_str());
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800218 fmt = nice_format;
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800219 }
220
221 static const char naughty_format[] = " ~%s";
222 fmt = naughty_format + (*fmt != ' ');
223 for (it = mNaughty.begin(); it != mNaughty.end(); ++it) {
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700224 string += android::base::StringPrintf(fmt, (*it).format().c_str());
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800225 fmt = naughty_format;
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800226 }
227
Mark Salyzyn73160ac2015-08-20 10:01:44 -0700228 return string;
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800229}
230
231// ToDo: Lists are in sorted order, Prune->cmp() returns + or -
232// If there is scaling issues, resort to a better algorithm than linear
233// based on these assumptions.
234
235bool PruneList::naughty(LogBufferElement *element) {
236 PruneCollection::iterator it;
237 for (it = mNaughty.begin(); it != mNaughty.end(); ++it) {
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700238 if (!(*it).cmp(element)) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800239 return true;
240 }
241 }
242 return false;
243}
244
245bool PruneList::nice(LogBufferElement *element) {
246 PruneCollection::iterator it;
247 for (it = mNice.begin(); it != mNice.end(); ++it) {
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700248 if (!(*it).cmp(element)) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800249 return true;
250 }
251 }
252 return false;
253}