log: check tdm environment value only init
[platform/core/uifw/libtdm.git] / src / tdm_config.c
1 /**************************************************************************
2  *
3  * libtdm
4  *
5  * Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
6  *
7  * Contact: Eunchul Kim <chulspro.kim@samsung.com>,
8  *          JinYoung Jeon <jy0.jeon@samsung.com>,
9  *          Taeheon Kim <th908.kim@samsung.com>,
10  *          YoungJun Cho <yj44.cho@samsung.com>,
11  *          SooChan Lim <sc1.lim@samsung.com>,
12  *          Boram Park <boram1288.park@samsung.com>
13  *
14  * Permission is hereby granted, free of charge, to any person obtaining a
15  * copy of this software and associated documentation files (the
16  * "Software"), to deal in the Software without restriction, including
17  * without limitation the rights to use, copy, modify, merge, publish,
18  * distribute, sub license, and/or sell copies of the Software, and to
19  * permit persons to whom the Software is furnished to do so, subject to
20  * the following conditions:
21  *
22  * The above copyright notice and this permission notice (including the
23  * next paragraph) shall be included in all copies or substantial portions
24  * of the Software.
25  *
26  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
27  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
29  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
30  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
31  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
32  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33  *
34 **************************************************************************/
35
36 #ifdef HAVE_CONFIG_H
37 #include "config.h"
38 #endif
39
40 #include <iniparser.h>
41
42 #include "tdm_log.h"
43 #include "tdm_macro.h"
44 #include "tdm_list.h"
45 #include "tdm.h"
46 #include "tdm_private.h"
47 #include "tdm_config.h"
48
49 #define TDM_CONFIG_FILENAME "tdm.ini"
50 #define TDM_CONFIG_GENERAL_SECTION "general"
51
52 static pthread_mutex_t g_dic_lock = PTHREAD_MUTEX_INITIALIZER;
53 static dictionary *g_dic = NULL;
54 static int init_dic = 0;
55
56 static int
57 _tdm_config_check_file_owner(const char *filepath)
58 {
59         struct stat sb;
60
61         if (stat(filepath, &sb) < 0) {
62                 TDM_WRN("%s: %m", filepath);
63                 return -1;
64         }
65
66         if (sb.st_uid != getuid()) {
67                 TDM_WRN("'%s': not owned by %u", filepath, getuid());
68                 return -1;
69         }
70
71         return 0;
72 }
73
74 static dictionary *
75 _tdm_config_load_file(const char *dir, const char *filename)
76 {
77         char filepath[TDM_PATH_LEN];
78         dictionary *dic;
79
80         snprintf(filepath, sizeof filepath, "%s/%s", dir, filename);
81
82         if (_tdm_config_check_file_owner(filepath) < 0)
83                 return NULL;
84
85         dic = iniparser_load(filepath);
86         TDM_RETURN_VAL_IF_FAIL(dic != NULL, NULL);
87
88         if (!iniparser_find_entry(dic, TDM_CONFIG_GENERAL_SECTION)) {
89                 TDM_ERR("no '%s' section: '%s'", TDM_CONFIG_GENERAL_SECTION, filepath);
90                 iniparser_freedict(dic);
91                 return NULL;
92         }
93
94         TDM_INFO("opened successed: '%s'", filepath);
95
96         return dic;
97 }
98
99 static void
100 _tdm_config_check_logs(void)
101 {
102         const char *path;
103         int level;
104
105         pthread_mutex_unlock(&g_dic_lock);
106
107         level = tdm_config_get_int(TDM_CONFIG_KEY_DEBUG_LOG_LEVEL, -1);
108         if (level == -1) {
109                 const char *str = getenv("TDM_DEBUG_LEVEL");
110                 if (str)
111                         level = str[0] - '0';
112                 else
113                         level = 3;
114         }
115         tdm_log_set_debug_level(level);
116
117         level = tdm_config_get_int(TDM_CONFIG_KEY_DEBUG_ASSERT_LEVEL, -1);
118         if (level == -1) {
119                 const char *str = getenv("TDM_ASSERT_LEVEL");
120                 if (str)
121                         level = str[0] - '0';
122                 else
123                         level = 0;
124         }
125         tdm_log_set_assert_level(level);
126
127         /* if TDM_CONFIG_KEY_DEBUG_LOG_PATH is setted, TDM_CONFIG_KEY_DEBUG_DLOG will be ignored. */
128         path = tdm_config_get_string(TDM_CONFIG_KEY_DEBUG_LOG_PATH, NULL);
129         if (path) {
130                 tdm_log_enable_dlog(0);
131                 tdm_log_set_path(path);
132         } else {
133                 int dlog = tdm_config_get_int(TDM_CONFIG_KEY_DEBUG_DLOG, -1);
134                 if (dlog == -1) {
135                         const char *str = getenv("TDM_DLOG");
136                         if (str)
137                                 dlog = (str[0] == '1') ? 1 : 0;
138                         else
139                                 dlog = 1;
140                 }
141                 tdm_log_enable_dlog(dlog);
142         }
143
144         pthread_mutex_lock(&g_dic_lock);
145 }
146
147 static void
148 _tdm_config_check_init(void)
149 {
150         if (init_dic)
151                 return;
152
153         init_dic = 1;
154
155         g_dic = _tdm_config_load_file(TDM_DATA_PATH, TDM_CONFIG_FILENAME);
156
157         _tdm_config_check_logs();
158
159         TDM_INFO("tdm config init %s (%p)", (g_dic) ? "successed" : "failed", g_dic);
160 }
161
162 INTERN void
163 tdm_config_deinit(void)
164 {
165         pthread_mutex_lock(&g_dic_lock);
166
167         if (!g_dic) {
168                 pthread_mutex_unlock(&g_dic_lock);
169                 return;
170         }
171
172         iniparser_freedict(g_dic);
173         g_dic = NULL;
174         init_dic = 0;
175
176         TDM_INFO("tdm config deinit done");
177
178         pthread_mutex_unlock(&g_dic_lock);
179 }
180
181 static const char*
182 _tdm_config_get_string_internal(dictionary *dic, const char *key, const char *default_value)
183 {
184         char *temp = NULL;
185         const char *result;
186
187         if (default_value) {
188                 temp = strdup(default_value);
189                 if (!temp) {
190                         TDM_ERR("strdup failed: %m");
191                         return default_value;
192                 }
193         }
194
195         result = (const char *)iniparser_getstring(dic, key, temp);
196         if (!result || strlen(result) == 0) {
197                 free(temp);
198                 return default_value;
199         }
200
201         free(temp);
202
203         return result;
204 }
205
206 EXTERN int
207 tdm_config_get_int(const char *key, int default_value)
208 {
209         const char *result;
210         int value;
211
212         TDM_RETURN_VAL_IF_FAIL(key != NULL, default_value);
213
214         pthread_mutex_lock(&g_dic_lock);
215
216         _tdm_config_check_init();
217         if (!g_dic) {
218                 TDM_INFO("%s = %d: default", key, default_value);
219                 pthread_mutex_unlock(&g_dic_lock);
220                 return default_value;
221         }
222
223         result = _tdm_config_get_string_internal(g_dic, key, NULL);
224         pthread_mutex_unlock(&g_dic_lock);
225
226         if (!result) {
227                 TDM_INFO("%s = %d: no key", key, default_value);
228                 return default_value;
229         }
230
231         value = (int)strtol(result, NULL, 0);
232
233         TDM_INFO("%s = %d", key, value);
234
235         return value;
236 }
237
238 EXTERN const char*
239 tdm_config_get_string(const char *key, const char *default_value)
240 {
241         const char *result;
242
243         TDM_RETURN_VAL_IF_FAIL(key != NULL, default_value);
244
245         pthread_mutex_lock(&g_dic_lock);
246
247         _tdm_config_check_init();
248         if (!g_dic) {
249                 TDM_INFO("%s = %s: default", key, default_value);
250                 pthread_mutex_unlock(&g_dic_lock);
251                 return default_value;
252         }
253
254         result = _tdm_config_get_string_internal(g_dic, key, default_value);
255         pthread_mutex_unlock(&g_dic_lock);
256
257         TDM_INFO("%s = %s", key, result);
258
259         return result;
260 }
261
262 EXTERN tdm_error
263 tdm_config_set_int(const char *key, int value)
264 {
265         char temp[TDM_NAME_LEN];
266         int ret;
267
268         TDM_RETURN_VAL_IF_FAIL(key != NULL, TDM_ERROR_INVALID_PARAMETER);
269
270         snprintf(temp, sizeof temp, "%d", value);
271
272         pthread_mutex_lock(&g_dic_lock);
273
274         _tdm_config_check_init();
275         if (!g_dic) {
276                 TDM_INFO("%s = %d set failed", key, value);
277                 pthread_mutex_unlock(&g_dic_lock);
278                 return TDM_ERROR_BAD_REQUEST;
279         }
280
281         ret = iniparser_set(g_dic, key, (const char*)temp);
282
283         pthread_mutex_unlock(&g_dic_lock);
284
285         TDM_RETURN_VAL_IF_FAIL(ret == 0, TDM_ERROR_OPERATION_FAILED);
286
287         TDM_INFO("%s = %d set done", key, value);
288
289         return TDM_ERROR_NONE;
290 }
291
292 EXTERN tdm_error
293 tdm_config_set_string(const char *key, const char *value)
294 {
295         int ret;
296
297         TDM_RETURN_VAL_IF_FAIL(key != NULL, TDM_ERROR_INVALID_PARAMETER);
298
299         pthread_mutex_lock(&g_dic_lock);
300
301         _tdm_config_check_init();
302         if (!g_dic) {
303                 TDM_INFO("%s = %s set failed", key, value);
304                 pthread_mutex_unlock(&g_dic_lock);
305                 return TDM_ERROR_BAD_REQUEST;
306         }
307
308         ret = iniparser_set(g_dic, key, value);
309
310         pthread_mutex_unlock(&g_dic_lock);
311
312         TDM_RETURN_VAL_IF_FAIL(ret == 0, TDM_ERROR_OPERATION_FAILED);
313
314         TDM_INFO("%s = %s set done", key, value);
315
316         return TDM_ERROR_NONE;
317 }