Fix wrong log formats
[platform/core/appfw/ui-gadget-1.git] / src / module.c
1 /*
2  *  UI Gadget
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <linux/limits.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <dlfcn.h>
28 #include <unistd.h>
29 #include <sys/types.h>
30
31 #include <aul.h>
32 #include <pkgmgr-info.h>
33
34 #include "ug-module.h"
35 #include "ug-dbg.h"
36
37 #include <tzplatform_config.h>
38
39 #define UG_MODULE_INIT_SYM "UG_MODULE_INIT"
40 #define UG_MODULE_EXIT_SYM "UG_MODULE_EXIT"
41
42 #define MEM_ADDR_LEN 8
43 #define MEM_ADDR_TOT_LEN 17
44
45 #ifndef UG_API
46 #define UG_API __attribute__ ((visibility("default")))
47 #endif
48
49
50 static char *__ug_module_get_addr(const char *ug_name)
51 {
52         FILE *file;
53         char buf[PATH_MAX] = {0,};
54         char mem[PATH_MAX] = {0,};
55
56         char *token_param = NULL;
57         char *saveptr = NULL;
58         int cnt = 0;
59
60         if (ug_name == NULL)
61                 goto func_out;
62
63         snprintf(buf, sizeof(buf), "/proc/%d/maps", getpid());
64
65         file = fopen(buf, "r");
66         if (file == NULL) {
67                 _WRN("proc open fail(%d)", errno);
68                 goto func_out;
69         }
70
71         memset(buf, 0x00, PATH_MAX);
72
73         while (fgets(buf, PATH_MAX, file) != NULL) {
74                 if (strstr(buf, ug_name)) {
75                         token_param = strtok_r(buf, " ", &saveptr);
76                         if ((token_param == NULL) || (strlen(token_param) > MEM_ADDR_TOT_LEN)) {
77                                 _ERR("proc token param(%s) error", token_param);
78                                 goto close_out;
79                         }
80
81                         if (cnt > 0) {
82                                 memcpy((void *)(mem+MEM_ADDR_LEN+1),
83                                         (const void *)(token_param+MEM_ADDR_LEN+1), MEM_ADDR_LEN);
84                         } else {
85                                 memcpy((void *)mem, (const void *)token_param, strlen(token_param));
86                                 cnt++;
87                         }
88                 } else {
89                         if (cnt > 0)
90                                 goto close_out;
91                 }
92
93                 memset(buf, 0x00, PATH_MAX);
94                 saveptr = NULL;
95         }
96
97 close_out:
98         fclose(file);
99         file = NULL;
100
101 func_out:
102         if (strlen(mem) > 0)
103                 return strdup(mem);
104         else
105                 return NULL;
106 }
107
108 static int __file_exist(const char *path)
109 {
110         int ret;
111
112         ret = access(path, R_OK);
113         LOGD("ug_file(%s) check %s", path, ret ? "fail" : "ok");
114
115         return ret;
116 }
117
118 static int __get_ug_info(const char *name, char **ug_file_path)
119 {
120         char ug_file[PATH_MAX];
121         char app_id[NAME_MAX];
122         char *root_path;
123         char *res_path = NULL;
124         pkgmgrinfo_appinfo_h appinfo = NULL;
125
126         /* get path using name(file name) */
127         snprintf(ug_file, PATH_MAX, "%s/lib/libug-%s.so",
128                         tzplatform_getenv(TZ_SYS_RO_UG), name);
129         if (!__file_exist(ug_file))
130                 goto out_func;
131         snprintf(ug_file, PATH_MAX, "%s/lib/lib%s.so",
132                         tzplatform_getenv(TZ_SYS_RO_UG), name);
133         if (!__file_exist(ug_file))
134                 goto out_func;
135
136         /* get path using appid */
137         if (aul_app_get_appid_bypid(getpid(), app_id, sizeof(app_id))) {
138                 LOGE("failed to get appid");
139                 return -1;
140         }
141         snprintf(ug_file, PATH_MAX, "%s/lib/libug-%s.so",
142                         tzplatform_getenv(TZ_SYS_RO_UG), app_id);
143         if (!__file_exist(ug_file))
144                 goto out_func;
145         snprintf(ug_file, PATH_MAX, "%s/lib/lib%s.so",
146                         tzplatform_getenv(TZ_SYS_RO_UG), app_id);
147         if (!__file_exist(ug_file))
148                 goto out_func;
149
150         /* get app root path */
151         if (pkgmgrinfo_appinfo_get_usr_appinfo(app_id, getuid(), &appinfo)) {
152                 LOGE("failed to get app info");
153                 return -1;
154         }
155         if (pkgmgrinfo_appinfo_get_root_path(appinfo, &root_path)) {
156                 LOGE("failed to get app root path");
157                 pkgmgrinfo_appinfo_destroy_appinfo(appinfo);
158                 return -1;
159         }
160         /* get path using name and root path.
161          * in this case, try to get ug app's library in the same pacakge.
162          */
163         snprintf(ug_file, PATH_MAX, "%s/lib/ug/libug-%s.so", root_path, name);
164         if (!__file_exist(ug_file))
165                 goto out_func;
166         snprintf(ug_file, PATH_MAX, "%s/lib/ug/lib%s.so", root_path, name);
167         if (!__file_exist(ug_file))
168                 goto out_func;
169         /* get path using appid and root path */
170         snprintf(ug_file, PATH_MAX, "%s/lib/ug/libug-%s.so", root_path, app_id);
171         if (!__file_exist(ug_file))
172                 goto out_func;
173         snprintf(ug_file, PATH_MAX, "%s/lib/ug/lib%s.so", root_path, app_id);
174         if (!__file_exist(ug_file))
175                 goto out_func;
176
177         /* get path using name and shared resource path.
178          * in this case, we need to get other package's ug library
179          * and the 'name' should be ug's appid.
180          */
181         if (aul_get_app_shared_resource_path_by_appid(name, &res_path)) {
182                 LOGE("failed to get shared resource path");
183                 pkgmgrinfo_appinfo_destroy_appinfo(appinfo);
184                 return -1;
185         }
186         snprintf(ug_file, PATH_MAX, "%s/lib/ug/libug-%s.so", res_path, name);
187         if (!__file_exist(ug_file))
188                 goto out_func;
189         snprintf(ug_file, PATH_MAX, "%s/lib/ug/lib-%s.so", res_path, name);
190         if (!__file_exist(ug_file))
191                 goto out_func;
192
193 out_func:
194         if ((strlen(ug_file) > 0) && (ug_file_path))
195                 *ug_file_path = strdup(ug_file);
196
197         free(res_path);
198         if (appinfo)
199                 pkgmgrinfo_appinfo_destroy_appinfo(appinfo);
200
201         return 0;
202 }
203
204 struct ug_module *ug_module_load(const char *name)
205 {
206         void *handle;
207         struct ug_module *module;
208         int (*module_init) (struct ug_module_ops *ops);
209         char *ug_file = NULL;
210
211         if (__get_ug_info(name, &ug_file) < 0) {
212                 _ERR("error in getting ug file path");
213                 return NULL;
214         }
215
216         module = calloc(1, sizeof(struct ug_module));
217         if (!module) {
218                 errno = ENOMEM;
219                 free(ug_file);
220                 return NULL;
221         }
222
223         handle = dlopen(ug_file, RTLD_LAZY);
224         if (!handle) {
225                 _ERR("dlopen failed: %s", dlerror());
226                 goto module_free;
227         }
228
229         module_init = dlsym(handle, UG_MODULE_INIT_SYM);
230         if (!module_init) {
231                 _ERR("dlsym failed: %s", dlerror());
232                 goto module_dlclose;
233         }
234
235         if (module_init(&module->ops))
236                 goto module_dlclose;
237
238         module->handle = handle;
239         module->module_name = strdup(name);
240
241         module->addr = __ug_module_get_addr(name);
242
243         free(ug_file);
244         return module;
245
246  module_dlclose:
247         dlclose(handle);
248
249  module_free:
250         free(module);
251         free(ug_file);
252         return NULL;
253 }
254
255 int ug_module_unload(struct ug_module *module)
256 {
257         void (*module_exit) (struct ug_module_ops *ops);
258
259         if (!module) {
260                 errno = EINVAL;
261                 return -1;
262         }
263
264         if (module->handle) {
265                 module_exit = dlsym(module->handle, UG_MODULE_EXIT_SYM);
266                 if (module_exit)
267                         module_exit(&module->ops);
268                 else
269                         _ERR("dlsym failed: %s", dlerror());
270
271                 _DBG("dlclose(%s)", module->module_name);
272                 dlclose(module->handle);
273                 module->handle = NULL;
274         }
275
276         if (module->module_name)
277                 free(module->module_name);
278
279         if (module->addr)
280                 free(module->addr);
281
282         free(module);
283         return 0;
284 }
285
286 UG_API int ug_module_get_file_path(const char *name, char **ug_file_path)
287 {
288         if (__get_ug_info(name, ug_file_path) < 0) {
289                 _ERR("error in getting ug file path");
290                 return -1;
291         }
292
293         return 0;
294 }