xref: /titanic_41/usr/src/cmd/lms/glue.cpp (revision 1d6979b7d6d2e03997e402187268fb05906caeb6)
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 
55 static void parser_init(parser_t *cfg)
56 {
57 	if (!cfg) {
58 		return;
59 	}
60 
61 	cfg->count = 0;
62 }
63 
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 
78 static int parser_length(parser_t *cfg)
79 {
80 	if (!cfg) {
81 		return 0;
82 	}
83 
84 	return cfg->count;
85 }
86 
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 
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 
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 
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 
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 
203 glue::glue() : funcs(NULL)
204 {
205 }
206 
207 glue::~glue()
208 {
209 }
210 
211 
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 
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 
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 
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 
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 
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