eaae2d667e3ac32b62ada673a673fc1ccf7b85b4
[platform/adaptation/xf86-module-xdbg.git] / common / xdbg_evlog.c
1 /**************************************************************************
2
3 xdbg
4
5 Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
6
7 Contact: Boram Park <boram1288.park@samsung.com>
8          Sangjin LEE <lsj119@samsung.com>
9
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
17
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
20 of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 **************************************************************************/
31
32 #include <stdio.h>
33 #include <string.h>
34 #include <strings.h>
35 #include <sys/types.h>
36 #include <sys/fcntl.h>
37 #include <unistd.h>
38 #include <stdarg.h>
39 #include <fcntl.h>
40 #include <unistd.h>
41 #include <time.h>
42
43 #include "xdbg_types.h"
44 #include "xdbg_evlog.h"
45 #include "bool_exp_rule_checker.h"
46
47 static char *evt_type[] = { "Event", "Request", "Reply", "Flush" };
48 static char *evt_dir[]  = { "<====", "---->",   "<----", "*****" };
49
50 static RULE_CHECKER rc = NULL;
51
52 static void
53 _mergeArgs (char * target, int argc, const char ** argv)
54 {
55     int i;
56     int len;
57
58     for (i=0; i<argc; i++)
59     {
60         len = sprintf (target, "%s", argv[i]);
61         target += len;
62
63         if (i != argc - 1)
64             *(target++) = ' ';
65     }
66 }
67
68 static int
69 _strcasecmp(const char *str1, const char *str2)
70 {
71     const u_char *us1 = (const u_char *) str1, *us2 = (const u_char *) str2;
72
73     while (tolower(*us1) == tolower(*us2)) {
74         if (*us1++ == '\0')
75             return 0;
76         us2++;
77     }
78
79     return (tolower(*us1) - tolower(*us2));
80 }
81
82 char*
83 xDbgEvlogGetCmd (char *path)
84 {
85     char *p;
86     if (!path)
87         return NULL;
88     p = strrchr (path, '/');
89     return (p)?p+1:path;
90 }
91
92 Bool
93 xDbgEvlogRuleSet (const int argc, const char **argv, char *reply, int *len)
94 {
95     const char * command;
96
97     if (rc == NULL)
98         rc = rulechecker_init();
99
100     if (argc == 0)
101     {
102         rulechecker_print_rule (rc, reply);
103         return TRUE;
104     }
105
106     command = argv[0];
107
108     if (!_strcasecmp (command, "add"))
109     {
110         POLICY_TYPE policy_type;
111         RC_RESULT_TYPE result;
112         const char * policy = argv[1];
113         char rule[8192];
114
115         if (argc < 3)
116         {
117             REPLY ("Error : Too few arguments.\n");
118             return FALSE;
119         }
120
121         if (!_strcasecmp (policy, "ALLOW"))
122             policy_type = ALLOW;
123         else if (!_strcasecmp (policy, "DENY"))
124             policy_type = DENY;
125         else
126         {
127             REPLY ("Error : Unknown policy : [%s].\n          Policy should be ALLOW or DENY.\n", policy);
128             return FALSE;
129         }
130
131         _mergeArgs (rule, argc - 2, &(argv[2]));
132
133         result = rulechecker_add_rule (rc, policy_type, rule);
134         if (result == RC_ERR_TOO_MANY_RULES)
135         {
136             REPLY ("Error : Too many rules were added.\n");
137             return FALSE;
138         }
139         else if (result == RC_ERR_PARSE_ERROR)
140         {
141             REPLY ("Error : An error occured during parsing the rule [%s]\n", rule);
142             return FALSE;
143         }
144
145         REPLY ("The rule was successfully added.\n\n");
146         rulechecker_print_rule (rc, reply);
147         return TRUE;
148     }
149     else if (!_strcasecmp (command, "remove"))
150     {
151         const char * remove_idx;
152         int i;
153
154         if (argc < 2)
155         {
156             REPLY ("Error : Too few arguments.\n");
157             return FALSE;
158         }
159
160         for (i=0; i<argc - 1; i++)
161         {
162             remove_idx = argv[i+1];
163
164             if (!_strcasecmp (remove_idx, "all"))
165             {
166                 rulechecker_destroy (rc);
167                 rc = rulechecker_init();
168                 REPLY ("Every rules were successfully removed.\n");
169             }
170             else
171             {
172                 int index = atoi (remove_idx);
173                 if (isdigit (*remove_idx) && rulechecker_remove_rule (rc, index) == 0)
174                     REPLY ("The rule [%d] was successfully removed.\n", index);
175                 else
176                     REPLY ("Rule remove fail : No such rule [%s].\n", remove_idx);
177             }
178         }
179         rulechecker_print_rule (rc, reply);
180         return TRUE;
181     }
182     else if (!_strcasecmp (command, "print"))
183     {
184         rulechecker_print_rule (rc, reply);
185         return TRUE;
186     }
187     else if (!_strcasecmp (command, "help"))
188     {
189         REPLY ("%s", rulechecker_print_usage());
190         return TRUE;
191     }
192
193     REPLY ("%s\nUnknown command : [%s].\n\n", rulechecker_print_usage(), command);
194
195     return TRUE;
196 }
197
198 Bool
199 xDbgEvlogRuleValidate (EvlogInfo *evinfo)
200 {
201     const char *evlog_name = "";
202     char *cmd = "";
203
204     if (rc == NULL)
205         rc = rulechecker_init ();
206
207     if (!rc)
208     {
209         fprintf (stderr, "failed: create rulechecker\n");
210         return FALSE;
211     }
212
213     cmd = xDbgEvlogGetCmd (evinfo->client.command);
214
215     if (evinfo->type == REQUEST)
216         evlog_name = evinfo->req.name;
217     else if (evinfo->type == EVENT)
218         evlog_name = evinfo->evt.name;
219
220     return rulechecker_validate_rule (rc,
221                                       evinfo->type,
222                                       evinfo->req.id,
223                                       evlog_name,
224                                       evinfo->client.pid,
225                                       cmd);
226 }
227
228 void
229 xDbgEvlogFillLog (EvlogInfo *evinfo, char *reply, int *len)
230 {
231     static CARD32 prev;
232
233     RETURN_IF_FAIL (evinfo->type >= 0 && (sizeof (evt_dir) / sizeof (char*)));
234     RETURN_IF_FAIL (evinfo->type >= 0 && (sizeof (evt_type) / sizeof (char*)));
235
236     REPLY ("[%10.3f][%5ld] %22s(%2d:%5d) %s %s",
237                 evinfo->time / 1000.0,
238                 evinfo->time - prev,
239                 xDbgEvlogGetCmd (evinfo->client.command),
240                 evinfo->client.index,
241                 evinfo->client.pid,
242                 evt_dir[evinfo->type],
243                 evt_type[evinfo->type]);
244
245     if (evinfo->type == REQUEST)
246     {
247         REPLY ("(");
248         reply = xDbgEvlogReqeust (evinfo, reply, len);
249         REPLY (")");
250     }
251     else if (evinfo->type == EVENT)
252     {
253         REPLY ("(");
254         reply = xDbgEvlogEvent (evinfo, reply, len);
255         REPLY (")");
256     }
257     else
258     {
259         const char *evlog_name = "";
260         if (evinfo->type == REQUEST)
261             evlog_name = evinfo->req.name;
262         else if (evinfo->type == EVENT)
263             evlog_name = evinfo->evt.name;
264         REPLY ("(%s)", evlog_name);
265     }
266
267     REPLY ("\n");
268
269     prev = evinfo->time;
270 }