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