/** convert cmd exports to current format. * @param ver - module interface versions (0 == ser, 1 == kam). * @param src - null terminated array of cmd exports * (either ser_cmd_export_t or kam_cmd_export_t, depending * on ver). * @param mod - pointer to module exports structure. * @return - pkg_malloc'ed null terminated sr_cmd_export_v31_t array with * the converted cmd exports or 0 on error. */ static sr31_cmd_export_t* sr_cmd_exports_convert(unsigned ver, void* src, void* mod) { int i, n; ser_cmd_export_t* ser_cmd; kam_cmd_export_t* kam_cmd; sr31_cmd_export_t* ret; ser_cmd = 0; kam_cmd = 0; ret = 0; n = 0; /* count the number of elements */ if (ver == 0) { ser_cmd = src; for (; ser_cmd[n].name; n++); } else if (ver == 1) { kam_cmd = src; for (; kam_cmd[n].name; n++); } else goto error; /* unknown interface version */ /* alloc & init new array */ ret = pkg_malloc(sizeof(*ret)*(n+1)); memset(ret, 0, sizeof(*ret)*(n+1)); /* convert/copy */ for (i=0; i < n; i++) { if (ver == 0) { ret[i].name = ser_cmd[i].name; ret[i].function = ser_cmd[i].function; ret[i].param_no = ser_cmd[i].param_no; ret[i].fixup = ser_cmd[i].fixup; ret[i].free_fixup = 0; /* no present in ser <= 2.1 */ ret[i].flags = ser_cmd[i].flags; } else { ret[i].name = kam_cmd[i].name; ret[i].function = kam_cmd[i].function; ret[i].param_no = kam_cmd[i].param_no; ret[i].fixup = kam_cmd[i].fixup; ret[i].free_fixup = kam_cmd[i].free_fixup; ret[i].flags = kam_cmd[i].flags; } /* 3.1+ specific stuff */ ret[i].fixup_flags = 0; ret[i].module_exports = mod; /* fill known free fixups */ if (ret[i].fixup && ret[i].free_fixup == 0) ret[i].free_fixup = get_fixup_free(ret[i].fixup); } return ret; error: return 0; }
/* registers a module, register_f= module register functions * returns <0 on error, 0 on success */ static int register_module(module_exports_t* e, char* path, void* handle) { int ret, i; struct sr_module* mod; char defmod[64]; int n = 0; ret=-1; /* add module to the list */ if ((mod=pkg_malloc(sizeof(struct sr_module)))==0){ LM_ERR("memory allocation failure\n"); ret=E_OUT_OF_MEM; goto error; } memset(mod, 0, sizeof(struct sr_module)); mod->path=path; mod->handle=handle; /* copy and convert fields */ mod->exports.name = e->name; mod->exports.dlflags = e->dlflags; if(e->cmds) { for (n=0; e->cmds[n].name; n++); } mod->exports.cmds = pkg_malloc(sizeof(ksr_cmd_export_t)*(n+1)); memset(mod->exports.cmds, 0, sizeof(ksr_cmd_export_t)*(n+1)); for (i=0; i < n; i++) { mod->exports.cmds[i].name = e->cmds[i].name; mod->exports.cmds[i].function = e->cmds[i].function; mod->exports.cmds[i].param_no = e->cmds[i].param_no; mod->exports.cmds[i].fixup = e->cmds[i].fixup; mod->exports.cmds[i].free_fixup = e->cmds[i].free_fixup; mod->exports.cmds[i].flags = e->cmds[i].flags; mod->exports.cmds[i].fixup_flags = 0; mod->exports.cmds[i].module_exports = mod; /* fill known free fixups */ if (mod->exports.cmds[i].fixup && mod->exports.cmds[i].free_fixup == 0) { mod->exports.cmds[i].free_fixup = get_fixup_free(mod->exports.cmds[i].fixup); } } mod->exports.params = e->params; mod->exports.rpc_methods = e->rpc_methods; mod->exports.pv_items = e->pv_items; mod->exports.response_f = e->response_f; mod->exports.init_mod_f = e->init_mod_f; mod->exports.init_child_f = e->init_child_f; mod->exports.destroy_mod_f = e->destroy_mod_f; if (mod->exports.pv_items) { /* register module pseudo-variables for kamailio modules */ LM_DBG("register PV from: %s\n", mod->exports.name); if (register_pvars_mod(mod->exports.name, mod->exports.pv_items)!=0) { LM_ERR("failed to register pseudo-variables for module %s (%s)\n", mod->exports.name, path); ret = E_UNSPEC; goto error; } } if (mod->exports.rpc_methods){ /* register rpcs for ser modules */ i=rpc_register_array(mod->exports.rpc_methods); if (i<0){ LM_ERR("failed to register RPCs for module %s (%s)\n", mod->exports.name, path); ret = E_UNSPEC; goto error; }else if (i>0){ LM_ERR("%d duplicate RPCs name detected while registering RPCs" " declared in module %s (%s)\n", i, mod->exports.name, path); ret = E_UNSPEC; goto error; } /* i==0 => success */ } /* add cfg define for each module: MOD_modulename */ if(strlen(mod->exports.name)>=60) { LM_ERR("too long module name: %s\n", mod->exports.name); goto error; } strcpy(defmod, "MOD_"); strcat(defmod, mod->exports.name); pp_define_set_type(0); if(pp_define(strlen(defmod), defmod)<0) { LM_ERR("unable to set cfg define for module: %s\n", mod->exports.name); goto error; } /* link module in the list */ mod->next=modules; modules=mod; return 0; error: if (mod) pkg_free(mod); return ret; }