cecf12e22c05544ea5423c0e3b950fe886797562
[platform/framework/web/livebox-cpp.git] / src / CModule.cpp
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.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://floralicense.org
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 <stdio.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include <errno.h>
21 #include <dlfcn.h>
22
23 #include <dlog.h>
24 #include <livebox-service.h>
25 #include <livebox-errno.h>
26
27 #include "debug.h"
28 #include "livebox-cpp.h"
29 #include "livebox-impl.h"
30 #include "CModule.h"
31 #include "dlist.h"
32
33 const char *CModule::m_sModulePath = "/opt/usr/live/%s/libexec/liblive-%s.so";
34 struct dlist *CModule::m_pModuleList = NULL;
35
36 CModule *CModule::Load(const char *pkgname)
37 {
38         CModule *inst;
39         char *tmp;
40         char *module_path;
41         int ret;
42
43         tmp = strdup(pkgname);
44         if (!tmp) {
45                 ErrPrint("Memory: %s\n", strerror(errno));
46                 return NULL;
47         }
48
49         try {
50                 inst = new CModule(tmp);
51         } catch (...) {
52                 ErrPrint("Memory\n");
53                 free(tmp);
54                 return NULL;
55         }
56
57         module_path = livebox_service_libexec(pkgname);
58         if (!module_path) {
59                 delete inst;
60                 free(tmp);
61                 return NULL;
62         }
63
64         inst->m_pHandle = dlopen(module_path, RTLD_LOCAL | RTLD_NOW | RTLD_DEEPBIND);
65         free(module_path);
66
67         if (!inst->m_pHandle) {
68                 ErrPrint("dlopen: %s\n", dlerror());
69                 delete inst;
70                 free(tmp);
71                 return NULL;
72         }
73
74         inst->m_fNew = (void *(*)(void))dlsym(inst->m_pHandle, "livebox_new");
75         if (!inst->m_fNew) {
76                 ErrPrint("symbol: livebox_new is not found: %s\n", dlerror());
77                 dlclose(inst->m_pHandle);
78                 delete inst;
79                 free(tmp);
80                 return NULL;
81         }
82
83         inst->m_fNeedToCreate = (int (*)(const char *, const char *))dlsym(inst->m_pHandle, "livebox_need_to_create");
84         if (!inst->m_fNeedToCreate)
85                 DbgPrint("%s has no livebox_need_to_create\n", pkgname);
86
87         inst->m_fInitialize = (int (*)(const char *))dlsym(inst->m_pHandle, "livebox_initialize");
88         if (!inst->m_fInitialize) {
89                 DbgPrint("%s has no livebox_initialize\n", pkgname);
90         } else {
91                 ret = inst->m_fInitialize(pkgname);
92                 if (ret < 0) {
93                         ErrPrint("livebox_finalize(%s) returns %d\n", pkgname, ret);
94                         dlclose(inst->m_pHandle);
95                         delete inst;
96                         free(tmp);
97                         return NULL;
98                 }
99         }
100
101         inst->m_fFinalize = (int (*)(void))dlsym(inst->m_pHandle, "livebox_finalize");
102         if (!inst->m_fFinalize)
103                 DbgPrint("%s has no livebox_finalize\n", pkgname);
104
105         m_pModuleList = dlist_append(m_pModuleList, inst);
106         return inst;
107 }
108
109 int CModule::Unload(void)
110 {
111         struct dlist *l;
112
113         l = dlist_find_data(m_pModuleList, this);
114         m_pModuleList = dlist_remove(m_pModuleList, l);
115
116         if (m_fFinalize) {
117                 int ret;
118                 ret = m_fFinalize();
119                 DbgPrint("livebox_finalize of %s returns %d\n", m_sPkgname, ret);
120         }
121
122         dlclose(m_pHandle);
123         free(m_sPkgname);
124         delete this;
125         return LB_STATUS_SUCCESS;
126 }
127
128 int CModule::Create(const char *filename, const char *content, const char *cluster, const char *category)
129 {
130         CLiveBoxImpl *inst;
131
132         inst = (CLiveBoxImpl *)m_fNew();
133         if (inst) {
134                 int ret;
135                 ret = inst->Create(filename, content, cluster, category);
136                 if (ret < 0) {
137                         delete inst;
138                         return ret;
139                 }
140
141                 m_pList = dlist_append(m_pList, inst);
142                 return 0;
143         }
144
145         return LB_STATUS_ERROR_FAULT;
146 }
147
148 int CModule::Destroy(CLiveBoxImpl *inst)
149 {
150         struct dlist *l;
151
152         l = dlist_find_data(m_pList, inst);
153         if (!l)
154                 return LB_STATUS_ERROR_NOT_EXIST;
155
156         m_pList = dlist_remove(m_pList, l);
157         delete inst;
158         return LB_STATUS_SUCCESS;
159 }
160
161 CLiveBoxImpl *CModule::FindLiveBox(const char *filename)
162 {
163         struct dlist *l;
164         void *item;
165         CLiveBoxImpl *box;
166
167         dlist_foreach(m_pList, l, item) {
168                 box = (CLiveBoxImpl *)item;
169                 if (!strcmp(filename, box->Filename()))
170                         return box;
171         }
172
173         return NULL;
174 }
175
176 int CModule::NeedToCreate(const char *cluster, const char *category)
177 {
178         if (!m_fNeedToCreate)
179                 return 0;
180
181         return m_fNeedToCreate(cluster, category);
182 }
183
184 CModule *CModule::FindModule(const char *pkgname)
185 {
186         struct dlist *l;
187         void *item;
188         CModule *module;
189
190         dlist_foreach(m_pModuleList, l, item) {
191                 module = (CModule *)item;
192                 if (!strcmp(pkgname, module->PackageName())) {
193                         return module;
194                 }
195         }
196
197         return NULL;
198 }
199
200 /* End of a file */