int sipstate_load(const char *filename) { lua_State *L = siplua_L; struct stat sb; int ret; const char *errmsg; if (!filename) filename = sipstate_filename; if (!filename) { siplua_log(L_ERR, "siplua Lua filename is NULL"); return -1; } ret = stat(filename, &sb); if (!ret && sipstate_filename && sb.st_mtime == sipstate_time) return 0; if (luaL_loadfile(L, filename) || lua_pcall(L, 0, 0, 0)) { errmsg = lua_tostring(L, -1); siplua_log(L_ERR, "siplua error loading file %s: %s", filename, errmsg); lua_remove(L, -1); return -1; } else { siplua_log(L_INFO, "siplua file %s successfully reloaded", filename); sipstate_filename = filename; sipstate_time = sb.st_mtime; return 0; } }
static void siplua_moduleFunc_free(const char *func, cmd_export_t *exp_func_struct, action_elem_t *elems, int nargs) { int i; for (i = 0; i < nargs; ++i) { if (!elems[i + 1].u.data) continue; switch (elems[i + 1].type) { case STRING_ST: pkg_free(elems[i + 1].u.data); break; case MODFIXUP_ST: if (!exp_func_struct->free_fixup) { if (warn_missing_free_fixup) siplua_log(L_DBG, "moduleFunction (%s): A fixup function was called without corresponding free_fixup. " "This currently *COULD* creates a memory leak.\n", func); } else exp_func_struct->free_fixup(&elems[i + 1].u.data, i + 1); break; } } }
static int l_sipstate_xlog(lua_State *L) { const char *level; const char *str; int lev = L_ERR; size_t len; int n; n = lua_gettop(L); if (n < 2) str = luaL_checklstring(L, 1, &len); else { level = luaL_checkstring(L, 1); if (strlen(level) < 3) return luaL_error(L, "wrong log level %s", level); switch (level[2]) { case 'A': lev = L_ALERT; break; case 'C': lev = L_CRIT; break; case 'E': lev = L_ERR; break; case 'W': lev = L_WARN; break; case 'N': lev = L_NOTICE; break; case 'I': lev = L_INFO; break; case 'D': lev = L_DBG; break; default: return luaL_error(L, "unknown log level %s", level); } str = luaL_checklstring(L, 2, &len); } siplua_log(lev, "%.*s", (int)len, str); return 0; }
int siplua_meminfo(struct sip_msg *msg) { struct mem_info info; shm_info(&info); siplua_log(L_INFO, "free/%d used/%d real_used/%d max_used/%d min_frag/%d total_frags/%d", info.free, info.used, info.real_used, info.max_used, info.min_frag, info.total_frags); return -1; }
static int l_sipstate_xdbg(lua_State *L) { const char *str; size_t len; str = luaL_checklstring(L, 1, &len); siplua_log(L_DBG, "%.*s", (int)len, str); return 0; }
int sipstate_open(char *allocator) { lua_State *L; const luaL_Reg *lib = siplua_libs; const char *errmsg; if (!strcmp(allocator, "opensips")) L = lua_newstate(siplua_lua_Alloc, NULL); else if (!strcmp(allocator, "malloc")) L = lua_newstate(siplua_lua_Alloc2, NULL); else { siplua_log(L_ERR, "Unknown Lua memory allocator"); return -1; } if (!(siplua_L = L)) { siplua_log(L_ERR, "Failed to open Lua state"); return -1; } else siplua_log(L_DBG, "Lua state opened"); for (; lib->func; lib++) { lua_pushcfunction(L, lib->func); lua_pushstring(L, lib->name); if (lua_pcall(L, 1, 0, 0)) { errmsg = lua_tostring(L, -1); siplua_log(L_ERR, "Error loading library `%s': %s", lib->name, errmsg); lua_remove(L, -1); sipstate_close(); return -1; } } siplua_register_state_cclosures(L); siplua_register_api_cclosures(L); siplua_register_mysql_cclosures(L); siplua_register_memcache_cclosures(L); siplua_register_watch_cclosures(L); siplua_register_datetime_cclosures(L); siplua_msg = sipapi_create_object(L); return 0; }
/* * FIXME: Don't work and returns false IPs. Cheers! * PS: Probably not in network host order. */ static int l_siplua_getDstIp(lua_State *L) { struct sipapi_object *o; struct sockaddr sa; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; o = luaL_checkudata(L, 1, "siplua.api"); sa.sa_family = o->msg->rcv.dst_ip.af; memcpy(sa.sa_data, &o->msg->rcv.dst_ip.u, o->msg->rcv.dst_ip.len); if (getnameinfo(&sa, sizeof(sa), hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) { siplua_log(L_DBG, "could not get numeric hostname"); lua_pushnil(L); } else { siplua_log(L_DBG, "host=%s, serv=%s\n", hbuf, sbuf); lua_pushstring(L, hbuf); } return 1; }
int sipstate_call(struct sip_msg *msg, const char *fnc, const char *mystr) { lua_State *L = siplua_L; int ref; const char *errmsg; int n; if (lua_auto_reload) sipstate_load(NULL); if (!fnc) return -1; lua_getglobal(L, fnc); if (lua_isnil(L, -1)) { siplua_log(L_ERR, "siplua Lua function %s is nil", fnc); lua_remove(L, -1); return -1; } sipapi_set_object(siplua_msg, msg); ref = sipapi_get_object_ref(siplua_msg); lua_rawgeti(L, LUA_REGISTRYINDEX, ref); if (mystr) lua_pushstring(L, mystr); if (lua_pcall(siplua_L, (mystr ? 2 : 1), 1, 0)) { errmsg = lua_tostring(L, -1); siplua_log(L_ERR, "siplua error running function %s: %s", fnc, errmsg); lua_remove(L, -1); n = -1; } else { n = lua_tointeger(L, -1); lua_remove(L, -1); /* siplua_log(L_DBG , "siplua Lua function %s returned %d\n", fnc, n); */ } return n; }
/* I was tired of not seing output when i wrongly used print() instead of xlog() */ static int l_sipstate_print(lua_State *L) { const char *str; size_t len; int top; int i; top = lua_gettop(L); for (i = 0; i < top; ++i) { str = luaL_checklstring(L, i + 1, &len); siplua_log(L_ALERT, "%.*s", (int)len, str); } return 0; }
static int l_siplua_getContact(lua_State *L) { struct sipapi_object *o; struct hdr_field *_p; contact_t *_c; int n = 1; int found_hf_no_star = 0; int found_hf_star = 0; int expires; o = luaL_checkudata(L, 1, "siplua.api"); if (!o->msg->contact) { lua_pushnil(L); return 1; } lua_newtable(L); _p = o->msg->contact; for (_p = o->msg->contact; _p; _p = _p->next) { /* siplua_log(L_DBG, "l_siplua_getContact _p/%p", _p); */ if (_p->type == HDR_CONTACT_T) { if (parse_contact(_p) < 0) { return luaL_error(L, "failed to parse Contact body"); } if (((contact_body_t *)_p->parsed)->star) { lua_pushinteger(L, n++); lua_newtable(L); lua_pushstring(L, "star"); lua_pushboolean(L, 1); lua_rawset(L, -3); lua_pushstring(L, "name"); lua_pushstring(L, "*"); lua_rawset(L, -3); lua_pushstring(L, "uri"); lua_pushstring(L, "*"); lua_rawset(L, -3); lua_rawset(L, -3); found_hf_star = 1; } for (_c = ((contact_body_t *)_p->parsed)->contacts; _c; _c = _c->next) { /* siplua_log(L_DBG, "l_siplua_getContact _c/%p", _c); */ if (!_c) break; lua_pushinteger(L, n++); lua_newtable(L); lua_pushstring(L, "name"); lua_pushlstring(L, _c->name.s, _c->name.len); lua_rawset(L, -3); lua_pushstring(L, "uri"); lua_pushlstring(L, _c->uri.s, _c->uri.len); lua_rawset(L, -3); /* siplua_log(L_DBG, "contact q/%p expires/%p", _c->q, _c->expires); */ if (_c->q) { lua_pushstring(L, "q"); lua_pushlstring(L, _c->q->body.s, _c->q->body.len); lua_pushnumber(L, lua_tonumber(L, -1)); lua_remove(L, -2); lua_rawset(L, -3); } if (_c->expires) { lua_pushstring(L, "expires"); lua_pushlstring(L, _c->expires->body.s, _c->expires->body.len); lua_pushnumber(L, lua_tonumber(L, -1)); lua_remove(L, -2); lua_rawset(L, -3); } lua_rawset(L, -3); found_hf_no_star = 1; } } } if (found_hf_star) { if (found_hf_no_star) { lua_remove(L, -1); lua_pushnil(L); siplua_log(L_DBG, "l_siplua_getContact Found Contact HF with both star and no star."); } else { /* siplua_log(L_DBG, "BEFORE"); */ expires = sipapi_getExpires(o->msg); /* siplua_log(L_DBG, "AFTER"); */ if (expires != 0 && expires != -1) { lua_remove(L, -1); lua_pushnil(L); siplua_log(L_DBG, "l_siplua_getContact Found Contact HF star with unvalid expires."); } } } /* siplua_log(L_DBG, "l_siplua_getContact returned."); */ return 1; }