bool read_schematic_def(lua_State *L, int index,
	Schematic *schem, std::vector<std::string> *names)
{
	if (!lua_istable(L, index))
		return false;

	//// Get schematic size
	lua_getfield(L, index, "size");
	v3s16 size = check_v3s16(L, -1);
	lua_pop(L, 1);

	schem->size = size;

	//// Get schematic data
	lua_getfield(L, index, "data");
	luaL_checktype(L, -1, LUA_TTABLE);

	int numnodes = size.X * size.Y * size.Z;
	schem->schemdata = new MapNode[numnodes];
	int i = 0;

	size_t names_base = names->size();
	std::map<std::string, content_t> name_id_map;

	lua_pushnil(L);
	while (lua_next(L, -2)) {
		if (i >= numnodes) {
			i++;
			lua_pop(L, 1);
			continue;
		}

		// same as readnode, except param1 default is MTSCHEM_PROB_CONST
		lua_getfield(L, -1, "name");
		std::string name = luaL_checkstring(L, -1);
		lua_pop(L, 1);

		u8 param1;
		lua_getfield(L, -1, "param1");
		param1 = !lua_isnil(L, -1) ? lua_tonumber(L, -1) : MTSCHEM_PROB_ALWAYS;
		lua_pop(L, 1);

		u8 param2;
		lua_getfield(L, -1, "param2");
		param2 = !lua_isnil(L, -1) ? lua_tonumber(L, -1) : 0;
		lua_pop(L, 1);

		std::map<std::string, content_t>::iterator it = name_id_map.find(name);
		content_t name_index;
		if (it != name_id_map.end()) {
			name_index = it->second;
		} else {
			name_index = names->size() - names_base;
			name_id_map[name] = name_index;
			names->push_back(name);
		}

		schem->schemdata[i] = MapNode(name_index, param1, param2);

		i++;
		lua_pop(L, 1);
	}

	if (i != numnodes) {
		errorstream << "read_schematic_def: incorrect number of "
			"nodes provided in raw schematic data (got " << i <<
			", expected " << numnodes << ")." << std::endl;
		return false;
	}

	//// Get Y-slice probability values (if present)
	schem->slice_probs = new u8[size.Y];
	for (i = 0; i != size.Y; i++)
		schem->slice_probs[i] = MTSCHEM_PROB_ALWAYS;

	lua_getfield(L, index, "yslice_prob");
	if (lua_istable(L, -1)) {
		lua_pushnil(L);
		while (lua_next(L, -2)) {
			if (getintfield(L, -1, "ypos", i) && i >= 0 && i < size.Y) {
				schem->slice_probs[i] = getintfield_default(L, -1,
					"prob", MTSCHEM_PROB_ALWAYS);
			}
			lua_pop(L, 1);
		}
	}

	return true;
}
Exemple #2
0
// register_decoration({lots of stuff})
int ModApiBasic::l_register_decoration(lua_State *L)
{
	int index = 1;
	luaL_checktype(L, index, LUA_TTABLE);

	EmergeManager *emerge = getServer(L)->getEmergeManager();
	BiomeDefManager *bdef = emerge->biomedef;

	enum DecorationType decotype = (DecorationType)getenumfield(L, index,
				"deco_type", es_DecorationType, -1);
	if (decotype == -1) {
		errorstream << "register_decoration: unrecognized "
			"decoration placement type";
		return 0;
	}
	
	Decoration *deco = createDecoration(decotype);
	if (!deco) {
		errorstream << "register_decoration: decoration placement type "
			<< decotype << " not implemented";
		return 0;
	}

	deco->c_place_on    = CONTENT_IGNORE;
	deco->place_on_name = getstringfield_default(L, index, "place_on", "ignore");
	deco->fill_ratio    = getfloatfield_default(L, index, "fill_ratio", 0.02);
	deco->sidelen       = getintfield_default(L, index, "sidelen", 8);
	if (deco->sidelen <= 0) {
		errorstream << "register_decoration: sidelen must be "
			"greater than 0" << std::endl;
		delete deco;
		return 0;
	}
	
	lua_getfield(L, index, "noise_params");
	deco->np = read_noiseparams(L, -1);
	lua_pop(L, 1);
	
	lua_getfield(L, index, "biomes");
	if (lua_istable(L, -1)) {
		lua_pushnil(L);
		while (lua_next(L, -2)) {
			const char *s = lua_tostring(L, -1);
			u8 biomeid = bdef->getBiomeIdByName(s);
			if (biomeid)
				deco->biomes.insert(biomeid);

			lua_pop(L, 1);
		}
		lua_pop(L, 1);
	}
	
	switch (decotype) {
		case DECO_SIMPLE: {
			DecoSimple *dsimple = (DecoSimple *)deco;
			dsimple->c_deco     = CONTENT_IGNORE;
			dsimple->c_spawnby  = CONTENT_IGNORE;
			dsimple->spawnby_name    = getstringfield_default(L, index, "spawn_by", "air");
			dsimple->deco_height     = getintfield_default(L, index, "height", 1);
			dsimple->deco_height_max = getintfield_default(L, index, "height_max", 0);
			dsimple->nspawnby        = getintfield_default(L, index, "num_spawn_by", -1);
			
			lua_getfield(L, index, "decoration");
			if (lua_istable(L, -1)) {
				lua_pushnil(L);
				while (lua_next(L, -2)) {
					const char *s = lua_tostring(L, -1);
					std::string str(s);
					dsimple->decolist_names.push_back(str);

					lua_pop(L, 1);
				}
			} else if (lua_isstring(L, -1)) {
				dsimple->deco_name = std::string(lua_tostring(L, -1));
			} else {
				dsimple->deco_name = std::string("air");
			}
			lua_pop(L, 1);
			
			if (dsimple->deco_height <= 0) {
				errorstream << "register_decoration: simple decoration height"
					" must be greater than 0" << std::endl;
				delete dsimple;
				return 0;
			}

			break; }
		case DECO_SCHEMATIC: {
			DecoSchematic *dschem = (DecoSchematic *)deco;
			dschem->flags    = getflagsfield(L, index, "flags", flagdesc_deco_schematic);
			dschem->rotation = (Rotation)getenumfield(L, index,
								"rotation", es_Rotation, ROTATE_0);

			lua_getfield(L, index, "replacements");
			if (lua_istable(L, -1)) {
				int i = lua_gettop(L);
				lua_pushnil(L);
				while (lua_next(L, i) != 0) {
					// key at index -2 and value at index -1
					lua_rawgeti(L, -1, 1);
					std::string replace_from = lua_tostring(L, -1);
					lua_pop(L, 1);
					lua_rawgeti(L, -1, 2);
					std::string replace_to = lua_tostring(L, -1);
					lua_pop(L, 1);
					dschem->replacements[replace_from] = replace_to;
					// removes value, keeps key for next iteration
					lua_pop(L, 1);
				}
			}
			lua_pop(L, 1);

			lua_getfield(L, index, "schematic");
			if (!read_schematic(L, -1, dschem, getServer(L))) {
				delete dschem;
				return 0;
			}
			lua_pop(L, -1);
			
			if (!dschem->filename.empty() && !dschem->loadSchematicFile()) {
				errorstream << "register_decoration: failed to load schematic file '"
					<< dschem->filename << "'" << std::endl;
				delete dschem;
				return 0;
			}
			break; }
		case DECO_LSYSTEM: {
			//DecoLSystem *decolsystem = (DecoLSystem *)deco;
		
			break; }
	}

	emerge->decorations.push_back(deco);

	verbosestream << "register_decoration: decoration '" << deco->getName()
		<< "' registered" << std::endl;
	return 0;
}
Exemple #3
0
int lbot_checkID(lua_State *L, int idx)
{
  luaL_checktype(L, idx, LUA_TLIGHTUSERDATA);
  return reinterpret_cast<int>(lua_touserdata(L, idx));
}
static int
ngx_http_lua_ngx_req_set_uri(lua_State *L)
{
    ngx_http_request_t          *r;
    size_t                       len;
    u_char                      *p;
    int                          n;
    int                          jump = 0;
    ngx_http_lua_ctx_t          *ctx;

    n = lua_gettop(L);

    if (n != 1 && n != 2) {
        return luaL_error(L, "expecting 1 argument but seen %d", n);
    }

    lua_pushlightuserdata(L, &ngx_http_lua_request_key);
    lua_rawget(L, LUA_GLOBALSINDEX);
    r = lua_touserdata(L, -1);
    lua_pop(L, 1);

    if (n == 2) {

        luaL_checktype(L, 2, LUA_TBOOLEAN);
        jump = lua_toboolean(L, 2);

        if (jump) {

            ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
            if (ctx == NULL) {
                return luaL_error(L, "no ctx found");
            }

            dd("rewrite: %d, access: %d, content: %d",
                    (int) ctx->entered_rewrite_phase,
                    (int) ctx->entered_access_phase,
                    (int) ctx->entered_content_phase);

            ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE);

            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                           "lua set uri jump to \"%V\"", &r->uri);

            ngx_http_lua_check_if_abortable(L, ctx);
        }
    }

    p = (u_char *) luaL_checklstring(L, 1, &len);

    if (len == 0) {
        return luaL_error(L, "attempt to use zero-length uri");
    }

    r->uri.data = ngx_palloc(r->pool, len);
    if (r->uri.data == NULL) {
        return luaL_error(L, "out of memory");
    }

    ngx_memcpy(r->uri.data, p, len);

    r->uri.len = len;

    r->internal = 1;
    r->valid_unparsed_uri = 0;

    ngx_http_set_exten(r);

    if (jump) {
        r->uri_changed = 1;

        return lua_yield(L, 0);
    }

    r->valid_location = 0;
    r->uri_changed = 0;

    return 0;
}
bool read_schematic(lua_State *L, int index, DecoSchematic *dschem, Server *server) {
	if (index < 0)
		index = lua_gettop(L) + 1 + index;

	INodeDefManager *ndef = server->getNodeDefManager();

	if (lua_istable(L, index)) {
		lua_getfield(L, index, "size");
		v3s16 size = read_v3s16(L, -1);
		lua_pop(L, 1);
		
		int numnodes = size.X * size.Y * size.Z;
		MapNode *schemdata = new MapNode[numnodes];
		int i = 0;
		
		// Get schematic data
		lua_getfield(L, index, "data");
		luaL_checktype(L, -1, LUA_TTABLE);
		
		lua_pushnil(L);
		while (lua_next(L, -2)) {
			if (i < numnodes) {
				// same as readnode, except param1 default is MTSCHEM_PROB_CONST
				lua_getfield(L, -1, "name");
				const char *name = luaL_checkstring(L, -1);
				lua_pop(L, 1);
				
				u8 param1;
				lua_getfield(L, -1, "param1");
				param1 = !lua_isnil(L, -1) ? lua_tonumber(L, -1) : MTSCHEM_PROB_ALWAYS;
				lua_pop(L, 1);
	
				u8 param2;
				lua_getfield(L, -1, "param2");
				param2 = !lua_isnil(L, -1) ? lua_tonumber(L, -1) : 0;
				lua_pop(L, 1);
				
				schemdata[i] = MapNode(ndef, name, param1, param2);
			}
			
			i++;
			lua_pop(L, 1);
		}
		
		if (i != numnodes) {
			errorstream << "read_schematic: incorrect number of "
				"nodes provided in raw schematic data (got " << i <<
				", expected " << numnodes << ")." << std::endl;
			return false;
		}

		u8 *sliceprobs = new u8[size.Y];
		for (i = 0; i != size.Y; i++)
			sliceprobs[i] = MTSCHEM_PROB_ALWAYS;

		// Get Y-slice probability values (if present)
		lua_getfield(L, index, "yslice_prob");
		if (lua_istable(L, -1)) {
			lua_pushnil(L);
			while (lua_next(L, -2)) {
				if (getintfield(L, -1, "ypos", i) && i >= 0 && i < size.Y) {
					sliceprobs[i] = getintfield_default(L, -1,
						"prob", MTSCHEM_PROB_ALWAYS);
				}
				lua_pop(L, 1);
			}
		}

		dschem->size        = size;
		dschem->schematic   = schemdata;
		dschem->slice_probs = sliceprobs;

	} else if (lua_isstring(L, index)) {
		dschem->filename = std::string(lua_tostring(L, index));
	} else {
		errorstream << "read_schematic: missing schematic "
			"filename or raw schematic data" << std::endl;
		return false;
	}
	
	return true;
}
int EventDispatcherBinder::removeEventListener(lua_State* L)
{
	StackChecker checker(L, "EventDispatcherBinder::removeEventListener", 0);

	Binder binder(L);
	EventDispatcher* eventDispatcher = static_cast<EventDispatcher*>(binder.getInstance("EventDispatcher"));

	luaL_checktype(L, 2, LUA_TSTRING);
	luaL_checktype(L, 3, LUA_TFUNCTION);

	bool hasData = lua_gettop(L) >= 4;

	createEventsTable(L, 1);	// create __events table if it's not created

	EventBinderMap& map = getOrCreateEventBinderMap(eventDispatcher);

	const char* event = lua_tostring(L, 2);
	int eventid = StringId::instance().id(event);

	const std::vector<CppLuaBridge*>& bridges = map[eventid]; 

	lua_getfield(L, 1, "__events");

	// check if the event is already registered
	CppLuaBridge* bridge = 0;
	for (std::size_t i = 0; i < bridges.size(); ++i)
	{
		lua_pushlightuserdata(L, bridges[i]);
		lua_rawget(L, -2);	// we get the event check closure
		if (hasData == false)
		{
			lua_pushvalue(L, 3);	// function
			lua_call(L, 1, 1);
		}
		else
		{
			lua_pushvalue(L, 3);	// function
			lua_pushvalue(L, 4);	// data
			lua_call(L, 2, 1);
		}

		if (lua_toboolean(L, -1))
		{
			bridge = bridges[i];
			lua_pop(L, 1);
			break;
		}
		else
			lua_pop(L, 1);
	}

	if (bridge == 0)	// event is not registered
	{
		lua_pop(L, 1);		// pop __events
		return 0;
	}

	luaL_rawgetptr(L, LUA_REGISTRYINDEX, &key_eventClosures);
	lua_pushlightuserdata(L, bridge);	// key=bridge
	lua_pushnil(L);						// value=nil
	lua_rawset(L, -3);					// envtable["eventClosures"][bridge] = nil
	lua_pop(L, 1);						// pop envtable["eventClosures"]

	lua_pushlightuserdata(L, bridge);	// key=bridge
	lua_pushnil(L);						// value = nil
	lua_settable(L, -3);				// __events[bridge] = nil

	eventDispatcher->removeEventListener(LuaEvent::Type(event), bridge, &CppLuaBridge::luaEvent);

	map.remove(eventid, bridge);
		
	lua_pop(L, 1);		// pop __events

	return 0;
}
Exemple #7
0
// Push the list of callbacks (a lua table).
// Then push nargs arguments.
// Then call this function, which
// - runs the callbacks
// - removes the table and arguments from the lua stack
// - pushes the return value, computed depending on mode
void scriptapi_run_callbacks(lua_State *L, int nargs,
		RunCallbacksMode mode)
{
	// Insert the return value into the lua stack, below the table
	assert(lua_gettop(L) >= nargs + 1);
	lua_pushnil(L);
	lua_insert(L, -(nargs + 1) - 1);
	// Stack now looks like this:
	// ... <return value = nil> <table> <arg#1> <arg#2> ... <arg#n>

	int rv = lua_gettop(L) - nargs - 1;
	int table = rv + 1;
	int arg = table + 1;

	luaL_checktype(L, table, LUA_TTABLE);

	// Foreach
	lua_pushnil(L);
	bool first_loop = true;
	while(lua_next(L, table) != 0){
		// key at index -2 and value at index -1
		luaL_checktype(L, -1, LUA_TFUNCTION);
		// Call function
		for(int i = 0; i < nargs; i++)
			lua_pushvalue(L, arg+i);
		if(lua_pcall(L, nargs, 1, 0))
			script_error(L, "error: %s", lua_tostring(L, -1));

		// Move return value to designated space in stack
		// Or pop it
		if(first_loop){
			// Result of first callback is always moved
			lua_replace(L, rv);
			first_loop = false;
		} else {
			// Otherwise, what happens depends on the mode
			if(mode == RUN_CALLBACKS_MODE_FIRST)
				lua_pop(L, 1);
			else if(mode == RUN_CALLBACKS_MODE_LAST)
				lua_replace(L, rv);
			else if(mode == RUN_CALLBACKS_MODE_AND ||
					mode == RUN_CALLBACKS_MODE_AND_SC){
				if((bool)lua_toboolean(L, rv) == true &&
						(bool)lua_toboolean(L, -1) == false)
					lua_replace(L, rv);
				else
					lua_pop(L, 1);
			}
			else if(mode == RUN_CALLBACKS_MODE_OR ||
					mode == RUN_CALLBACKS_MODE_OR_SC){
				if((bool)lua_toboolean(L, rv) == false &&
						(bool)lua_toboolean(L, -1) == true)
					lua_replace(L, rv);
				else
					lua_pop(L, 1);
			}
			else
				assert(0);
		}

		// Handle short circuit modes
		if(mode == RUN_CALLBACKS_MODE_AND_SC &&
				(bool)lua_toboolean(L, rv) == false)
			break;
		else if(mode == RUN_CALLBACKS_MODE_OR_SC &&
				(bool)lua_toboolean(L, rv) == true)
			break;

		// value removed, keep key for next iteration
	}

	// Remove stuff from stack, leaving only the return value
	lua_settop(L, rv);

	// Fix return value in case no callbacks were called
	if(first_loop){
		if(mode == RUN_CALLBACKS_MODE_AND ||
				mode == RUN_CALLBACKS_MODE_AND_SC){
			lua_pop(L, 1);
			lua_pushboolean(L, true);
		}
		else if(mode == RUN_CALLBACKS_MODE_OR ||
				mode == RUN_CALLBACKS_MODE_OR_SC){
			lua_pop(L, 1);
			lua_pushboolean(L, false);
		}
	}
}
Exemple #8
0
// register_ore({lots of stuff})
int ModApiMapgen::l_register_ore(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	int index = 1;
	luaL_checktype(L, index, LUA_TTABLE);

	INodeDefManager *ndef = getServer(L)->getNodeDefManager();
	BiomeManager *bmgr    = getServer(L)->getEmergeManager()->biomemgr;
	OreManager *oremgr    = getServer(L)->getEmergeManager()->oremgr;

	enum OreType oretype = (OreType)getenumfield(L, index,
				"ore_type", es_OreType, ORE_SCATTER);
	Ore *ore = oremgr->create(oretype);
	if (!ore) {
		errorstream << "register_ore: ore_type " << oretype << " not implemented\n";
		return 0;
	}

	ore->name           = getstringfield_default(L, index, "name", "");
	ore->ore_param2     = (u8)getintfield_default(L, index, "ore_param2", 0);
	ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1);
	ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1);
	ore->clust_size     = getintfield_default(L, index, "clust_size", 0);
	ore->noise          = NULL;
	ore->flags          = 0;

	//// Get noise_threshold
	warn_if_field_exists(L, index, "noise_threshhold",
		"Deprecated: new name is \"noise_threshold\".");

	float nthresh;
	if (!getfloatfield(L, index, "noise_threshold", nthresh) &&
			!getfloatfield(L, index, "noise_threshhold", nthresh))
		nthresh = 0;
	ore->nthresh = nthresh;

	//// Get y_min/y_max
	warn_if_field_exists(L, index, "height_min",
		"Deprecated: new name is \"y_min\".");
	warn_if_field_exists(L, index, "height_max",
		"Deprecated: new name is \"y_max\".");

	int ymin, ymax;
	if (!getintfield(L, index, "y_min", ymin) &&
		!getintfield(L, index, "height_min", ymin))
		ymin = -31000;
	if (!getintfield(L, index, "y_max", ymax) &&
		!getintfield(L, index, "height_max", ymax))
		ymax = 31000;
	ore->y_min = ymin;
	ore->y_max = ymax;

	if (ore->clust_scarcity <= 0 || ore->clust_num_ores <= 0) {
		errorstream << "register_ore: clust_scarcity and clust_num_ores"
			"must be greater than 0" << std::endl;
		delete ore;
		return 0;
	}

	//// Get flags
	getflagsfield(L, index, "flags", flagdesc_ore, &ore->flags, NULL);

	//// Get biomes associated with this decoration (if any)
	lua_getfield(L, index, "biomes");
	if (get_biome_list(L, -1, bmgr, &ore->biomes))
		infostream << "register_ore: couldn't get all biomes " << std::endl;
	lua_pop(L, 1);

	//// Get noise parameters if needed
	lua_getfield(L, index, "noise_params");
	if (read_noiseparams(L, -1, &ore->np)) {
		ore->flags |= OREFLAG_USE_NOISE;
	} else if (ore->NEEDS_NOISE) {
		errorstream << "register_ore: specified ore type requires valid "
			"'noise_params' parameter" << std::endl;
		delete ore;
		return 0;
	}
	lua_pop(L, 1);

	//// Get type-specific parameters
	switch (oretype) {
		case ORE_SHEET: {
			OreSheet *oresheet = (OreSheet *)ore;

			oresheet->column_height_min = getintfield_default(L, index,
				"column_height_min", 1);
			oresheet->column_height_max = getintfield_default(L, index,
				"column_height_max", ore->clust_size);
			oresheet->column_midpoint_factor = getfloatfield_default(L, index,
				"column_midpoint_factor", 0.5f);

			break;
		}
		case ORE_PUFF: {
			OrePuff *orepuff = (OrePuff *)ore;

			lua_getfield(L, index, "np_puff_top");
			read_noiseparams(L, -1, &orepuff->np_puff_top);
			lua_pop(L, 1);

			lua_getfield(L, index, "np_puff_bottom");
			read_noiseparams(L, -1, &orepuff->np_puff_bottom);
			lua_pop(L, 1);

			break;
		}
		case ORE_VEIN: {
			OreVein *orevein = (OreVein *)ore;

			orevein->random_factor = getfloatfield_default(L, index,
				"random_factor", 1.f);

			break;
		}
		case ORE_STRATUM: {
			OreStratum *orestratum = (OreStratum *)ore;

			lua_getfield(L, index, "np_stratum_thickness");
			if (read_noiseparams(L, -1, &orestratum->np_stratum_thickness))
				ore->flags |= OREFLAG_USE_NOISE2;
			lua_pop(L, 1);

			orestratum->stratum_thickness = getintfield_default(L, index,
				"stratum_thickness", 8);

			break;
		}
		default:
			break;
	}

	ObjDefHandle handle = oremgr->add(ore);
	if (handle == OBJDEF_INVALID_HANDLE) {
		delete ore;
		return 0;
	}

	ore->m_nodenames.push_back(getstringfield_default(L, index, "ore", ""));

	size_t nnames = getstringlistfield(L, index, "wherein", &ore->m_nodenames);
	ore->m_nnlistsizes.push_back(nnames);

	ndef->pendNodeResolve(ore);

	lua_pushinteger(L, handle);
	return 1;
}
Exemple #9
0
bool read_schematic_def(lua_State *L, int index,
	Schematic *schem, std::vector<std::string> *names)
{
	if (!lua_istable(L, index))
		return false;

	//// Get schematic size
	lua_getfield(L, index, "size");
	v3s16 size = check_v3s16(L, -1);
	lua_pop(L, 1);

	schem->size = size;

	//// Get schematic data
	lua_getfield(L, index, "data");
	luaL_checktype(L, -1, LUA_TTABLE);

	u32 numnodes = size.X * size.Y * size.Z;
	schem->schemdata = new MapNode[numnodes];

	size_t names_base = names->size();
	std::unordered_map<std::string, content_t> name_id_map;

	u32 i = 0;
	for (lua_pushnil(L); lua_next(L, -2); i++, lua_pop(L, 1)) {
		if (i >= numnodes)
			continue;

		//// Read name
		std::string name;
		if (!getstringfield(L, -1, "name", name))
			throw LuaError("Schematic data definition with missing name field");

		//// Read param1/prob
		u8 param1;
		if (!getintfield(L, -1, "param1", param1) &&
			!getintfield(L, -1, "prob", param1))
			param1 = MTSCHEM_PROB_ALWAYS_OLD;

		//// Read param2
		u8 param2 = getintfield_default(L, -1, "param2", 0);

		//// Find or add new nodename-to-ID mapping
		std::unordered_map<std::string, content_t>::iterator it = name_id_map.find(name);
		content_t name_index;
		if (it != name_id_map.end()) {
			name_index = it->second;
		} else {
			name_index = names->size() - names_base;
			name_id_map[name] = name_index;
			names->push_back(name);
		}

		//// Perform probability/force_place fixup on param1
		param1 >>= 1;
		if (getboolfield_default(L, -1, "force_place", false))
			param1 |= MTSCHEM_FORCE_PLACE;

		//// Actually set the node in the schematic
		schem->schemdata[i] = MapNode(name_index, param1, param2);
	}

	if (i != numnodes) {
		errorstream << "read_schematic_def: incorrect number of "
			"nodes provided in raw schematic data (got " << i <<
			", expected " << numnodes << ")." << std::endl;
		return false;
	}

	//// Get Y-slice probability values (if present)
	schem->slice_probs = new u8[size.Y];
	for (i = 0; i != (u32) size.Y; i++)
		schem->slice_probs[i] = MTSCHEM_PROB_ALWAYS;

	lua_getfield(L, index, "yslice_prob");
	if (lua_istable(L, -1)) {
		for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
			u16 ypos;
			if (!getintfield(L, -1, "ypos", ypos) || (ypos >= size.Y) ||
				!getintfield(L, -1, "prob", schem->slice_probs[ypos]))
				continue;

			schem->slice_probs[ypos] >>= 1;
		}
	}

	return true;
}
Exemple #10
0
 inline int __call(lua_State *L)
 {
     luaL_checktype(L, lua_upvalueindex(1), LUA_TLIGHTUSERDATA);
     callsite * site = reinterpret_cast<callsite*>(lua_touserdata(L, lua_upvalueindex(1)));
     return site->call(L);
 }
Exemple #11
0
// register_decoration({lots of stuff})
int ModApiMapgen::l_register_decoration(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	int index = 1;
	luaL_checktype(L, index, LUA_TTABLE);

	INodeDefManager *ndef      = getServer(L)->getNodeDefManager();
	DecorationManager *decomgr = getServer(L)->getEmergeManager()->decomgr;
	BiomeManager *biomemgr     = getServer(L)->getEmergeManager()->biomemgr;
	SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr;

	enum DecorationType decotype = (DecorationType)getenumfield(L, index,
				"deco_type", es_DecorationType, -1);

	Decoration *deco = decomgr->create(decotype);
	if (!deco) {
		errorstream << "register_decoration: decoration placement type "
			<< decotype << " not implemented" << std::endl;
		return 0;
	}

	deco->name           = getstringfield_default(L, index, "name", "");
	deco->fill_ratio     = getfloatfield_default(L, index, "fill_ratio", 0.02);
	deco->y_min          = getintfield_default(L, index, "y_min", -31000);
	deco->y_max          = getintfield_default(L, index, "y_max", 31000);
	deco->nspawnby       = getintfield_default(L, index, "num_spawn_by", -1);
	deco->place_offset_y = getintfield_default(L, index, "place_offset_y", 0);
	deco->sidelen        = getintfield_default(L, index, "sidelen", 8);
	if (deco->sidelen <= 0) {
		errorstream << "register_decoration: sidelen must be "
			"greater than 0" << std::endl;
		delete deco;
		return 0;
	}

	//// Get node name(s) to place decoration on
	size_t nread = getstringlistfield(L, index, "place_on", &deco->m_nodenames);
	deco->m_nnlistsizes.push_back(nread);

	//// Get decoration flags
	getflagsfield(L, index, "flags", flagdesc_deco, &deco->flags, NULL);

	//// Get NoiseParams to define how decoration is placed
	lua_getfield(L, index, "noise_params");
	if (read_noiseparams(L, -1, &deco->np))
		deco->flags |= DECO_USE_NOISE;
	lua_pop(L, 1);

	//// Get biomes associated with this decoration (if any)
	lua_getfield(L, index, "biomes");
	if (get_biome_list(L, -1, biomemgr, &deco->biomes))
		infostream << "register_decoration: couldn't get all biomes " << std::endl;
	lua_pop(L, 1);

	//// Get node name(s) to 'spawn by'
	size_t nnames = getstringlistfield(L, index, "spawn_by", &deco->m_nodenames);
	deco->m_nnlistsizes.push_back(nnames);
	if (nnames == 0 && deco->nspawnby != -1) {
		errorstream << "register_decoration: no spawn_by nodes defined,"
			" but num_spawn_by specified" << std::endl;
	}

	//// Handle decoration type-specific parameters
	bool success = false;
	switch (decotype) {
	case DECO_SIMPLE:
		success = read_deco_simple(L, (DecoSimple *)deco);
		break;
	case DECO_SCHEMATIC:
		success = read_deco_schematic(L, schemmgr, (DecoSchematic *)deco);
		break;
	case DECO_LSYSTEM:
		break;
	}

	if (!success) {
		delete deco;
		return 0;
	}

	ndef->pendNodeResolve(deco);

	ObjDefHandle handle = decomgr->add(deco);
	if (handle == OBJDEF_INVALID_HANDLE) {
		delete deco;
		return 0;
	}

	lua_pushinteger(L, handle);
	return 1;
}
Exemple #12
0
/**
 * Allocate a structure, initialize with zero and return it.
 *
 * This is NOT intended for objects or structures that have specialized
 * creator functions, like gtk_window_new and such.  Use it for simple
 * structures like GtkTreeIter.
 *
 * The object is, as usual, a Lua wrapper in the form of a userdata,
 * containing a pointer to the actual object.
 *
 * @param L  Lua State
 * @param mi  Module that handles the type
 * @param is_array  If true, Stack[2] is the count, else allocate a single
 *  object.
 *
 * @luaparam typename  Type of the structure to allocate
 * @luaparam ...  array size, or optional additional arguments to the allocator
 *	function.
 * @luareturn The new structure
 */
static int lg_generic_new_array(lua_State *L, cmi mi, int is_array)
{
    typespec_t ts;
    void *p;
    char tmp_name[80];
    const char *type_name;
    int flags;
    const char *name_in = luaL_checkstring(L, 1);
    int count = 0;

    if (is_array) {
	count = luaL_checknumber(L, 2);
	if (count <= 0)
	    return luaL_error(L, "%s Invalid array size %d", msgprefix, count);
    }

    // add the prefix if available.
    if (mi->prefix_type) {
	strcpy(tmp_name, mi->prefix_type);
	strcat(tmp_name, name_in);
	type_name = tmp_name;
    } else
	type_name = name_in;

    // look for the type; if not found, try again without the prefix.
    for (;;) {
	ts = lg_find_struct(L, type_name, 1);
	if (ts.value)
	    break;
	ts = lg_find_struct(L, type_name, 0);
	if (ts.value)
	    break;
	if (type_name == name_in)
	    return luaL_error(L, "%s type %s* not found\n", msgprefix,
		type_name);
	type_name = name_in;
    }

    /* There may be an allocator function; if so, use it (but only for single
     * objects, not for arrays); use the optional additional arguments */
    if (count == 0) {
	char func_name[80];
	struct func_info fi;

	lg_make_func_name(mi, func_name, sizeof(func_name), type_name, "new");
	if (lg_find_func(L, mi, func_name, &fi))
	    return lg_call(L, &fi, 2);
    }

    /* no additional arguments must be given - they won't be used. */
    luaL_checktype(L, 3, LUA_TNONE);

    if (mi->allocate_object)
	p = mi->allocate_object(mi, L, ts, count, &flags);
    else
	p = default_allocate_object(mi, L, ts, count, &flags);

    /* Allocate and initialize the object.  I used to allocate just one
     * userdata big enough for both the wrapper and the object, but many free
     * functions exist, like gtk_tree_iter_free, and they expect a memory block
     * allocated by g_slice_alloc0.  Therefore this optimization is not
     * possible. */

    /* Make a Lua wrapper for it, push it on the stack.  FLAG_ALLOCATED causes
     * the _malloc_handler be used, and FLAG_NEW_OBJECT makes it not complain
     * about increasing the (non existant) refcounter. */
    lg_get_object(L, p, ts, flags);

    if (count) {
	struct object *w = (struct object*) lua_touserdata(L, -1);
	w->array_size = count;
    }
    
    return 1;
}
Exemple #13
0
Fichier : file.c Projet : halfd/lem
/*
 * file:lock() method
 */
static void
file_lock_work(struct lem_async *a)
{
	struct file *f = (struct file *)a;
	struct flock fl = {
		.l_type = f->lock.type,
		.l_whence = SEEK_SET,
		.l_start = f->lock.start,
		.l_len = f->lock.len,
	};

	if (fcntl(f->fd, F_SETLK, &fl) == -1)
		f->ret = errno;
	else
		f->ret = 0;
}

static void
file_lock_reap(struct lem_async *a)
{
	struct file *f = (struct file *)a;
	lua_State *T = f->T;

	f->T = NULL;

	if (f->ret) {
		lem_queue(T, io_strerror(T, f->ret));
		return;
	}

	lua_pushboolean(T, 1);
	lem_queue(T, 1);
}

static int
file_lock(lua_State *T)
{
	static const short mode[] = { F_RDLCK, F_WRLCK, F_UNLCK };
	static const char *const modenames[] = { "r", "w", "u", NULL };
	struct file *f;
	int op;
	lua_Number start;
	lua_Number len;

	luaL_checktype(T, 1, LUA_TUSERDATA);
	op = luaL_checkoption(T, 2, NULL, modenames);
	start = luaL_optnumber(T, 3, 0);
	len = luaL_optnumber(T, 4, 0);
	f = lua_touserdata(T, 1);
	f->lock.start = (off_t)start;
	luaL_argcheck(T, (lua_Number)f->lock.start == start, 3,
			"not an integer in proper range");
	f->lock.len = (off_t)len;
	luaL_argcheck(T, (lua_Number)f->lock.len == len, 4,
			"not an integer in proper range");
	if (f->fd < 0)
		return io_closed(T);
	if (f->T != NULL)
		return io_busy(T);

	f->T = T;
	f->lock.type = mode[op];
	lem_async_do(&f->a, file_lock_work, file_lock_reap);

	lua_settop(T, 1);
	return lua_yield(T, 1);
}
// register_ore({lots of stuff})
int ModApiMapgen::l_register_ore(lua_State *L)
{
	int index = 1;
	luaL_checktype(L, index, LUA_TTABLE);

	INodeDefManager *ndef = getServer(L)->getNodeDefManager();
	BiomeManager *bmgr    = getServer(L)->getEmergeManager()->biomemgr;
	OreManager *oremgr    = getServer(L)->getEmergeManager()->oremgr;

	enum OreType oretype = (OreType)getenumfield(L, index,
				"ore_type", es_OreType, ORE_SCATTER);
	Ore *ore = oremgr->create(oretype);
	if (!ore) {
		errorstream << "register_ore: ore_type " << oretype << " not implemented";
		return 0;
	}

	ore->name           = getstringfield_default(L, index, "name", "");
	ore->ore_param2     = (u8)getintfield_default(L, index, "ore_param2", 0);
	ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1);
	ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1);
	ore->clust_size     = getintfield_default(L, index, "clust_size", 0);
	ore->nthresh        = getfloatfield_default(L, index, "noise_threshhold", 0);
	ore->noise          = NULL;
	ore->flags          = 0;

	//// Get y_min/y_max
	warn_if_field_exists(L, index, "height_min",
		"Deprecated: new name is \"y_min\".");
	warn_if_field_exists(L, index, "height_max",
		"Deprecated: new name is \"y_max\".");

	int ymin, ymax;
	if (!getintfield(L, index, "y_min", ymin) &&
		!getintfield(L, index, "height_min", ymin))
		ymin = -31000;
	if (!getintfield(L, index, "y_max", ymax) &&
		!getintfield(L, index, "height_max", ymax))
		ymax = 31000;
	ore->y_min = ymin;
	ore->y_max = ymax;

	if (ore->clust_scarcity <= 0 || ore->clust_num_ores <= 0) {
		errorstream << "register_ore: clust_scarcity and clust_num_ores"
			"must be greater than 0" << std::endl;
		delete ore;
		return 0;
	}

	//// Get flags
	getflagsfield(L, index, "flags", flagdesc_ore, &ore->flags, NULL);

	//// Get biomes associated with this decoration (if any)
	lua_getfield(L, index, "biomes");
	if (get_biome_list(L, -1, bmgr, &ore->biomes))
		errorstream << "register_ore: couldn't get all biomes " << std::endl;
	lua_pop(L, 1);

	//// Get noise parameters if needed
	lua_getfield(L, index, "noise_params");
	if (read_noiseparams(L, -1, &ore->np)) {
		ore->flags |= OREFLAG_USE_NOISE;
	} else if (ore->NEEDS_NOISE) {
		errorstream << "register_ore: specified ore type requires valid "
			"noise parameters" << std::endl;
		delete ore;
		return 0;
	}
	lua_pop(L, 1);

	if (oretype == ORE_VEIN) {
		OreVein *orevein = (OreVein *)ore;
		orevein->random_factor = getfloatfield_default(L, index,
			"random_factor", 1.f);
	}

	ObjDefHandle handle = oremgr->add(ore);
	if (handle == OBJDEF_INVALID_HANDLE) {
		delete ore;
		return 0;
	}

	ore->m_nodenames.push_back(getstringfield_default(L, index, "ore", ""));

	size_t nnames = getstringlistfield(L, index, "wherein", &ore->m_nodenames);
	ore->m_nnlistsizes.push_back(nnames);

	ndef->pendNodeResolve(ore, NODE_RESOLVE_DEFERRED);

	lua_pushinteger(L, handle);
	return 1;
}
Exemple #15
0
static int
lload(lua_State *L) {
    int top = lua_gettop(L);
    FILE *fp; 
    struct png_source source;
    if (top == 1) {
        const char *filename = luaL_checkstring(L,1);
        fp = fopen(filename, "rb");
        if (fp == NULL) {
            return luaL_error(L, strerror(errno));
        }
        unsigned char header[PNGSIGSIZE];
        if (fread(header, 1, PNGSIGSIZE, fp) != PNGSIGSIZE) {
            return luaL_error(L, "png invalid");
        }
        if (png_sig_cmp(header, 0, PNGSIGSIZE)) {
            return luaL_error(L, "png sig invalid");
        }
        fseek(fp, 0, SEEK_SET);
    } else if (top == 2) {
        luaL_checktype(L,1,LUA_TLIGHTUSERDATA);
        void *data = lua_touserdata(L,1);
        size_t size = luaL_checkinteger(L,2);
        if (size < PNGSIGSIZE) {
            return luaL_error(L, "png invalid");
        }
        if (png_sig_cmp(data, 0, PNGSIGSIZE)) {
            return luaL_error(L, "png sig invalid");
        }
        source.data = data;
        source.size = size;
        source.offset = 0;
    } else {
        return luaL_error(L, "invalid argument number");
    }
    
    png_structp png_ptr;
    png_infop info_ptr;
    png_uint_32 width, height;
    int bit_depth, color_type, interlace_type;
    int step;//, type;

    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (png_ptr == NULL) {
        return 0;
    }

    info_ptr = png_create_info_struct(png_ptr);
    if (info_ptr == NULL) {
        png_destroy_read_struct(&png_ptr, NULL, NULL);
        return 0;
    }

    if (setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        return 0;
    }

    if (top == 1)
        png_init_io(png_ptr, fp);
    else
        png_set_read_fn(png_ptr, (void *)&source, png_read_cb);

    //png_set_sig_bytes(png_ptr, PNGSIGSIZE);

    png_read_info(png_ptr, info_ptr);

    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
            &interlace_type, NULL, NULL);

    if (color_type == PNG_COLOR_TYPE_PALETTE)
        png_set_palette_to_rgb(png_ptr);

    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) {
        bit_depth = 8;
        png_set_expand_gray_1_2_4_to_8(png_ptr);
    }

    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) != 0)
        png_set_tRNS_to_alpha(png_ptr);

    if (bit_depth == 16)
        png_set_strip_16(png_ptr);

    if (bit_depth < 8)
        png_set_packing(png_ptr);

    png_read_update_info(png_ptr, info_ptr);
    bit_depth = png_get_bit_depth(png_ptr, info_ptr);
    color_type = png_get_color_type(png_ptr, info_ptr);
    switch (color_type) {
    case PNG_COLOR_TYPE_GRAY:
        // type = TEXTURE_DEPTH;
        step = 1;
        break;
    case PNG_COLOR_TYPE_RGB:
        //type = TEXTURE_RGB;
        step = 3;
        break;
    case PNG_COLOR_TYPE_RGB_ALPHA:
        //type = TEXTURE_RGBA;
        step = 4;
        break;
    default:
        return luaL_error(L, "png color type %d not support", color_type);
    } 

    png_bytep *row_pointers = (png_bytep *)malloc(height * sizeof(png_bytep));

    png_size_t rowbytes = png_get_rowbytes(png_ptr,info_ptr);

    size_t bytes = rowbytes * height;
    uint8_t *buffer = (uint8_t *)malloc(bytes);
    int i;
    for (i=0; i<height; ++i) {
        row_pointers[i] = buffer + i*rowbytes;
    }
    
    png_read_image(png_ptr, row_pointers);

    png_read_end(png_ptr, info_ptr);

    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

    free(row_pointers);

    switch (color_type) {
    case PNG_COLOR_TYPE_GRAY:
        lua_pushliteral(L,"GRAY");
        break;
    case PNG_COLOR_TYPE_RGB:
        lua_pushliteral(L,"RGB8");
        break;
    case PNG_COLOR_TYPE_RGBA:
        lua_pushliteral(L,"RGBA8");
        break;
    }
    lua_pushinteger(L,width);
    lua_pushinteger(L,height);
    int n = width * height * step;
    lua_createtable(L,n,0);
    for (i=0; i<n; ++i) {
        lua_pushinteger(L, buffer[i]);
        lua_rawseti(L, -2, i+1);
    }

    free(buffer);
    return 4;
}
Exemple #16
0
// satisfies wrapper
tb_int_t xm_semver_select(lua_State* lua)
{
    semver_t semver = {0};
    semvers_t matches = {0};
    semver_range_t range = {0};
    lua_Integer i;
    size_t range_len = 0, source_len;
    tb_char_t const* source_str;
    tb_char_t const* source;
    tb_bool_t is_range;

    lua_settop(lua, 4);

    // check
    tb_assert_and_check_return_val(lua, 0);

    // get the version string
    tb_char_t const* range_str = luaL_checkstring(lua, 1);
    tb_check_return_val(range_str, 0);
    range_len = tb_strlen(range_str);

    is_range = semver_rangen(&range, range_str, range_len) == 0;
    if (is_range) {
        source = "versions";
        luaL_checktype(lua, 2, LUA_TTABLE);
        for (i = lua_objlen(lua, 2); i > 0; --i) {
            lua_pushinteger(lua, i);
            lua_gettable(lua, 2);

            source_str = luaL_checkstring(lua, -1);
            tb_check_return_val(source_str, 0);

            if (semver_tryn(&semver, source_str, tb_strlen(source_str)) == 0) {
                if (semver_range_match(semver, range)) {
                    semvers_push(matches, semver);
                } else {
                    semver_dtor(&semver);
                }
            }
        }
        if (matches.length) {
            goto match;
        }
        semvers_clear(matches);
        source = "tags";
        luaL_checktype(lua, 3, LUA_TTABLE);
        for (i = lua_objlen(lua, 3); i > 0; --i) {
            lua_pushinteger(lua, i);
            lua_gettable(lua, 3);

            source_str = luaL_checkstring(lua, -1);
            tb_check_return_val(source_str, 0);

            if (semver_tryn(&semver, source_str, tb_strlen(source_str)) == 0) {
                if (semver_range_match(semver, range)) {
                    semvers_push(matches, semver);
                } else {
                    semver_dtor(&semver);
                }
            }
        }
        if (matches.length) {
            goto match;
        }
        semvers_dtor(matches);
        semver_range_dtor(&range);
    }

    source = "branches";
    luaL_checktype(lua, 4, LUA_TTABLE);
    for (i = lua_objlen(lua, 4); i > 0; --i) {
        lua_pushinteger(lua, i);
        lua_gettable(lua, 4);

        source_str = luaL_checkstring(lua, -1);
        tb_check_return_val(source_str, 0);
        source_len = tb_strlen(source_str);

        if (source_len == range_len && tb_memcmp(source_str, range_str, source_len) == 0) {
            lua_createtable(lua, 0, 2);

            lua_pushlstring(lua, source_str, source_len);
            lua_setfield(lua, -2, "version");

            lua_pushstring(lua, source);
            lua_setfield(lua, -2, "source");

            return 1;
        }
    }

    if (!is_range)  {
        lua_pushnil(lua);
        lua_pushfstring(lua, "Unable to parse semver range '%s'", range_str);

        return 2;
    }
    lua_pushnil(lua);
    lua_pushfstring(lua, "Unable to select version for range '%s'", range_str);

    return 2;
    match:
    semvers_sort(matches);
    semver = semvers_pop(matches);
    lua_createtable(lua, 0, 2);

    lua_pushstring(lua, semver.raw);
    lua_setfield(lua, -2, "version");

    lua_pushstring(lua, source);
    lua_setfield(lua, -2, "source");

    semvers_dtor(matches);
    semver_dtor(&semver);
    semver_range_dtor(&range);

    return 1;
}
Exemple #17
0
static int luaModelInsertMix(lua_State *L)
{
  unsigned int chn = luaL_checkunsigned(L, 1);
  unsigned int idx = luaL_checkunsigned(L, 2);

  unsigned int first = getFirstMix(chn);
  unsigned int count = getMixesCountFromFirst(chn, first);

  if (chn<NUM_CHNOUT && getExpoMixCount(0)<MAX_MIXERS && idx<=count) {
    idx += first;
    s_currCh = chn+1;
    insertExpoMix(0, idx);
    MixData *mix = mixAddress(idx);
    luaL_checktype(L, -1, LUA_TTABLE);
    for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
      luaL_checktype(L, -2, LUA_TSTRING); // key is string
      const char * key = luaL_checkstring(L, -2);
      if (!strcmp(key, "name")) {
        const char * name = luaL_checkstring(L, -1);
        str2zchar(mix->name, name, sizeof(mix->name));
      }
      else if (!strcmp(key, "source")) {
        mix->srcRaw = luaL_checkinteger(L, -1);
      }
      else if (!strcmp(key, "weight")) {
        mix->weight = luaL_checkinteger(L, -1);
      }
      else if (!strcmp(key, "offset")) {
        mix->offset = luaL_checkinteger(L, -1);
      }
      else if (!strcmp(key, "switch")) {
        mix->swtch = luaL_checkinteger(L, -1);
      }
      else if (!strcmp(key, "curveType")) {
        mix->curve.type = luaL_checkinteger(L, -1);
      }
      else if (!strcmp(key, "curveValue")) {
        mix->curve.value = luaL_checkinteger(L, -1);
      }
      else if (!strcmp(key, "multiplex")) {
        mix->mltpx = luaL_checkinteger(L, -1);
      }
      else if (!strcmp(key, "flightModes")) {
        mix->flightModes = luaL_checkinteger(L, -1);
      }
      else if (!strcmp(key, "carryTrim")) {
        mix->carryTrim = lua_toboolean(L, -1);
      }
      else if (!strcmp(key, "mixWarn")) {
        mix->mixWarn = luaL_checkinteger(L, -1);
      }
      else if (!strcmp(key, "delayUp")) {
        mix->delayUp = luaL_checkinteger(L, -1);
      }
      else if (!strcmp(key, "delayDown")) {
        mix->delayDown = luaL_checkinteger(L, -1);
      }
      else if (!strcmp(key, "speedUp")) {
        mix->speedUp = luaL_checkinteger(L, -1);
      }
      else if (!strcmp(key, "speedDown")) {
        mix->speedDown = luaL_checkinteger(L, -1);
      }
    }
  }

  return 0;
}
Exemple #18
0
// register_ore({lots of stuff})
int ModApiMapgen::l_register_ore(lua_State *L)
{
	int index = 1;
	luaL_checktype(L, index, LUA_TTABLE);

	EmergeManager *emerge = getServer(L)->getEmergeManager();

	enum OreType oretype = (OreType)getenumfield(L, index,
				"ore_type", es_OreType, ORE_SCATTER);
	Ore *ore = createOre(oretype);
	if (!ore) {
		errorstream << "register_ore: ore_type "
			<< oretype << " not implemented";
		return 0;
	}

	ore->ore_name       = getstringfield_default(L, index, "ore", "");
	ore->ore_param2     = (u8)getintfield_default(L, index, "ore_param2", 0);
	ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1);
	ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1);
	ore->clust_size     = getintfield_default(L, index, "clust_size", 0);
	ore->height_min     = getintfield_default(L, index, "height_min", 0);
	ore->height_max     = getintfield_default(L, index, "height_max", 0);
	ore->nthresh        = getfloatfield_default(L, index, "noise_threshhold", 0.);
	ore->flags          = 0;
	getflagsfield(L, index, "flags", flagdesc_ore, &ore->flags, NULL);

	lua_getfield(L, index, "wherein");
	if (lua_istable(L, -1)) {
		int  i = lua_gettop(L);
		lua_pushnil(L);
		while(lua_next(L, i) != 0) {
			ore->wherein_names.push_back(lua_tostring(L, -1));
			lua_pop(L, 1);
		}
	} else if (lua_isstring(L, -1)) {
		ore->wherein_names.push_back(lua_tostring(L, -1));
	} else {
		ore->wherein_names.push_back("");
	}
	lua_pop(L, 1);

	lua_getfield(L, index, "noise_params");
	ore->np = read_noiseparams(L, -1);
	lua_pop(L, 1);

	ore->noise = NULL;

	if (ore->clust_scarcity <= 0 || ore->clust_num_ores <= 0) {
		errorstream << "register_ore: clust_scarcity and clust_num_ores"
			"must be greater than 0" << std::endl;
		delete ore;
		return 0;
	}

	emerge->ores.push_back(ore);

	verbosestream << "register_ore: ore '" << ore->ore_name
		<< "' registered" << std::endl;
	return 0;
}
int EventDispatcherBinder::addEventListener(lua_State* L)
{
	StackChecker checker(L, "EventDispatcherBinder::addEventListener", 0);

	Binder binder(L);
	EventDispatcher* eventDispatcher = static_cast<EventDispatcher*>(binder.getInstance("EventDispatcher", 1));

	luaL_checktype(L, 2, LUA_TSTRING);
	luaL_checktype(L, 3, LUA_TFUNCTION);

    bool hasData = !lua_isnoneornil(L, 4);

	createEventsTable(L, 1);	// create self.__events table if it's not created

	EventBinderMap& map = getOrCreateEventBinderMap(eventDispatcher);

	const char* event = lua_tostring(L, 2);
	int eventid = StringId::instance().id(event);

	const std::vector<CppLuaBridge*>& bridges = map[eventid]; 

	lua_getfield(L, 1, "__events");		// key is CppLuaBridge*, value is 'event check closure'

	// check if the event is already registered
	bool isFound = false;
	for (std::size_t i = 0; i < bridges.size(); ++i)
	{
		lua_pushlightuserdata(L, bridges[i]);
		lua_rawget(L, -2);	// we get the event check closure
		if (hasData == false)
		{
			lua_pushvalue(L, 3);	// function
			lua_call(L, 1, 1);
		}
		else
		{
			lua_pushvalue(L, 3);	// function
			lua_pushvalue(L, 4);	// data
			lua_call(L, 2, 1);
		}

		if (lua_toboolean(L, -1))
		{
			lua_pop(L, 1);
			isFound = true;
			break;
		}
		else
			lua_pop(L, 1);
	}

	if (isFound == true)
	{
		lua_pop(L, 1);		// pop __events, leave stack as it is
		return 0;
	}

    LuaApplication *application = (LuaApplication*)luaL_getdata(L);
    lua_State *mainL = application->getLuaState();

    CppLuaBridge* bridge = new CppLuaBridge(mainL);

	// create event closure
	luaL_rawgetptr(L, LUA_REGISTRYINDEX, &key_eventClosures);
	lua_pushlightuserdata(L, bridge);	// key=bridge
	if (hasData == false)				// value=closure
	{
        // self ve function'in eventClosure'in icine upvalue olarak koyulmasi garbage collect edilmesini engelliyor
        // bu yuzden {self, function} seklinde bi weak table yaratip ilk upvalue olarak onu set ediyoruz
		luaL_newweaktable(L);

        lua_pushvalue(L, 1);	// self
		lua_rawseti(L, -2, 1);

		lua_pushvalue(L, 3);	// function
        lua_rawseti(L, -2, 2);

        lua_pushcclosure(L, &eventClosure, 1);
	}
	else
	{
        // self, function ve data'nin eventClosure'in icine upvalue olarak koyulmasi garbage collect edilmesini engelliyor
        // bu yuzden {self, function, data} seklinde bi weak table yaratip ilk upvalue olarak onu set ediyoruz
		luaL_newweaktable(L);

        lua_pushvalue(L, 1);	// self
		lua_rawseti(L, -2, 1);

        lua_pushvalue(L, 3);	// function
        lua_rawseti(L, -2, 2);

        lua_pushvalue(L, 4);	// data
        lua_rawseti(L, -2, 3);

        lua_pushcclosure(L, &eventClosureWithData, 1);
	}
	lua_rawset(L, -3);					// envtable["eventClosures"][bridge] = closure
	lua_pop(L, 1);						// pop envtable["eventClosures"]

	// create event check closure
	lua_pushlightuserdata(L, bridge);
	if (hasData == false)
	{
		lua_pushvalue(L, 3);	// function
		lua_pushcclosure(L, &eventCheckClosure, 1);
	}
	else
	{
		lua_pushvalue(L, 3);	// function
		lua_pushvalue(L, 4);	// data
		lua_pushcclosure(L, &eventCheckClosureWithData, 2);
	}
	lua_rawset(L, -3);
	
	map.push_back(eventid, bridge);

	bridge->unref();
	
	eventDispatcher->addEventListener(LuaEvent::Type(event), bridge, &CppLuaBridge::luaEvent);

	lua_pop(L, 1);			// pop __events, leave stack as it is

	return 0;
}
static int lp_foldcapture (lua_State *L) {
  luaL_checktype(L, 2, LUA_TFUNCTION);
  return capture_aux(L, Cfold, 2);
}
Exemple #21
0
/*---------------------------------------------------------------------*/
static int
pkteng_link(lua_State *L)
{
	TRACE_LUA_FUNC_START();
	PktEngine_Intf *pe = check_pkteng(L, 1);
	Linker_Intf *linker;
	Brick *first_brick;
	int nargs = lua_gettop(L);
	int i;

	/* check if args2 is user-data */
	luaL_checktype(L, 2, LUA_TUSERDATA);
	
	/* Retrieve linker data */
	linker = (Linker_Intf *)luaL_optudata(L, 2);

	/* set values as default */
	pe->batch = DEFAULT_BATCH_SIZE;
	pe->qid = -1;

	/* if 3rd arg is passed, fill it with batch size */
	if (nargs >= 3)
		pe->batch = luaL_checkint(L, 3);
	/* if 4th arg is passed, fill it with qid */
	if (nargs >= 4)
		pe->qid = luaL_checkint(L, 4);
	lua_settop(L, 1);

	TRACE_DEBUG_LOG("Engine info so far...:\n"
			"\tName: %s\n"
			"\tCpu: %d\n"
			"\tBatch: %d\n"
			"\tQid: %d\n",
			pe->eng_name,
			pe->cpu,
			pe->batch,
			pe->qid);
	
	for (i = 0; i < linker->input_count; i++) {
		/* link the source(s) with the packet engine */
		pktengine_link_iface((uint8_t *)pe->eng_name, 
				     (uint8_t *)linker->input_link[i], 
				     pe->batch, pe->qid);
		TRACE_LOG("Linking %s with link %s with batch size: %d and qid: %d\n",
			  pe->eng_name, linker->input_link[i], pe->batch, pe->qid);
	}
	first_brick = createBrick(linker->type);
	if (first_brick == NULL) {
		TRACE_LUA_FUNC_END();
		return 1;
	}

	first_brick->eng = engine_find((unsigned char *)pe->eng_name);
	first_brick->elib->init(first_brick, linker);
	if (first_brick->eng == NULL) {
		TRACE_LOG("Could not find engine with name: %s\n",
			  pe->eng_name);
		TRACE_LUA_FUNC_END();
		free(first_brick);
		return 1;
	}
	first_brick->elib->link(first_brick, linker);
	
	/* if there are pipelines, link them as well */
	while (linker->next_linker != NULL) {
		linker = linker->next_linker;
		first_brick->elib->link(first_brick, linker); 
	}

	TRACE_LUA_FUNC_END();
	return 1;
}
Exemple #22
0
LUA_EXPORT(int openldap_uv_lua_search(lua_State *L))
{
    openldap_uv_lua_handle_t *ldap = luaL_checkudata(L, 1, META_TABLE);

    if(!ldap->ldap)
    {
        luaL_error(L, "Handle is not connected");
    }

    const char *dn = openldap_uv_lua__string_or_null(L, 2);
    const char *scope = luaL_checkstring(L, 3);

    int _scope;
    if(strcmp(scope, "LDAP_SCOPE_BASE") == 0 || strcmp(scope, "LDAP_SCOPE_BASEOBJECT") == 0) _scope = LDAP_SCOPE_BASEOBJECT;
    else if(strcmp(scope, "LDAP_SCOPE_ONE") == 0 || strcasecmp(scope, "LDAP_SCOPE_ONELEVEL") == 0) _scope = LDAP_SCOPE_ONELEVEL;
    else if(strcmp(scope, "LDAP_SCOPE_SUB") == 0 || strcasecmp(scope, "LDAP_SCOPE_SUBTREE") == 0) _scope = LDAP_SCOPE_SUBTREE;
    else if(strcmp(scope, "LDAP_SCOPE_CHILDREN") == 0 || strcasecmp(scope, "LDAP_SCOPE_SUBORDINATE") == 0) _scope = LDAP_SCOPE_CHILDREN;
    else luaL_error(L, "Unsupported scope %s", scope);

    const char *filter = openldap_uv_lua__string_or_null(L, 4);

    char **fieldSelector = NULL;

    if(!lua_isnil(L, 5))
    {
        luaL_checktype(L, 5, LUA_TTABLE);
        int size = lua_objlen(L, 5);

        fieldSelector = malloc(sizeof(*fieldSelector) * (size + 1));

        lua_pushnil(L);

        for(int i = 0; lua_next(L, 5); i++)
        {
            fieldSelector[i] = (char *)lua_tostring(L, -1);
            fieldSelector[i+1] = 0;
            lua_pop(L, 1);
        }
        lua_pop(L, 1);
    }

    int onlyFieldNames = lua_toboolean(L, 6) ? 1 : 0;

    LDAPMessage *message = 0;
    int err = ldap_search_ext_s(ldap->ldap, dn, _scope, filter, fieldSelector, onlyFieldNames, 0, 0, 0, LDAP_NO_LIMIT, &message);

    if(err != 0)
    {
        ldap_msgfree(message);
        openldap_uv_lua__check_error(L, ldap, err);
    }

    LDAPMessage *entry = ldap_first_entry(ldap->ldap, message);

    lua_newtable(L);

    while(entry)
    {
        char *dn = ldap_get_dn(ldap->ldap, entry);
        lua_pushstring(L, dn);
        free(dn);

        lua_newtable(L);

        BerElement *ber;
        char *attr = ldap_first_attribute(ldap->ldap, entry, &ber);

        int j = 0;
        while(attr)
        {
            struct berval **vals = ldap_get_values_len(ldap->ldap, entry, attr );

            if(vals)
            {
                for(int i = 0; vals[i]; i++)
                {
                    lua_pushnumber(L, ++j);

                    lua_newtable(L);

                    lua_pushnumber(L, 1);
                    lua_pushstring(L, attr);
                    lua_rawset(L, -3);

                    lua_pushnumber(L, 2);
                    lua_pushlstring(L, vals[i]->bv_val, vals[i]->bv_len);
                    lua_rawset(L, -3);

                    lua_rawset(L, -3);
                }

                ldap_value_free_len( vals );
            }

            ldap_memfree( attr );

            attr = ldap_next_attribute( ldap->ldap, entry, ber);
        }

        lua_rawset(L, -3);

        entry = ldap_next_entry(ldap->ldap, entry);
    }

    ldap_msgfree(message);

    return 1;
}
Exemple #23
0
static int l_mainloop(lua_State *L)
{
    luaL_checktype(L, 1, LUA_TTHREAD);
    lua_State *dispatcher = lua_tothread(L, 1);

    fps_ctrl *fps_control = (fps_ctrl*)lua_touserdata(L, luaT_upvalueindex(1));
    SDL_TimerID timer = SDL_AddTimer(30, timer_frame_callback, NULL);
    SDL_Event e;

    while(SDL_WaitEvent(&e) != 0)
    {
        bool do_frame = false;
        bool do_timer = false;
        do
        {
            int nargs;
            switch(e.type)
            {
            case SDL_QUIT:
                goto leave_loop;
            case SDL_KEYDOWN:
                lua_pushliteral(dispatcher, "keydown");
                lua_pushstring(dispatcher, SDL_GetKeyName(e.key.keysym.sym));
                l_push_modifiers_table(dispatcher, e.key.keysym.mod);
                lua_pushboolean(dispatcher, e.key.repeat != 0);
                nargs = 4;
                break;
            case SDL_KEYUP:
                lua_pushliteral(dispatcher, "keyup");
                lua_pushstring(dispatcher, SDL_GetKeyName(e.key.keysym.sym));
                nargs = 2;
                break;
            case SDL_TEXTINPUT:
                lua_pushliteral(dispatcher, "textinput");
                lua_pushstring(dispatcher, e.text.text);
                nargs = 2;
                break;
            case SDL_TEXTEDITING:
                lua_pushliteral(dispatcher, "textediting");
                lua_pushstring(dispatcher, e.edit.text);
                lua_pushinteger(dispatcher, e.edit.start);
                lua_pushinteger(dispatcher, e.edit.length);
                nargs = 4;
                break;
            case SDL_MOUSEBUTTONDOWN:
                lua_pushliteral(dispatcher, "buttondown");
                lua_pushinteger(dispatcher, e.button.button);
                lua_pushinteger(dispatcher, e.button.x);
                lua_pushinteger(dispatcher, e.button.y);
                nargs = 4;
                break;
            case SDL_MOUSEBUTTONUP:
                lua_pushliteral(dispatcher, "buttonup");
                lua_pushinteger(dispatcher, e.button.button);
                lua_pushinteger(dispatcher, e.button.x);
                lua_pushinteger(dispatcher, e.button.y);
                nargs = 4;
                break;
            case SDL_MOUSEWHEEL:
                lua_pushliteral(dispatcher, "mousewheel");
                lua_pushinteger(dispatcher, e.wheel.x);
                lua_pushinteger(dispatcher, e.wheel.y);
                nargs = 3;
                break;
            case SDL_MOUSEMOTION:
                lua_pushliteral(dispatcher, "motion");
                lua_pushinteger(dispatcher, e.motion.x);
                lua_pushinteger(dispatcher, e.motion.y);
                lua_pushinteger(dispatcher, e.motion.xrel);
                lua_pushinteger(dispatcher, e.motion.yrel);
                nargs = 5;
                break;
            case SDL_WINDOWEVENT:
                switch (e.window.event) {
                    case SDL_WINDOWEVENT_FOCUS_GAINED:
                        lua_pushliteral(dispatcher, "active");
                        lua_pushinteger(dispatcher, 1);
                        nargs = 2;
                        break;
                    case SDL_WINDOWEVENT_FOCUS_LOST:
                        lua_pushliteral(dispatcher, "active");
                        lua_pushinteger(dispatcher, 0);
                        nargs = 2;
                        break;
                    default:
                        nargs = 0;
                        break;
                }
                break;
            case SDL_USEREVENT_MUSIC_OVER:
                lua_pushliteral(dispatcher, "music_over");
                nargs = 1;
                break;
            case SDL_USEREVENT_CPCALL:
                if(luaT_cpcall(L, (lua_CFunction)e.user.data1, e.user.data2))
                {
                    SDL_RemoveTimer(timer);
                    lua_pushliteral(L, "callback");
                    return 2;
                }
                nargs = 0;
                break;
            case SDL_USEREVENT_TICK:
                do_timer = true;
                nargs = 0;
                break;
            case SDL_USEREVENT_MOVIE_OVER:
                lua_pushliteral(dispatcher, "movie_over");
                nargs = 1;
                break;
            case SDL_USEREVENT_SOUND_OVER:
                lua_pushliteral(dispatcher, "sound_over");
                lua_pushinteger(dispatcher, *(static_cast<int*>(e.user.data1)));
                nargs = 2;
                break;
            default:
                nargs = 0;
                break;
            }
            if(nargs != 0)
            {
                if(luaT_resume(dispatcher, dispatcher, nargs) != LUA_YIELD)
                {
                    goto leave_loop;
                }
                do_frame = do_frame || (lua_toboolean(dispatcher, 1) != 0);
                lua_settop(dispatcher, 0);
            }
        } while(SDL_PollEvent(&e) != 0);
        if(do_timer)
        {
            lua_pushliteral(dispatcher, "timer");
            if(luaT_resume(dispatcher, dispatcher, 1) != LUA_YIELD)
            {
                break;
            }
            do_frame = do_frame || (lua_toboolean(dispatcher, 1) != 0);
            lua_settop(dispatcher, 0);
        }
        if(do_frame || !fps_control->limit_fps)
        {
            do
            {
                if(fps_control->track_fps)
                {
                    fps_control->count_frame();
                }
                lua_pushliteral(dispatcher, "frame");
                if(luaT_resume(dispatcher, dispatcher, 1) != LUA_YIELD)
                {
                    goto leave_loop;
                }
                lua_settop(dispatcher, 0);
            } while(fps_control->limit_fps == false && SDL_PollEvent(NULL) == 0);
        }

        // No events pending - a good time to do a bit of garbage collection
        lua_gc(L, LUA_GCSTEP, 2);
    }

leave_loop:
    SDL_RemoveTimer(timer);
    int n = lua_gettop(dispatcher);
    if(lua_status(dispatcher) >= LUA_ERRRUN)
    {
        n = 1;
    }
    lua_checkstack(L, n);
    lua_xmove(dispatcher, L, n);
    return n;
}
Exemple #24
0
/* Request internal information from the curl session */
static int lcurl_easy_getinfo(lua_State* L)
{
	curlT* c=tocurl(L, 1);
	CURLINFO nInfo;
	CURLcode code=-1;
	luaL_checktype(L, 2, LUA_TNUMBER);   /* accept info code number only */
	nInfo=lua_tonumber(L, 2);
	if (nInfo>CURLINFO_SLIST)
	{
		/* string list */
		struct curl_slist *slist=0;
		if (CURLE_OK == (code=curl_easy_getinfo(c->curl, nInfo, &slist)))
		{
			if (slist)
			{
				int i;
				lua_newtable(L);
				for (i=1; slist; i++, slist=slist->next)
				{
					lua_pushnumber(L, i);
					lua_pushstring(L, slist->data);
					lua_settable(L, -3);
				}
				curl_slist_free_all(slist);
			} else
			{
				lua_pushnil(L);
			}
			return 1;
		} else
		{
			/* curl_easy_getinfo returns error */
		}
	} else
	if (nInfo>CURLINFO_DOUBLE)
	{
		/* double */
		double value;
		if (CURLE_OK == (code=curl_easy_getinfo(c->curl, nInfo, &value)))
		{
			lua_pushnumber(L, value);
			return 1;
		} else
		{
			/* curl_easy_getinfo returns error */
		}
	} else
	if (nInfo>CURLINFO_LONG)
	{
		/* long */
		long value;
		if (CURLE_OK == (code=curl_easy_getinfo(c->curl, nInfo, &value)))
		{
			lua_pushinteger(L, (lua_Integer)value);
			return 1;
		} else
		{
			/* curl_easy_getinfo returns error */
		}
	} else
	if (nInfo>CURLINFO_STRING)
	{
		/* string */
		char* value;
		if (CURLE_OK == (code=curl_easy_getinfo(c->curl, nInfo, &value)))
		{
			lua_pushstring(L, value);
			return 1;
		} else
		{
			/* curl_easy_getinfo returns error */
		}
	}
/* on error */
	/* return nil, error message, error code */
	lua_pushnil(L);
	if (code>CURLE_OK)
	{
		#if CURL_NEWER(7,11,2)
			lua_pushstring(L, curl_easy_strerror(code));
		#else
			lua_pushfstring(L, "Curl error: #%d", (code));
		#endif
		lua_pushnumber(L, code);
		return 3;
	}
	else
	{
		lua_pushfstring(L, "Invalid CURLINFO number: %d", nInfo);
		return 2;
	}
}
static int
ngx_http_lua_ngx_location_capture_multi(lua_State *L)
{
    ngx_http_request_t              *r;
    ngx_http_request_t              *sr; /* subrequest object */
    ngx_http_post_subrequest_t      *psr;
    ngx_http_lua_ctx_t              *sr_ctx;
    ngx_http_lua_ctx_t              *ctx;
    ngx_array_t                     *extra_vars;
    ngx_str_t                        uri;
    ngx_str_t                        args;
    ngx_str_t                        extra_args;
    ngx_uint_t                       flags;
    u_char                          *p;
    u_char                          *q;
    size_t                           len;
    size_t                           nargs;
    int                              rc;
    int                              n;
    ngx_uint_t                       method;
    ngx_http_request_body_t         *body;
    int                              type;
    ngx_buf_t                       *b;
    unsigned                         vars_action;
    ngx_uint_t                       nsubreqs;
    ngx_uint_t                       index;
    size_t                           sr_statuses_len;
    size_t                           sr_headers_len;
    size_t                           sr_bodies_len;
    unsigned                         custom_ctx;
    ngx_http_lua_co_ctx_t           *coctx;

    ngx_http_lua_post_subrequest_data_t      *psr_data;

    n = lua_gettop(L);
    if (n != 1) {
        return luaL_error(L, "only one argument is expected, but got %d", n);
    }

    luaL_checktype(L, 1, LUA_TTABLE);

    nsubreqs = lua_objlen(L, 1);
    if (nsubreqs == 0) {
        return luaL_error(L, "at least one subrequest should be specified");
    }

    lua_pushlightuserdata(L, &ngx_http_lua_request_key);
    lua_rawget(L, LUA_GLOBALSINDEX);
    r = lua_touserdata(L, -1);
    lua_pop(L, 1);

    if (r == NULL) {
        return luaL_error(L, "no request object found");
    }

    ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
    if (ctx == NULL) {
        return luaL_error(L, "no ctx found");
    }

    ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE
                               | NGX_HTTP_LUA_CONTEXT_ACCESS
                               | NGX_HTTP_LUA_CONTEXT_CONTENT);

    coctx = ctx->cur_co_ctx;
    if (coctx == NULL) {
        return luaL_error(L, "no co ctx found");
    }

    sr_statuses_len = nsubreqs * sizeof(ngx_int_t);
    sr_headers_len  = nsubreqs * sizeof(ngx_http_headers_out_t *);
    sr_bodies_len   = nsubreqs * sizeof(ngx_str_t);

    p = ngx_pcalloc(r->pool, sr_statuses_len + sr_headers_len +
                    sr_bodies_len);

    if (p == NULL) {
        return luaL_error(L, "out of memory");
    }

    coctx->sr_statuses = (void *) p;
    p += sr_statuses_len;

    coctx->sr_headers = (void *) p;
    p += sr_headers_len;

    coctx->sr_bodies = (void *) p;

    coctx->nsubreqs = nsubreqs;

    coctx->pending_subreqs = 0;

    extra_vars = NULL;

    for (index = 0; index < nsubreqs; index++) {
        coctx->pending_subreqs++;

        lua_rawgeti(L, 1, index + 1);
        if (lua_isnil(L, -1)) {
            return luaL_error(L, "only array-like tables are allowed");
        }

        dd("queries query: top %d", lua_gettop(L));

        if (lua_type(L, -1) != LUA_TTABLE) {
            return luaL_error(L, "the query argument %d is not a table, "
                              "but a %s",
                              index, lua_typename(L, lua_type(L, -1)));
        }

        nargs = lua_objlen(L, -1);

        if (nargs != 1 && nargs != 2) {
            return luaL_error(L, "query argument %d expecting one or "
                              "two arguments", index);
        }

        lua_rawgeti(L, 2, 1); /* queries query uri */

        dd("queries query uri: %d", lua_gettop(L));

        dd("first arg in first query: %s", lua_typename(L, lua_type(L, -1)));

        body = NULL;

        extra_args.data = NULL;
        extra_args.len = 0;

        if (extra_vars != NULL) {
            /* flush out existing elements in the array */
            extra_vars->nelts = 0;
        }

        vars_action = 0;

        custom_ctx = 0;

        if (nargs == 2) {
            /* check out the options table */

            lua_rawgeti(L, 2, 2); /* queries query uri opts */

            dd("queries query uri opts: %d", lua_gettop(L));

            if (lua_type(L, 4) != LUA_TTABLE) {
                return luaL_error(L, "expecting table as the 2nd argument for "
                                  "subrequest %d, but got %s", index,
                                  luaL_typename(L, 4));
            }

            dd("queries query uri opts: %d", lua_gettop(L));

            /* check the args option */

            lua_getfield(L, 4, "args");

            type = lua_type(L, -1);

            switch (type) {
            case LUA_TTABLE:
                ngx_http_lua_process_args_option(r, L, -1, &extra_args);
                break;

            case LUA_TNIL:
                /* do nothing */
                break;

            case LUA_TNUMBER:
            case LUA_TSTRING:
                extra_args.data = (u_char *) lua_tolstring(L, -1, &len);
                extra_args.len = len;

                break;

            default:
                return luaL_error(L, "Bad args option value");
            }

            lua_pop(L, 1);

            dd("queries query uri opts: %d", lua_gettop(L));

            /* check the vars option */

            lua_getfield(L, 4, "vars");

            switch (lua_type(L, -1)) {
            case LUA_TTABLE:
                ngx_http_lua_process_vars_option(r, L, -1, &extra_vars);

                dd("post process vars top: %d", lua_gettop(L));
                break;

            case LUA_TNIL:
                /* do nothing */
                break;

            default:
                return luaL_error(L, "Bad vars option value");
            }

            lua_pop(L, 1);

            dd("queries query uri opts: %d", lua_gettop(L));

            /* check the share_all_vars option */

            lua_getfield(L, 4, "share_all_vars");

            switch (lua_type(L, -1)) {
            case LUA_TNIL:
                /* do nothing */
                break;

            case LUA_TBOOLEAN:
                if (lua_toboolean(L, -1)) {
                    vars_action |= NGX_HTTP_LUA_SHARE_ALL_VARS;
                }
                break;

            default:
                return luaL_error(L, "Bad share_all_vars option value");
            }

            lua_pop(L, 1);

            dd("queries query uri opts: %d", lua_gettop(L));

            /* check the copy_all_vars option */

            lua_getfield(L, 4, "copy_all_vars");

            switch (lua_type(L, -1)) {
            case LUA_TNIL:
                /* do nothing */
                break;

            case LUA_TBOOLEAN:
                if (lua_toboolean(L, -1)) {
                    vars_action |= NGX_HTTP_LUA_COPY_ALL_VARS;
                }
                break;

            default:
                return luaL_error(L, "Bad copy_all_vars option value");
            }

            lua_pop(L, 1);

            dd("queries query uri opts: %d", lua_gettop(L));

            /* check the "method" option */

            lua_getfield(L, 4, "method");

            type = lua_type(L, -1);

            if (type == LUA_TNIL) {
                method = NGX_HTTP_GET;

            } else {
                if (type != LUA_TNUMBER) {
                    return luaL_error(L, "Bad http request method");
                }

                method = (ngx_uint_t) lua_tonumber(L, -1);
            }

            lua_pop(L, 1);

            dd("queries query uri opts: %d", lua_gettop(L));

            /* check the "ctx" option */

            lua_getfield(L, 4, "ctx");

            type = lua_type(L, -1);

            if (type != LUA_TNIL) {
                if (type != LUA_TTABLE) {
                    return luaL_error(L, "Bad ctx option value type %s, "
                                      "expected a Lua table", lua_typename(L, type));
                }

                custom_ctx = 1;

            } else {
                lua_pop(L, 1);
            }

            dd("queries query uri opts ctx?: %d", lua_gettop(L));

            /* check the "body" option */

            lua_getfield(L, 4, "body");

            type = lua_type(L, -1);

            if (type != LUA_TNIL) {
                if (type != LUA_TSTRING && type != LUA_TNUMBER) {
                    return luaL_error(L, "Bad http request body");
                }

                body = ngx_pcalloc(r->pool,
                                   sizeof(ngx_http_request_body_t));

                if (body == NULL) {
                    return luaL_error(L, "out of memory");
                }

                q = (u_char *) lua_tolstring(L, -1, &len);

                dd("request body: [%.*s]", (int) len, q);

                if (len) {
                    b = ngx_create_temp_buf(r->pool, len);
                    if (b == NULL) {
                        return luaL_error(L, "out of memory");
                    }

                    b->last = ngx_copy(b->last, q, len);

                    body->bufs = ngx_alloc_chain_link(r->pool);
                    if (body->bufs == NULL) {
                        return luaL_error(L, "out of memory");
                    }

                    body->bufs->buf = b;
                    body->bufs->next = NULL;

                    body->buf = b;
                }
            }

            lua_pop(L, 1); /* pop the body */

            /* stack: queries query uri opts ctx? */

            lua_remove(L, 4);

            /* stack: queries query uri ctx? */

            dd("queries query uri ctx?: %d", lua_gettop(L));

        } else {
            method = NGX_HTTP_GET;
        }

        /* stack: queries query uri ctx? */

        p = (u_char *) luaL_checklstring(L, 3, &len);

        uri.data = ngx_palloc(r->pool, len);
        if (uri.data == NULL) {
            return luaL_error(L, "memory allocation error");
        }

        ngx_memcpy(uri.data, p, len);

        uri.len = len;

        args.data = NULL;
        args.len = 0;

        flags = 0;

        rc = ngx_http_parse_unsafe_uri(r, &uri, &args, &flags);
        if (rc != NGX_OK) {
            dd("rc = %d", (int) rc);

            return luaL_error(L, "unsafe uri in argument #1: %s", p);
        }

        if (args.len == 0) {
            args = extra_args;

        } else if (extra_args.len) {
            /* concatenate the two parts of args together */
            len = args.len + (sizeof("&") - 1) + extra_args.len;

            p = ngx_palloc(r->pool, len);
            if (p == NULL) {
                return luaL_error(L, "out of memory");
            }

            q = ngx_copy(p, args.data, args.len);
            *q++ = '&';
            ngx_memcpy(q, extra_args.data, extra_args.len);

            args.data = p;
            args.len = len;
        }

        p = ngx_pnalloc(r->pool, sizeof(ngx_http_post_subrequest_t)
                        + sizeof(ngx_http_lua_ctx_t)
                        + sizeof(ngx_http_lua_post_subrequest_data_t));
        if (p == NULL) {
            return luaL_error(L, "out of memory");
        }

        psr = (ngx_http_post_subrequest_t *) p;

        p += sizeof(ngx_http_post_subrequest_t);

        sr_ctx = (ngx_http_lua_ctx_t *) p;

        p += sizeof(ngx_http_lua_ctx_t);

        psr_data = (ngx_http_lua_post_subrequest_data_t *) p;

        ngx_memzero(sr_ctx, sizeof(ngx_http_lua_ctx_t));

        /* set by ngx_memzero:
         *      sr_ctx->run_post_subrequest = 0
         *      sr_ctx->free = NULL
         */

        ngx_http_lua_init_ctx(sr_ctx);

        sr_ctx->capture = 1;
        sr_ctx->index = index;

        psr_data->ctx = sr_ctx;
        psr_data->pr_co_ctx = coctx;

        psr->handler = ngx_http_lua_post_subrequest;
        psr->data = psr_data;

        rc = ngx_http_lua_subrequest(r, &uri, &args, &sr, psr, 0);

        if (rc != NGX_OK) {
            return luaL_error(L, "failed to issue subrequest: %d", (int) rc);
        }

        ngx_http_set_ctx(sr, sr_ctx, ngx_http_lua_module);

        rc = ngx_http_lua_adjust_subrequest(sr, method, body, vars_action,
                                            extra_vars);

        if (rc != NGX_OK) {
            ngx_http_lua_cancel_subreq(sr);
            return luaL_error(L, "failed to adjust the subrequest: %d",
                              (int) rc);
        }

        dd("queries query uri opts ctx? %d", lua_gettop(L));

        /* stack: queries query uri ctx? */

        if (custom_ctx) {
            ngx_http_lua_ngx_set_ctx_helper(L, sr, sr_ctx, -1);
            lua_pop(L, 3);

        } else {
            lua_pop(L, 2);
        }

        /* stack: queries */
    }

    if (extra_vars) {
        ngx_array_destroy(extra_vars);
    }

    ctx->no_abort = 1;

    return lua_yield(L, 0);
}
Exemple #26
0
/* set any supported curl option (see also ALL_CURL_OPT) */
static int lcurl_easy_setopt(lua_State* L)
{
	union luaValueT v;                   /* the result option value */
	int curlOpt;                         /* the provided option code  */
	CURLcode code;                       /* return error code from curl */
	curlT* c = tocurl(L, 1);             /* get self object */
	luaL_checktype(L, 2, LUA_TNUMBER);   /* accept only number option codes */
	if (lua_gettop(L)<3)                 /* option value is always required */
	{
		luaL_error(L, "Invalid number of arguments %d to `setopt' method", lua_gettop(L));
	}
	curlOpt=(int)lua_tonumber(L, 2);     /* get the curl option code */
	v.nval=0;

	switch (curlOpt)
	{
		case CURLOPT_PROGRESSFUNCTION:
		case CURLOPT_READFUNCTION:
		case CURLOPT_WRITEFUNCTION:
		case CURLOPT_HEADERFUNCTION:
		case CURLOPT_IOCTLFUNCTION:
			luaL_checktype(L, 3, LUA_TFUNCTION); /* callback options require Lua function value */

		case CURLOPT_READDATA:
		case CURLOPT_WRITEDATA:
		case CURLOPT_PROGRESSDATA:
		case CURLOPT_HEADERDATA:
#if CURL_NEWER(7,12,3)
		case CURLOPT_IOCTLDATA:
#endif
			switch (lua_type(L, 3))             /* handle table, userdata and funtion callback params specially */
			{
				case LUA_TTABLE:
				case LUA_TUSERDATA:
				case LUA_TTHREAD:
				case LUA_TFUNCTION:
				{
					int ref;
					lua_pushvalue(L, 3);                                  
					ref=luaL_ref(L, LUA_REGISTRYINDEX);  /* get reference to the lua object in registry */

					if (curlOpt == CURLOPT_READFUNCTION)
					{
						luaL_unref(L, LUA_REGISTRYINDEX, c->freaderRef); /* unregister previous reference to reader if any */
						c->freaderRef=ref;                               /* keep the reader function reference in self */
						v.rcb=(curl_read_callback)readerCallback;        /* redirect the option value to readerCallback */
						if (CURLE_OK != (code=curl_easy_setopt(c->curl, CURLOPT_READDATA, c))) goto on_error;
					}
					else if (curlOpt == CURLOPT_WRITEFUNCTION)
					{
						luaL_unref(L, LUA_REGISTRYINDEX, c->fwriterRef);
						c->fwriterRef=ref;
						v.wcb=(curl_write_callback)writerCallback;
						if (CURLE_OK != (code=curl_easy_setopt(c->curl, CURLOPT_WRITEDATA, c))) goto on_error;
					}
					else if (curlOpt == CURLOPT_PROGRESSFUNCTION)
					{
						luaL_unref(L, LUA_REGISTRYINDEX, c->fprogressRef);
						c->fprogressRef=ref;
						v.pcb=(curl_progress_callback)progressCallback;
						if (CURLE_OK != (code=curl_easy_setopt(c->curl, CURLOPT_PROGRESSDATA, c))) goto on_error;
					}
					else if (curlOpt == CURLOPT_HEADERFUNCTION)
					{
						luaL_unref(L, LUA_REGISTRYINDEX, c->fheaderRef);
						c->fheaderRef=ref;
						v.wcb=(curl_write_callback)headerCallback;
						if (CURLE_OK != (code=curl_easy_setopt(c->curl, CURLOPT_HEADERDATA, c))) goto on_error;
					}
#if CURL_NEWER(7,12,3)
					else if (curlOpt == CURLOPT_IOCTLFUNCTION)
					{
						luaL_unref(L, LUA_REGISTRYINDEX, c->fioctlRef);
						c->fioctlRef=ref;
						v.icb=ioctlCallback;
						if (CURLE_OK != (code=curl_easy_setopt(c->curl, CURLOPT_IOCTLDATA, c))) goto on_error;
					}
#endif
					else
					{
						/* When the option code is any of CURLOPT_xxxDATA and the argument is table, 
						   userdata or function set the curl option value to the lua object reference */
						v.nval=ref;
					}
				}break;
			}break;

/* Handle all supported curl options differently according the specific option argument type */
#undef C_OPT
#define C_OPT(n, t) \
		case CURLOPT_##n: \
			v=get_##t(L, 3); \
			break;

#undef C_OPT_SL
#define C_OPT_SL(n) \
		case CURLOPT_##n: \
			{ \
				v=get_slist(L, 3, &KEY_##n); \
			}break;

/* Expands all the list of switch-case's here */
ALL_CURL_OPT

		default:
			luaL_error(L, "Not supported curl option %d", curlOpt);
	}

	/* additional check if the option value has compatible type with the option code */
	switch (lua_type(L, 3))
	{
		case LUA_TFUNCTION:                        /* allow function argument only for the special option codes */
			if (curlOpt == CURLOPT_READFUNCTION
				|| curlOpt == CURLOPT_WRITEFUNCTION
				|| curlOpt == CURLOPT_PROGRESSFUNCTION
				|| curlOpt == CURLOPT_HEADERFUNCTION
				|| curlOpt == CURLOPT_IOCTLFUNCTION
				)
				break;
		case LUA_TTABLE:                           /* allow table or userdata only for the callback parameter option */
		case LUA_TUSERDATA:
			if (curlOpt != CURLOPT_READDATA
				&& curlOpt != CURLOPT_WRITEDATA
				&& curlOpt != CURLOPT_PROGRESSDATA
				&& curlOpt != CURLOPT_HEADERDATA
#if CURL_NEWER(7,12,3)
				&& curlOpt != CURLOPT_IOCTLDATA
#endif
				)
				luaL_error(L, "argument #2 type %s is not compatible with this option", lua_typename(L, 3));
			break;
	}

	/* handle curl option for setting callback parameter */
	switch (curlOpt)
	{
		case CURLOPT_READDATA:
			if (c->rudtype == LUA_TFUNCTION || c->rudtype == LUA_TUSERDATA || c->rudtype == LUA_TTABLE || c->rudtype == LUA_TTHREAD)
				luaL_unref(L, LUA_REGISTRYINDEX, c->rud.nval); /* unref previously referenced read data */
			c->rudtype=lua_type(L, 3);                         /* set the read data type */
			c->rud=v;                                          /* set the read data value (it can be reference) */
			v.ptr=c;                                           /* set the real read data to curl as our self object */
			break;
		case CURLOPT_WRITEDATA:
			if (c->wudtype == LUA_TFUNCTION || c->wudtype == LUA_TUSERDATA || c->wudtype == LUA_TTABLE || c->wudtype == LUA_TTHREAD)
				luaL_unref(L, LUA_REGISTRYINDEX, c->wud.nval);
			c->wudtype=lua_type(L, 3);
			c->wud=v;
			v.ptr=c;
			break;
		case CURLOPT_PROGRESSDATA:
			if (c->pudtype == LUA_TFUNCTION || c->pudtype == LUA_TUSERDATA || c->pudtype == LUA_TTABLE || c->pudtype == LUA_TTHREAD)
				luaL_unref(L, LUA_REGISTRYINDEX, c->pud.nval);
			c->pudtype=lua_type(L, 3);
			c->pud=v;
			v.ptr=c;
			break;
		case CURLOPT_HEADERDATA:
			if (c->hudtype == LUA_TFUNCTION || c->hudtype == LUA_TUSERDATA || c->hudtype == LUA_TTABLE || c->hudtype == LUA_TTHREAD)
				luaL_unref(L, LUA_REGISTRYINDEX, c->hud.nval);
			c->hudtype=lua_type(L, 3);
			c->hud=v;
			v.ptr=c;
			break;
#if CURL_NEWER(7,12,3)
		case CURLOPT_IOCTLDATA:
			if (c->iudtype == LUA_TFUNCTION || c->iudtype == LUA_TUSERDATA || c->iudtype == LUA_TTABLE || c->iudtype == LUA_TTHREAD)
				luaL_unref(L, LUA_REGISTRYINDEX, c->iud.nval);
			c->iudtype=lua_type(L, 3);
			c->iud=v;
			v.ptr=c;
			break;
#endif
	}

	/* set easy the curl option with the processed value */
	if (CURLE_OK == (code=curl_easy_setopt(c->curl, (int)lua_tonumber(L, 2), v.nval)))
	{
		/* on success return true */
		lua_pushboolean(L, 1);
		return 1;
	} 
on_error:
	/* on fail return nil, error message, error code */
	lua_pushnil(L);
#if CURL_NEWER(7,11,2)
	lua_pushstring(L, curl_easy_strerror(code));
#else
	lua_pushfstring(L, "Curl error: #%d", (code));
#endif
	lua_pushnumber(L, code);
	return 3;
}
Exemple #27
0
//////////////////////////////////////////////////////////////////////
// Constructor:
static int ar_read(lua_State *L) {
    struct archive** self_ref;
    static named_setter format_names[] = {
        /* Copied from archive.h */
        { "all",       archive_read_support_format_all },
        { "ar",        archive_read_support_format_ar },
        { "cpio",      archive_read_support_format_cpio },
        { "empty",     archive_read_support_format_empty },
        { "gnutar",    archive_read_support_format_gnutar },
        { "iso9660",   archive_read_support_format_iso9660 },
        { "mtree",     archive_read_support_format_mtree },
        { "tar",       archive_read_support_format_tar },
        { "zip",       archive_read_support_format_zip },
        { NULL,        NULL }
    };
    static named_setter compression_names[] = {
        { "all",      archive_read_support_compression_all },
        { "bzip2",    archive_read_support_compression_bzip2 },
        { "compress", archive_read_support_compression_compress },
        { "gzip",     archive_read_support_compression_gzip },
        { "lzma",     archive_read_support_compression_lzma },
        { "none",     archive_read_support_compression_none },
        { "xz",       archive_read_support_compression_xz },
        { NULL,       NULL }
    };

    luaL_checktype(L, 1, LUA_TTABLE);

    self_ref = (struct archive**)
        lua_newuserdata(L, sizeof(struct archive*)); // {ud}
    *self_ref = NULL;
    luaL_getmetatable(L, AR_READ); // {ud}, [read]
    lua_setmetatable(L, -2); // {ud}
    __ref_count++;
    *self_ref = archive_read_new();

    // Register it in the weak metatable:
    ar_registry_set(L, *self_ref);

    // Create an environment to store a reference to the callbacks:
    lua_createtable(L, 1, 0); // {ud}, {fenv}
    lua_getfield(L, 1, "reader"); // {ud}, {fenv}, fn
    if ( ! lua_isfunction(L, -1) ) err("MissingArgument: required parameter 'reader' must be a function");
    lua_setfield(L, -2, "reader"); // {ud}, {fenv}
    lua_setfenv(L, -2); // {ud}

    // Do it the easy way for now... perhaps in the future we will
    // have a parameter to support toggling which algorithms are
    // supported:
    if ( ARCHIVE_OK != archive_read_support_compression_all(*self_ref) ) {
        err("archive_read_support_compression_all: %s", archive_error_string(*self_ref));
    }
    if ( ARCHIVE_OK != archive_read_support_format_all(*self_ref) ) {
        err("archive_read_support_format_all: %s", archive_error_string(*self_ref));
    }


    // Extract various fields and prepare the archive:
    lua_getfield(L, 1, "format");
    if ( NULL == lua_tostring(L, -1) ) {
        lua_pop(L, 1);
        lua_pushliteral(L, "all");
    }
    if ( 0 == call_setters(L,
                           *self_ref,
                           "archive_read_support_format_",
                           format_names,
                           lua_tostring(L, -1)) )
    {
        // We will be strict for now... perhaps in the future we will
        // default to "all"?
        err("empty format='%s' is not allowed, you must specify at least one format",
            lua_tostring(L, -1));
    }
    lua_pop(L, 1);

    lua_getfield(L, 1, "compression");
    if ( NULL == lua_tostring(L, -1) ) {
        lua_pop(L, 1);
        lua_pushliteral(L, "none");
    }
    call_setters(L, 
                 *self_ref,
                 "archive_read_support_compression_",
                 compression_names,
                 lua_tostring(L, -1));
    lua_pop(L, 1);

    lua_getfield(L, 1, "options");
    if ( ! lua_isnil(L, -1) &&
         ARCHIVE_OK != archive_read_set_options(*self_ref, lua_tostring(L, -1)) )
    {
        err("archive_read_set_options: %s",  archive_error_string(*self_ref));
    }
    lua_pop(L, 1);


    if ( ARCHIVE_OK != archive_read_open(*self_ref, L, NULL, &ar_read_cb, NULL) ) {
        err("archive_read_open: %s", archive_error_string(*self_ref));
    }

    return 1;
}
Exemple #28
0
static int
lsave(lua_State *L) {
    int color_type;
    int step;
    int bit_depth = 8;
    const char *filename = luaL_checkstring(L,1);
    const char *type = luaL_checkstring(L,2);
    if (!strcmp(type, "RGBA8")) {
        color_type = PNG_COLOR_TYPE_RGB_ALPHA;
        step = 4;
    } else if (!strcmp(type, "RGB8")) {
        color_type = PNG_COLOR_TYPE_RGB;
        step = 3;
    } else if (!strcmp(type, "GRAY")) {
        color_type = PNG_COLOR_TYPE_GRAY;
        step = 1;
    } else {
        return luaL_error(L, "png type %s not support", type);
    }

    int width = luaL_checkinteger(L,3);
    int height = luaL_checkinteger(L,4);
  
    luaL_checktype(L,5, LUA_TTABLE);
    int n = lua_rawlen(L,5);
    if (n != width * height * step) {
        return luaL_error(L, "Data number %d invalid, should be %d*%d*%d = %d", n,
                width, height, step, width * height * step);
    }
    
    FILE *fp = fopen(filename, "wb");
    if (fp == NULL) {
        return luaL_error(L, strerror(errno));
    }

    png_structp png_ptr;
    png_infop info_ptr;
    png_colorp palette;
    png_bytep *row_pointers;

    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
    if (png_ptr == NULL) {
        return luaL_error(L, "png_create_write_struct fail");
    }

    info_ptr = png_create_info_struct(png_ptr);
    if (info_ptr == NULL) {
        png_destroy_write_struct(&png_ptr, NULL);
        return luaL_error(L, "png_destroy_write_struct fail");
    }

    if (setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_write_struct(&png_ptr, &info_ptr);
        return 0;
    }

    uint8_t *buffer = (uint8_t *)malloc(width * height *step);
    int i;
    for (i=0; i<height *width; ++i) {
        lua_rawgeti(L,5,i*step+1);
        lua_rawgeti(L,5,i*step+2);
        lua_rawgeti(L,5,i*step+3);
        lua_rawgeti(L,5,i*step+4);
        buffer[i*step+0] = (uint8_t)lua_tointeger(L,-4);
        buffer[i*step+1] = (uint8_t)lua_tointeger(L,-3);
        buffer[i*step+2] = (uint8_t)lua_tointeger(L,-2);
        buffer[i*step+3] = (uint8_t)lua_tointeger(L,-1);
        lua_pop(L,4);
    }
    png_init_io(png_ptr, fp);

    png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, 
            color_type, 
            PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

    palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH
            * (sizeof (png_color)));
    png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH);

    png_write_info(png_ptr, info_ptr);

    png_set_packing(png_ptr);

    row_pointers = (png_bytep*)malloc(height * sizeof(png_bytep));

    for (i = 0; i<height; i++)
        row_pointers[i] = buffer + i* width* step;

    png_write_image(png_ptr, row_pointers);

    png_write_end(png_ptr, info_ptr);

    png_free(png_ptr, palette);

    png_destroy_write_struct(&png_ptr, &info_ptr);

    free(row_pointers);
    free(buffer);

    fclose(fp);
    return 0;
}
static int
ngx_http_lua_socket_udp_setpeername(lua_State *L)
{
    ngx_http_request_t          *r;
    ngx_http_lua_ctx_t          *ctx;
    ngx_str_t                    host;
    int                          port;
    ngx_resolver_ctx_t          *rctx, temp;
    ngx_http_core_loc_conf_t    *clcf;
    int                          saved_top;
    int                          n;
    u_char                      *p;
    size_t                       len;
    ngx_url_t                    url;
    ngx_int_t                    rc;
    ngx_http_lua_loc_conf_t     *llcf;
    int                          timeout;
    ngx_http_lua_co_ctx_t       *coctx;

    ngx_http_lua_udp_connection_t           *uc;
    ngx_http_lua_socket_udp_upstream_t      *u;

    /*
     * TODO: we should probably accept an extra argument to setpeername()
     * to allow the user bind the datagram unix domain socket himself,
     * which is necessary for systems without autobind support.
     */

    n = lua_gettop(L);
    if (n != 2 && n != 3) {
        return luaL_error(L, "ngx.socket.udp setpeername: expecting 2 or 3 "
                          "arguments (including the object), but seen %d", n);
    }

    r = ngx_http_lua_get_req(L);
    if (r == NULL) {
        return luaL_error(L, "no request found");
    }

    ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
    if (ctx == NULL) {
        return luaL_error(L, "no ctx found");
    }

    ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE
                               | NGX_HTTP_LUA_CONTEXT_ACCESS
                               | NGX_HTTP_LUA_CONTEXT_CONTENT
                               | NGX_HTTP_LUA_CONTEXT_TIMER
                               | NGX_HTTP_LUA_CONTEXT_SSL_CERT);

    luaL_checktype(L, 1, LUA_TTABLE);

    p = (u_char *) luaL_checklstring(L, 2, &len);

    host.data = ngx_palloc(r->pool, len + 1);
    if (host.data == NULL) {
        return luaL_error(L, "no memory");
    }

    host.len = len;

    ngx_memcpy(host.data, p, len);
    host.data[len] = '\0';

    if (n == 3) {
        port = luaL_checkinteger(L, 3);

        if (port < 0 || port > 65535) {
            lua_pushnil(L);
            lua_pushfstring(L, "bad port number: %d", port);
            return 2;
        }

    } else { /* n == 2 */
        port = 0;
    }

    lua_rawgeti(L, 1, SOCKET_CTX_INDEX);
    u = lua_touserdata(L, -1);
    lua_pop(L, 1);

    if (u) {
        if (u->request && u->request != r) {
            return luaL_error(L, "bad request");
        }

        if (u->waiting) {
            lua_pushnil(L);
            lua_pushliteral(L, "socket busy");
            return 2;
        }

        if (u->udp_connection.connection) {
            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                           "lua udp socket reconnect without shutting down");

            ngx_http_lua_socket_udp_finalize(r, u);
        }

        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "lua reuse socket upstream ctx");

    } else {
        u = lua_newuserdata(L, sizeof(ngx_http_lua_socket_udp_upstream_t));
        if (u == NULL) {
            return luaL_error(L, "no memory");
        }

#if 1
        lua_pushlightuserdata(L, &ngx_http_lua_udp_udata_metatable_key);
        lua_rawget(L, LUA_REGISTRYINDEX);
        lua_setmetatable(L, -2);
#endif

        lua_rawseti(L, 1, SOCKET_CTX_INDEX);
    }

    ngx_memzero(u, sizeof(ngx_http_lua_socket_udp_upstream_t));

    u->request = r; /* set the controlling request */
    llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);

    u->conf = llcf;

    uc = &u->udp_connection;

    uc->log = *r->connection->log;

    dd("lua peer connection log: %p", &uc->log);

    lua_rawgeti(L, 1, SOCKET_TIMEOUT_INDEX);
    timeout = (ngx_int_t) lua_tointeger(L, -1);
    lua_pop(L, 1);

    if (timeout > 0) {
        u->read_timeout = (ngx_msec_t) timeout;

    } else {
        u->read_timeout = u->conf->read_timeout;
    }

    ngx_memzero(&url, sizeof(ngx_url_t));

    url.url.len = host.len;
    url.url.data = host.data;
    url.default_port = (in_port_t) port;
    url.no_resolve = 1;

    if (ngx_parse_url(r->pool, &url) != NGX_OK) {
        lua_pushnil(L);

        if (url.err) {
            lua_pushfstring(L, "failed to parse host name \"%s\": %s",
                            host.data, url.err);

        } else {
            lua_pushfstring(L, "failed to parse host name \"%s\"", host.data);
        }

        return 2;
    }

    u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t));
    if (u->resolved == NULL) {
        return luaL_error(L, "no memory");
    }

    if (url.addrs && url.addrs[0].sockaddr) {
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "lua udp socket network address given directly");

        u->resolved->sockaddr = url.addrs[0].sockaddr;
        u->resolved->socklen = url.addrs[0].socklen;
        u->resolved->naddrs = 1;
        u->resolved->host = url.addrs[0].name;

    } else {
        u->resolved->host = host;
        u->resolved->port = (in_port_t) port;
    }

    if (u->resolved->sockaddr) {
        rc = ngx_http_lua_socket_resolve_retval_handler(r, u, L);
        if (rc == NGX_AGAIN) {
            return lua_yield(L, 0);
        }

        return rc;
    }

    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

    temp.name = host;
    rctx = ngx_resolve_start(clcf->resolver, &temp);
    if (rctx == NULL) {
        u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER;
        lua_pushnil(L);
        lua_pushliteral(L, "failed to start the resolver");
        return 2;
    }

    if (rctx == NGX_NO_RESOLVER) {
        u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER;
        lua_pushnil(L);
        lua_pushfstring(L, "no resolver defined to resolve \"%s\"", host.data);
        return 2;
    }

    rctx->name = host;
#if !defined(nginx_version) || nginx_version < 1005008
    rctx->type = NGX_RESOLVE_A;
#endif
    rctx->handler = ngx_http_lua_socket_resolve_handler;
    rctx->data = u;
    rctx->timeout = clcf->resolver_timeout;

    u->co_ctx = ctx->cur_co_ctx;
    u->resolved->ctx = rctx;

    saved_top = lua_gettop(L);

    coctx = ctx->cur_co_ctx;
    ngx_http_lua_cleanup_pending_operation(coctx);
    coctx->cleanup = ngx_http_lua_udp_resolve_cleanup;

    if (ngx_resolve_name(rctx) != NGX_OK) {
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "lua udp socket fail to run resolver immediately");

        u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER;

        u->resolved->ctx = NULL;
        lua_pushnil(L);
        lua_pushfstring(L, "%s could not be resolved", host.data);

        return 2;
    }

    if (u->waiting == 1) {
        /* resolved and already connecting */
        return lua_yield(L, 0);
    }

    n = lua_gettop(L) - saved_top;
    if (n) {
        /* errors occurred during resolving or connecting
         * or already connected */
        return n;
    }

    /* still resolving */

    u->waiting = 1;
    u->prepare_retvals = ngx_http_lua_socket_resolve_retval_handler;

    coctx->data = u;

    if (ctx->entered_content_phase) {
        r->write_event_handler = ngx_http_lua_content_wev_handler;

    } else {
        r->write_event_handler = ngx_http_core_run_phases;
    }

    return lua_yield(L, 0);
}
Exemple #30
0
static int luaB_rawget (lua_State *L) {
  luaL_checktype(L, 1, LUA_TTABLE);
  luaL_checkany(L, 2);
  lua_rawget(L, 1);
  return 1;
}