tizen 2.3.1 release
[framework/system/dlog.git] / src / libdlog / logconfig.c
1 /*
2  * DLOG
3  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <errno.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22
23 #include "logconfig.h"
24 #include "loglimiter.h"
25
26 /* Functions possible return value */
27 #define RET_ERROR                      (-1)
28 #define RET_SUCCESS                    0
29
30 #define CONFIG_LINE_MAX_LEN            256
31 #define CONFIG_OPTION_MAX_LEN          64
32
33 /* Shortcut macros */
34 #define isCOMMENT(c)                   ('#' == c)
35 #define isNEWLINE(c)                   ('\n' == c || '\r' == c)
36
37 /* Dlog options definition */
38 #define LOG_PLATFORM_STRING            "PlatformLogs"
39 #define LOG_LIMITER_STRING             "LogLimiter"
40
41 /* Define options possible values */
42 #define ALLOW_STRING                   "allow"
43 #define DENY_STRING                    "deny"
44 #define ON_STRING                      "on"
45 #define OFF_STRING                     "off"
46 #define isYES(c)                       (c == '1')
47 #define isNO(c)                        (c == '0')
48
49
50 static int log_config_multiplex_opt(char* opt_str, char* val_str, int prio,
51                                     struct log_config* config)
52 {
53         int value = 0;
54
55         /* There are only two ways to interpret the lines, so make here a short circuit */
56         if (0 < prio) { /* Is it a rule or an option  ? */
57                 /* For the filtering rule ... */
58
59                 if (!strncasecmp(ALLOW_STRING, val_str, sizeof(ALLOW_STRING))) {
60                         value = __LOG_LIMITER_LIMIT_MAX + 1;
61                 } else if (!strncasecmp(DENY_STRING, val_str,
62                                                      sizeof(DENY_STRING))) {
63                         value = 0;
64                 } else {
65                         char* endptr = NULL;
66
67                         value = strtoul(val_str, &endptr, 0);
68                         if (*endptr != '\0') {
69                                 return RET_ERROR;
70                         }
71                 }
72
73                 return __log_limiter_add_rule(opt_str, prio, value);
74
75         } else { /* It's an option then */
76                 if (isYES(*val_str)) {
77                         value = 1;
78                 } else if (isNO(*val_str)) {
79                         value = 0;
80                 } else if (!strncasecmp(ON_STRING, val_str,
81                                         sizeof(ON_STRING))) {
82                         value = 1;
83                 } else if (!strncasecmp(OFF_STRING, val_str,
84                                         sizeof(OFF_STRING))) {
85                         value = 0;
86                 } else {
87                         return RET_ERROR;
88                 }
89
90                 if (!strncasecmp(LOG_PLATFORM_STRING, opt_str,
91                                  sizeof(LOG_PLATFORM_STRING))) {
92                         config->lc_plog = value;
93                 } else if (!strncasecmp(LOG_LIMITER_STRING, opt_str,
94                                        sizeof(LOG_LIMITER_STRING))) {
95                         config->lc_limiter = value;
96                 } else {
97                         return RET_ERROR;
98                 }
99         }
100
101         return RET_SUCCESS;
102 }
103
104 /* Function returns 0 for success or -1 when error occurred */
105 int __log_config_read(const char* config_file, struct log_config* config)
106 {
107         FILE* fconfig = NULL;
108         char buf[CONFIG_LINE_MAX_LEN];
109         char opt[CONFIG_OPTION_MAX_LEN];
110         char opt_value[CONFIG_OPTION_MAX_LEN];
111         int prio = (-1);
112         int ret = 0;
113
114         /* Check input */
115         if (NULL == config_file || NULL == config) {
116                 return RET_ERROR;
117         }
118
119         if (NULL == (fconfig = fopen(config_file, "r"))) {
120                 return RET_ERROR;
121         }
122
123         while (1) {
124                 memset(buf, 0, CONFIG_LINE_MAX_LEN);
125                 errno = 0;
126                 if (NULL == fgets(buf, CONFIG_LINE_MAX_LEN, fconfig)) {
127                         if (!errno) {
128                                 break;
129                         }
130                         goto bailout;
131                 }
132
133                 /* We ignore comments and blank lines */
134                 if (isCOMMENT(*buf) || isNEWLINE(*buf)) {
135                         continue;
136                 }
137
138                 memset(opt, 0, sizeof(opt));
139                 memset(opt_value, 0, sizeof(opt_value));
140                 prio = (-1);
141                 /* Read configure line, sscanf() should return two tokens,
142                  * even for tag filtering rule */
143                 ret = sscanf(buf, "%[A-z0-9-]\t%[A-z0-9]",
144                                   opt, opt_value);
145                 if (ret != 2) { /* The line is malformed ? */
146                         char c = 0;
147                         /* This could be rule with space inside TAG */
148                         ret = sscanf(buf, "\"%[]A-z0-9*\x20_+:;/-]\"\t|\t%c\t%[A-z0-9]",
149                                           opt, &c, opt_value);
150                         if (ret != 3) {
151                                 goto bailout;
152                         }
153                         prio = (int)c;
154                 }
155
156
157                 if (0 > log_config_multiplex_opt(opt, opt_value, prio, config)) {
158                         goto bailout;
159                 }
160         }
161
162         fclose(fconfig);
163         return RET_SUCCESS;
164
165 bailout:
166         /* These actions should warranty that
167            we cleanly handle initialization errors */
168         fclose(fconfig);
169         /* Clean rules list to prevent log limiter initialization,
170            if configuration error occured. */
171         __log_limiter_rules_purge();
172
173         return RET_ERROR;
174 }