const char* luaC_pushdstring(lua_State* L, int idx, int lem) { size_t len; lua_checkstack(L, 4); int t = lua_type(L, idx); lua_pushvalue(L, idx); //|XX| lua_pushstring(L, "["); lua_pushstring(L, lua_typename(L, t)); lua_pushstring(L, "]"); lua_concat(L, 3); //|TS|XX| lua_insert(L, -2); //|XX|TS| const char* s = lua_tolstring(L, -1, &len); if (s == NULL) { if (t == LUA_TBOOLEAN) { if (lua_toboolean(L, -1)) lua_pushstring(L, "<true>"); else lua_pushstring(L, "<false>"); //|VS|XX|TS| lua_remove(L, -2); //|VS|TS| } else { lua_pushstring(L, ""); //|""|XX|TS| lua_remove(L, -2); //|""|TS| } } else if (t == LUA_TSTRING) { //|VS|TS| lua_pushstring(L, "\""); //|"|VS|TS| lua_pushstring(L, "\""); //|"|"|VS|TS| lua_insert(L, -3); //|"|VS|"|TS| lua_concat(L, 3); //|VS|TS| } lua_concat(L, 2); //|RS| s = lua_tolstring(L, -1, &len); if ((int)len >= lem) { lua_pushlstring(L, s, lem-1); //|RS|RS| lua_remove(L, -2); //|RS| lua_pushstring(L, ">"); //|>|RS| lua_concat(L, 2); //|RS| } return lua_tostring(L, -1); }
static int luazmq_skt_recvx (lua_State *L) { zsocket *skt = luazmq_getsocket(L); zmq_msg_t msg; int flags = luaL_optint(L,2,0); int i = 0; lua_settop(L, 1); while(1){ int ret = zmq_msg_init(&msg); if(-1 == ret){ ret = luazmq_fail(L, skt); {int j;for(j = ret; j >= 0; --j){ lua_insert(L, 1); }} return ret + i; } ret = zmq_msg_recv(&msg, skt->skt, flags); if(-1 == ret){ zmq_msg_close(&msg); ret = luazmq_fail(L, skt); {int j;for(j = ret; j >= 0; --j){ lua_insert(L, 1); }} return ret + i; } i++; lua_checkstack(L, i); lua_pushlstring(L, zmq_msg_data(&msg), zmq_msg_size(&msg)); ret = zmq_msg_more(&msg); zmq_msg_close(&msg); if(!ret) break; } return i; }
bool CLuaRules::AllowFeatureBuildStep(const CUnit* builder, const CFeature* feature, float part) { if (!haveAllowFeatureBuildStep) { return true; // the call is not defined } LUA_CALL_IN_CHECK(L); lua_checkstack(L, 7); static const LuaHashString cmdStr("AllowFeatureBuildStep"); if (!cmdStr.GetGlobalFunc(L)) { return true; // the call is not defined } lua_pushnumber(L, builder->id); lua_pushnumber(L, builder->team); lua_pushnumber(L, feature->id); lua_pushnumber(L, feature->def->id); lua_pushnumber(L, part); // call the function if (!RunCallIn(cmdStr, 5, 1)) { return true; } // get the results if (!lua_isboolean(L, -1)) { logOutput.Print("%s() bad return value\n", cmdStr.GetString().c_str()); lua_pop(L, 1); return true; } const bool retval = !!lua_toboolean(L, -1); lua_pop(L, 1); return retval; }
bool CLuaRules::MoveCtrlNotify(const CUnit* unit, int data) { if (!haveMoveCtrlNotify) { return false; // the call is not defined } LUA_CALL_IN_CHECK(L); lua_checkstack(L, 6); static const LuaHashString cmdStr("MoveCtrlNotify"); if (!cmdStr.GetGlobalFunc(L)) { return false; // the call is not defined } // push the unit info lua_pushnumber(L, unit->id); lua_pushnumber(L, unit->unitDef->id); lua_pushnumber(L, unit->team); lua_pushnumber(L, data); // call the function if (!RunCallIn(cmdStr, 4, 1)) { return false; } // get the results if (!lua_isboolean(L, -1)) { logOutput.Print("%s() bad return value\n", cmdStr.GetString().c_str()); lua_pop(L, 1); return false; } const bool retval = !!lua_toboolean(L, -1); lua_pop(L, 1); return retval; }
bool CLuaRules::AllowFeatureCreation(const FeatureDef* featureDef, int teamID, const float3& pos) { if (!haveAllowFeatureCreation) { return true; // the call is not defined } LUA_CALL_IN_CHECK(L); lua_checkstack(L, 7); static const LuaHashString cmdStr("AllowFeatureCreation"); if (!cmdStr.GetGlobalFunc(L)) { return true; // the call is not defined } lua_pushnumber(L, featureDef->id); lua_pushnumber(L, teamID); lua_pushnumber(L, pos.x); lua_pushnumber(L, pos.y); lua_pushnumber(L, pos.z); // call the function if (!RunCallIn(cmdStr, 5, 1)) { return true; } // get the results if (!lua_isboolean(L, -1)) { logOutput.Print("%s() bad return value\n", cmdStr.GetString().c_str()); lua_pop(L, 1); return true; } const bool retval = !!lua_toboolean(L, -1); lua_pop(L, 1); return retval; }
static int path_append_helper(lua_State *L, int stackStart, int stackTop) { int concatBottom = stackTop; int newTop; int i; for (i = stackStart; i <= stackTop; ++i) { const char *path = luaL_checkstring(L, i); if (path[0] > 0) { if (*path == '/' || *path == '\\' || (path[0] && path[1] == ':')) concatBottom = lua_gettop(L); lua_checkstack(L, 2); lua_pushvalue(L, i); lua_pushliteral(L, "/"); } } newTop = lua_gettop(L); if (newTop - concatBottom > 0) { lua_remove(L, lua_gettop(L)); --newTop; } lua_concat(L, newTop - concatBottom); return 1; }
void scriptapi_export(lua_State *L, Server *server) { realitycheck(L); assert(lua_checkstack(L, 20)); verbosestream<<"scriptapi_export()"<<std::endl; StackUnroller stack_unroller(L); // Store server as light userdata in registry lua_pushlightuserdata(L, server); lua_setfield(L, LUA_REGISTRYINDEX, "minetest_server"); // Register global functions in table minetest lua_newtable(L); luaL_register(L, NULL, minetest_f); lua_setglobal(L, "minetest"); // Get the main minetest table lua_getglobal(L, "minetest"); // Add tables to minetest lua_newtable(L); lua_setfield(L, -2, "object_refs"); lua_newtable(L); lua_setfield(L, -2, "luaentities"); // Register wrappers LuaItemStack::Register(L); InvRef::Register(L); NodeMetaRef::Register(L); NodeTimerRef::Register(L); ObjectRef::Register(L); EnvRef::Register(L); LuaPseudoRandom::Register(L); LuaPerlinNoise::Register(L); LuaPerlinNoiseMap::Register(L); }
bool CLuaRules::DrawShield(const CUnit* unit, const CWeapon* weapon) { if (!haveDrawShield) return false; LUA_CALL_IN_CHECK(L, false); lua_checkstack(L, 5); static const LuaHashString cmdStr(__FUNCTION__); if (!cmdStr.GetRegistryFunc(L)) return false; const bool oldDrawState = LuaOpenGL::IsDrawingEnabled(L); LuaOpenGL::SetDrawingEnabled(L, true); lua_pushnumber(L, unit->id); lua_pushnumber(L, weapon->weaponNum); lua_pushnumber(L, game->GetDrawMode()); const bool success = RunCallIn(cmdStr, 3, 1); LuaOpenGL::SetDrawingEnabled(L, oldDrawState); if (!success) return false; if (!lua_isboolean(L, -1)) { LOG_L(L_WARNING, "%s() bad return-type (bool expected, got %s)", __FUNCTION__, lua_typename(L, lua_type(L, -1))); lua_pop(L, 1); return false; } const bool retval = !!lua_toboolean(L, -1); lua_pop(L, 1); return retval; }
static void PushProfilePermissions(lua_State * L, const uint16_t &iProfile) { ProfileItem *Prof = ProfileMan->ProfilesTable[iProfile]; lua_checkstack(L, 3); // we need 3 (1 table, 2 id, 3 value) empty slots in stack, check it to be sure lua_newtable(L); int t = lua_gettop(L); lua_pushliteral(L, "bIsOP"); Prof->bPermissions[ProfileManager::HASKEYICON] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bNoDefloodGetNickList"); Prof->bPermissions[ProfileManager::NODEFLOODGETNICKLIST] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bNoDefloodNMyINFO"); Prof->bPermissions[ProfileManager::NODEFLOODMYINFO] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bNoDefloodSearch"); Prof->bPermissions[ProfileManager::NODEFLOODSEARCH] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bNoDefloodPM"); Prof->bPermissions[ProfileManager::NODEFLOODPM] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bNoDefloodMainChat"); Prof->bPermissions[ProfileManager::NODEFLOODMAINCHAT] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bMassMsg"); Prof->bPermissions[ProfileManager::MASSMSG] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bTopic"); Prof->bPermissions[ProfileManager::TOPIC] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bTempBan"); Prof->bPermissions[ProfileManager::TEMP_BAN] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bTempUnban"); Prof->bPermissions[ProfileManager::TEMP_UNBAN] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bRefreshTxt"); Prof->bPermissions[ProfileManager::REFRESHTXT] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bNoTagCheck"); Prof->bPermissions[ProfileManager::NOTAGCHECK] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bDelRegUser"); Prof->bPermissions[ProfileManager::DELREGUSER] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bAddRegUser"); Prof->bPermissions[ProfileManager::ADDREGUSER] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bNoChatLimits"); Prof->bPermissions[ProfileManager::NOCHATLIMITS] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bNoMaxHubCheck"); Prof->bPermissions[ProfileManager::NOMAXHUBCHECK] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bNoSlotHubRatio"); Prof->bPermissions[ProfileManager::NOSLOTHUBRATIO] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bNoSlotCheck"); Prof->bPermissions[ProfileManager::NOSLOTCHECK] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bNoShareLimit"); Prof->bPermissions[ProfileManager::NOSHARELIMIT] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bClrPermBan"); Prof->bPermissions[ProfileManager::CLRPERMBAN] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bClrTempBan"); Prof->bPermissions[ProfileManager::CLRTEMPBAN] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bGetInfo"); Prof->bPermissions[ProfileManager::GETINFO] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bGetBans"); Prof->bPermissions[ProfileManager::GETBANLIST] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bRestartScripts"); Prof->bPermissions[ProfileManager::RSTSCRIPTS] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bRestartHub"); Prof->bPermissions[ProfileManager::RSTHUB] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bTempOP"); Prof->bPermissions[ProfileManager::TEMPOP] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bGag"); Prof->bPermissions[ProfileManager::GAG] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bRedirect"); Prof->bPermissions[ProfileManager::REDIRECT] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bBan"); Prof->bPermissions[ProfileManager::BAN] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bUnban"); Prof->bPermissions[ProfileManager::UNBAN] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bKick"); Prof->bPermissions[ProfileManager::KICK] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bDrop"); Prof->bPermissions[ProfileManager::DROP] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bEnterFullHub"); Prof->bPermissions[ProfileManager::ENTERFULLHUB] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bEnterIfIPBan"); Prof->bPermissions[ProfileManager::ENTERIFIPBAN] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bAllowedOPChat"); Prof->bPermissions[ProfileManager::ALLOWEDOPCHAT] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bSendFullMyinfos"); Prof->bPermissions[ProfileManager::SENDFULLMYINFOS] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bSendAllUserIP"); Prof->bPermissions[ProfileManager::SENDALLUSERIP] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bRangeBan"); Prof->bPermissions[ProfileManager::RANGE_BAN] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bRangeUnban"); Prof->bPermissions[ProfileManager::RANGE_UNBAN] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bRangeTempBan"); Prof->bPermissions[ProfileManager::RANGE_TBAN] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bRangeTempUnban"); Prof->bPermissions[ProfileManager::RANGE_TUNBAN] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bGetRangeBans"); Prof->bPermissions[ProfileManager::GET_RANGE_BANS] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bClearRangePermBans"); Prof->bPermissions[ProfileManager::CLR_RANGE_BANS] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bClearRangeTempBans"); Prof->bPermissions[ProfileManager::CLR_RANGE_TBANS] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bNoIpCheck"); Prof->bPermissions[ProfileManager::NOIPCHECK] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bClose"); Prof->bPermissions[ProfileManager::CLOSE] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bNoSearchLimits"); Prof->bPermissions[ProfileManager::NOSEARCHLIMITS] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bNoDefloodCTM"); Prof->bPermissions[ProfileManager::NODEFLOODCTM] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bNoDefloodRCTM"); Prof->bPermissions[ProfileManager::NODEFLOODRCTM] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bNoDefloodSR"); Prof->bPermissions[ProfileManager::NODEFLOODSR] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bNoDefloodRecv"); Prof->bPermissions[ProfileManager::NODEFLOODRECV] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bNoChatInterval"); Prof->bPermissions[ProfileManager::NOCHATINTERVAL] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bNoPMInterval"); Prof->bPermissions[ProfileManager::NOPMINTERVAL] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bNoSearchInterval"); Prof->bPermissions[ProfileManager::NOSEARCHINTERVAL] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bNoMaxUsersSameIP"); Prof->bPermissions[ProfileManager::NOUSRSAMEIP] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); lua_pushliteral(L, "bNoReConnTime"); Prof->bPermissions[ProfileManager::NORECONNTIME] == true ? lua_pushboolean(L, 1) : lua_pushnil(L); lua_rawset(L, t); }
bool luaW_toconfig(lua_State *L, int index, config &cfg) { if (!lua_checkstack(L, LUA_MINSTACK)) return false; // Get the absolute index of the table. index = lua_absindex(L, index); int initial_top = lua_gettop(L); switch (lua_type(L, index)) { case LUA_TTABLE: break; case LUA_TUSERDATA: { if (vconfig * ptr = static_cast<vconfig *> (luaL_testudata(L, index, vconfigKey))) { cfg = ptr->get_parsed_config(); return true; } else { return false; } } case LUA_TNONE: case LUA_TNIL: return true; default: return false; } // First convert the children (integer indices). for (int i = 1, i_end = lua_rawlen(L, index); i <= i_end; ++i) { lua_rawgeti(L, index, i); if (!lua_istable(L, -1)) return_misformed(); lua_rawgeti(L, -1, 1); char const *m = lua_tostring(L, -1); if (!m) return_misformed(); lua_rawgeti(L, -2, 2); if (!luaW_toconfig(L, -1, cfg.add_child(m))) return_misformed(); lua_pop(L, 3); } // Then convert the attributes (string indices). for (lua_pushnil(L); lua_next(L, index); lua_pop(L, 1)) { if (lua_isnumber(L, -2)) continue; if (!lua_isstring(L, -2)) return_misformed(); config::attribute_value &v = cfg[lua_tostring(L, -2)]; if (lua_istable(L, -1)) { int subindex = lua_absindex(L, -1); std::ostringstream str; for (int i = 1, i_end = lua_rawlen(L, subindex); i <= i_end; ++i, lua_pop(L, 1)) { lua_rawgeti(L, -1, i); config::attribute_value item; if (!luaW_toscalar(L, -1, item)) return_misformed(); if (i > 1) str << ','; str << item; } // If there are any string keys, it's misformed for (lua_pushnil(L); lua_next(L, subindex); lua_pop(L, 1)) { if (!lua_isnumber(L, -2)) return_misformed(); } v = str.str(); } else if (!luaW_toscalar(L, -1, v)) return_misformed(); } lua_settop(L, initial_top); return true; }
JNIEXPORT jint JNICALL Java_m_lua_Lua_checkStack (JNIEnv* env, jobject thiz, jlong nativeObj, jint sz) { pushJNIEnv(env, nativeObj); return (jint) lua_checkstack((lua_State*) nativeObj, (int) sz); }
int serialize_data(lua_sandbox* lsb, int index, output_data* output) { output->m_pos = 0; switch (lua_type(lsb->m_lua, index)) { case LUA_TNUMBER: if (dynamic_snprintf(output, "%0.9g", lua_tonumber(lsb->m_lua, index))) { return 1; } break; case LUA_TSTRING: // The stack is cleaned up on failure by preserve_global_data // but for clarity it is incrementally cleaned up anyway. lua_checkstack(lsb->m_lua, 4); lua_getglobal(lsb->m_lua, "string"); if (!lua_istable(lsb->m_lua, -1)) { snprintf(lsb->m_error_message, ERROR_SIZE, "serialize_data cannot access the string table"); lua_pop(lsb->m_lua, 1); // Remove bogus string table. return 1; } lua_getfield(lsb->m_lua, -1, "format"); if (!lua_isfunction(lsb->m_lua, -1)) { snprintf(lsb->m_error_message, ERROR_SIZE, "serialize_data cannot access the string format function"); lua_pop(lsb->m_lua, 2); // Remove the bogus format function and // string table. return 1; } lua_pushstring(lsb->m_lua, "%q"); lua_pushvalue(lsb->m_lua, index - 3); if (lua_pcall(lsb->m_lua, 2, 1, 0) == 0) { if (dynamic_snprintf(output, "%s", lua_tostring(lsb->m_lua, -1))) { lua_pop(lsb->m_lua, 1); // Remove the string table. return 1; } } else { snprintf(lsb->m_error_message, ERROR_SIZE, "serialize_data '%s'", lua_tostring(lsb->m_lua, -1)); lua_pop(lsb->m_lua, 2); // Remove the error message and the string // table. return 1; } lua_pop(lsb->m_lua, 2); // Remove the pcall result and the string table. break; case LUA_TNIL: if (dynamic_snprintf(output, "nil")) { return 1; } break; case LUA_TBOOLEAN: if (dynamic_snprintf(output, "%s", lua_toboolean(lsb->m_lua, index) ? "true" : "false")) { return 1; } break; default: snprintf(lsb->m_error_message, ERROR_SIZE, "serialize_data cannot preserve type '%s'", lua_typename(lsb->m_lua, lua_type(lsb->m_lua, index))); return 1; } return 0; }
bool CLuaHandle::MapDrawCmd(int playerID, int type, const float3* pos0, const float3* pos1, const string* label) { if (!CheckModUICtrl()) { return false; } LUA_CALL_IN_CHECK(L); lua_checkstack(L, 9); static const LuaHashString cmdStr("MapDrawCmd"); if (!PushUnsyncedCallIn(cmdStr)) { return false; // the call is not defined } int args; lua_pushnumber(L, playerID); if (type == CInMapDraw::NET_POINT) { HSTR_PUSH(L, "point"); lua_pushnumber(L, pos0->x); lua_pushnumber(L, pos0->y); lua_pushnumber(L, pos0->z); lua_pushstring(L, label->c_str()); args = 6; } else if (type == CInMapDraw::NET_LINE) { HSTR_PUSH(L, "line"); lua_pushnumber(L, pos0->x); lua_pushnumber(L, pos0->y); lua_pushnumber(L, pos0->z); lua_pushnumber(L, pos1->x); lua_pushnumber(L, pos1->y); lua_pushnumber(L, pos1->z); args = 8; } else if (type == CInMapDraw::NET_ERASE) { HSTR_PUSH(L, "erase"); lua_pushnumber(L, pos0->x); lua_pushnumber(L, pos0->y); lua_pushnumber(L, pos0->z); lua_pushnumber(L, 100.0f); // radius args = 6; } else { logOutput.Print("Unknown MapDrawCmd() type"); lua_pop(L, 2); // pop the function and playerID return false; } // call the routine if (!RunCallInUnsynced(cmdStr, args, 1)) { return false; } // take the event? if (!lua_isboolean(L, -1)) { lua_pop(L, 1); return false; } const bool retval = lua_toboolean(L, -1); lua_pop(L, 1); return retval; }
int writeObjectRaw() { lua_State *L = m_L; uint8_t iType; // Save the index to the cache lua_pushvalue(L, 2); lua_pushnumber(L, (lua_Number)(m_iNextIndex++)); lua_settable(L, 1); // Lookup the object in the permanents table lua_pushvalue(L, 2); lua_gettable(L, luaT_upvalueindex(1)); if(lua_type(L, -1) != LUA_TNIL) { // Object is in the permanents table. uint8_t iType = PERSIST_TPERMANENT; writeByteStream(&iType, 1); // Replace self's environment with self (for call to writeStackObject) lua_pushvalue(L, luaT_upvalueindex(2)); lua_replace(L, 1); // Write the key corresponding to the permanent object writeStackObject(-1); } else { // Object is not in the permanents table. lua_pop(L, 1); switch(lua_type(L, 2)) { // LUA_TNIL handled in writeStackObject // LUA_TBOOLEAN handled in writeStackObject // LUA_TNUMBER handled in writeStackObject case LUA_TSTRING: { iType = LUA_TSTRING; writeByteStream(&iType, 1); // Strings are simple: length and then bytes (not null terminated) size_t iLength; const char *sString = lua_tolstring(L, 2, &iLength); writeVUInt(iLength); writeByteStream(reinterpret_cast<const uint8_t*>(sString), iLength); break; } case LUA_TTABLE: { // Replace self's environment with self (for calls to writeStackObject) lua_pushvalue(L, luaT_upvalueindex(2)); lua_replace(L, 1); // Save env and insert prior to table lua_getfenv(L, 1); lua_insert(L, 2); int iTable = 3; table_reentry: // Handle the metatable if(lua_getmetatable(L, iTable)) { iType = PERSIST_TTABLE_WITH_META; writeByteStream(&iType, 1); writeStackObject(-1); lua_pop(L, 1); } else { iType = LUA_TTABLE; writeByteStream(&iType, 1); } // Write the children as key, value pairs lua_pushnil(L); while(lua_next(L, iTable)) { writeStackObject(-2); // The naive thing to do now would be writeStackObject(-1) // but this can easily lead to Lua's C call stack limit // being hit. To reduce the likelyhood of this happening, // we check to see if about to write another table. if(lua_type(L, -1) == LUA_TTABLE) { lua_pushvalue(L, -1); lua_rawget(L, 2); lua_pushvalue(L, -2); lua_gettable(L, luaT_upvalueindex(1)); if(lua_isnil(L, -1) && lua_isnil(L, -2)) { lua_pop(L, 2); lua_checkstack(L, 10); iTable += 2; lua_pushvalue(L, iTable); lua_pushnumber(L, (lua_Number)(m_iNextIndex++)); lua_settable(L, 2); goto table_reentry; table_resume: iTable -= 2; } else { lua_pop(L, 2); writeStackObject(-1); } } else writeStackObject(-1); lua_pop(L, 1); } // Write a nil to mark the end of the children (as nil is the // only value which cannot be used as a key in a table). iType = LUA_TNIL; writeByteStream(&iType, 1); if(iTable != 3) goto table_resume; break; } case LUA_TFUNCTION: if(lua_iscfunction(L, 2)) { setErrorObject(2); setError("Cannot persist C functions"); } else { iType = LUA_TFUNCTION; writeByteStream(&iType, 1); // Replace self's environment with self (for calls to writeStackObject) lua_pushvalue(L, luaT_upvalueindex(2)); lua_replace(L, 1); // Write the prototype (the part of a function which is common across // multiple closures - see LClosure / Proto in Lua's lobject.h). lua_Debug proto_info; lua_pushvalue(L, 2); lua_getinfo(L, ">Su", &proto_info); writePrototype(&proto_info, 2); // Write the values of the upvalues // If available, also write the upvalue IDs (so that in // the future, we could hypothetically rejoin shared // upvalues). An ID is just an opaque sequence of bytes. writeVUInt(proto_info.nups); #if LUA_VERSION_NUM >= 502 writeVUInt(sizeof(void*)); #else writeVUInt(0); #endif for(int i = 1; i <= proto_info.nups; ++i) { lua_getupvalue(L, 2, i); writeStackObject(-1); #if LUA_VERSION_NUM >= 502 void *pUpvalueID = lua_upvalueid(L, 2, i); writeByteStream((uint8_t*)&pUpvalueID, sizeof(void*)); #endif } // Write the environment table lua_getfenv(L, 2); writeStackObject(-1); lua_pop(L, 1); } break; case LUA_TUSERDATA: if(!_checkThatUserdataCanBeDepersisted(2)) break; // Replace self's environment with self (for calls to writeStackObject) lua_pushvalue(L, luaT_upvalueindex(2)); lua_replace(L, 1); // Write type, metatable, and then environment iType = LUA_TUSERDATA; writeByteStream(&iType, 1); writeStackObject(-1); lua_getfenv(L, 2); writeStackObject(-1); lua_pop(L, 1); // Write the raw data if(lua_type(L, -1) == LUA_TTABLE) { lua_getfield(L, -1, "__persist"); if(lua_isnil(L, -1)) lua_pop(L, 1); else { lua_pushvalue(L, 2); lua_pushvalue(L, luaT_upvalueindex(2)); lua_call(L, 2, 0); } } writeVUInt((uint64_t)0x42); // sync marker break; default: setError(lua_pushfstring(L, "Cannot persist %s values", luaL_typename(L, 2))); break; } } lua_pushnumber(L, 0); return 1; }
int rx_gsub (lua_State *L, int is_function, int is_wide) { size_t len, flen; TFarRegex* fr; FARAPIREGEXPCONTROL RegExpControl = GetRegExpControl(L); const wchar_t *s, *f; int max_rep_capture, ftype, n, matches, reps; luaL_Buffer out; struct RegExpSearch data; memset(&data, 0, sizeof(data)); if (is_function) { if (is_wide) data.Text = check_utf16_string(L, 1, &len); else data.Text = check_utf8_string(L, 1, &len); fr = push_far_regex(L, RegExpControl, check_regex_pattern(L, 2, 5)); lua_replace(L, 2); } else { fr = CheckFarRegex(L, 1); if (is_wide) data.Text = check_utf16_string(L, 2, &len); else data.Text = check_utf8_string(L, 2, &len); } data.Length = len; s = data.Text; f = NULL; flen = 0; max_rep_capture = 0; ftype = lua_type(L, 3); if (ftype == LUA_TSTRING) { const wchar_t* p; f = check_utf8_string(L, 3, &flen); for (p=f; *p; p++) { if (*p == L'%') { int n, ch; if ((ch = *++p) == 0) break; n = (ch >= L'0' && ch <= L'9') ? ch - L'0' : (ch >= L'A' && ch <= L'Z') ? ch - L'A' + 10 : (ch >= L'a' && ch <= L'z') ? ch - L'a' + 10 : -1; if (max_rep_capture < n) max_rep_capture = n; } } } else if (ftype != LUA_TTABLE && ftype != LUA_TFUNCTION) luaL_argerror(L, 3, "string or table or function"); if (lua_isnoneornil(L, 4)) n = -1; else { n = (int)luaL_checkinteger(L, 4); if (n < 0) n = 0; } lua_settop(L, 3); data.Count = RegExpControl(fr->hnd, RECTL_BRACKETSCOUNT, 0, 0); if ( (ftype == LUA_TSTRING) && !(max_rep_capture == 1 && data.Count == 1) && (data.Count <= max_rep_capture)) luaL_error(L, "replace string: invalid capture index"); data.Match = (struct RegExpMatch*)lua_newuserdata(L, data.Count*sizeof(struct RegExpMatch)); data.Match[0].end = -1; matches = reps = 0; luaL_buffinit(L, &out); while (n < 0 || reps < n) { int rep; intptr_t from, to; intptr_t prev_end = data.Match[0].end; if (!RegExpControl(fr->hnd, RECTL_SEARCHEX, 0, &data)) break; if (data.Match[0].end == prev_end) { if (data.Position < data.Length) { luaL_addlstring(&out, (const char*)(s+data.Position), sizeof(wchar_t)); data.Position++; continue; } break; } matches++; rep = 0; from = data.Match[0].start; to = data.Match[0].end; luaL_addlstring(&out, (const char*)(s + data.Position), (from - data.Position) * sizeof(wchar_t)); if (ftype == LUA_TSTRING) { size_t i, start = 0; for (i=0; i<flen; i++) { if (f[i] == L'%') { if (++i < flen) { int ch = f[i]; int n = (ch >= L'0' && ch <= L'9') ? ch - L'0' : (ch >= L'A' && ch <= L'Z') ? ch - L'A' + 10 : (ch >= L'a' && ch <= L'z') ? ch - L'a' + 10 : -1; if (n >= 0) { if (n==1 && data.Count==1) n = 0; luaL_addlstring(&out, (const char*)(f+start), (i-1-start)*sizeof(wchar_t)); if (data.Match[n].start >= 0) { luaL_addlstring(&out, (const char*)(s + data.Match[n].start), (data.Match[n].end - data.Match[n].start) * sizeof(wchar_t)); } } else { // delete the percent sign luaL_addlstring(&out, (const char*)(f+start), (i-1-start)*sizeof(wchar_t)); luaL_addlstring(&out, (const char*)(f+i), sizeof(wchar_t)); } start = i+1; } else { luaL_addlstring(&out, (const char*)(f+start), (i-1-start)*sizeof(wchar_t)); start = flen; break; } } } rep++; luaL_addlstring(&out, (const char*)(f+start), (flen-start)*sizeof(wchar_t)); } else if (ftype == LUA_TTABLE) { int n = data.Count==1 ? 0:1; if (data.Match[n].start >= 0) { if (is_wide) push_utf16_string(L, s + data.Match[n].start, (data.Match[n].end - data.Match[n].start)); else push_utf8_string(L, s + data.Match[n].start, (data.Match[n].end - data.Match[n].start)); lua_gettable(L, 3); if (lua_isstring(L, -1)) { if (!is_wide) { size_t len; const wchar_t* ws = check_utf8_string(L, -1, &len); lua_pushlstring(L, (const char*)ws, len*sizeof(wchar_t)); lua_remove(L, -2); } luaL_addvalue(&out); rep++; } else if (lua_toboolean(L,-1)) luaL_error(L, "invalid replacement type"); else lua_pop(L, 1); } } else { // if (ftype == LUA_TFUNCTION) intptr_t i, skip = data.Count==1 ? 0:1; lua_checkstack(L, (int)(data.Count+1-skip)); lua_pushvalue(L, 3); for (i=skip; i<data.Count; i++) { if (data.Match[i].start >= 0) { if (is_wide) push_utf16_string(L, s + data.Match[i].start, (data.Match[i].end - data.Match[i].start)); else push_utf8_string(L, s + data.Match[i].start, (data.Match[i].end - data.Match[i].start)); } else lua_pushboolean(L, 0); } if (lua_pcall(L, (int)(data.Count-skip), 1, 0) == 0) { if (lua_isstring(L, -1)) { if (!is_wide) { size_t len; const wchar_t* ws = check_utf8_string(L, -1, &len); lua_pushlstring(L, (const char*)ws, len*sizeof(wchar_t)); lua_remove(L, -2); } luaL_addvalue(&out); rep++; } else if (lua_toboolean(L,-1)) luaL_error(L, "invalid return type"); else lua_pop(L, 1); } else luaL_error(L, lua_tostring(L, -1)); } if (rep) reps++; else luaL_addlstring(&out, (const char*)(s+from), (to-from)*sizeof(wchar_t)); if (data.Position < to) data.Position = to; else if (data.Position < data.Length) { luaL_addlstring(&out, (const char*)(s + data.Position), sizeof(wchar_t)); data.Position++; } else break; } luaL_addlstring(&out, (const char*)(s + data.Position), (data.Length - data.Position) * sizeof(wchar_t)); luaL_pushresult(&out); if (!is_wide) { push_utf8_string(L, (const wchar_t*)lua_tostring(L, -1), lua_objlen(L, -1) / sizeof(wchar_t)); } lua_pushinteger(L, matches); lua_pushinteger(L, reps); return 3; }
/* Choose whether to do a regular or special persistence based on an object's * metatable. "default" is whether the object, if it doesn't have a __persist * entry, is literally persistable or not. * Pushes the unpersist closure and returns true if special persistence is * used. */ static int persistspecialobject(PersistInfo *pi, int defaction) { /* perms reftbl ... obj */ lua_checkstack(pi->L, 4); /* Check whether we should persist literally, or via the __persist * metafunction */ if(!lua_getmetatable(pi->L, -1)) { if(defaction) { { int zero = 0; pi->writer(pi->L, &zero, sizeof(int), pi->ud); } return 0; } else { lua_pushstring(pi->L, "Type not literally persistable by default"); lua_error(pi->L); } } /* perms reftbl sptbl ... obj mt */ lua_pushstring(pi->L, "__persist"); /* perms reftbl sptbl ... obj mt "__persist" */ lua_rawget(pi->L, -2); /* perms reftbl sptbl ... obj mt __persist? */ if(lua_isnil(pi->L, -1)) { /* perms reftbl sptbl ... obj mt nil */ lua_pop(pi->L, 2); /* perms reftbl sptbl ... obj */ if(defaction) { { int zero = 0; pi->writer(pi->L, &zero, sizeof(int), pi->ud); } return 0; } else { lua_pushstring(pi->L, "Type not literally persistable by default"); lua_error(pi->L); return 0; /* not reached */ } } else if(lua_isboolean(pi->L, -1)) { /* perms reftbl sptbl ... obj mt bool */ if(lua_toboolean(pi->L, -1)) { /* perms reftbl sptbl ... obj mt true */ lua_pop(pi->L, 2); /* perms reftbl sptbl ... obj */ { int zero = 0; pi->writer(pi->L, &zero, sizeof(int), pi->ud); } return 0; } else { lua_pushstring(pi->L, "Metatable forbade persistence"); lua_error(pi->L); return 0; /* not reached */ } } else if(!lua_isfunction(pi->L, -1)) { lua_pushstring(pi->L, "__persist not nil, boolean, or function"); lua_error(pi->L); } /* perms reftbl ... obj mt __persist */ lua_pushvalue(pi->L, -3); /* perms reftbl ... obj mt __persist obj */ #ifdef PLUTO_PASS_USERDATA_TO_PERSIST lua_pushlightuserdata(pi->L, (void*)pi->writer); lua_pushlightuserdata(pi->L, pi->ud); /* perms reftbl ... obj mt __persist obj ud */ lua_call(pi->L, 3, 1); /* perms reftbl ... obj mt func? */ #else lua_call(pi->L, 1, 1); /* perms reftbl ... obj mt func? */ #endif /* perms reftbl ... obj mt func? */ if(!lua_isfunction(pi->L, -1)) { lua_pushstring(pi->L, "__persist function did not return a function"); lua_error(pi->L); } /* perms reftbl ... obj mt func */ { int one = 1; pi->writer(pi->L, &one, sizeof(int), pi->ud); } persist(pi); /* perms reftbl ... obj mt func */ lua_pop(pi->L, 2); /* perms reftbl ... obj */ return 1; }
virtual void fastWriteStackObject(int iIndex) { lua_State *L = m_L; if(lua_type(L, iIndex) != LUA_TUSERDATA) { writeStackObject(iIndex); return; } // Convert index from relative to absolute if(iIndex < 0 && iIndex > LUA_REGISTRYINDEX) iIndex = lua_gettop(L) + 1 + iIndex; // Check for no cycle lua_getfenv(L, 1); lua_pushvalue(L, iIndex); lua_rawget(L, -2); lua_rawgeti(L, -2, 1); lua_pushvalue(L, iIndex); lua_gettable(L, -2); lua_replace(L, -2); if(!lua_isnil(L, -1) || !lua_isnil(L, -2)) { lua_pop(L, 3); writeStackObject(iIndex); return; } lua_pop(L, 2); // Save the index to the cache lua_pushvalue(L, iIndex); lua_pushnumber(L, (lua_Number)(m_iNextIndex++)); lua_settable(L, -3); if(!_checkThatUserdataCanBeDepersisted(iIndex)) return; // Write type, metatable, and then environment uint8_t iType = LUA_TUSERDATA; writeByteStream(&iType, 1); writeStackObject(-1); lua_getfenv(L, iIndex); writeStackObject(-1); lua_pop(L, 1); // Write the raw data if(lua_type(L, -1) == LUA_TTABLE) { lua_getfield(L, -1, "__persist"); if(lua_isnil(L, -1)) lua_pop(L, 1); else { lua_pushvalue(L, iIndex); lua_checkstack(L, 20); lua_CFunction fn = lua_tocfunction(L, -2); fn(L); lua_pop(L, 2); } } writeVUInt((uint64_t)0x42); // sync marker lua_pop(L, 1); }
lsb_err_value preserve_global_data(lsb_lua_sandbox *lsb) { if (!lsb->lua || !lsb->state_file) { return NULL; } lua_sethook(lsb->lua, NULL, 0, 0); // make sure the string library is loaded before we start lua_getglobal(lsb->lua, LUA_STRLIBNAME); if (!lua_istable(lsb->lua, -1)) { lua_getglobal(lsb->lua, "require"); if (!lua_iscfunction(lsb->lua, -1)) { snprintf(lsb->error_message, LSB_ERROR_SIZE, "preserve_global_data 'require' function not found"); return LSB_ERR_LUA; } lua_pushstring(lsb->lua, LUA_STRLIBNAME); if (lua_pcall(lsb->lua, 1, 1, 0)) { int len = snprintf(lsb->error_message, LSB_ERROR_SIZE, "preserve_global_data failed loading 'string'"); if (len >= LSB_ERROR_SIZE || len < 0) { lsb->error_message[LSB_ERROR_SIZE - 1] = 0; } return LSB_ERR_LUA; } } lua_pop(lsb->lua, 1); lua_pushvalue(lsb->lua, LUA_GLOBALSINDEX); FILE *fh = fopen(lsb->state_file, "wb" CLOSE_ON_EXEC); if (fh == NULL) { int len = snprintf(lsb->error_message, LSB_ERROR_SIZE, "preserve_global_data could not open: %s", lsb->state_file); if (len >= LSB_ERROR_SIZE || len < 0) { lsb->error_message[LSB_ERROR_SIZE - 1] = 0; } return LSB_ERR_LUA;; } lsb_err_value ret = NULL; serialization_data data; data.fh = fh; // Clear the sandbox limits during preservation. #ifdef LUA_JIT lua_gc(lsb->lua, LUA_GCSETMEMLIMIT, 0); #else // size_t limit = lsb->usage[LSB_UT_MEMORY][LSB_US_LIMIT]; lsb->usage[LSB_UT_MEMORY][LSB_US_LIMIT] = 0; #endif // size_t cur_output_size = lsb->output.size; // size_t max_output_size = lsb->output.maxsize; lsb->output.maxsize = 0; // end clear data.tables.size = 64; data.tables.pos = 0; data.tables.array = malloc(data.tables.size * sizeof(table_ref)); if (data.tables.array == NULL || lsb_init_output_buffer(&data.keys, 0)) { snprintf(lsb->error_message, LSB_ERROR_SIZE, "preserve_global_data out of memory"); ret = LSB_ERR_UTIL_OOM; } else { fprintf(data.fh, "if %s and %s ~= %d then return end\n", preservation_version, preservation_version, get_preservation_version(lsb->lua)); ret = lsb_outputs(&data.keys, "_G", 2); if (!ret) { data.keys.pos += 1; // preserve the NUL in this use case data.globals = lua_topointer(lsb->lua, -1); lua_checkstack(lsb->lua, 2); lua_pushnil(lsb->lua); while (!ret && lua_next(lsb->lua, -2) != 0) { ret = serialize_kvp(lsb, &data, 0); lua_pop(lsb->lua, 1); } } lua_pop(lsb->lua, lua_gettop(lsb->lua)); // Wipe the entire Lua stack. Since incremental cleanup on failure // was added the stack should only contain table _G. } free(data.tables.array); lsb_free_output_buffer(&data.keys); fclose(fh); if (ret) remove(lsb->state_file); // Uncomment if we start preserving state when not destroying the sandbox // Note: serialization uses the output buffer, inprogress output can be // destroyed if the user was collecting output between calls. /* // Restore the sandbox limits after preservation #ifdef LUA_JIT lua_gc(lsb->lua, LUA_GCSETMEMLIMIT, lsb->usage[LSB_UT_MEMORY][LSB_US_LIMIT]); #else lua_gc(lsb->lua, LUA_GCCOLLECT, 0); lsb->usage[LSB_UT_MEMORY][LSB_US_LIMIT] = limit; lsb->usage[LSB_UT_MEMORY][LSB_US_MAXIMUM] = lsb->usage[LSB_UT_MEMORY][LSB_US_CURRENT]; #endif lsb->output.maxsize = max_output_size; lsb_clear_output_buffer(lsb->output); if (lsb->output.size > cur_output_size) { void* ptr = realloc(lsb->output.data, cur_output_size); if (!ptr) return 1; lsb->output.data = ptr; lsb->output.size = cur_output_size; } // end restore */ return ret; }
virtual bool readStackObject() { uint64_t iIndex; if(!readVUInt(iIndex)) { setError("Expected stack object"); return false; } lua_State *L = m_L; if(lua_type(L, 1) != LUA_TTABLE) { // Ensure that index #1 is self environment lua_getfenv(L, 1); lua_replace(L, 1); } if(iIndex >= PERSIST_TCOUNT) { iIndex += 1 - PERSIST_TCOUNT; if(iIndex < (uint64_t)INT_MAX) lua_rawgeti(L, 1, (int)iIndex); else { lua_pushnumber(L, (lua_Number)iIndex); lua_rawget(L, 1); } if(lua_isnil(L, -1)) { setError("Cycle while depersisting permanent object key or userdata metatable"); return false; } } else { uint8_t iType = (uint8_t)iIndex; switch(iType) { case LUA_TNIL: lua_pushnil(L); break; case PERSIST_TPERMANENT: { uint64_t iOldIndex = m_iNextIndex; ++m_iNextIndex; // Temporary marker lua_rawgeti(L, 1, 0); // Permanents table if(!readStackObject()) return false; lua_gettable(L, -2); lua_replace(L, -2); // Replace marker with actual object uint64_t iNewIndex = m_iNextIndex; m_iNextIndex = iOldIndex; saveStackObject(); m_iNextIndex = iNewIndex; break; } case LUA_TBOOLEAN: lua_pushboolean(L, 0); break; case PERSIST_TTRUE: lua_pushboolean(L, 1); break; case LUA_TSTRING: { size_t iLength; if(!readVUInt(iLength)) return false; while(iLength > m_iStringBufferLength) { m_iStringBufferLength *= 2; m_sStringBuffer = (char*)realloc(m_sStringBuffer, m_iStringBufferLength); } if(!readByteStream((uint8_t*)m_sStringBuffer, iLength)) return false; lua_pushlstring(L, m_sStringBuffer, iLength); saveStackObject(); break; } case LUA_TTABLE: lua_newtable(L); saveStackObject(); if(!lua_checkstack(L, 8)) return false; if(!readTableContents()) return false; break; case PERSIST_TTABLE_WITH_META: lua_newtable(L); saveStackObject(); if(!lua_checkstack(L, 8)) return false; if(!readStackObject()) return false; lua_setmetatable(L, -2); if(!readTableContents()) return false; break; case LUA_TNUMBER: { double fValue; if(!readByteStream(reinterpret_cast<uint8_t*>(&fValue), sizeof(double))) return false; lua_pushnumber(L, fValue); break; } case LUA_TFUNCTION: { if(!lua_checkstack(L, 8)) return false; uint64_t iOldIndex = m_iNextIndex; ++m_iNextIndex; // Temporary marker if(!readStackObject()) return false; lua_call(L, 0, 2); // Replace marker with closure uint64_t iNewIndex = m_iNextIndex; m_iNextIndex = iOldIndex; saveStackObject(); m_iNextIndex = iNewIndex; // Set upvalues lua_insert(L, -2); int iNups, i; if(!readVUInt(iNups)) return false; size_t iIDSize; if(!readVUInt(iIDSize)) return false; for(i = 0; i < iNups; ++i) { if(!readStackObject()) return false; // For now, just skip over the upvalue IDs. In the future, // the ID may be used to rejoin shared upvalues. if(!readByteStream(NULL, iIDSize)) return false; } lua_call(L, iNups, 0); // Read environment if(!readStackObject()) return false; lua_setfenv(L, -2); break; } case PERSIST_TPROTOTYPE: { if(!lua_checkstack(L, 8)) return false; uint64_t iOldIndex = m_iNextIndex; ++m_iNextIndex; // Temporary marker int iNups; if(!readVUInt(iNups)) return false; if(iNups == 0) lua_pushliteral(L, "return function() end,"); else { lua_pushliteral(L, "local "); lua_checkstack(L, (iNups + 1) * 2); for(int i = 0; i < iNups; ++i) { if(i != 0) lua_pushliteral(L, ","); if(!readStackObject()) return false; if(lua_type(L, -1) != LUA_TSTRING) { setError("Upvalue name not a string"); return false; } } lua_concat(L, iNups * 2 - 1); lua_pushliteral(L, ";return function(...)"); lua_pushvalue(L, -2); lua_pushliteral(L, "=...end,"); lua_concat(L, 5); } // Fetch name and then lookup filename and code if(!readStackObject()) return false; lua_pushliteral(L, "@"); lua_rawgeti(L, 1, -1); lua_pushvalue(L, -3); lua_gettable(L, -2); lua_replace(L, -2); if(lua_isnil(L, -1)) { setError(lua_pushfstring(L, "Unable to depersist prototype" " \'%s\'", lua_tostring(L, -3))); return false; } lua_concat(L, 2); // Prepend the @ to the filename lua_rawgeti(L, 1, -2); lua_pushvalue(L, -3); lua_gettable(L, -2); lua_replace(L, -2); lua_remove(L, -3); // Construct the closure factory LoadMultiBuffer_t ls; ls.s[0] = lua_tolstring(L, -3, &ls.i[0]); ls.s[1] = lua_tolstring(L, -1, &ls.i[1]); if(lua_load(L, LoadMultiBuffer_t::load_fn, &ls, lua_tostring(L, -2)) != 0) { // Should never happen lua_error(L); return false; } lua_replace(L, -4); lua_pop(L, 2); // Replace marker with closure factory uint64_t iNewIndex = m_iNextIndex; m_iNextIndex = iOldIndex; saveStackObject(); m_iNextIndex = iNewIndex; break; } case LUA_TUSERDATA: { bool bHasSetMetatable = false; uint64_t iOldIndex = m_iNextIndex; ++m_iNextIndex; // Temporary marker // Read metatable if(!readStackObject()) return false; lua_getfield(L, -1, "__depersist_size"); if(!lua_isnumber(L, -1)) { setError("Userdata missing __depersist_size metafield"); return false; } lua_newuserdata(L, (size_t)lua_tonumber(L, -1)); lua_replace(L, -2); // Replace marker with userdata uint64_t iNewIndex = m_iNextIndex; m_iNextIndex = iOldIndex; saveStackObject(); m_iNextIndex = iNewIndex; // Perform immediate initialisation lua_getfield(L, -2, "__pre_depersist"); if(lua_isnil(L, -1)) lua_pop(L, 1); else { // Set metatable now, as pre-depersister may expect it // NB: Setting metatable if there isn't a pre-depersister // is not a good idea, as if there is an error while the // environment table is being de-persisted, then the __gc // handler of the userdata will eventually be called with // the userdata's contents still being uninitialised. lua_pushvalue(L, -3); lua_setmetatable(L, -3); bHasSetMetatable = true; lua_pushvalue(L, -2); lua_call(L, 1, 0); } // Read environment if(!readStackObject()) return false; lua_setfenv(L, -2); // Set metatable and read the raw data if(!bHasSetMetatable) { lua_pushvalue(L, -2); lua_setmetatable(L, -2); } lua_getfield(L, -2, "__depersist"); if(lua_isnil(L, -1)) lua_pop(L, 1); else { lua_pushvalue(L, -2); lua_rawgeti(L, 1, -3); lua_call(L, 2, 1); if(lua_toboolean(L, -1) != 0) { lua_pop(L, 1); lua_rawgeti(L, 1, -3); lua_getmetatable(L, -1); lua_replace(L, -2); lua_pushvalue(L, -2); lua_rawseti(L, -2, (int)lua_objlen(L, -2) + 1); } lua_pop(L, 1); } lua_replace(L, -2); uint64_t iSyncMarker; if(!readVUInt(iSyncMarker)) return false; if(iSyncMarker != 0x42) { setError("sync fail"); return false; } break; } case PERSIST_TINTEGER: { uint16_t iValue; if(!readVUInt(iValue)) return false; lua_pushinteger(L, iValue); break; } default: lua_pushliteral(L, "Unable to depersist values of type \'"); if(iType <= LUA_TTHREAD) lua_pushstring(L, lua_typename(L, iType)); else { switch(iType) { case PERSIST_TPERMANENT: lua_pushliteral(L, "permanent"); break; case PERSIST_TTRUE: lua_pushliteral(L, "boolean-true"); break; case PERSIST_TTABLE_WITH_META: lua_pushliteral(L, "table-with-metatable"); break; case PERSIST_TINTEGER: lua_pushliteral(L, "integer"); break; case PERSIST_TPROTOTYPE: lua_pushliteral(L, "prototype"); break; case PERSIST_TRESERVED1: lua_pushliteral(L, "reserved1"); break; case PERSIST_TRESERVED2: lua_pushliteral(L, "reserved2"); break; } } lua_pushliteral(L, "\'"); lua_concat(L, 3); setError(lua_tostring(L, -1)); lua_pop(L, 1); return false; } } return true; }
static int pmain(lua_State* L) { struct Smain* s = (struct Smain*)lua_touserdata(L, 1); int argc=s->argc; char** argv=s->argv; Proto* f; int scripts=0; int i; if (!lua_checkstack(L,argc)) fatal("too many input files"); lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ luaL_openlibs(L); /* open libraries */ lua_gc(L, LUA_GCRESTART, 0); /* compile each script from command line into a Lua function. */ for (i=0; i<argc; i++) { const char* filename=IS("-") ? NULL : argv[i]; if(IS("-L")) break; if (luaL_loadfile(L,filename)!=0) fatal(lua_tostring(L,-1)); scripts++; } /* compile each preload library from the command line into a Lua function. */ for (i=0; i<preloads; i++) { char* filename=preload_libs[i]; char* p; /* try loading library as if it is a normal file. */ if (luaL_loadfile(L,filename)!=0) { /* try pre-loading library with 'require' module loading system. */ lua_getglobal(L, "require"); lua_pushstring(L, filename); lua_pushboolean(L, 1); lua_call(L, 2, 1); if (lua_iscfunction(L, -1)) { /* make sure it is not a C-Function. */ lua_pop(L, 1); lua_pushfstring(L, "\nCan't preload C module: '%s'\n", filename); lua_concat(L, 2); /* accumulate with error from luaL_findfile */ fatal(lua_tostring(L,-1)); } if (!lua_isfunction(L, -1)) { /* did we get an error? */ lua_pushliteral(L, "\n"); lua_concat(L, 3); /* accumulate with error from luaL_findfile */ fatal(lua_tostring(L,-1)); } else { lua_remove(L, -2); /* remove error from luaL_findfile. */ } } else { /* convert filename into package name. */ p= filename + strlen(filename); for(;p >= filename; p--) { if(p[0] == '.') { /* Remove file extension. */ p[0] = '\0'; continue; } if(p[0] == '/') { /* Remove file path. */ preload_libs[i] = p+1; break; } } } } /* generate a new Lua function to combine all of the compiled scripts. */ f=combine(L, scripts); if (listing) luaU_print(f,listing>1); if (c_code && !parse_only) { FILE* D= (output==NULL) ? stdout : fopen(output,"wb"); if (D==NULL) cannot("open"); lua_lock(L); slua_dumper_dump(D, output, L, f, stripping); lua_unlock(L); if (ferror(D)) cannot("write"); if (fclose(D)) cannot("close"); } if (dumping && !parse_only) { FILE* D= (output==NULL) ? stdout : fopen(output,"wb"); if (D==NULL) cannot("open"); lua_lock(L); luaU_dump(L,f,writer,D,stripping); lua_unlock(L); if (ferror(D)) cannot("write"); if (fclose(D)) cannot("close"); } return 0; }
LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) { if (!lua_checkstack(L, space)) luaL_error(L, "stack overflow (%s)", mes); }
int main(int argc, char **argv) { lua_State *L; unsigned i, it; int c; unsigned long n; char *p; unsigned iters = 1000; param_type_t param_type = PARAM_UNSPEC; unsigned num_params = 0; typedef struct { size_t size; char *buf; xsbuf_t *xsbuf; } param_t; param_t params[MAXPARAM] = {{ 0 }}; size_t max_param_size = 0; struct timespec real_start, real_end, proc_start, proc_end; double totalmem; int maxmem; while ((c = getopt(argc, argv, "i:" "x:" "LMSs:")) != EOF) { switch (c) { case 'i': iters = strtoul(optarg, &p, 10); if (*p) die("invalid iter count: -i%s\n", optarg); break; case 'x': n = strtoul(optarg, &p, 10); if (*p || n > 1) die("invalid string param type (0/1): -x%s\n", optarg); param_type = (param_type_t)n; break; case 'L': n = LARGE; goto add_param; case 'M': n = MEDIUM; goto add_param; case 'S': n = SMALL; goto add_param; case 's': n = strtoul(optarg, &p, 0); if (*p == 'k') { n *= 1024; ++p; } else if (*p == 'm') { n *= 1024 * 1024; ++p; } if (*p || n < MINPARAMSIZE) die("invalid param size: -s%s\n", optarg); add_param: if (num_params >= MAXPARAM) die("too many parameters; increase MAXPARAM\n"); if (!(p = calloc(n, 1))) die("Unable to allocate %lu for parameter %u\n", n, num_params + 1); params[num_params].size = n; params[num_params].buf = p; ++num_params; if (n > max_param_size) max_param_size = n; break; } } if (param_type < 0) die("must specify string param type (-x0 or -x1)\n"); if (!num_params) die("must specify at least one parameter size\n"); printf("Test info:\n" " %u iterations\n" " %u %s strings: ", iters, num_params, param_type ? "EXTERNAL" : "LUA"); for (i = 0; i < num_params; ++i) { const size_t s = params[i].size; if (s >= 1024 && !(s & 1023)) printf(" %zuk", s / 1024); else printf(" %zu", s); } printf("\n"); /* * set up Lua environ */ L = luaL_newstate(); assert(L); luaL_openlibs(L); if (luaL_dofile(L, "xsperf.lua")) die("Can't load xsperf.lua: %s\n", lua_tostring(L, -1)); lua_settop(L, 0); /* * run the test */ srand48(getpid()); lua_checkstack(L, 2 + num_params); if (clock_gettime(CLOCK_REALTIME, &real_start)) die("Can't get starting real time: %s\n", strerror(errno)); if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &proc_start)) die("Can't get starting process time: %s\n", strerror(errno)); totalmem = 0; maxmem = 0; for (it = 0; it < iters; ++it) { xsbuf_t *b; int mem; lua_getglobal(L, "test_iter"); for (i = 0; i < num_params; ++i) { const param_t *par = ¶ms[i]; /* modify all the param strings to defeat hashing */ snprintf(par->buf, par->size, "param %2u: %lX", i + 1, (unsigned long)lrand48()); switch (param_type) { case PARAM_LUASTRING: lua_pushlstring(L, par->buf, par->size); break; case PARAM_XSTRING: b = xsbuf_new(par->buf, par->size); params[i].xsbuf = b; xstring_new(L, b); break; case PARAM_UNSPEC: ; /* silence gcc warning */ } } if (lua_pcall(L, num_params, 0, 0)) die("Call #%u to test_iter() failed: %s\n", it + 1, lua_tostring(L, -1)); if (param_type == PARAM_XSTRING) { for (i = 0; i < num_params; ++i) { xsbuf_kill( params[i].xsbuf); xsbuf_discard(params[i].xsbuf); } } mem = lua_gc(L, LUA_GCCOUNT, 0); totalmem += mem; if (mem > maxmem) maxmem = mem; } lua_gc(L, LUA_GCCOLLECT, 0); if (clock_gettime(CLOCK_REALTIME, &real_end)) die("Can't get ending real time: %s\n", strerror(errno)); if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &proc_end)) die("Can't get ending process time: %s\n", strerror(errno)); for (i = 0; i < num_params; ++i) free(params[i].buf); lua_close(L); printf("Done!\n"); printf("User time: %.3f\n", tsdiff(proc_start, proc_end)); printf("Clock time: %.3f\n", tsdiff(real_start, real_end)); printf("Average mem: %.0f KiB\n", totalmem / iters); printf("Maximum mem: %d KiB\n", maxmem); return 0; }
/// Returns a table array containing all the file names of the // files in the specified directory. // // <b>Important</b>: this function lists both files from actual directories on // hard disk, and virtual directories loaded through // @{blitwizard.loadResourceArchive|loaded zip resource archives}. // Virtual files will take precedence over real files (you won't // receive duplicates). // // If you don't want virtual files listed (e.g. because you want // to examine any directory supplied by the user and not part of your // project) // @function ls // @tparam string directory path, empty string ("") for current directory // @tparam boolean virtual_files (optional) Specify true to list virtual files inside virtual directories aswell (the default behaviour), false to list only files in the actual file system on disk // @usage // -- list all files in current directory: // for i,file in ipairs(os.ls("")) do // print("file name: " .. file) // end int luafuncs_ls(lua_State *l) { const char *p = lua_tostring(l, 1); if (!p) { lua_pushstring(l, "First argument is not a valid path string"); return lua_error(l); } char *pnative = file_getAbsolutePathFromRelativePath(p); char *pcross = strdup(pnative); char *pcrossResourceDir = strdup(pnative); if (!pnative || !pcross || !pcrossResourceDir) { free(pnative); free(pcross); free(pcrossResourceDir); return haveluaerror(l, "failed to allocate file paths"); } file_makeSlashesNative(pnative); file_makeSlashesCrossplatform(pcross); file_makePathRelative(pcrossResourceDir, main_getRunDir()); if (!file_IsPathRelative(pcrossResourceDir)) { free(pcrossResourceDir); pcrossResourceDir = NULL; } // check parameter if we want to list internal zip stuff or not: int list_virtual = 1; if (lua_gettop(l) >= 2 && lua_type(l, 2) != LUA_TNIL) { if (lua_type(l, 2) != LUA_TNUMBER) { free(pnative); free(pcross); free(pcrossResourceDir); return haveluaerror(l, badargument1, 2, "os.ls", "boolean or nil", lua_strtype(l, 2)); } list_virtual = lua_toboolean(l, 2); } // get virtual filelist: char **filelist = NULL; #ifdef USE_PHYSFS if (list_virtual && pcrossResourceDir) { filelist = resource_getFileList(pcrossResourceDir); //printf("got filelist for %s: %p\n", pcrossrelative, filelist); char **p = filelist; if (p) { while (*p) { assert(strlen(*p) <= 512); assert(*p[0] >= 32); p++; } } } #endif // get iteration context for "real" on disk directory: struct filelistcontext *ctx = filelist_Create(pnative); if (!ctx && (!list_virtual || !filelist)) { char errmsg[500]; snprintf(errmsg, sizeof(errmsg), "failed to ls folder: %s", pnative); errmsg[sizeof(errmsg)-1] = 0; lua_pushstring(l, errmsg); free(pnative); free(pcross); free(pcrossResourceDir); if (filelist) { size_t i = 0; while (filelist[i]) { free(filelist[i]); i++; } free(filelist); } return lua_error(l); } // create file listing table lua_newtable(l); // add all files/folders to file listing table char filenamebuf[500]; int isdir; int returnvalue = 0; unsigned int i = 0; // loop through all files: if (ctx) { while ((returnvalue = filelist_GetNextFile(ctx, filenamebuf, sizeof(filenamebuf), &isdir)) == 1) { i++; lua_checkstack(l, 3); int duplicate = 0; // if we list against virtual folders too, // check for this being a duplicate: if (filelist) { unsigned int i2 = 0; while (filelist[i2]) { if (strcasecmp(filelist[i2], filenamebuf) == 0) { duplicate = 1; break; } i2++; } } if (duplicate) { // don't add this one. i--; continue; } lua_pushinteger(l, i); lua_pushstring(l, filenamebuf); lua_settable(l, -3); } // free file list filelist_Free(ctx); } if (filelist) { // add file list to table: i = 0; while (filelist[i]) { lua_pushinteger(l, i + 1); lua_pushstring(l, filelist[i]); lua_settable(l, -3); i++; } // free virtual file list: i = 0; while (filelist[i]) { free(filelist[i]); i++; } free(filelist); } // process error during listing if (returnvalue < 0) { lua_pop(l, 1); // remove file listing table char errmsg[500]; snprintf(errmsg, sizeof(errmsg), "Error while processing ls in folder: %s", pnative); errmsg[sizeof(errmsg)-1] = 0; lua_pushstring(l, errmsg); free(pnative); free(pcross); free(pcrossResourceDir); return lua_error(l); } // return file list free(pnative); free(pcross); free(pcrossResourceDir); return 1; }
static int ck_query(lua_State *L) { ck_errno = CK_ERR_OK; int n = lua_gettop(L); CKPackage *results = NULL; if (n != 2) { lua_pushstring(L, "Wrong number of arguments"); lua_error(L); } if (!lua_isstring(L, 1) || !lua_isstring(L,2)) { lua_pushstring(L, "incorrect argument type"); lua_error(L); } const char *qtype = luaL_checkstring(L, 1); const char *qstring = luaL_checkstring(L, 2); results = cronkite_get(qtype[0], qstring); if (!results) { // get ck_error and raise exception with it const char *errmsg = cronkite_strerror(ck_errno); lua_pushstring(L, errmsg); lua_error(L); } CKPackage *pkg = results; // lua tables start at 1 int i = 1; lua_newtable(L); int outer_top = lua_gettop(L); int inner_top = 0; // ensure stack is large enough for building inner table in loop lua_checkstack(L, 30); while (pkg) { // push array index for parent table lua_pushinteger(L, i); // build new package table lua_newtable(L); inner_top = lua_gettop(L); lua_pushstring(L, "id"); lua_pushstring(L, pkg->values[0]); lua_pushstring(L, "url"); lua_pushstring(L, pkg->values[1]); lua_pushstring(L, "name"); lua_pushstring(L, pkg->values[2]); lua_pushstring(L, "version"); lua_pushstring(L, pkg->values[3]); lua_pushstring(L, "urlpath"); lua_pushstring(L, pkg->values[4]); lua_pushstring(L, "license"); lua_pushstring(L, pkg->values[5]); lua_pushstring(L, "numvotes"); lua_pushstring(L, pkg->values[6]); lua_pushstring(L, "outofdate"); lua_pushstring(L, pkg->values[7]); lua_pushstring(L, "categoryid"); lua_pushstring(L, pkg->values[8]); lua_pushstring(L, "description"); lua_pushstring(L, pkg->values[9]); // build inner table for (int j=0; j<10; j++) { lua_settable(L, inner_top); } // add inner table to the outer table lua_settable(L, outer_top); i++; pkg = pkg->next; } // do cronkite cleanup cronkite_cleanup(results); return 1; }
static int lluv_tcp_bind(lua_State *L){ static const lluv_uv_const_t FLAGS[] = { { UV_TCP_IPV6ONLY , "ipv6only" }, { 0, NULL } }; lluv_handle_t *handle = lluv_check_tcp(L, 1, LLUV_FLAG_OPEN); struct sockaddr_storage sa; int err = lluv_check_addr(L, 2, &sa); unsigned int flags = 0; int top = lua_gettop(L); if(top > 5)lua_settop(L, top = 5); if((top > 4) || (!lua_isfunction(L, 4))){ flags = lluv_opt_flags_ui(L, 4, flags, FLAGS); } if(err < 0){ lua_checkstack(L, 3); lua_pushvalue(L, 2); lua_pushliteral(L, ":"); lua_pushvalue(L, 3); lua_concat(L, 3); if(!lua_isfunction(L, top)){ return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, lua_tostring(L, -1)); } lluv_error_create(L, LLUV_ERR_UV, err, lua_tostring(L, -1)); lua_remove(L, -2); lua_pushvalue(L, 1); lua_insert(L, -2); lluv_loop_defer_call(L, lluv_loop_by_handle(&handle->handle), 2); lua_settop(L, 1); return 1; } err = uv_tcp_bind(LLUV_H(handle, uv_tcp_t), (struct sockaddr *)&sa, flags); if(err < 0){ lua_checkstack(L, 3); lua_pushvalue(L, 2); lua_pushliteral(L, ":"); lua_pushvalue(L, 3); lua_concat(L, 3); if(!lua_isfunction(L, top)){ return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, lua_tostring(L, -1)); } lluv_error_create(L, LLUV_ERR_UV, err, lua_tostring(L, -1)); lua_remove(L, -2); lua_pushvalue(L, 1); lua_insert(L, -2); lluv_loop_defer_call(L, lluv_loop_by_handle(&handle->handle), 2); lua_settop(L, 1); return 1; } if(lua_isfunction(L, top)){ lua_pushvalue(L, 1); lua_pushnil(L); lluv_loop_defer_call(L, lluv_loop_by_handle(&handle->handle), lluv_push_addr(L, &sa) + 2 ); } lua_settop(L, 1); return 1; }
static void rdns_regress_callback (struct rdns_reply *reply, void *arg) { struct rdns_reply_entry *entry; char out[INET6_ADDRSTRLEN + 1]; const struct rdns_request_name *name; //llpm_entry_add //printf("In the callback function with lcore = %u\n", rte_lcore_id()); lua_State *tl = spam_tls[rte_lcore_id()]; if (reply->code == RDNS_RC_NOERROR) { entry = reply->entries; while (entry != NULL) { if (entry->type == RDNS_REQUEST_A) { inet_ntop (AF_INET, &entry->content.a.addr, out, sizeof (out)); printf ("%s has A record %s\n", (char *)arg, out); int ip4[4]; sscanf(arg, "%d.%d.%d.%d.zen.spamhaus.org", &ip4[0], &ip4[1], &ip4[2], &ip4[3]); unsigned int ip = (ip4[3] << 24) + (ip4[2] << 16) + (ip4[1] << 8) + ip4[0]; lua_checkstack(tl, 20); /* push functions and arguments */ lua_getglobal(tl, "llpm_entry_add"); /* function to be called */ lua_pushinteger(tl, ip); /* push 1st argument */ lua_pushinteger(tl, 32); /* push 2nd argument */ lua_pushinteger(tl, 1); /* push 2nd argument */ if (lua_pcall(tl, 3, 1, 0) != 0) error(tl, "error running function `llpm_entry_add': %s", lua_tostring(tl, -1)); lua_pop(tl, 1); /* pop returned value */ } else if (entry->type == RDNS_REQUEST_AAAA) { inet_ntop (AF_INET6, &entry->content.aaa.addr, out, sizeof (out)); printf ("%s has AAAA record %s\n", (char *)arg, out); } else if (entry->type == RDNS_REQUEST_SOA) { printf ("%s has SOA record %s %s %u %d %d %d\n", (char *)arg, entry->content.soa.mname, entry->content.soa.admin, entry->content.soa.serial, entry->content.soa.refresh, entry->content.soa.retry, entry->content.soa.expire); } else if (entry->type == RDNS_REQUEST_TLSA) { char *hex, *p; unsigned i; hex = malloc (entry->content.tlsa.datalen * 2 + 1); p = hex; for (i = 0; i < entry->content.tlsa.datalen; i ++) { sprintf (p, "%02x", entry->content.tlsa.data[i]); p += 2; } printf ("%s has TLSA record (%d %d %d) %s\n", (char *)arg, (int)entry->content.tlsa.usage, (int)entry->content.tlsa.selector, (int)entry->content.tlsa.match_type, hex); free (hex); } entry = entry->next; } } else { name = rdns_request_get_name (reply->request, NULL); printf ("Cannot resolve %s record for %s: %s\n", rdns_strtype (name->type), (char *)arg, rdns_strerror (reply->code)); int ip4[4]; sscanf(arg, "%d.%d.%d.%d.zen.spamhaus.org", &ip4[0], &ip4[1], &ip4[2], &ip4[3]); unsigned int ip = (ip4[3] << 24) + (ip4[2] << 16) + (ip4[1] << 8) + ip4[0]; //printf("%d.%d.%d.%d\n", ip4[3], ip4[2], ip4[1], ip4[0]); lua_checkstack(tl, 20); /* push functions and arguments */ lua_getglobal(tl, "llpm_entry_add"); /* function to be called */ lua_pushinteger(tl, ip); /* push 1st argument */ lua_pushinteger(tl, 32); /* push 2nd argument */ lua_pushinteger(tl, 0); /* push 2nd argument */ if (lua_pcall(tl, 3, 1, 0) != 0) error(tl, "error running function `llpm_entry_add': %s", lua_tostring(tl, -1)); lua_pop(tl, 1); /* pop returned value */ } if (--remain_tests == 0 && finished == 1) { printf ("End of test cycle\n"); rdns_resolver_release (reply->resolver); } }
/** ** Append the fields (keys and values) of a Lua table to the Lua ** source code. ** ** @param table_index ** The index of the table in the Lua stack. ** @param is_root ** True if the table is a global environment and this function ** should generate a series of assignment statements. ** False if the table is something else and this function should ** generate a fieldlist for a tableconstructor. ** ** @return ** CSerializeLua::OK if it appended the fields as requested. ** CSerializeLua::FAIL if something went seriously wrong and the ** whole serialization should be aborted. ** CSerializeLua::SKIP if is_root is false and the table contains ** something that cannot be serialized. ** ** If is_root is true and the table contains a field that cannot be ** serialized, then this function just skips that field and continues ** serializing the rest of the table. This is so that the global ** environment can be serialized even though it contains functions. */ CSerializeLua::Result CSerializeLua::AppendLuaFields(int table_index, bool is_root) { if (!lua_checkstack(this->lstate, 10)) return FAIL; const int top_on_entry = lua_gettop(this->lstate); Assert(lua_istable(this->lstate, table_index)); lua_Number seq = 1; bool is_first = true; lua_pushnil(this->lstate); while (lua_next(this->lstate, table_index)) { const int key_index = top_on_entry + 1; const int value_index = top_on_entry + 2; Result result; // If there's any problem with the field, then we // remove it from the output vector by truncating // back to this size. const size_t undo = this->output.size(); if (!is_root) { if (is_first) { this->AppendChar('\n'); } else { this->AppendCString(",\n"); } this->AppendIndent(); } // Append the key and and equals sign, if necessary. bool increment_seq = false; const int key_type = lua_type(this->lstate, key_index); if (is_root) { if (key_type != LUA_TSTRING) { goto skip_field; } size_t key_len; const char *key_str = lua_tolstring(this->lstate, key_index, &key_len); if (!IsIdentifier(key_str, key_len) || IsBlacklistedGlobal(key_str)) { goto skip_field; } this->AppendChars(key_str, key_len); this->AppendCString(" = "); } else if (key_type == LUA_TSTRING) { size_t key_len; const char *key_str = lua_tolstring(this->lstate, key_index, &key_len); if (IsIdentifier(key_str, key_len)) { this->AppendChars(key_str, key_len); } else { this->AppendChar('['); this->AppendQuotedString(key_str, key_len); this->AppendChar(']'); } this->AppendCString(" = "); } else if (key_type == LUA_TNUMBER) { if (lua_tonumber(this->lstate, key_index) == seq) { // Increment seq only after the value // has been successfully serialized. increment_seq = true; } else { this->AppendChar('['); result = this->AppendLuaAsString(key_index); if (result != OK) { return result; } this->AppendCString("] = "); } } else { goto skip_field; } result = this->AppendLuaValue(value_index); switch (result) { case OK: if (is_root) { this->AppendCString(";\n"); } is_first = false; if (increment_seq) ++seq; break; case SKIP: skip_field: this->output.resize(undo); if (!is_root) { lua_settop(this->lstate, top_on_entry); return SKIP; } break; case FAIL: default: lua_settop(this->lstate, top_on_entry); return result; } lua_pop(this->lstate, 1); // pop the value } if (!is_first && !is_root) { this->AppendChar(' '); } return OK; }
/* Persist all stack members */ static void persistthread(PersistInfo *pi) { size_t posremaining; lua_State *L2; /* perms reftbl ... thr */ L2 = lua_tothread(pi->L, -1); lua_checkstack(pi->L, L2->top - L2->stack + 1); if(pi->L == L2) { lua_pushstring(pi->L, "Can't persist currently running thread"); lua_error(pi->L); return; /* not reached */ } /* Persist the stack */ posremaining = revappendstack(L2, pi->L); /* perms reftbl ... thr (rev'ed contents of L2) */ pi->writer(pi->L, &posremaining, sizeof(size_t), pi->ud); for(; posremaining > 0; posremaining--) { persist(pi); lua_pop(pi->L, 1); } /* perms reftbl ... thr */ /* Now, persist the CallInfo stack. */ { size_t i, numframes = (L2->ci - L2->base_ci) + 1; pi->writer(pi->L, &numframes, sizeof(size_t), pi->ud); for(i=0; i<numframes; i++) { CallInfo *ci = L2->base_ci + i; size_t stackbase = ci->base - L2->stack; size_t stackfunc = ci->func - L2->stack; size_t stacktop = ci->top - L2->stack; size_t savedpc = (ci != L2->base_ci) ? ci->savedpc - ci_func(ci)->l.p->code : 0; pi->writer(pi->L, &stackbase, sizeof(size_t), pi->ud); pi->writer(pi->L, &stackfunc, sizeof(size_t), pi->ud); pi->writer(pi->L, &stacktop, sizeof(size_t), pi->ud); pi->writer(pi->L, &ci->nresults, sizeof(int), pi->ud); pi->writer(pi->L, &savedpc, sizeof(size_t), pi->ud); } } /* Serialize the state's other parameters, with the exception of upval stuff */ { size_t stackbase = L2->base - L2->stack; size_t stacktop = L2->top - L2->stack; lua_assert(L2->nCcalls <= 1); pi->writer(pi->L, &L2->status, sizeof(lu_byte), pi->ud); pi->writer(pi->L, &stackbase, sizeof(size_t), pi->ud); pi->writer(pi->L, &stacktop, sizeof(size_t), pi->ud); pi->writer(pi->L, &L2->errfunc, sizeof(ptrdiff_t), pi->ud); } /* Finally, record upvalues which need to be reopened */ /* See the comment above persistupval() for why we do this */ { GCObject *gco; UpVal *uv; /* perms reftbl ... thr */ for(gco = L2->openupval; gco != NULL; gco = uv->next) { size_t stackpos; uv = gco2uv(gco); /* Make sure upvalue is really open */ lua_assert(uv->v != &uv->u.value); pushupval(pi->L, uv); /* perms reftbl ... thr uv */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... thr */ stackpos = uv->v - L2->stack; pi->writer(pi->L, &stackpos, sizeof(size_t), pi->ud); } /* perms reftbl ... thr */ lua_pushnil(pi->L); /* perms reftbl ... thr nil */ persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... thr */ } /* perms reftbl ... thr */ }
/*! Prepares a Lua state for, and catches errors from, CorsixTH_lua_main(). By executing in Lua mode as soon as possible, errors can be nicely caught sooner, hence this function does as little as possible and leaves the rest for CorsixTH_lua_main(). */ int SDL_main(int argc, char** argv, JNIEnv* env) { jEnv = env; /* char dir[255]; getcwd(dir,sizeof(dir)); LOGI(dir); */ struct compile_time_lua_check { // Lua 5.1, not 5.0, is required int lua_5_point_1_required[LUA_VERSION_NUM >= 501 ? 1 : -1]; // Lua numbers must be doubles so that the mantissa has at least // 32 bits (floats only have 24 bits) int number_is_double[types_equal<lua_Number, double>::result]; }; bool bRun = true; while (bRun) { lua_State *L = NULL; L = luaL_newstate(); if (L == NULL) { fprintf(stderr, "Fatal error starting CorsixTH: " "Cannot open Lua state.\n"); return 0; } lua_atpanic(L, CorsixTH_lua_panic); luaL_openlibs(L); lua_register(L, "showkeyboard", showkeyboard); lua_register(L, "hidekeyboard", hidekeyboard); lua_settop(L, 0); lua_pushcfunction(L, CorsixTH_lua_stacktrace); lua_pushcfunction(L, CorsixTH_lua_main); // Move command line parameters onto the Lua stack lua_checkstack(L, argc); for (int i = 0; i < argc; ++i) { lua_pushstring(L, argv[i]); } if (lua_pcall(L, argc, 0, 1) != 0) { const char* err = lua_tostring(L, -1); if (err != NULL) { fprintf(stderr, "%s\n", err); } else { fprintf(stderr, "An error has occured in CorsixTH:\n" "Uncaught non-string Lua error\n"); } lua_pushcfunction(L, Bootstrap_lua_error_report); lua_insert(L, -2); if (lua_pcall(L, 1, 0, 0) != 0) { fprintf(stderr, "%s\n", lua_tostring(L, -1)); } } lua_getfield(L, LUA_REGISTRYINDEX, "_RESTART"); bRun = lua_toboolean(L, -1) != 0; // Get cleanup functions out of the Lua state (but don't run them yet) std::stack<void(*)(void)> stkCleanup; lua_getfield(L, LUA_REGISTRYINDEX, "_CLEANUP"); if (lua_type(L, -1) == LUA_TTABLE) { for (unsigned int i = 1; i <= lua_objlen(L, -1); ++i) { lua_rawgeti(L, -1, (int) i); stkCleanup.push((void(*)(void))lua_touserdata(L, -1));lua_pop (L, 1); } } lua_close(L); // The cleanup functions are executed _after_ the Lua state is fully // closed, and in reserve order to that in which they were registered. while (!stkCleanup.empty()) { if (stkCleanup.top() != NULL) stkCleanup.top()(); stkCleanup.pop(); } if (bRun) { printf("Restarting...\n"); } } return 0; }
/* Top-level delegating persist function */ static void persist(PersistInfo *pi) { /* perms reftbl ... obj */ lua_checkstack(pi->L, 2); /* If the object has already been written, write a reference to it */ lua_pushvalue(pi->L, -1); /* perms reftbl ... obj obj */ lua_rawget(pi->L, 2); /* perms reftbl ... obj ref? */ if(!lua_isnil(pi->L, -1)) { /* perms reftbl ... obj ref */ int zero = 0; int ref = (int)lua_touserdata(pi->L, -1); pi->writer(pi->L, &zero, sizeof(int), pi->ud); pi->writer(pi->L, &ref, sizeof(int), pi->ud); lua_pop(pi->L, 1); /* perms reftbl ... obj ref */ #ifdef PLUTO_DEBUG printindent(pi->level); printf("0 %d\n", ref); #endif return; } /* perms reftbl ... obj nil */ lua_pop(pi->L, 1); /* perms reftbl ... obj */ /* If the object is nil, write the pseudoreference 0 */ if(lua_isnil(pi->L, -1)) { int zero = 0; /* firsttime */ pi->writer(pi->L, &zero, sizeof(int), pi->ud); /* ref */ pi->writer(pi->L, &zero, sizeof(int), pi->ud); #ifdef PLUTO_DEBUG printindent(pi->level); printf("0 0\n"); #endif return; } { /* indicate that it's the first time */ int one = 1; pi->writer(pi->L, &one, sizeof(int), pi->ud); } lua_pushvalue(pi->L, -1); /* perms reftbl ... obj obj */ lua_pushlightuserdata(pi->L, (void*)(++(pi->counter))); /* perms reftbl ... obj obj ref */ lua_rawset(pi->L, 2); /* perms reftbl ... obj */ pi->writer(pi->L, &pi->counter, sizeof(int), pi->ud); /* At this point, we'll give the permanents table a chance to play. */ { lua_pushvalue(pi->L, -1); /* perms reftbl ... obj obj */ lua_gettable(pi->L, 1); /* perms reftbl ... obj permkey? */ if(!lua_isnil(pi->L, -1)) { /* perms reftbl ... obj permkey */ int type = PLUTO_TPERMANENT; #ifdef PLUTO_DEBUG printindent(pi->level); printf("1 %d PERM\n", pi->counter); pi->level++; #endif pi->writer(pi->L, &type, sizeof(int), pi->ud); persist(pi); lua_pop(pi->L, 1); /* perms reftbl ... obj */ #ifdef PLUTO_DEBUG pi->level--; #endif return; } else { /* perms reftbl ... obj nil */ lua_pop(pi->L, 1); /* perms reftbl ... obj */ } /* perms reftbl ... obj */ } { int type = lua_type(pi->L, -1); pi->writer(pi->L, &type, sizeof(int), pi->ud); #ifdef PLUTO_DEBUG printindent(pi->level); printf("1 %d %d\n", pi->counter, type); pi->level++; #endif } switch(lua_type(pi->L, -1)) { case LUA_TBOOLEAN: persistboolean(pi); break; case LUA_TLIGHTUSERDATA: persistlightuserdata(pi); break; case LUA_TNUMBER: persistnumber(pi); break; case LUA_TSTRING: persiststring(pi); break; case LUA_TTABLE: persisttable(pi); break; case LUA_TFUNCTION: persistfunction(pi); break; case LUA_TTHREAD: persistthread(pi); break; case LUA_TPROTO: persistproto(pi); break; case LUA_TUPVAL: persistupval(pi); break; case LUA_TUSERDATA: persistuserdata(pi); break; default: lua_assert(0); } #ifdef PLUTO_DEBUG pi->level--; #endif }