661b8cca114055be875b42eba2fc834c8b682a27
[pkgs/u/ui-gadget.git] / src / module.c
1 /*
2  * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * This file is part of the UI Gadget
5  * Written by Jayoun Lee <airjany@samsung.com>, Jinwoo Nam <jwoo.nam@samsung.com>
6  *
7  * PROPRIETARY/CONFIDENTIAL
8  *
9  * This software is the confidential and proprietary information of
10  * SAMSUNG ELECTRONICS (Confidential Information).
11  * You shall not disclose such Confidential Information and shall
12  * use it only in accordance with the terms of the license agreement
13  * you entered into with SAMSUNG ELECTRONICS.  SAMSUNG make no
14  * representations or warranties about the suitability
15  * of the software, either express or implied, including but not
16  * limited to the implied warranties of merchantability, fitness for a particular purpose, or non-
17  * infringement. SAMSUNG shall not be liable for any damages suffered by licensee as
18  * a result of using, modifying or distributing this software or its derivatives.
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 "ug-module.h"
32 #include "ug-dbg.h"
33
34 #define UG_MODULE_INIT_SYM "UG_MODULE_INIT"
35 #define UG_MODULE_EXIT_SYM "UG_MODULE_EXIT"
36
37 static int file_exist(const char *filename)
38 {
39         FILE *file;
40         if ((file = fopen(filename, "r"))) {
41                 fclose(file);
42                 return 0;
43         }
44
45         return -1;
46 }
47
48 struct ug_module *ug_module_load(const char *name)
49 {
50         void *handle;
51         struct ug_module *module;
52         char ug_file[PATH_MAX];
53
54         char *pkg_name = NULL;
55         uid_t uid;
56
57         int (*module_init) (struct ug_module_ops *ops);
58
59         module = calloc(1, sizeof(struct ug_module));
60
61         if (!module) {
62                 errno = ENOMEM;
63                 return NULL;
64         }
65
66         pkg_name = getenv("PKG_NAME");
67         uid = geteuid();
68
69         if (pkg_name) {
70                 if (snprintf
71                     (ug_file, PATH_MAX, "/opt/apps/%s/lib/libug-%s.so",
72                      pkg_name, name) < 0) {
73                         goto module_free;
74                 } else if (file_exist(ug_file) < 0) {
75                         if (snprintf
76                             (ug_file, PATH_MAX, "/usr/ug/lib/libug-%s.so",
77                              name) < 0) {
78                                 goto module_free;
79                         } else if (file_exist(ug_file) < 0) {
80                                 if (snprintf
81                                     (ug_file, PATH_MAX,
82                                      "/opt/ug/lib/libug-%s.so", name) < 0) {
83                                         goto module_free;
84                                 } else if (file_exist(ug_file) < 0) {
85                                         goto module_free;
86                                 }
87                         }
88                 }
89         } else {
90                 if (snprintf(ug_file, PATH_MAX, "/usr/ug/lib/libug-%s.so", name)
91                     < 0) {
92                         goto module_free;
93                 } else if (file_exist(ug_file) < 0) {
94                         if (snprintf
95                             (ug_file, PATH_MAX, "/opt/ug/lib/libug-%s.so",
96                              name) < 0) {
97                                 goto module_free;
98                         } else if (file_exist(ug_file) < 0) {
99                                 goto module_free;
100                         }
101                 }
102         }
103
104         handle = dlopen(ug_file, RTLD_LAZY);
105         if (!handle) {
106                 _ERR("dlopen failed: %s\n", dlerror());
107                 goto module_free;
108         }
109
110         module_init = dlsym(handle, UG_MODULE_INIT_SYM);
111         if (!module_init) {
112                 _ERR("dlsym failed: %s\n", dlerror());
113                 goto module_dlclose;
114         }
115
116         if (module_init(&module->ops))
117                 goto module_dlclose;
118
119         module->handle = handle;
120         return module;
121
122  module_dlclose:
123         dlclose(handle);
124
125  module_free:
126         free(module);
127         return NULL;
128 }
129
130 int ug_module_unload(struct ug_module *module)
131 {
132         void (*module_exit) (struct ug_module_ops *ops);
133
134         if (!module) {
135                 errno = EINVAL;
136                 return -1;
137         }
138
139         if (module->handle) {
140                 module_exit = dlsym(module->handle, UG_MODULE_EXIT_SYM);
141                 if (module_exit)
142                         module_exit(&module->ops);
143                 else
144                         _ERR("dlsym failed: %s\n", dlerror());
145
146                 dlclose(module->handle);
147         }
148
149         free(module);
150         return 0;
151 }