Пример #1
0
static int aux_close (lua_State *L) {
  lua_getfenv(L, 1);
  lua_getfield(L, -1, "__close");
  return (lua_tocfunction(L, -1))(L);
}
Пример #2
0
static int aux_getfenv (lua_State *L) {
  lua_getfenv(L, -1);
  lua_pushliteral(L, "__fenv");
  lua_rawget(L, -2);
  return !lua_isnil(L, -1);
}
Пример #3
0
/* Registers a callback, callback_index can't be negative */
void luv_register_event(lua_State* L, int userdata_index, const char* name, int callback_index) {
  lua_getfenv(L, userdata_index);
  lua_pushvalue(L, callback_index);
  lua_setfield(L, -2, name);
  lua_pop(L, 1);
}
Пример #4
0
//! Get a field from the environment table of an object
void luaT_getenvfield(lua_State *L, int index, const char *k)
{
    lua_getfenv(L, index);
    lua_getfield(L, -1, k);
    lua_replace(L, -2);
}
Пример #5
0
static void
lua_getuservalue(lua_State *L, int idx) {
    lua_getfenv(L, idx);
}
Пример #6
0
void LuaInterface::getEnv(int index)
{
    assert(hasIndex(index));
    lua_getfenv(L, index);
}
Пример #7
0
static int db_getfenv (lua_State *L) {
  lua_getfenv(L, 1);
  return 1;
}
Пример #8
0
static int db_getfenv (lua_State *L) {
  luaL_checkany(L, 1);
  lua_getfenv(L, 1);
  return 1;
}
Пример #9
0
/* Class index function
	* If the object is a userdata (ie, an object), it searches the field in
	* the alternative table stored in the corresponding "ubox" table.
*/
static int class_index_event (lua_State* L)
{
 int t = lua_type(L,1);
	if (t == LUA_TUSERDATA)
	{
		/* Access alternative table */
		#ifdef LUA_VERSION_NUM /* new macro on version 5.1 */
		lua_getfenv(L,1);
		if (!lua_rawequal(L, -1, TOLUA_NOPEER)) {
			lua_pushvalue(L, 2); /* key */
			lua_gettable(L, -2); /* on lua 5.1, we trade the "tolua_peers" lookup for a gettable call */
			if (!lua_isnil(L, -1))
				return 1;
		};
		#else
		lua_pushstring(L,"tolua_peers");
		lua_rawget(L,LUA_REGISTRYINDEX);        /* stack: obj key ubox */
		lua_pushvalue(L,1);
		lua_rawget(L,-2);                       /* stack: obj key ubox ubox[u] */
		if (lua_istable(L,-1))
		{
			lua_pushvalue(L,2);  /* key */
			lua_rawget(L,-2);                      /* stack: obj key ubox ubox[u] value */
			if (!lua_isnil(L,-1))
				return 1;
		}
		#endif
		lua_settop(L,2);                        /* stack: obj key */
		/* Try metatables */
		lua_pushvalue(L,1);                     /* stack: obj key obj */
		while (lua_getmetatable(L,-1))
		{                                       /* stack: obj key obj mt */
			lua_remove(L,-2);                      /* stack: obj key mt */
			if (lua_isnumber(L,2))                 /* check if key is a numeric value */
			{
				/* try operator[] */
				lua_pushstring(L,".geti");
				lua_rawget(L,-2);                      /* stack: obj key mt func */
				if (lua_isfunction(L,-1))
				{
					lua_pushvalue(L,1);
					lua_pushvalue(L,2);
					lua_call(L,2,1);
					return 1;
				}
			}
			else
			{
			 lua_pushvalue(L,2);                    /* stack: obj key mt key */
				lua_rawget(L,-2);                      /* stack: obj key mt value */
				if (!lua_isnil(L,-1))
					return 1;
				else
					lua_pop(L,1);
				/* try C/C++ variable */
				lua_pushstring(L,".get");
				lua_rawget(L,-2);                      /* stack: obj key mt tget */
				if (lua_istable(L,-1))
				{
					lua_pushvalue(L,2);
					lua_rawget(L,-2);                      /* stack: obj key mt value */
					if (lua_iscfunction(L,-1))
					{
						lua_pushvalue(L,1);
						lua_pushvalue(L,2);
						lua_call(L,2,1);
						return 1;
					}
					else if (lua_istable(L,-1))
					{
						/* deal with array: create table to be returned and cache it in ubox */
						void* u = *((void**)lua_touserdata(L,1));
						lua_newtable(L);                /* stack: obj key mt value table */
						lua_pushstring(L,".self");
						lua_pushlightuserdata(L,u);
						lua_rawset(L,-3);               /* store usertype in ".self" */
						lua_insert(L,-2);               /* stack: obj key mt table value */
						lua_setmetatable(L,-2);         /* set stored value as metatable */
						lua_pushvalue(L,-1);            /* stack: obj key met table table */
						lua_pushvalue(L,2);             /* stack: obj key mt table table key */
						lua_insert(L,-2);               /*  stack: obj key mt table key table */
						storeatubox(L,1);               /* stack: obj key mt table */
						return 1;
					}
				}
			}
			lua_settop(L,3);
		}
		lua_pushnil(L);
		return 1;
	}
	else if (t== LUA_TTABLE)
	{
		module_index_event(L);
		return 1;
	}
	lua_pushnil(L);
	return 1;
}
Пример #10
0
/*
 * Arguments: dpool_udata, [timeout (milliseconds)]
 * Returns: data_items (any) ...
 */
static int
dpool_get (lua_State *L)
{
    struct sys_thread *td = sys_thread_get();
    struct data_pool *dp = checkudata(L, 1, DPOOL_TYPENAME);
    const msec_t timeout = lua_isnoneornil(L, 2)
     ? TIMEOUT_INFINITE : (msec_t) lua_tointeger(L, 2);
    int nput;

    if (!td) luaL_argerror(L, 0, "Threading not initialized");

    lua_settop(L, 1);
    lua_getfenv(L, 1);  /* storage */
    lua_insert(L, 1);

    if ((dp->flags & DPOOL_GETONEMPTY) && !dp->n) {
	lua_rawgetp(L, 1, (void *) DPOOL_GETONEMPTY);
	lua_insert(L, 2);
	lua_call(L, 1, LUA_MULTRET);
	nput = lua_gettop(L) - 1;
	if (nput) return nput;
    }

    for (; ; ) {
	/* get from storage */
	if (dp->n) {
	    const int idx = dp->idx + 1;
	    int i;

	    lua_rawgeti(L, 1, idx);
	    nput = lua_tointeger(L, -1);
	    lua_pushnil(L);
	    lua_rawseti(L, 1, idx);
	    dp->idx = idx + nput;
	    for (i = dp->idx; i > idx; --i) {
		lua_rawgeti(L, 1, i);
		lua_pushnil(L);
		lua_rawseti(L, 1, i);
	    }
	    if (dp->idx == dp->top)
		dp->idx = dp->top = 0;
	    if (dp->n-- == dp->max) {
		thread_event_signal(&dp->tev);
	    }
	    return nput;
	}

	/* wait signal */
	{
	    int res;

	    dp->nwaits++;
	    res = thread_event_wait(&dp->tev, td, timeout);
	    dp->nwaits--;

	    sys_thread_check(td);
	    if (res) {
		if (res == 1) {
		    lua_pushboolean(L, 0);
		    return 1;  /* timed out */
		}
		return sys_seterror(L, 0);
	    }
	}

	/* get directly from another thread */
	nput = dp->nput;
	if (nput) {
	    dp->nput = 0;
	    luaL_checkstack(L, nput, NULL);
	    lua_xmove(dp->td->L, L, nput);
	    return nput;
	}
    }
}
Пример #11
0
/**
 * walk through the content array
 *
 * content = { "<pre>", { file = "/content" } , "</pre>" }
 *
 * header["Content-Type"] = "text/html"
 *
 * return 200
 */
static int
magnet_attach_content(server * srv, connection * con, plugin_data * p,
					  lua_State * L)
{
	UNUSED(p);
	/**
	 * get the environment of the function
	 */

	assert(lua_isfunction(L, -1));
	lua_getfenv(L, -1);			/* -1 is the function */

	lua_getfield(L, -1, "lighty");	/* lighty.* from the env */
	assert(lua_istable(L, -1));

	lua_getfield(L, -1, "content");	/* lighty.content */
	if (lua_istable(L, -1))
	{
		int i;
		/*
		 * header is found, and is a table 
		 */

		for (i = 1;; i++)
		{
			lua_rawgeti(L, -1, i);

			/*
			 * -1 is the value and should be the value ... aka a table 
			 */
			if (lua_isstring(L, -1))
			{
				size_t s_len = 0;
				const char *s = lua_tolstring(L, -1, &s_len);

				chunkqueue_append_mem(con->write_queue, s, s_len + 1);
			} else if (lua_istable(L, -1))
			{
				lua_getfield(L, -1, "filename");
				lua_getfield(L, -2, "length");
				lua_getfield(L, -3, "offset");

				if (lua_isstring(L, -3))
				{				/* filename has to be a string */
					buffer *fn = buffer_init();
					stat_cache_entry *sce;

					buffer_copy_string(fn, lua_tostring(L, -3));

					if (HANDLER_GO_ON ==
						stat_cache_get_entry(srv, con, fn, &sce))
					{
						off_t off = 0;
						off_t len = 0;

						if (lua_isnumber(L, -1))
						{
							off = lua_tonumber(L, -1);
						}

						if (lua_isnumber(L, -2))
						{
							len = lua_tonumber(L, -2);
						} else
						{
							len = sce->st.st_size;
						}

						if (off < 0)
						{
							return luaL_error(L,
											  "offset for '%s' is negative",
											  fn->ptr);
						}

						if (len < off)
						{
							return luaL_error(L,
											  "offset > length for '%s'",
											  fn->ptr);
						}

						chunkqueue_append_file(con->write_queue,
											   fn, off, len - off);
					}

					buffer_free(fn);
				} else
				{
					lua_pop(L, 3 + 2);	/* correct the stack */

					return luaL_error(L,
									  "content[%d] is a table and requires the field \"filename\"",
									  i);
				}

				lua_pop(L, 3);
			} else if (lua_isnil(L, -1))
			{
				/*
				 * oops, end of list 
				 */

				lua_pop(L, 1);

				break;
			} else
			{
				lua_pop(L, 4);

				return luaL_error(L,
								  "content[%d] is neither a string nor a table: ",
								  i);
			}

			lua_pop(L, 1);		/* pop the content[...] table */
		}
	} else
	{
		return luaL_error(L, "lighty.content has to be a table");
	}
	lua_pop(L, 1);				/* pop the header-table */
	lua_pop(L, 1);				/* pop the lighty-table */
	lua_pop(L, 1);				/* php the function env */

	return 0;
}
Пример #12
0
int main(int argc, const char **argv)
{
    bind_port = default_port;
    char *cwd = init_process_title(argc, argv);
    char *msg = NULL;
    update_time();

    if(getarg("cache-size")) {
        msg = getarg("cache-size");
        YAC_CACHE_SIZE = atoi(msg);

        if(msg[strlen(msg) - 1] == 'm') {
            YAC_CACHE_SIZE = YAC_CACHE_SIZE * 1024 * 1024;

        } else if(msg[strlen(msg) - 1] == 'k') {
            YAC_CACHE_SIZE = YAC_CACHE_SIZE * 1024;
        }

    }

    if(YAC_CACHE_SIZE < 1024 * 1024 * 2) {
        YAC_CACHE_SIZE = 1024 * 1024 * 2;
    }

    if(!yac_storage_startup(YAC_CACHE_SIZE / 16, YAC_CACHE_SIZE - (YAC_CACHE_SIZE / 16), &msg)) {
        LOGF(ERR, "Shared memory allocator startup failed at '%s': %s", msg, strerror(errno));
        exit(1);
    }

    lua_State *L = luaL_newstate();

    if(!L) {
        LOGF(ERR, "error for luaL_newstate");
        exit(1);
    }

    luaL_openlibs(L);
    lua_getglobal(L, "_VERSION");
    const char *lua_ver = lua_tostring(L, -1);
    lua_getglobal(L, "jit");

    if(lua_istable(L, -1)) {
        lua_getfield(L, -1, "version");

        if(lua_isstring(L, -1)) {
            lua_ver = lua_tostring(L, -1);
        }
    }

    sprintf(hostname, "%s", lua_ver);
    lua_close(L);

    _L = luaL_newstate();
    lua_gc(_L, LUA_GCSTOP, 0);
    luaL_openlibs(_L);    /* Load Lua libraries */
    lua_gc(_L, LUA_GCRESTART, 0);

    if(getarg("host-route")) {
        lua_pushstring(_L, getarg("host-route"));
        lua_setglobal(_L, "HOST_ROUTE");
    }

    if(!update_vhost_routes(getarg("host-route")) && !getarg("app")) {
        LOGF(WARN, "no host-route or app arguments! using defalut settings.");
        sprintf(tbuf_4096, "%s/host-route.lua", process_chdir);
        update_vhost_routes(tbuf_4096);
    }

    if(getarg("code-cache-ttl")) {       /// default = 60s
        lua_pushnumber(_L, atoi(getarg("code-cache-ttl")));
        lua_setglobal(_L, "CODE_CACHE_TTL");

    } else {
        lua_pushnumber(_L, code_cache_ttl);
        lua_setglobal(_L, "CODE_CACHE_TTL");
    }

    lua_getglobal(_L, "require");
    lua_pushcfunction(_L, lua_f_package_require);
    lua_getfenv(_L, -2);
    int ret = lua_setfenv(_L, -2);
    lua_setglobal(_L, "require");
    lua_pop(_L, 1);

    lua_register(_L, "echo", lua_echo);
    lua_register(_L, "print_error", lua_print_error);
    lua_register(_L, "sendfile", lua_sendfile);
    lua_register(_L, "header", lua_header);
    lua_register(_L, "clear_header", lua_clear_header);
    lua_register(_L, "__end", lua_end);
    lua_register(_L, "die", lua_die);
    lua_register(_L, "flush", lua_flush);
    lua_register(_L, "read_request_body", lua_read_request_body);
    lua_register(_L, "get_boundary", lua_f_get_boundary);
    lua_register(_L, "check_timeout", lua_check_timeout);
    lua_register(_L, "is_websocket", lua_f_is_websocket);
    lua_register(_L, "upgrade_to_websocket", lua_f_upgrade_to_websocket);
    lua_register(_L, "websocket_send", lua_f_websocket_send);
    lua_register(_L, "check_websocket_close", lua_f_check_websocket_close);

    lua_register(_L, "router", lua_f_router);

    lua_register(_L, "random_string", lua_f_random_string);
    lua_register(_L, "file_exists", lua_f_file_exists);
    lua_register(_L, "readfile", lua_f_readfile);
    lua_register(_L, "filemtime", lua_f_filemtime);

    lua_register(_L, "cache_set", lua_f_cache_set);
    lua_register(_L, "cache_get", lua_f_cache_get);
    lua_register(_L, "cache_del", lua_f_cache_del);

    luaopen_fastlz(_L);
    luaopen_coevent(_L);
    luaopen_libfs(_L);
    luaopen_string_utils(_L);
    luaopen_i18n(_L);
    luaopen_crypto(_L);

    lua_pop(_L, 1);

    sprintf(tbuf_4096,
            "package.path = '%slua-libs/?.lua;' .. package.path package.cpath = '%slua-libs/?.so;' .. package.cpath", cwd, cwd);
    luaL_dostring(_L, tbuf_4096);

    luaL_dostring(_L, ""
                  "if not CODE_CACHE_TTL then CODE_CACHE_TTL = 60 end " \
                  "startloop = nil __CodeCache = {{},{}} __CodeCacheC = {false,false} "
                 );

    if(getarg("accesslog")) {
        ACCESS_LOG = open_log(getarg("accesslog"), 40960);

        if(!ACCESS_LOG) {
            LOGF(ERR, "Couldn't open access log file: %s", getarg("accesslog"));
        }
    }

    if(getarg("ssl-bind") && getarg("ssl-cert") && getarg("ssl-key")) {
        ssl_ctx = SSL_CTX_new(SSLv23_server_method());

        if(!ssl_ctx) {
            LOGF(ERR, "SSL_CTX_new Failed");
            exit(1);
        }

        if(SSL_CTX_use_certificate_file(ssl_ctx, getarg("ssl-cert"), SSL_FILETYPE_PEM) != 1) {
            SSL_CTX_free(ssl_ctx);
            LOGF(ERR, "SSL_CTX_use_certificate_file");
            exit(1);
        }

        if(SSL_CTX_use_PrivateKey_file(ssl_ctx, getarg("ssl-key"), SSL_FILETYPE_PEM) != 1) {
            SSL_CTX_free(ssl_ctx);
            LOGF(ERR, "SSL_CTX_use_PrivateKey_file");
            exit(1);
        }

        SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL);

        if(getarg("ssl-ca")) {
            ssl_epd_idx = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);

            if(ssl_epd_idx == -1) {
                LOGF(ERR, "SSL_get_ex_new_index Failed");
                exit(1);
            }

            if(SSL_CTX_load_verify_locations(ssl_ctx, getarg("ssl-ca"), NULL) != 1) {
                SSL_CTX_free(ssl_ctx);
                LOGF(ERR, "SSL_CTX_load_verify_locations");
                exit(1);

            } else {
                SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback);
                SSL_CTX_set_verify_depth(ssl_ctx, 4);

            }
        }
    }

    _shm_serv_status = shm_malloc(sizeof(serv_status_t));
    bzero(_shm_serv_status->p, sizeof(serv_status_t));

    attach_on_exit(on_master_exit_handler);
    return merry_start(argc, argv, help, master_main, on_master_exit_handler, worker_main, 0);
}
Пример #13
0
static int l_str_reload_actual(lua_State *L)
{
    // Reload a single string proxy
    // Stack: reload_cache proxy_to_reload <top

    // Mark string as reloaded
    lua_pushvalue(L, 2);
    lua_pushvalue(L, 2);
    lua_settable(L, 1);

    // Pull instructions out of the environment and remake value
    lua_getfenv(L, 2);
    bool bIsIndexOperation = false;
    int iCount = (int)lua_objlen(L, 3);
    aux_push_weak_table(L, 0);
    lua_pushvalue(L, 2);
    if(iCount != 0)
    {
        // Fetch reconstruction information, reloading any de-proxying any
        // string proxies which we come across. Also replace any references
        // to the root with the new root.
        lua_checkstack(L, iCount + 1);
        for(int i = 1; i <= iCount; ++i)
        {
            lua_rawgeti(L, 3, i);
            if(lua_type(L, -1) == LUA_TUSERDATA)
            {
                if(i == 1)
                    bIsIndexOperation = true;
                lua_gettable(L, 1); // reload / change root
                lua_pushvalue(L, -1);
                lua_rawseti(L, 3, i);
                lua_rawget(L, 4); // de-proxy
            }
        }

        if(iCount == 2 && bIsIndexOperation)
        {
            // If there were two values, and the first was a proxy, then the
            // instruction is to perform a table lookup.
            lua_gettable(L, -2);
            lua_replace(L, -2);
        }
        else
        {
            // Otherwise, the first value was a method or method name.
            if(lua_type(L, 6) != LUA_TFUNCTION)
            {
                lua_pushvalue(L, 6);
                lua_gettable(L, 7);
                lua_replace(L, 6);
            }
            lua_call(L, iCount - 1, 1);
        }
    }
    else
    {
        // Root object
        lua_settop(L, 2);
        return 1;
    }
    // Update value
    lua_rawset(L, -3);
    lua_pop(L, 2);
    return 1;
}
Пример #14
0
// __depersist metamethod handler
static int l_str_depersist(lua_State *L)
{
    lua_settop(L, 2);
    lua_insert(L, 1);
    LuaPersistReader *pReader = (LuaPersistReader*)lua_touserdata(L, 1);

    // Read the instructions for re-creating the value
    if(!pReader->readStackObject())
        return 0;
    if(lua_type(L, 3) == LUA_TBOOLEAN && lua_toboolean(L, 3) == 1)
    {
        // The current code uses a boolean marker to indicate that the
        // instructions were stored in the environment. Replace the marker
        // with them.
        lua_getfenv(L, 2);
        lua_replace(L, 3);
    }
    else
    {
        // Older versions of the code wrote the instructions here, or nil for
        // no instructions. Convert nil to the empty table, and store the
        // instructions as the userdata's environment.
        if(lua_type(L, 3) == LUA_TNIL)
        {
            lua_newtable(L);
            lua_replace(L, 3);
        }
        lua_pushvalue(L, 3);
        lua_setfenv(L, 2);
    }

    // Prepare t, k for saving the value
    aux_push_weak_table(L, 0);
    lua_pushvalue(L, 2);

    if(lua_objlen(L, 3) == 0)
    {
        // No instructions provided, so read the value itself
        if(!pReader->readStackObject())
            return 0;
    }
    else
    {
        // The instructions are a table of values; unpack them and replace
        // proxies with their values.
        bool bIsIndexOperation = false;
        int iCount = (int)lua_objlen(L, 3);
        lua_checkstack(L, iCount + 1);
        for(int i = 1; i <= iCount; ++i)
        {
            lua_rawgeti(L, 3, i);
            if(lua_type(L, -1) == LUA_TUSERDATA)
            {
                if(i == 1)
                    bIsIndexOperation = true;
                lua_rawget(L, 4);
            }
        }

        if(iCount == 2 && bIsIndexOperation)
        {
            // If there were two values, and the first was a proxy, then the
            // instruction is to perform a table lookup.
            lua_gettable(L, -2);
            lua_replace(L, -2);
        }
        else
        {
            // Otherwise, the first value was a method or method name.
            if(lua_type(L, 6) != LUA_TFUNCTION)
            {
                lua_pushvalue(L, 6);
                lua_gettable(L, 7);
                lua_replace(L, 6);
            }
            lua_call(L, iCount - 1, 1);
        }
    }

    // Save the value
    lua_rawset(L, 4);
    return 0;
}