| 207 | } |
| 208 | |
| 209 | static xo_encoder_node_t * |
| 210 | xo_encoder_discover (const char *name) |
| 211 | { |
| 212 | void *dlp = NULL; |
| 213 | char buf[MAXPATHLEN]; |
| 214 | xo_string_node_t *xsp; |
| 215 | xo_encoder_node_t *xep = NULL; |
| 216 | |
| 217 | XO_STRING_LIST_FOREACH(xsp, &xo_encoder_path) { |
| 218 | static const char fmt[] = "%s/%s.enc"; |
| 219 | char *dir = xsp->xs_data; |
| 220 | size_t len = snprintf(buf, sizeof(buf), fmt, dir, name); |
| 221 | |
| 222 | if (len > sizeof(buf)) /* Should not occur */ |
| 223 | continue; |
| 224 | |
| 225 | dlp = dlopen((const char *) buf, RTLD_NOW); |
| 226 | if (dlp) |
| 227 | break; |
| 228 | } |
| 229 | |
| 230 | if (dlp) { |
| 231 | /* |
| 232 | * If the library exists, find the initializer function and |
| 233 | * call it. |
| 234 | */ |
| 235 | xo_encoder_init_func_t func; |
| 236 | |
| 237 | func = (xo_encoder_init_func_t) dlfunc(dlp, XO_ENCODER_INIT_NAME); |
| 238 | if (func) { |
| 239 | xo_encoder_init_args_t xei; |
| 240 | |
| 241 | bzero(&xei, sizeof(xei)); |
| 242 | |
| 243 | xei.xei_version = XO_ENCODER_VERSION; |
| 244 | ssize_t rc = func(&xei); |
| 245 | if (rc == 0 && xei.xei_handler) { |
| 246 | xep = xo_encoder_list_add(name); |
| 247 | if (xep) { |
| 248 | xep->xe_handler = xei.xei_handler; |
| 249 | xep->xe_dlhandle = dlp; |
| 250 | } |
| 251 | } |
| 252 | } |
| 253 | |
| 254 | if (xep == NULL) |
| 255 | dlclose(dlp); |
| 256 | } |
| 257 | |
| 258 | return xep; |
| 259 | } |
| 260 | |
| 261 | void |
| 262 | xo_encoder_register (const char *name, xo_encoder_func_t func) |
no test coverage detected