cdb47c4df62169c3a1042319ad070538690bf7b9
[platform/core/connectivity/stc-manager.git] / plugin / exception / stc-plugin-exception.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
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
17 #include <errno.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <syspopup_caller.h>
22 #include <bundle.h>
23 #include <bundle_internal.h>
24 #include <dlog.h>
25 #include <gio/gio.h>
26 #include <pkgmgr-info.h>
27
28 #include "stc-plugin-exception.h"
29
30 //LCOV_EXCL_START
31 #define EXE_TYPE_APPLICATION "app"
32 #define EXE_TYPE_INSTRUCTION "inst"
33 #define EXE_TYPE_SYSTEM      "sys"
34 #define EXE_TYPE_SCRIPT      "script"
35
36 /* 1 day */
37 #define EXCNS_TIMER_INTERVAL 86400
38
39 #define EXCEPTION_BUF_MAX   64
40 #define EXCEPTION_STORAGE   "/var/lib/stc/exceptions"
41
42 #define INTERNET_PRIVILEGE  "http://tizen.org/privilege/internet"
43
44 typedef struct {
45         char *process_name;
46         char *exe_type;
47 } stc_exceptions_info;
48
49 typedef stc_cb_ret_e
50 (*stc_exceptions_info_cb)(const stc_exceptions_info *info,
51                               void *user_data);
52
53 static GHashTable *g_excns_hash;  /**< exception hash table */
54 static GHashTable *g_pkginfo_filter_hash;
55 static guint g_excns_timer_id;
56
57 static int __pkginfo_filter_list_cb(pkgmgrinfo_pkginfo_h handle, void *user_data)
58 {
59         int ret = 0;
60         char *pkgname = NULL;
61
62         ret = pkgmgrinfo_pkginfo_get_pkgname(handle, &pkgname);
63         if (ret == PMINFO_R_OK) {
64                 if (g_hash_table_insert(g_pkginfo_filter_hash,
65                                 g_strdup(pkgname), g_strdup(EXE_TYPE_APPLICATION)) != TRUE)
66                         STC_LOGE("Failed to insert hash table");
67         }
68
69         return STC_CONTINUE;
70 }
71
72 static int __pkginfo_pkg_list_cb(pkgmgrinfo_pkginfo_h handle, void *user_data)
73 {
74         int ret = 0;
75         char *pkgname = NULL;
76         char *exe_type = NULL;
77         stc_exceptions_info data;
78         const stc_exceptions_info_cb excn_cb = user_data;
79
80         ret = pkgmgrinfo_pkginfo_get_pkgname(handle, &pkgname);
81         if (ret == PMINFO_R_OK) {
82                 exe_type = g_hash_table_lookup(g_pkginfo_filter_hash, pkgname);
83                 if (exe_type)
84                         return STC_CONTINUE;
85
86                 data.process_name = pkgname;
87                 data.exe_type = EXE_TYPE_APPLICATION;
88
89                 if (excn_cb(&data, NULL) == STC_CANCEL)
90                         STC_LOGE("Failed to insert hash table");
91         }
92
93         return STC_CONTINUE;
94 }
95
96 static void __excn_hash_foreach_print(gpointer key, gpointer value,
97                                           gpointer data)
98 {
99         const char *process_name = key;
100         const char *exe_type = value;
101
102         if (STC_DEBUG_LOG && STC_STAT_LOG)
103                 STC_LOGI("Process_name[%s] exe_type[%s]",
104                         process_name, exe_type);
105 }
106
107 static void __excn_hash_printall(void)
108 {
109         g_hash_table_foreach(g_excns_hash,
110                 __excn_hash_foreach_print, NULL);
111 }
112
113 static gboolean __remove_exception_app(gpointer key, gpointer value,
114                                         gpointer data)
115 {
116         const char *exe_type = value;
117
118         if (g_strcmp0(exe_type, EXE_TYPE_APPLICATION) == 0)
119                 return TRUE;
120
121         return FALSE;
122 }
123
124 static void __remove_exception_appall(void)
125 {
126         g_hash_table_foreach_remove(g_excns_hash,
127                 __remove_exception_app, NULL);
128 }
129
130 static stc_cb_ret_e __insert_exception_cb(const stc_exceptions_info *info,
131                                             void *user_data)
132 {
133         stc_cb_ret_e ret = STC_CONTINUE;
134
135         if (g_hash_table_insert(g_excns_hash,
136                         g_strdup(info->process_name),
137                         g_strdup(info->exe_type)) != TRUE)
138                 ret = STC_CANCEL;
139
140         return ret;
141 }
142
143 static gboolean __update_exceptions_app_list(void *user_data)
144 {
145         stc_plugin_exception_update_list();
146         return TRUE;
147 }
148
149 static stc_error_e pkginfo_exceptions_foreach(const stc_exceptions_info_cb exception_cb,
150                                        void *user_data)
151 {
152         int ret = 0;
153         int err = STC_ERROR_NONE;
154         pkgmgrinfo_pkginfo_filter_h handle;
155
156         g_pkginfo_filter_hash = g_hash_table_new_full(g_str_hash,
157                                                 g_str_equal, g_free, g_free);
158
159         ret = pkgmgrinfo_pkginfo_filter_create(&handle);
160         ret_value_msg_if(ret != PMINFO_R_OK, STC_ERROR_FAIL,
161                         "Failed to create pkginfo filter");
162
163         ret = pkgmgrinfo_pkginfo_filter_add_string(handle,
164                         PMINFO_PKGINFO_PROP_PACKAGE_PRIVILEGE,
165                         INTERNET_PRIVILEGE);
166         if (ret != PMINFO_R_OK) {
167                 STC_LOGE("Failed to add pkginfo filter string");
168                 err = STC_ERROR_FAIL;
169                 goto out;
170         }
171
172         ret = pkgmgrinfo_pkginfo_filter_foreach_pkginfo(handle,
173                         __pkginfo_filter_list_cb, NULL);
174         if (ret != PMINFO_R_OK) {
175                 STC_LOGE("Failed to foreach pkginfo filter");
176                 err = STC_ERROR_FAIL;
177                 goto out;
178         }
179
180         ret = pkgmgrinfo_pkginfo_get_list(__pkginfo_pkg_list_cb, exception_cb);
181         if (ret != PMINFO_R_OK) {
182                 STC_LOGE("Failed to get pkginfo list");
183                 err = STC_ERROR_FAIL;
184                 goto out;
185         }
186
187 out:
188         if (g_pkginfo_filter_hash) {
189                 g_hash_table_destroy(g_pkginfo_filter_hash);
190                 g_pkginfo_filter_hash = NULL;
191         }
192
193         if (handle)
194                 pkgmgrinfo_pkginfo_filter_destroy(handle);
195
196         return err;
197 }
198
199 static stc_error_e table_exceptions_foreach(const stc_exceptions_info_cb exception_cb,
200                                        void *user_data)
201 {
202         stc_error_e error_code = STC_ERROR_NONE;
203         stc_exceptions_info data;
204
205         FILE *fp = NULL;
206         char buf[EXCEPTION_BUF_MAX] = {0, };
207
208         fp = fopen(EXCEPTION_STORAGE, "r");
209         ret_value_msg_if(!fp, STC_ERROR_FAIL, "Failed to open %s file",
210                          EXCEPTION_STORAGE);
211
212         while (fgets(buf, sizeof(buf), fp) != NULL) {
213                 char *process_name, *exe_type;
214                 char *save_ptr = NULL;
215
216                 process_name = strtok_r(buf, ":", &save_ptr);
217                 if (process_name != NULL)
218                         data.process_name = process_name;
219                 else
220                         data.process_name = "none";
221
222                 exe_type = strtok_r(NULL, "\n", &save_ptr);
223                 if (exe_type != NULL)
224                         data.exe_type = exe_type;
225                 else
226                         data.exe_type = "none";
227
228                 if (exception_cb(&data, user_data) == STC_CANCEL)
229                         break;
230         }
231         fclose(fp);
232
233         return error_code;
234 }
235
236 int stc_plugin_exception_initialize(void)
237 {
238         g_excns_hash = g_hash_table_new_full(g_str_hash,
239                                         g_str_equal, g_free, g_free);
240
241         return STC_ERROR_NONE;
242 }
243
244 int stc_plugin_exception_deinitialize(void)
245 {
246         if (g_excns_timer_id > 0) {
247                 g_source_remove(g_excns_timer_id);
248                 g_excns_timer_id = 0;
249         }
250
251         g_hash_table_destroy(g_excns_hash);
252
253         return STC_ERROR_NONE;
254 }
255
256 int stc_plugin_exception_fill_list(void)
257 {
258         table_exceptions_foreach(__insert_exception_cb, NULL);
259         pkginfo_exceptions_foreach(__insert_exception_cb, NULL);
260
261         if (STC_DEBUG_LOG && STC_STAT_LOG)
262                 __excn_hash_printall();
263
264         g_excns_timer_id = g_timeout_add_seconds(EXCNS_TIMER_INTERVAL,
265                         __update_exceptions_app_list,
266                         NULL);
267
268         return STC_ERROR_NONE;
269 }
270
271 int stc_plugin_exception_update_list(void)
272 {
273         __remove_exception_appall();
274         pkginfo_exceptions_foreach(__insert_exception_cb, NULL);
275
276         if (STC_DEBUG_LOG && STC_STAT_LOG)
277                 __excn_hash_printall();
278
279         return STC_ERROR_NONE;
280 }
281
282 int stc_plugin_exception_check_by_cmdline(char *cmdline)
283 {
284         char *exe_type = NULL;
285
286         exe_type = g_hash_table_lookup(g_excns_hash, cmdline);
287         if (!exe_type)
288                 return STC_ERROR_NO_DATA;
289
290         return STC_ERROR_NONE;
291 }
292
293 API stc_plugin_exception_s stc_plugin_exception = {
294         .initialize_plugin =
295                 stc_plugin_exception_initialize,
296         .deinitialize_plugin =
297                 stc_plugin_exception_deinitialize,
298         .fill_exception_list =
299                 stc_plugin_exception_fill_list,
300         .update_exception_list =
301                 stc_plugin_exception_update_list,
302         .check_exception_by_cmdline =
303                 stc_plugin_exception_check_by_cmdline
304 };
305 //LCOV_EXCL_STOP