1 /*******************************************************************************
2 * Copyright (C) 2004-2008 Intel Corp. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * - Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 *
10 * - Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * - Neither the name of Intel Corp. nor the names of its
15 * contributors may be used to endorse or promote products derived from this
16 * software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 *******************************************************************************/
30
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34 #include <cstdlib>
35 #include <cstdio>
36 #include <cstring>
37 #include <sys/types.h>
38 #include <dlfcn.h>
39 #include "glue.h"
40
41 #ifdef __sun
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #endif // __sun
46
47 #define PARSER_MAX 32
48
49 typedef struct parser_s {
50 unsigned int count;
51 char *line[PARSER_MAX];
52 } parser_t;
53
54
parser_init(parser_t * cfg)55 static void parser_init(parser_t *cfg)
56 {
57 if (!cfg) {
58 return;
59 }
60
61 cfg->count = 0;
62 }
63
parser_add(parser_t * cfg,char * buf)64 static int parser_add(parser_t *cfg, char *buf)
65 {
66 if ((!cfg) || (cfg->count > PARSER_MAX)) {
67 return -1;
68 }
69
70 cfg->line[cfg->count] = strdup(buf);
71 if (cfg->line[cfg->count]) {
72 cfg->count ++;
73 }
74
75 return 0;
76 }
77
parser_length(parser_t * cfg)78 static int parser_length(parser_t *cfg)
79 {
80 if (!cfg) {
81 return 0;
82 }
83
84 return cfg->count;
85 }
86
parser_get(parser_t * cfg,unsigned int index)87 static char *parser_get(parser_t *cfg, unsigned int index)
88 {
89 if ((!cfg) || (index >= cfg->count)) {
90 return NULL;
91 }
92
93 return (cfg->line[index]);
94 }
95
96
parser_read(parser_t * cfg,FILE * fp)97 static int parser_read(parser_t *cfg, FILE *fp)
98 {
99 char line[512];
100 char *head, *tail;
101 int len;
102
103 if ((!fp) || (!cfg)) {
104 return -1;
105 }
106
107 while (fgets(line, 511, fp)) {
108 head = line;
109 while (*head == 0x20 || *head == '\t') {
110 head ++;
111 }
112 if ((*head == '#') || (*head == '\n') ||
113 (*head == '\r') || (*head == '\0')) {
114 continue;
115 }
116 len = strlen(head);
117 tail = head + len - 1;
118 if (tail <= head) {
119 continue;
120 }
121 while ((*tail == '\r') || (*tail == '\n')) {
122 tail --;
123 }
124 *(tail + 1) = '\0';
125
126 parser_add(cfg, head);
127 }
128 return 0;
129 }
130
parser_free(parser_t * cfg)131 static void parser_free(parser_t *cfg)
132 {
133 unsigned int i;
134
135 for (i = 0; i < cfg->count; i ++) {
136 free(cfg->line[i]);
137 }
138 }
139
140
141 /* glue functions */
142
handle_init(int index,const char * file)143 void glue::handle_init(int index, const char *file)
144 {
145 int i = index;
146
147 if (!file) {
148 return;
149 }
150 printf("file:%s\n", file);
151
152 funcs[i].handle = dlopen(file, RTLD_NOW);
153 if (!funcs[i].handle) {
154 printf("can't open:%s, %s\n", file, dlerror());
155 return;
156 }
157
158 funcs[i].init_funcs = (lms_init_t)dlsym(funcs[i].handle,
159 LMS_INIT_FUNC_NAME);
160 if (!funcs[i].init_funcs) {
161 printf("dl error:%s\n", dlerror());
162 return;
163 }
164
165 if (LMS_OK != funcs[i].init_funcs()) {
166 return;
167 }
168
169 funcs[i].version_funcs = (lms_version_t)dlsym(funcs[i].handle,
170 LMS_VERSION_FUNC_NAME);
171 funcs[i].pre_funcs = (lms_pre_t)dlsym(funcs[i].handle,
172 LMS_PRE_FUNC_NAME);
173 funcs[i].retry_funcs = (lms_retry_t)dlsym(funcs[i].handle,
174 LMS_RETRY_FUNC_NAME);
175 funcs[i].post_funcs = (lms_post_t)dlsym(funcs[i].handle,
176 LMS_POST_FUNC_NAME);
177 funcs[i].deinit_funcs = (lms_deinit_t)dlsym(funcs[i].handle,
178 LMS_DEINIT_FUNC_NAME);
179 }
180
mem_init(void)181 int glue::mem_init(void)
182 {
183 int i;
184
185 funcs = new glue_funcs[cnt];
186 if (!funcs) {
187 return LMS_ERROR;
188 }
189
190 for (i = 0;i < cnt; i++) {
191 funcs[i].handle = NULL;
192 funcs[i].init_funcs = NULL;
193 funcs[i].version_funcs = NULL;
194 funcs[i].pre_funcs = NULL;
195 funcs[i].retry_funcs = NULL;
196 funcs[i].post_funcs = NULL;
197 funcs[i].deinit_funcs = NULL;
198 }
199
200 return LMS_OK;
201 }
202
glue()203 glue::glue() : funcs(NULL)
204 {
205 }
206
~glue()207 glue::~glue()
208 {
209 }
210
211
init(void)212 int glue::init(void)
213 {
214 FILE *fp;
215 parser_t cfg;
216 int i;
217
218 parser_init(&cfg);
219
220 fp = fopen(LMS_PLUGIN_CONFIG_FILE, "rb");
221 if ((!fp) || (parser_read(&cfg, fp) != 0)) {
222 cnt = 0;
223 if (fp) {
224 fclose(fp);
225 }
226 return LMS_OK;
227 }
228
229 do {
230 cnt = parser_length(&cfg);
231 if (0 == cnt) {
232 break;
233 }
234 if (mem_init()) {
235 break;
236 }
237 for (i = 0; i < cnt; i++) {
238 handle_init(i, parser_get(&cfg, i));
239 }
240 } while (0);
241
242 fclose(fp);
243 parser_free(&cfg);
244 return LMS_OK;
245 }
246
deinit(void)247 void glue::deinit(void)
248 {
249 int i;
250
251 if (!funcs) {
252 return;
253 }
254
255 for (i = 0; i < cnt; i++) {
256 if (funcs[i].deinit_funcs) {
257 funcs[i].deinit_funcs();
258 }
259 if (funcs[i].handle) {
260 dlclose(funcs[i].handle);
261 }
262 }
263
264 delete[] funcs;
265 }
266
version(unsigned char version)267 void glue::version(unsigned char version)
268 {
269 int i;
270
271 if (!funcs) {
272 return;
273 }
274
275 for (i = 0; i < cnt; i++) {
276 if (!funcs[i].version_funcs) {
277 continue;
278 }
279 funcs[i].version_funcs(version);
280 }
281 }
282
preprocess(unsigned char * buff,int len)283 int glue::preprocess(unsigned char *buff, int len)
284 {
285 int i;
286 int ret = LMS_ACCEPTED;
287
288 if (!funcs) {
289 return ret;
290 }
291
292 for (i = 0; i < cnt; i++) {
293 if (!funcs[i].pre_funcs) {
294 continue;
295 }
296 ret = funcs[i].pre_funcs(buff, len);
297 if (ret != LMS_ACCEPTED) {
298 return ret;
299 }
300 }
301
302 return LMS_ACCEPTED;
303 }
304
retry(unsigned char * buff,int len)305 int glue::retry(unsigned char *buff, int len)
306 {
307 int i;
308 int ret = LMS_ACCEPTED;
309
310 if (!funcs) {
311 return ret;
312 }
313
314 for (i = 0; i < cnt; i++) {
315 if (!funcs[i].retry_funcs) {
316 continue;
317 }
318 ret = funcs[i].retry_funcs(buff, len);
319 if (ret != LMS_ACCEPTED) {
320 return ret;
321 }
322 }
323
324 return LMS_ACCEPTED;
325 }
326
327
postprocess(unsigned char * buff,int len,int status)328 int glue::postprocess(unsigned char *buff, int len, int status)
329 {
330 int i;
331 int ret = LMS_ACCEPTED;
332
333 if (!funcs) {
334 return ret;
335 }
336
337 for (i = 0; i < cnt; i++) {
338 if (!funcs[i].post_funcs) {
339 continue;
340 }
341 ret = funcs[i].post_funcs(buff, len, status);
342 if (ret != LMS_ACCEPTED) {
343 return ret;
344 }
345 }
346
347 return LMS_ACCEPTED;
348 }
349
350