blob: 0406bf3d0617bf6e3fa0c96c96e91afa9be2a69f [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 <string>
20
21#include <base/stringprintf.h>
Mark Salyzyndfa7a072014-02-11 12:29:31 -080022
23#include "LogWhiteBlackList.h"
24
25// White and Black list
26
Mark Salyzyn77187782015-05-12 15:21:31 -070027Prune::Prune(uid_t uid, pid_t pid) : mUid(uid), mPid(pid) {
28}
Mark Salyzyndfa7a072014-02-11 12:29:31 -080029
30int Prune::cmp(uid_t uid, pid_t pid) const {
31 if ((mUid == uid_all) || (mUid == uid)) {
32 if (mPid == pid_all) {
33 return 0;
34 }
35 return pid - mPid;
36 }
37 return uid - mUid;
38}
39
40void Prune::format(char **strp) {
41 if (mUid != uid_all) {
Chih-Hung Hsieh634118e2014-09-12 16:02:28 -070042 if (mPid != pid_all) {
43 asprintf(strp, "%u/%u", mUid, mPid);
44 } else {
45 asprintf(strp, "%u", mUid);
46 }
47 } else if (mPid != pid_all) {
48 asprintf(strp, "/%u", mPid);
49 } else { // NB: mPid == pid_all can not happen if mUid == uid_all
50 asprintf(strp, "/");
Mark Salyzyndfa7a072014-02-11 12:29:31 -080051 }
52}
53
Mark Salyzyn77187782015-05-12 15:21:31 -070054PruneList::PruneList() : mWorstUidEnabled(true) {
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
67int PruneList::init(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
77 if (!str) {
78 return 0;
79 }
80
81 mWorstUidEnabled = false;
82
83 for(; *str; ++str) {
84 if (isspace(*str)) {
85 continue;
86 }
87
88 PruneCollection *list;
89 if ((*str == '~') || (*str == '!')) { // ~ supported, ! undocumented
90 ++str;
91 // special case, translates to worst UID at priority in blacklist
92 if (*str == '!') {
93 mWorstUidEnabled = true;
94 ++str;
95 if (!*str) {
96 break;
97 }
98 if (!isspace(*str)) {
99 return 1;
100 }
101 continue;
102 }
103 if (!*str) {
104 return 1;
105 }
106 list = &mNaughty;
107 } else {
108 list = &mNice;
109 }
110
111 uid_t uid = Prune::uid_all;
112 if (isdigit(*str)) {
113 uid = 0;
114 do {
115 uid = uid * 10 + *str++ - '0';
116 } while (isdigit(*str));
117 }
118
119 pid_t pid = Prune::pid_all;
120 if (*str == '/') {
121 ++str;
122 if (isdigit(*str)) {
123 pid = 0;
124 do {
125 pid = pid * 10 + *str++ - '0';
126 } while (isdigit(*str));
127 }
128 }
129
130 if ((uid == Prune::uid_all) && (pid == Prune::pid_all)) {
131 return 1;
132 }
133
134 if (*str && !isspace(*str)) {
135 return 1;
136 }
137
138 // insert sequentially into list
139 PruneCollection::iterator it = list->begin();
140 while (it != list->end()) {
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700141 Prune &p = *it;
142 int m = uid - p.mUid;
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800143 if (m == 0) {
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700144 if (p.mPid == p.pid_all) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800145 break;
146 }
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700147 if ((pid == p.pid_all) && (p.mPid != p.pid_all)) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800148 it = list->erase(it);
149 continue;
150 }
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700151 m = pid - p.mPid;
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800152 }
Mark Salyzyn22e287d2014-03-21 13:12:16 -0700153 if (m <= 0) {
154 if (m < 0) {
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700155 list->insert(it, Prune(uid,pid));
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800156 }
157 break;
158 }
159 ++it;
160 }
161 if (it == list->end()) {
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700162 list->push_back(Prune(uid,pid));
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800163 }
164 if (!*str) {
165 break;
166 }
167 }
168
169 return 0;
170}
171
172void PruneList::format(char **strp) {
173 if (*strp) {
174 free(*strp);
175 *strp = NULL;
176 }
177
178 static const char nice_format[] = " %s";
179 const char *fmt = nice_format + 1;
180
Mark Salyzynb332f1c2015-08-19 13:53:20 -0700181 std::string string;
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800182
183 if (mWorstUidEnabled) {
Mark Salyzynb332f1c2015-08-19 13:53:20 -0700184 string = "~!";
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800185 fmt = nice_format;
186 }
187
188 PruneCollection::iterator it;
189
190 for (it = mNice.begin(); it != mNice.end(); ++it) {
191 char *a = NULL;
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700192 (*it).format(&a);
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800193
Mark Salyzynb332f1c2015-08-19 13:53:20 -0700194 string += android::base::StringPrintf(fmt, a);
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800195 fmt = nice_format;
196
197 free(a);
198 }
199
200 static const char naughty_format[] = " ~%s";
201 fmt = naughty_format + (*fmt != ' ');
202 for (it = mNaughty.begin(); it != mNaughty.end(); ++it) {
203 char *a = NULL;
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700204 (*it).format(&a);
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800205
Mark Salyzynb332f1c2015-08-19 13:53:20 -0700206 string += android::base::StringPrintf(fmt, a);
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800207 fmt = naughty_format;
208
209 free(a);
210 }
211
Mark Salyzynb332f1c2015-08-19 13:53:20 -0700212 *strp = strdup(string.c_str());
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800213}
214
215// ToDo: Lists are in sorted order, Prune->cmp() returns + or -
216// If there is scaling issues, resort to a better algorithm than linear
217// based on these assumptions.
218
219bool PruneList::naughty(LogBufferElement *element) {
220 PruneCollection::iterator it;
221 for (it = mNaughty.begin(); it != mNaughty.end(); ++it) {
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700222 if (!(*it).cmp(element)) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800223 return true;
224 }
225 }
226 return false;
227}
228
229bool PruneList::nice(LogBufferElement *element) {
230 PruneCollection::iterator it;
231 for (it = mNice.begin(); it != mNice.end(); ++it) {
Mark Salyzyne0ed16c2015-08-19 13:31:31 -0700232 if (!(*it).cmp(element)) {
Mark Salyzyndfa7a072014-02-11 12:29:31 -0800233 return true;
234 }
235 }
236 return false;
237}