static ngx_int_t
ngx_http_lua_balancer_by_chunk(lua_State *L, ngx_http_request_t *r)
{
    u_char                  *err_msg;
    size_t                   len;
    ngx_int_t                rc;
    ngx_http_lua_ctx_t      *ctx;

    ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);

    if (ctx == NULL) {
        ctx = ngx_http_lua_create_ctx(r);
        if (ctx == NULL) {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

    } else {
        dd("reset ctx");
        ngx_http_lua_reset_ctx(r, L, ctx);
    }

    ctx->context = NGX_HTTP_LUA_CONTEXT_BALANCER;

    /* init nginx context in Lua VM */
    ngx_http_lua_set_req(L, r);
    ngx_http_lua_create_new_globals_table(L, 0 /* narr */, 1 /* nrec */);

    /*  {{{ make new env inheriting main thread's globals table */
    lua_createtable(L, 0, 1 /* nrec */);   /* the metatable for the new env */
    ngx_http_lua_get_globals_table(L);
    lua_setfield(L, -2, "__index");
    lua_setmetatable(L, -2);    /*  setmetatable({}, {__index = _G}) */
    /*  }}} */

    lua_setfenv(L, -2);    /*  set new running env for the code closure */

    lua_pushcfunction(L, ngx_http_lua_traceback);
    lua_insert(L, 1);  /* put it under chunk and args */

    /*  protected call user code */
    rc = lua_pcall(L, 0, 1, 1);

    lua_remove(L, 1);  /* remove traceback function */

    dd("rc == %d", (int) rc);

    if (rc != 0) {
        /*  error occured when running loaded code */
        err_msg = (u_char *) lua_tolstring(L, -1, &len);

        if (err_msg == NULL) {
            err_msg = (u_char *) "unknown reason";
            len = sizeof("unknown reason") - 1;
        }

        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                      "failed to run balancer_by_lua*: %*s", len, err_msg);

        lua_settop(L, 0); /*  clear remaining elems on stack */

        return NGX_ERROR;
    }

    lua_settop(L, 0); /*  clear remaining elems on stack */
    return rc;
}
Beispiel #2
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;
}
Beispiel #3
0
/*!
 * \brief Locate an extensions and optionally push the matching function on the
 * stack
 *
 * \param L the lua_State to use
 * \param context the context to look in
 * \param exten the extension to look up
 * \param priority the priority to check, '1' is the only valid priority
 * \param func the calling func, used to adjust matching behavior between,
 * match, canmatch, and matchmore
 * \param push_func whether or not to push the lua function for the given
 * extension onto the stack
 */
static int lua_find_extension(lua_State *L, const char *context, const char *exten, int priority, ast_switch_f *func, int push_func)
{
	int context_table, context_order_table, i;

	ast_debug(2, "Looking up %[email protected]%s:%i\n", exten, context, priority);
	if (priority != 1)
		return 0;

	/* load the 'extensions' table */
	lua_getglobal(L, "extensions");
	if (lua_isnil(L, -1)) {
		ast_log(LOG_ERROR, "Unable to find 'extensions' table in extensions.lua\n");
		lua_pop(L, 1);
		return 0;
	}

	/* load the given context */
	lua_getfield(L, -1, context);
	if (lua_isnil(L, -1)) {
		lua_pop(L, 2);
		return 0;
	}

	/* remove the extensions table */
	lua_remove(L, -2);

	context_table = lua_gettop(L);

	/* load the extensions order table for this context */
	lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order");
	lua_getfield(L, -1, context);

	lua_remove(L, -2);  /* remove the extensions order table */

	context_order_table = lua_gettop(L);
	
	/* step through the extensions looking for a match */
	for (i = 1; i < lua_objlen(L, context_order_table) + 1; i++) {
		int e_index, e_index_copy, match = 0;
		const char *e;

		lua_pushinteger(L, i);
		lua_gettable(L, context_order_table);
		e_index = lua_gettop(L);

		/* copy the key at the top of the stack for use later */
		lua_pushvalue(L, -1);
		e_index_copy = lua_gettop(L);

		if (!(e = lua_tostring(L, e_index_copy))) {
			lua_pop(L, 2);
			continue;
		}

		/* make sure this is not the 'include' extension */
		if (!strcasecmp(e, "include")) {
			lua_pop(L, 2);
			continue;
		}

		if (func == &matchmore)
			match = ast_extension_close(e, exten, E_MATCHMORE);
		else if (func == &canmatch)
			match = ast_extension_close(e, exten, E_CANMATCH);
		else
			match = ast_extension_match(e, exten);

		/* the extension matching functions return 0 on fail, 1 on
		 * match, 2 on earlymatch */

		if (!match) {
			/* pop the copy and the extension */
			lua_pop(L, 2);
			continue;	/* keep trying */
		}

		if (func == &matchmore && match == 2) {
			/* We match an extension ending in '!'. The decision in
			 * this case is final and counts as no match. */
			lua_pop(L, 4);
			return 0;
		}

		/* remove the context table, the context order table, the
		 * extension, and the extension copy (or replace the extension
		 * with the corresponding function) */
		if (push_func) {
			lua_pop(L, 1);  /* pop the copy */
			lua_gettable(L, context_table);
			lua_insert(L, -3);
			lua_pop(L, 2);
		} else {
			lua_pop(L, 4);
		}

		return 1;
	}

	/* load the includes for this context */
	lua_getfield(L, context_table, "include");
	if (lua_isnil(L, -1)) {
		lua_pop(L, 3);
		return 0;
	}

	/* remove the context and the order table*/
	lua_remove(L, context_order_table);
	lua_remove(L, context_table);

	/* Now try any includes we have in this context */
	for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
		const char *c = lua_tostring(L, -1);
		if (!c)
			continue;

		if (lua_find_extension(L, c, exten, priority, func, push_func)) {
			/* remove the value, the key, and the includes table
			 * from the stack.  Leave the function behind if
			 * necessary */

			if (push_func)
				lua_insert(L, -4);

			lua_pop(L, 3);
			return 1;
		}
	}

	/* pop the includes table */
	lua_pop(L, 1);
	return 0;
}
Beispiel #4
0
/**
  * wifi.sta.config()
  * Description:
  * 	Set current Station configuration.
  * 	Note: If there are multiple APs with the same ssid, you can connect to a specific one by entering it's MAC address into the "bssid" field.
  * Syntax:
  * 	wifi.sta.getconfig(ssid, password) --Set STATION configuration, Auto-connect by default, Connects to any BSSID
  * 	wifi.sta.getconfig(ssid, password, Auto_connect) --Set STATION configuration, Auto-connect(0 or 1), Connects to any BSSID
  * 	wifi.sta.getconfig(ssid, password, bssid) --Set STATION configuration, Auto-connect by default, Connects to specific BSSID
  * 	wifi.sta.getconfig(ssid, password, Auto_connect, bssid) --Set STATION configuration, Auto-connect(0 or 1), Connects to specific BSSID
  * Parameters:
  * 	ssid: string which is less than 32 bytes.
  * 	Password: string which is less than 64 bytes.
  * 	Auto_connect: 0 (disable Auto-connect) or 1 (to enable Auto-connect).
  * 	bssid: MAC address of Access Point you would like to connect to.
  * Returns:
  * 	Nothing.
  *
  *	Example:
  	  	--Connect to Access Point automatically when in range
  	  	wifi.sta.getconfig("myssid", "password")

  	  	--Connect to Access Point, User decides when to connect/disconnect to/from AP
  	  	wifi.sta.getconfig("myssid", "mypassword", 0)
  	  	wifi.sta.connect()
  	  	--do some wifi stuff
  	  	wifi.sta.disconnect()

  	  	--Connect to specific Access Point automatically when in range
  	  	wifi.sta.getconfig("myssid", "mypassword", "12:34:56:78:90:12")

  	  	--Connect to specific Access Point, User decides when to connect/disconnect to/from AP
  	  	wifi.sta.getconfig("myssid", "mypassword", 0)
  	  	wifi.sta.connect()
  	  	--do some wifi stuff
  	  	wifi.sta.disconnect()
  *
  */
static int wifi_station_config( lua_State* L )
{
  size_t sl, pl, ml;
  struct station_config sta_conf;
  int auto_connect=0;
  const char *ssid = luaL_checklstring( L, 1, &sl );
  if (sl>32 || ssid == NULL)
    return luaL_error( L, "ssid:<32" );
  const char *password = luaL_checklstring( L, 2, &pl );
  if (pl!=0 && (pl<8 || pl>64) || password == NULL)
    return luaL_error( L, "pwd:0,8~64" );

  if(lua_isnumber(L, 3))
  {
    auto_connect=luaL_checkinteger( L, 3 );;
    if ( auto_connect != 0 && auto_connect != 1)
    	return luaL_error( L, "wrong arg type" );
  }
  else if (lua_isstring(L, 3)&& !(lua_isnumber(L, 3)))
  {
	  lua_pushnil(L);
	  lua_insert(L, 3);
	  auto_connect=1;

  }
  else
  {
    if(lua_isnil(L, 3))
	   	return luaL_error( L, "wrong arg type" );
	auto_connect=1;
  }

  if(lua_isnumber(L, 4))
  {
    sta_conf.bssid_set = 0;
	c_memset(sta_conf.bssid, 0, 6);
  }
  else
  {
    if (lua_isstring(L, 4))
	{
	  const char *macaddr = luaL_checklstring( L, 4, &ml );
	  if (ml!=17)
	    return luaL_error( L, "MAC:FF:FF:FF:FF:FF:FF" );
	  c_memset(sta_conf.bssid, 0, 6);
	  os_str2macaddr(sta_conf.bssid, macaddr);
	  sta_conf.bssid_set = 1;
	}
	else
	{
	  sta_conf.bssid_set = 0;
	  c_memset(sta_conf.bssid, 0, 6);
	}
  }

  c_memset(sta_conf.ssid, 0, 32);
  c_memset(sta_conf.password, 0, 64);
  c_memcpy(sta_conf.ssid, ssid, sl);
  c_memcpy(sta_conf.password, password, pl);

  NODE_DBG(sta_conf.ssid);
  NODE_DBG(" %d\n", sl);
  NODE_DBG(sta_conf.password);
  NODE_DBG(" %d\n", pl);
  NODE_DBG(" %d\n", sta_conf.bssid_set);
  NODE_DBG( MACSTR, MAC2STR(sta_conf.bssid));
  NODE_DBG("\n");


  wifi_station_set_config(&sta_conf);
  wifi_station_disconnect();

  if(auto_connect==0)
  {
    wifi_station_set_auto_connect(false);

  }
  else
  {
    wifi_station_set_auto_connect(true);
    wifi_station_connect();
  }
//  station_check_connect(0);
  return 0;  
}
Beispiel #5
0
/*
* Function used as a callback for all Lua functions passed through
* get_as3_value_from_lua_stack()
*/
AS3_Val as3_lua_callback(void * data, AS3_Val args)
{
  /* WARNING: Panic alert! Use L*_FN checkers here! */

  SPAM(("as3_lua_callback(): begin"));

  AS3_Val res;
  LuaFunctionCallbackData * func_data = (LuaFunctionCallbackData *) data;
  int nargs = 0;
  int status = 0;
  int results_base = 0;
  lua_State * L = func_data->L;
  if (L == NULL)
  {
    /* TODO: Should we crash here?
    fatal_error("state expired"); / * Does not return * /
    */
    sztrace("as3_lua_callback: state expired");
    return AS3_Undefined();
  }

  { /* A new scope for LCALL to work (C89 conformance) */
    LCALL(L, stack);

    /* TODO: Cache that with lua_ref, it is faster */
    lua_getfield(L, LUA_REGISTRYINDEX, AS3LUA_CALLBACKS);

    /* TODO: Assert we have a table here */

    lua_rawgeti(L, -1, func_data->ref); /* push stored function */

    if (lua_istable(L, -1) == 0) /* Probably nil */
    {
      lua_pop(L, 1); /* Pop bad callback table */
      LCHECK_FN(L, stack, 0, fatal_error);

      fatal_error("function callback not found"); /* Does not return */
    }

    lua_rawgeti(L, -1, AS3LUA_CBFNINDEX); /* push stored callback function */

 #ifdef DO_SPAM
  {
    SPAM(("as3_lua_callback(): AS3 arguments"));
    AS3_Val a = AS3_CallS("join", args, AS3_Undefined());
    AS3_Trace(a);
    SAFE_RELEASE(a);
  }
#endif /* DO_SPAM */


    /* TODO: Assert we have Lua function (or other callable object) on the top of the stack */

    LCHECK_FN(L, stack, 2 + 1, fatal_error);

    nargs = push_as3_array_to_lua_stack(L, args); /* push arguments */

#ifdef DO_SPAM
    /* TODO: Remove */
    lua_pushcfunction(L, as3_trace);
    dump_lua_stack(L, LBASE(L, stack) + 2 + 1);
    lua_pushliteral(L, "ARGUMENTS");
    lua_pushnumber(L, nargs);
    lua_call(L, 3, 0);
#endif /* DO_SPAM */

    LCHECK_FN(L, stack, 2 + 1 + nargs, fatal_error);

    results_base = LBASE(L, stack) + 2;
    status = do_pcall_with_traceback(L, nargs, LUA_MULTRET);
    if (status != 0)
    {
      const char * msg = NULL;

      LCHECK_FN(L, stack, 2 + 1, fatal_error); /* Tables and error message */
      lua_remove(L, -2); /* Remove AS3LUA_CALLBACKS table */
      lua_remove(L, -2); /* Remove holder table */
      LCHECK_FN(L, stack, 1, fatal_error); /* Only error message */

      /* Error message is on stack */
      /* NOTE: It is not necessary string! If we want to preserve its type, see lua_DoString. */

      if (lua_tostring(L, -1) == NULL)
      {
        lua_pop(L, 1);
        lua_pushliteral(L, "(non-string)");
      }

      LCHECK_FN(L, stack, 1, fatal_error);

      lua_pushliteral(L, "Error in Lua callback:\n");
      lua_insert(L, -2);

      LCHECK_FN(L, stack, 2, fatal_error);

      lua_concat(L, 2);

      LCHECK_FN(L, stack, 1, fatal_error);

      sztrace((char *)lua_tostring(L, -1));

      /* TODO: ?! */
      /* lua_error(L); */

      msg = lua_tostring(L, -1);
      lua_pop(L, 1);

/*
      fatal_error(msg); / * Does not return * /
*/
    }

    /* Process results */

#ifdef DO_SPAM
    /* TODO: Remove */
    /*
    lua_pushcfunction(L, as3_trace);
    lua_pushliteral(L, "STACK");
    dump_lua_stack(L, results_base);
    lua_call(L, 2, 0);
    */
#endif /* DO_SPAM */

    res = create_as3_value_from_lua_stack(L, results_base + 1, LTOP(L, stack), TRUE);

#ifdef DO_SPAM
    SPAM(("as3_lua_callback() result type"));
    AS3_Trace(AS3_Call(getQualifiedClassName_method, NULL, AS3_Array("AS3ValType", res)));
#endif /* DO_SPAM */

    lua_settop(L, LBASE(L, stack)); /* Cleanup results and two holder tables */

    SPAM(("as3_lua_callback(): end"));

    return res;
  }

  /* Unreachable */
}
static void
ngx_http_lua_timer_handler(ngx_event_t *ev)
{
    int                      n;
    lua_State               *L;
    ngx_int_t                rc;
    ngx_log_t               *log;
    ngx_connection_t        *c = NULL, *saved_c = NULL;
    ngx_http_request_t      *r = NULL;
    ngx_http_lua_ctx_t      *ctx;
    ngx_http_cleanup_t      *cln;
    ngx_pool_cleanup_t      *pcln;
    ngx_http_log_ctx_t      *logctx;

    ngx_http_lua_timer_ctx_t         tctx;
    ngx_http_lua_main_conf_t        *lmcf;
    ngx_http_core_loc_conf_t        *clcf;

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
                   "lua ngx.timer expired");

    ngx_memcpy(&tctx, ev->data, sizeof(ngx_http_lua_timer_ctx_t));
    ngx_free(ev);
    ev = NULL;

    lmcf = tctx.lmcf;

    lmcf->pending_timers--;

    if (lmcf->running_timers >= lmcf->max_running_timers) {
        ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
                      "%i lua_max_running_timers are not enough",
                      lmcf->max_running_timers);
        goto abort;
    }

    /* create the fake connection (we temporarily use a valid fd (0) to make
       ngx_get_connection happy) */

    if (ngx_cycle->files) {
        saved_c = ngx_cycle->files[0];
    }

    c = ngx_get_connection(0, ngx_cycle->log);

    if (ngx_cycle->files) {
        ngx_cycle->files[0] = saved_c;
    }

    if (c == NULL) {
        goto abort;
    }

    c->fd = (ngx_socket_t) -1;

    c->pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, c->log);
    if (c->pool == NULL) {
        goto abort;
    }

    log = ngx_pcalloc(c->pool, sizeof(ngx_log_t));
    if (log == NULL) {
        goto abort;
    }

    logctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t));
    if (logctx == NULL) {
        goto abort;
    }

    dd("c pool allocated: %d", (int) (sizeof(ngx_log_t)
       + sizeof(ngx_http_log_ctx_t) + sizeof(ngx_http_request_t)));

    logctx->connection = c;
    logctx->request = NULL;
    logctx->current_request = NULL;

    c->log = log;
    c->log->connection = c->number;
    c->log->handler = ngx_http_lua_log_timer_error;
    c->log->data = logctx;
    c->log->action = NULL;

    c->log_error = NGX_ERROR_INFO;

#if 0
    c->buffer = ngx_create_temp_buf(c->pool, 2);
    if (c->buffer == NULL) {
        goto abort;
    }

    c->buffer->start[0] = CR;
    c->buffer->start[1] = LF;
#endif

    /* create the fake request */

    r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t));
    if (r == NULL) {
        goto abort;
    }

    c->requests++;
    logctx->request = r;
    logctx->current_request = r;

    r->pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, c->log);
    if (r->pool == NULL) {
        goto abort;
    }

    dd("r pool allocated: %d", (int) (sizeof(ngx_http_lua_ctx_t)
       + sizeof(void *) * ngx_http_max_module + sizeof(ngx_http_cleanup_t)));

#if 0
    hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t));
    if (hc == NULL) {
        goto abort;
    }

    r->header_in = c->buffer;
    r->header_end = c->buffer->start;

    if (ngx_list_init(&r->headers_out.headers, r->pool, 0,
                      sizeof(ngx_table_elt_t))
        != NGX_OK)
    {
        goto abort;
    }

    if (ngx_list_init(&r->headers_in.headers, r->pool, 0,
                      sizeof(ngx_table_elt_t))
        != NGX_OK)
    {
        goto abort;
    }
#endif

    r->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
    if (r->ctx == NULL) {
        goto abort;
    }

#if 0
    cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

    r->variables = ngx_pcalloc(r->pool, cmcf->variables.nelts
                                        * sizeof(ngx_http_variable_value_t));
    if (r->variables == NULL) {
        goto abort;
    }
#endif

    r->connection = c;
    r->main_conf = tctx.main_conf;
    r->srv_conf = tctx.srv_conf;
    r->loc_conf = tctx.loc_conf;

    dd("lmcf: %p", lmcf);

    ctx = ngx_http_lua_create_ctx(r);
    if (ctx == NULL) {
        goto abort;
    }

    if (tctx.vm_state) {
        ctx->vm_state = tctx.vm_state;

        pcln = ngx_pool_cleanup_add(r->pool, 0);
        if (pcln == NULL) {
            goto abort;
        }

        pcln->handler = ngx_http_lua_cleanup_vm;
        pcln->data = tctx.vm_state;
    }

    r->headers_in.content_length_n = 0;
    c->data = r;
#if 0
    hc->request = r;
    r->http_connection = hc;
#endif
    r->signature = NGX_HTTP_MODULE;
    r->main = r;
    r->count = 1;

    r->method = NGX_HTTP_UNKNOWN;

    r->headers_in.keep_alive_n = -1;
    r->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1;
    r->subrequests = NGX_HTTP_MAX_SUBREQUESTS + 1;

    r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;
    r->discard_body = 1;

    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
    c->log->file = clcf->error_log->file;
    if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
        c->log->log_level = clcf->error_log->log_level;
    }

    c->error = 1;

    ctx->cur_co_ctx = &ctx->entry_co_ctx;

    L = ngx_http_lua_get_lua_vm(r, ctx);

    cln = ngx_http_cleanup_add(r, 0);
    if (cln == NULL) {
        goto abort;
    }

    cln->handler = ngx_http_lua_request_cleanup_handler;
    cln->data = ctx;
    ctx->cleanup = &cln->handler;

    ctx->entered_content_phase = 1;
    ctx->context = NGX_HTTP_LUA_CONTEXT_TIMER;

    r->read_event_handler = ngx_http_block_reading;

    ctx->cur_co_ctx->co_ref = tctx.co_ref;
    ctx->cur_co_ctx->co = tctx.co;
    ctx->cur_co_ctx->co_status = NGX_HTTP_LUA_CO_RUNNING;

    dd("r connection: %p, log %p", r->connection, r->connection->log);

    /*  save the request in coroutine globals table */
    ngx_http_lua_set_req(tctx.co, r);

    lmcf->running_timers++;

    lua_pushboolean(tctx.co, tctx.premature);

    n = lua_gettop(tctx.co);
    if (n > 2) {
        lua_insert(tctx.co, 2);
    }

    rc = ngx_http_lua_run_thread(L, r, ctx, n - 1);

    dd("timer lua run thread: %d", (int) rc);

    if (rc == NGX_ERROR || rc >= NGX_OK) {
        /* do nothing */

    } else if (rc == NGX_AGAIN) {
        rc = ngx_http_lua_content_run_posted_threads(L, r, ctx, 0);

    } else if (rc == NGX_DONE) {
        rc = ngx_http_lua_content_run_posted_threads(L, r, ctx, 1);

    } else {
        rc = NGX_OK;
    }

    ngx_http_lua_finalize_request(r, rc);
    return;

abort:
    if (tctx.co_ref && tctx.co) {
        lua_pushlightuserdata(tctx.co, &ngx_http_lua_coroutines_key);
        lua_rawget(tctx.co, LUA_REGISTRYINDEX);
        luaL_unref(tctx.co, -1, tctx.co_ref);
        lua_settop(tctx.co, 0);
    }

    if (tctx.vm_state) {
        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "decrementing "
                       "the reference count for Lua VM: %i",
                       tctx.vm_state->count);

        tctx.vm_state->count--;
    }

    if (r && r->pool) {
        ngx_destroy_pool(r->pool);
    }

    if (c) {
        ngx_http_lua_close_fake_connection(c);
    }
}
int LuaStack::executeFunction(int handler, int numArgs, int numResults, const std::function<void(lua_State*,int)>& func)
{
    if (pushFunctionByHandler(handler))                 /* L: ... arg1 arg2 ... func */
    {
        if (numArgs > 0)
        {
            lua_insert(_state, -(numArgs + 1));                        /* L: ... func arg1 arg2 ... */
        }
        
        int functionIndex = -(numArgs + 1);
        
        if (!lua_isfunction(_state, functionIndex))
        {
            CCLOG("value at stack [%d] is not function", functionIndex);
            lua_pop(_state, numArgs + 1); // remove function and arguments
            return 0;
        }
        
        int traceCallback = 0;
        lua_getglobal(_state, "__G__TRACKBACK__");                        /* L: ... func arg1 arg2 ... G */
        if (!lua_isfunction(_state, -1))
        {
            lua_pop(_state, 1);                                           /* L: ... func arg1 arg2 ... */
        }
        else
        {
            lua_insert(_state, functionIndex - 1);                         /* L: ... G func arg1 arg2 ... */
            traceCallback = functionIndex - 1;
        }
        
        int error = 0;
        ++_callFromLua;
        error = lua_pcall(_state, numArgs, numResults, traceCallback);     /* L: ... [G] ret1 ret2 ... retResults*/
        --_callFromLua;
        
        if (error)
        {
            if (traceCallback == 0)
            {
                CCLOG("[LUA ERROR] %s", lua_tostring(_state, - 1));        /* L: ... error */
                lua_pop(_state, 1);                                        // remove error message from stack
            }
            else                                                           /* L: ... G error */
            {
                lua_pop(_state, 2);                                        // remove __G__TRACKBACK__ and error message from stack
            }
            return 0;
        }
        
        // get return value,don't pass LUA_MULTRET to numResults,
        do {
            
            if (numResults <= 0 || nullptr == func)
                break;
            
            func(_state, numResults);
            
        } while (0);
        
        if (traceCallback)
        {
            lua_pop(_state, 1);                                          // remove __G__TRACKBACK__ from stack      /* L: ... */
        }
    }
    
    return 1;
}
Beispiel #8
0
int lcurl_util_pcall_method(lua_State *L, const char *name, int nargs, int nresults, int errfunc){
  int obj_index = -nargs - 1;
  lua_getfield(L, obj_index, name);
  lua_insert(L, obj_index - 1);
  return lua_pcall(L, nargs + 1, nresults, errfunc);
}
Beispiel #9
0
static void maybe_insert_default_mv(lua_State *L) {
    if ((lua_gettop(L) >= 1 && lua_type(L, 1) != LUA_TSTRING) || lua_gettop(L) == 0) {
        lua_pushstring(L, am_conf_default_modelview_matrix_name);
        lua_insert(L, 1);
    }
}
Beispiel #10
0
void ListDirectoryContents(lua_State *L, const char *currentDir)
{
	std::wstring wsConvert;
	xl::text::transcode::UTF8_to_Unicode(currentDir, strlen(currentDir), wsConvert);
	const wchar_t *wCurrentDir =wsConvert.c_str();

	if (wcscmp(wCurrentDir, L"") == 0)
	{
		wchar_t szLogicalDriveStrings[MAX_PATH];                          //获取驱动器的内存
		wchar_t *szDrive;
		::ZeroMemory(szLogicalDriveStrings, MAX_PATH);                    //将内存清零,第一个参数是申请字符的地址
		::GetLogicalDriveStrings(MAX_PATH-1, szLogicalDriveStrings);      //获取磁盘中的所有驱动器
		szDrive=(wchar_t*)szLogicalDriveStrings;

		lua_newtable(L);
		int index = 1;

		do
		{
			int len = wcslen(szDrive);
			std::string sDriveConvert;
			xl::text::transcode::Unicode_to_UTF8(szDrive, wcslen(szDrive), sDriveConvert);
			const char* volume = sDriveConvert.c_str();
			UINT uDriveType = GetDriveType(szDrive);

			lua_newtable(L);
			lua_pushnumber(L, 1);
			lua_pushboolean(L, true); // has children
			lua_settable(L, -3);

			lua_pushnumber(L, 2);
			lua_pushstring(L, volume);
			lua_settable(L, -3);

			lua_pushnumber(L, index);
			lua_insert(L, -2); // 把栈顶的一维索引和rowtable换一下位置, 
			lua_settable(L, -3); // 把刚压栈的一维索引row, 和rowtable弹出, 放在要返回的return table中
			index++;

			szDrive += (len+1);
		}
		while(*szDrive!='\x00');
	}
	else 
	{
		WIN32_FIND_DATA fdFile;
		HANDLE hFind = NULL;
		wchar_t wPath[MAX_PATH];
		wsprintf(wPath, L"%s\\*", wCurrentDir);

		if( (hFind = FindFirstFile(wPath, &fdFile)) == INVALID_HANDLE_VALUE)
		{
			return;
		}
		int index = 1;
		lua_newtable(L);
		do
		{
			if (wcscmp(fdFile.cFileName, L".") != 0 && wcscmp(fdFile.cFileName, L"..") != 0 
				&& !(fdFile.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
				&& !(fdFile.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN))
			{
				lua_newtable(L);
				lua_pushnumber(L, 1);
				if (fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
				{			
					lua_pushboolean(L, true);
				} 
				else 
				{
					lua_pushboolean(L, false);
				}
				lua_settable(L, -3);

				std::string subDirString;
				xl::text::transcode::Unicode_to_UTF8(fdFile.cFileName, MAX_PATH, subDirString);

				lua_pushnumber(L, 2);
				lua_pushstring(L, subDirString.c_str());
				lua_settable(L, -3);
				
				lua_pushnumber(L, index);//把一维索引row压栈
				lua_insert(L, -2); // 把栈顶的一维索引和rowtable换一下位置, 
				lua_settable(L, -3); // 把刚压栈的一维索引row, 和rowtable弹出, 放在要返回的return table中
				index++;
			}
		} while(::FindNextFile(hFind, &fdFile));
		::FindClose(hFind);
	}
	return;
}
ngx_int_t
ngx_http_lua_header_filter_by_chunk(lua_State *L, ngx_http_request_t *r)
{
    int              old_exit_code = 0;
    ngx_int_t        rc;
    u_char          *err_msg;
    size_t           len;
#if (NGX_PCRE)
    ngx_pool_t      *old_pool;
#endif
    ngx_http_lua_ctx_t          *ctx;

    ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
    if (ctx->exited) {
        old_exit_code = ctx->exit_code;
    }

    /*  initialize nginx context in Lua VM, code chunk at stack top    sp = 1 */
    ngx_http_lua_header_filter_by_lua_env(L, r);

#if (NGX_PCRE)
    /* XXX: work-around to nginx regex subsystem */
    old_pool = ngx_http_lua_pcre_malloc_init(r->pool);
#endif

    lua_pushcfunction(L, ngx_http_lua_traceback);
    lua_insert(L, 1);  /* put it under chunk and args */

    /*  protected call user code */
    rc = lua_pcall(L, 0, 1, 1);

    lua_remove(L, 1);  /* remove traceback function */

#if (NGX_PCRE)
    /* XXX: work-around to nginx regex subsystem */
    ngx_http_lua_pcre_malloc_done(old_pool);
#endif

    dd("rc == %d", (int) rc);

    if (rc != 0) {
        /*  error occurred when running loaded code */
        err_msg = (u_char *) lua_tolstring(L, -1, &len);

        if (err_msg == NULL) {
            err_msg = (u_char *) "unknown reason";
            len = sizeof("unknown reason") - 1;
        }

        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                      "failed to run header_filter_by_lua*: %*s", len, err_msg);

        lua_settop(L, 0); /*  clear remaining elems on stack */

        return NGX_ERROR;
    }

    dd("exited: %d, exit code: %d, old exit code: %d",
       (int) ctx->exited, (int) ctx->exit_code, (int) old_exit_code);

#if 1
    /*  clear Lua stack */
    lua_settop(L, 0);
#endif

    if (ctx->exited && ctx->exit_code != old_exit_code) {
        if (ctx->exit_code == NGX_ERROR) {
            return NGX_ERROR;
        }

        dd("finalize request with %d", (int) ctx->exit_code);

        rc = ngx_http_filter_finalize_request(r, &ngx_http_lua_module,
                                              ctx->exit_code);
        if (rc == NGX_ERROR || rc == NGX_AGAIN) {
            return rc;
        }

        return NGX_DECLINED;
    }

    return NGX_OK;
}
Beispiel #12
0
int CorsixTH_lua_main_no_eval(lua_State *L) {
	// assert(_VERSION == LUA_VERSION)
	size_t iLength;
	lua_getglobal(L, "_VERSION");
	const char* sVersion = lua_tolstring(L, -1, &iLength);
    if(iLength != strlen(LUA_VERSION) || strcmp(sVersion, LUA_VERSION) != 0)
    {
        lua_pushliteral(L, "Linked against a version of Lua different to the "
            "one used when compiling.\nPlease recompile CorsixTH against the "
            "same Lua version it is linked against.");
		sendCommand(jvm,COMMAND_GAME_LOAD_ERROR);
        return lua_error(L);
    }
    lua_pop(L, 1);

    // registry._CLEANUP = {}
    lua_newtable(L);
    lua_setfield(L, LUA_REGISTRYINDEX, "_CLEANUP");

    // math.random* = Mersenne twister variant
    luaT_cpcall(L, luaopen_random, NULL);

    // package.preload["jit.opt"] = load(jit_opt_lua)
    // package.preload["jit.opt_inline"] = load(jit_opt_inline_lua)
    lua_getglobal(L, "package");
    lua_getfield(L, -1, "preload");
    luaL_loadbuffer(L, (const char*)jit_opt_lua, sizeof(jit_opt_lua),
        "jit/opt.luac");
    lua_setfield(L, -2, "jit.opt");
    luaL_loadbuffer(L, (const char*)jit_opt_inline_lua,
        sizeof(jit_opt_inline_lua), "jit/opt_inline.luac");
    lua_setfield(L, -2, "jit.opt_inline");
    lua_pop(L, 2);

    // if registry._LOADED.jit then
    // require"jit.opt".start()
    // else
    // print "Notice: ..."
    // end
    // (this could be done in Lua rather than here, but ideally the optimiser
    // should be turned on before any Lua code is loaded)
    lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
    lua_getfield(L, -1, "jit");
    if(lua_type(L, -1) == LUA_TNIL)
    {
        lua_pop(L, 2);
        lua_getglobal(L, "print");
        lua_pushliteral(L, "Notice: LuaJIT not being used.\nConsider replacing"
            " Lua with LuaJIT to improve performance.");
#ifdef CORSIX_TH_64BIT
        lua_pushliteral(L, " Note that there is not currently a 64 bit version"
            " of LuaJIT.");
        lua_concat(L, 2);
#endif
        lua_call(L, 1, 0);
    }
    else
    {
        lua_pop(L, 2);
        lua_getglobal(L, "require");
        lua_pushliteral(L, "jit.opt");
        lua_call(L, 1, 1);
        lua_getfield(L, -1, "start");
        lua_call(L, 0, 0);
        lua_pop(L, 1);
    }

    // Fill in package.preload table so that calls to require("X") from Lua
    // will call the appropriate luaopen_X function in C.
#define PRELOAD(name, fn) \
    luaT_execute(L, "package.preload." name " = ...", fn)
    PRELOAD("lfs", luaopen_lfs_ext);
    PRELOAD("lpeg", luaopen_lpeg);
    PRELOAD("rnc", luaopen_rnc);
    PRELOAD("TH", luaopen_th);
    PRELOAD("ISO_FS", luaopen_iso_fs);
    PRELOAD("persist", luaopen_persist);
    PRELOAD("sdl", luaopen_sdl);
#undef PRELOAD

    // require "debug" (Harmless in Lua 5.1, useful in 5.2 for compatbility)
    luaT_execute(L, "require \"debug\"");

    // Check for --interpreter and run that instead of CorsixTH.lua
    bool bGotScriptFile = false;
    int iNArgs = lua_gettop(L);
    for(int i = 1; i <= iNArgs; ++i)
    {
        if(lua_type(L, i) == LUA_TSTRING)
        {
            size_t iLen;
            const char* sCmd = lua_tolstring(L, i, &iLen);
            if(iLen > 14 && memcmp(sCmd, "--interpreter=", 14) == 0)
            {
                lua_getglobal(L, "assert");
                lua_getglobal(L, "loadfile");
                lua_pushlstring(L, sCmd + 14, iLen - 14);
                bGotScriptFile = true;
                break;
            }
        }
    }

    JNIEnv* jEnv;

    	jvm->AttachCurrentThread(&jEnv, NULL);

    	jclass cls = jEnv->FindClass("uk/co/armedpineapple/cth/SDLActivity");
    	jmethodID method = jEnv->GetStaticMethodID(cls, "nativeGetGamePath",
    			"()Ljava/lang/String;");

    	jstring jpath = (jstring) jEnv->CallStaticObjectMethod(cls, method);

    	const char* path = jEnv->GetStringUTFChars(jpath, 0);


    // Code to try several variations on finding CorsixTH.lua:
    // CorsixTH.lua
    // CorsixTH/CorsixTH.lua
    // ../CorsixTH.lua
    // ../CorsixTH/CorsixTH.lua
    // ../../CorsixTH.lua
    // ../../CorsixTH/CorsixTH.lua
    // ../../../CorsixTH.lua
    // ../../../CorsixTH/CorsixTH.lua
    // It is simpler to write this in Lua than in C.
	std::string	sLuaCorsixTHLua(
    "local name, sep, code = \"CorsixTH.lua\", package.config:sub(1, 1)\n"
    "local root = (... or \"\"):match(\"^(.*[\"..sep..\"])\") or \"\"\n"
					"code = loadfile(\"");
	sLuaCorsixTHLua.append(path);
	sLuaCorsixTHLua.append("\"..name)\n"
					"if code then return code end\n"
#ifdef __APPLE__ // Darrell: Search inside the bundle first.
                 // There's probably a better way of doing this.
#if defined(IS_CORSIXTH_APP)
    "code = loadfile(\"CorsixTH.app/Contents/Resources/\"..name)\n"
    "if code then return code end\n"
#elif defined(IS_MAPEDIT_APP)
    "code = loadfile(\"MapEdit.app/Contents/Resources/\"..name)\n"
    "if code then return code end\n"
#endif
#endif
    "for num_dotdot = 0, 3 do\n"
    "  for num_dir = 0, 1 do\n"
    "    code = loadfile(root..(\"..\"..sep):rep(num_dotdot)..\n"
    "                    (\"CorsixTH\"..sep):rep(num_dir)..name)\n"
    "    if code then return code end \n"
    "  end \n"
    "end \n"
    "return loadfile(name)");

	jEnv->ReleaseStringUTFChars(jpath, path);


    // return assert(loadfile"CorsixTH.lua")(...)
    if(!bGotScriptFile)
    {
        lua_getglobal(L, "assert");
        luaL_loadbuffer(L, sLuaCorsixTHLua.c_str(), sLuaCorsixTHLua.length(),
            "@main.cpp (l_main bootstrap)");
        if(lua_gettop(L) == 2)
            lua_pushnil(L);
        else
            lua_pushvalue(L, 1);
    }
    lua_call(L, 1, 2);
    lua_call(L, 2, 1);
    lua_insert(L, 1);
    return lua_gettop(L);
}
Beispiel #13
0
static int vlclua_add_callback( lua_State *L )
{
    vlclua_callback_t *p_callback;
    static int i_index = 0;
    vlc_object_t **pp_obj = luaL_checkudata( L, 1, "vlc_object" );
    const char *psz_var = luaL_checkstring( L, 2 );
    lua_settop( L, 4 ); /* makes sure that optional data arg is set */
    if( !lua_isfunction( L, 3 ) )
        return vlclua_error( L );
    i_index++;

    p_callback = (vlclua_callback_t*)malloc( sizeof( vlclua_callback_t ) );
    if( !p_callback )
        return vlclua_error( L );

    /* obj var func data */
    lua_getglobal( L, "vlc" );
    /* obj var func data vlc */
    lua_getfield( L, -1, "callbacks" );
    if( lua_isnil( L, -1 ) )
    {
        lua_pop( L, 1 );
        lua_newtable( L );
        lua_setfield( L, -2, "callbacks" );
        lua_getfield( L, -1, "callbacks" );
    }
    /* obj var func data vlc callbacks */
    lua_remove( L, -2 );
    /* obj var func data callbacks */
    lua_pushinteger( L, i_index );
    /* obj var func data callbacks index */
    lua_insert( L, -4 );
    /* obj var index func data callbacks */
    lua_insert( L, -4 );
    /* obj var callbacks index func data */
    lua_createtable( L, 0, 0 );
    /* obj var callbacks index func data cbtable */
    lua_insert( L, -2 );
    /* obj var callbacks index func cbtable data */
    lua_setfield( L, -2, "data" );
    /* obj var callbacks index func cbtable */
    lua_insert( L, -2 );
    /* obj var callbacks index cbtable func */
    lua_setfield( L, -2, "callback" );
    /* obj var callbacks index cbtable */
    lua_pushlightuserdata( L, *pp_obj ); /* will be needed in vlclua_del_callback */
    /* obj var callbacks index cbtable p_obj */
    lua_setfield( L, -2, "private1" );
    /* obj var callbacks index cbtable */
    lua_pushvalue( L, 2 ); /* will be needed in vlclua_del_callback */
    /* obj var callbacks index cbtable var */
    lua_setfield( L, -2, "private2" );
    /* obj var callbacks index cbtable */
    lua_pushlightuserdata( L, p_callback ); /* will be needed in vlclua_del_callback */
    /* obj var callbacks index cbtable p_callback */
    lua_setfield( L, -2, "private3" );
    /* obj var callbacks index cbtable */
    lua_settable( L, -3 );
    /* obj var callbacks */
    lua_pop( L, 3 );
    /* <empty stack> */

    /* Do not move this before the lua specific code (it somehow changes
     * the function in the stack to nil) */
    p_callback->i_index = i_index;
    p_callback->i_type = var_Type( *pp_obj, psz_var );
    p_callback->L = lua_newthread( L ); /* Do we have to keep a reference to this thread somewhere to prevent garbage collection? */

    var_AddCallback( *pp_obj, psz_var, vlclua_callback, p_callback );
    return 0;
}
Beispiel #14
0
static int js_getter_index (lua_State* L)
{
	// stack: self, key, _self

	while (lua_gettop(L) < 3) {
		lua_pushnil(L);
	}

	// _self or self
	if (lua_isnil(L, 3)) {
		lua_pushvalue(L, 1);
	} else {
		lua_pushvalue(L, 3);
	}

	if (lua_getmetatable(L, -1) == 0) {
		lua_pushnil(L);
		return 1;
	}

	// stack: self, key, _self, (_self or self), mt
	// Check getters
	lua_getfield(L, -1, "getters");
	if (!lua_isnil(L, -1)) {
		lua_pushvalue(L, 2);
		lua_rawget(L, -2);
		if (!lua_isnil(L, -1)) {
			lua_pushvalue(L, 1);
			lua_call(L, 1, 1);
			return 1;
		}
		lua_remove(L, -1);
	}
	lua_remove(L, -1);

	// stack: self, key, _self, (_self or self), mt
	// Get raw key or defer to proto getter
	lua_pushvalue(L, 2);
	// stack: self, key, _self, (_self or self), mt, key
	lua_rawget(L, -3);

	// stack: self, key, _self, (_self or self), mt, (_self or self)[key]
	if (lua_isnil(L, -1)) {
		// stack: self, key, _self, (_self or self), mt, nil
		lua_getfield(L, -2, "proto");
		// stack: self, key, _self, (_self or self), mt, nil, mt.proto
		lua_insert(L, 2);
		// stack: self, mt.proto, key, _self, (_self or self), mt, nil
		lua_remove(L, -1);
		// stack: self, mt.proto, key, _self, (_self or self), mt
		lua_remove(L, -1);
		// stack: self, mt.proto, key, _self, (_self or self)
		lua_remove(L, -1);
		// stack: self, mt.proto, key, _self
		lua_remove(L, -1);
		// stack: self, mt.proto, key
		return js_proto_get(L);
	}

	return 1;
}
Beispiel #15
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);
		}
	}
}
Beispiel #16
0
/*
 * Push a proxy userdata on the stack.
 * returns NULL if ok, else some error string related to bad idfunc behavior or module require problem
 * (error cannot happen with mode_ == eLM_ToKeeper)
 *
 * Initializes necessary structures if it's the first time 'idfunc' is being
 * used in this Lua state (metatable, registring it). Otherwise, increments the
 * reference count.
 */
char const* push_deep_proxy( struct s_Universe* U, lua_State* L, DEEP_PRELUDE* prelude, enum eLookupMode mode_)
{
	DEEP_PRELUDE** proxy;

	// Check if a proxy already exists
	push_registry_subtable_mode( L, DEEP_PROXY_CACHE_KEY, "v");                                        // DPC
	lua_pushlightuserdata( L, prelude->deep);                                                          // DPC deep
	lua_rawget( L, -2);                                                                                // DPC proxy
	if ( !lua_isnil( L, -1))
	{
		lua_remove( L, -2);                                                                              // proxy
		return NULL;
	}
	else
	{
		lua_pop( L, 1);                                                                                  // DPC
	}

	MUTEX_LOCK( &U->deep_lock);
	++ (prelude->refcount);  // one more proxy pointing to this deep data
	MUTEX_UNLOCK( &U->deep_lock);

	STACK_GROW( L, 7);
	STACK_CHECK( L);

	proxy = lua_newuserdata( L, sizeof( DEEP_PRELUDE*));                                               // DPC proxy
	ASSERT_L( proxy);
	*proxy = prelude;

	// Get/create metatable for 'idfunc' (in this state)
	lua_pushlightuserdata( L, prelude->idfunc);                                                        // DPC proxy idfunc
	get_deep_lookup( L);                                                                               // DPC proxy metatable?

	if( lua_isnil( L, -1)) // // No metatable yet.
	{
		char const* modname;
		int oldtop = lua_gettop( L);                                                                     // DPC proxy nil
		lua_pop( L, 1);                                                                                  // DPC proxy
		// 1 - make one and register it
		if( mode_ != eLM_ToKeeper)
		{
			prelude->idfunc( L, eDO_metatable);                                                            // DPC proxy metatable deepversion
			if( lua_gettop( L) - oldtop != 1 || !lua_istable( L, -2) || !lua_isstring( L, -1))
			{
				lua_settop( L, oldtop);                                                                      // DPC proxy X
				lua_pop( L, 3);                                                                              //
				return "Bad idfunc(eOP_metatable): unexpected pushed value";
			}
			luaG_pushdeepversion( L);                                                                      // DPC proxy metatable deepversion deepversion
			if( !lua501_equal( L, -1, -2))
			{
				lua_pop( L, 5);                                                                              //
				return "Bad idfunc(eOP_metatable): mismatched deep version";
			}
			lua_pop( L, 2);                                                                                // DPC proxy metatable
			// make sure the idfunc didn't export __gc, as we will store our own
			lua_getfield( L, -1, "__gc");                                                                  // DPC proxy metatable __gc
			if( !lua_isnil( L, -1))
			{
				lua_pop( L, 4);                                                                              //
				return "idfunc-created metatable shouldn't contain __gc";
			}
			lua_pop( L, 1);                                                                                // DPC proxy metatable
		}
		else
		{
			// keepers need a minimal metatable that only contains __gc
			lua_newtable( L);                                                                              // DPC proxy metatable
		}
		// Add our own '__gc' method
		lua_pushcfunction( L, deep_userdata_gc);                                                         // DPC proxy metatable __gc
		lua_setfield( L, -2, "__gc");                                                                    // DPC proxy metatable

		// Memorize for later rounds
		lua_pushvalue( L, -1);                                                                           // DPC proxy metatable metatable
		lua_pushlightuserdata( L, prelude->idfunc);                                                      // DPC proxy metatable metatable idfunc
		set_deep_lookup( L);                                                                             // DPC proxy metatable

		// 2 - cause the target state to require the module that exported the idfunc
		// this is needed because we must make sure the shared library is still loaded as long as we hold a pointer on the idfunc
		{
			int oldtop = lua_gettop( L);
			modname = (char const*) prelude->idfunc( L, eDO_module);                                       // DPC proxy metatable
			// make sure the function pushed nothing on the stack!
			if( lua_gettop( L) - oldtop != 0)
			{
				lua_pop( L, 3);                                                                              //
				return "Bad idfunc(eOP_module): should not push anything";
			}
		}
		if( modname) // we actually got a module name
		{
			// somehow, L.registry._LOADED can exist without having registered the 'package' library.
			lua_getglobal( L, "require");                                                                  // DPC proxy metatable require()
			// check that the module is already loaded (or being loaded, we are happy either way)
			if( lua_isfunction( L, -1))
			{
				lua_pushstring( L, modname);                                                                 // DPC proxy metatable require() "module"
				lua_getfield( L, LUA_REGISTRYINDEX, "_LOADED");                                              // DPC proxy metatable require() "module" _R._LOADED
				if( lua_istable( L, -1))
				{
					bool_t alreadyloaded;
					lua_pushvalue( L, -2);                                                                     // DPC proxy metatable require() "module" _R._LOADED "module"
					lua_rawget( L, -2);                                                                        // DPC proxy metatable require() "module" _R._LOADED module
					alreadyloaded = lua_toboolean( L, -1);
					if( !alreadyloaded) // not loaded
					{
						int require_result;
						lua_pop( L, 2);                                                                          // DPC proxy metatable require() "module"
						// require "modname"
						require_result = lua_pcall( L, 1, 0, 0);                                                 // DPC proxy metatable error?
						if( require_result != LUA_OK)
						{
							// failed, return the error message
							lua_pushfstring( L, "error while requiring '%s' identified by idfunc(eOP_module): ", modname);
							lua_insert( L, -2);                                                                    // DPC proxy metatable prefix error
							lua_concat( L, 2);                                                                     // DPC proxy metatable error
							return lua_tostring( L, -1);
						}
					}
					else // already loaded, we are happy
					{
						lua_pop( L, 4);                                                                          // DPC proxy metatable
					}
				}
				else // no L.registry._LOADED; can this ever happen?
				{
					lua_pop( L, 6);                                                                            //
					return "unexpected error while requiring a module identified by idfunc(eOP_module)";
				}
			}
			else // a module name, but no require() function :-(
			{
				lua_pop( L, 4);                                                                              //
				return "lanes receiving deep userdata should register the 'package' library";
			}
		}
	}
	STACK_MID( L, 2);                                                                                  // DPC proxy metatable
	ASSERT_L( lua_isuserdata( L, -2));
	ASSERT_L( lua_istable( L, -1));
	lua_setmetatable( L, -2);                                                                          // DPC proxy

	// If we're here, we obviously had to create a new proxy, so cache it.
	lua_pushlightuserdata( L, (*proxy)->deep);                                                         // DPC proxy deep
	lua_pushvalue( L, -2);                                                                             // DPC proxy deep proxy
	lua_rawset( L, -4);                                                                                // DPC proxy
	lua_remove( L, -2);                                                                                // proxy
	ASSERT_L( lua_isuserdata( L, -1));
	STACK_END( L, 0);
	return NULL;
}
Beispiel #17
0
////////////////////////////////////////////////
// parse object from struct address and offset
// function parseMemberObj(className, structAddress, offset)
// push a object with type className to stack
//
int luaU_parseMemberObj(lua_State* L)
{
	typedef LMREG::voidPtr2user voidPtr2user;

	const char* className = luaL_checkstring(L, 1);

	void* structAddr = NULL;
	if(lua_isnumber(L,2))
	{	structAddr = (void*)(uint_r)luaL_checknumber(L, 2); }
	else if(lua_islightuserdata(L,2))
	{	structAddr = lua_touserdata(L,2); }
	else if(lua_isstring(L, 2))
	{ structAddr = (void*)lua_tostring(L, 2); }
	else if(lua_isstring(L,2))
	{ structAddr = (void*)lua_tostring(L, 2); }
	else
	{
		luaL_argerror(L, 2, "address must be a number or pointer");
		return 0;
	}

	if(!lua_isnumber(L, 3))
	{
		luaL_argerror(L, 3, "offset must be a number value (1 based)");
		return 0;
	}
	int offset = (int)lua_tonumber(L, 3);
	if(offset < 1)
	{
		luaL_argerror(L, 3, "offset must be a number value (1 based)");
		return 0;
	}

	void* addr = *(void**)((char*)structAddr + offset - 1);
	if (!addr)
	{
		lua_pushnil(L);
		return 1;
	}

	lua_pushstring(L, className);
	lua_gettable(L, LUA_GLOBALSINDEX);
	if(!lua_istable(L, -1))
	{
		luaL_argerror(L, 1, "metatable for classname not found");
		return 0;
	}

	lua_pushstring(L, "__ref");
	lua_gettable(L, -2);
	if(lua_istable(L, -1))
	{
		lua_remove(L, -2);
		lua_pushlightuserdata(L, addr); //lua_pushnumber(L, (DWORD)addr);
		lua_rawget(L, -2); ASSERT(lua_isuserdata(L, -1));
		lua_remove(L, -2);
	}
	else
	{
		lua_pop(L, 1);
		void* pUserData = lua_newuserdata(L, sizeof(voidPtr2user));
		new (pUserData) voidPtr2user(addr);
		lua_insert(L, -2);
		lua_setmetatable(L, -2);
	}

	return 1;
}
Beispiel #18
0
static int py_asfunc_call(lua_State *L)
{
	lua_pushvalue(L, lua_upvalueindex(1));
	lua_insert(L, 1);
	return py_object_call(L);
}
int LuaStack::executeFunctionReturnArray(int handler,int numArgs,int numResults,__Array& resultArray)
{
    int top = lua_gettop(_state);
    if (pushFunctionByHandler(handler))                 /* L: ... arg1 arg2 ... func */
    {
        if (numArgs > 0)
        {
            lua_insert(_state, -(numArgs + 1));         /* L: ... func arg1 arg2 ... */
        }
        int functionIndex = -(numArgs + 1);
        if (!lua_isfunction(_state, functionIndex))
        {
            CCLOG("value at stack [%d] is not function", functionIndex);
            lua_pop(_state, numArgs + 1); // remove function and arguments
            lua_settop(_state,top);
            return 0;
        }
        
        int traceback = 0;
        lua_getglobal(_state, "__G__TRACKBACK__");                         /* L: ... func arg1 arg2 ... G */
        if (!lua_isfunction(_state, -1))
        {
            lua_pop(_state, 1);                                            /* L: ... func arg1 arg2 ... */
        }
        else
        {
            lua_insert(_state, functionIndex - 1);                         /* L: ... G func arg1 arg2 ... */
            traceback = functionIndex - 1;
        }
        
        int error = 0;
        ++_callFromLua;
        error = lua_pcall(_state, numArgs, numResults, traceback);                  /* L: ... [G] ret1 ret2 ... retResults*/
        --_callFromLua;
        if (error)
        {
            if (traceback == 0)
            {
                CCLOG("[LUA ERROR] %s", lua_tostring(_state, - 1));        /* L: ... error */
                lua_pop(_state, 1); // remove error message from stack
            }
            else                                                            /* L: ... G error */
            {
                lua_pop(_state, 2); // remove __G__TRACKBACK__ and error message from stack
            }
            lua_settop(_state,top);
            return 0;
        }
        
        // get return value,don't pass LUA_MULTRET to numResults,
        if (numResults <= 0)
        {
            lua_settop(_state,top);
            return 0;
        }
        
        for (int i = 0 ; i < numResults; i++)
        {
            if (lua_type(_state, -1) == LUA_TBOOLEAN) {
                
                bool value = lua_toboolean(_state, -1);
                resultArray.addObject(Bool::create(value)) ;
                
            }else if (lua_type(_state, -1) == LUA_TNUMBER) {
                
                double value = lua_tonumber(_state, -1);
                resultArray.addObject(Double::create(value));
                
            }else if (lua_type(_state, -1) == LUA_TSTRING) {
                
                const char* value = lua_tostring(_state, -1);
                resultArray.addObject(String::create(value));
                
            }else{
                
                resultArray.addObject(static_cast<Ref*>(tolua_tousertype(_state, -1, nullptr)));
            }
            // remove return value from stack
            lua_pop(_state, 1);                                                /* L: ... [G] ret1 ret2 ... ret*/
        }
        /* L: ... [G]*/
        
        if (traceback)
        {
            lua_pop(_state, 1); // remove __G__TRACKBACK__ from stack      /* L: ... */
        }
    }
    lua_settop(_state,top);
    return 1;
}
/**
**  Change the diplomacy from ThisPlayer to another player.
**
**  @param l  Lua state.
*/
static int CclDiplomacy(lua_State *l)
{
	lua_pushnumber(l, ThisPlayer->Index);
	lua_insert(l, 1);
	return CclSetDiplomacy(l);
}
Beispiel #21
0
/* note: this expects that the lua stack already contains the mapping rule,
 * needed by sbox_translate_path (lua code).
 * at exit the rule is still there.
*/
char *call_lua_function_sbox_translate_path(
	const path_mapping_context_t *ctx,
	int result_log_level,
	const char *abs_clean_virtual_path,
	int *flagsp,
	char **exec_policy_name_ptr)
{
	struct sb2context	*sb2ctx = ctx->pmc_sb2ctx;
	int flags;
	char *host_path = NULL;

	SB_LOG(SB_LOGLEVEL_NOISE, "calling sbox_translate_path for %s(%s), fn_class=0x%X",
		ctx->pmc_func_name, abs_clean_virtual_path, ctx->pmc_fn_class);
	if (!sb2ctx->lua) sb2context_initialize_lua(sb2ctx);
	SB_LOG(SB_LOGLEVEL_NOISE,
		"call_lua_function_sbox_translate_path: gettop=%d",
		lua_gettop(sb2ctx->lua));
	if(SB_LOG_IS_ACTIVE(SB_LOGLEVEL_NOISE3)) {
		dump_lua_stack("call_lua_function_sbox_translate_path entry",
			sb2ctx->lua);
	}

	lua_getfield(sb2ctx->lua, LUA_GLOBALSINDEX, "sbox_translate_path");
	/* stack now contains the rule object and string "sbox_translate_path",
         * move the string to the bottom: */
	lua_insert(sb2ctx->lua, -2);
	/* add other parameters */
	lua_pushstring(sb2ctx->lua, ctx->pmc_binary_name);
	lua_pushstring(sb2ctx->lua, ctx->pmc_func_name);
	lua_pushstring(sb2ctx->lua, abs_clean_virtual_path);
	lua_pushnumber(sb2ctx->lua, ctx->pmc_fn_class);
	 /* 5 arguments, returns rule,policy,path,flags */
	lua_call(sb2ctx->lua, 5, 4);

	host_path = (char *)lua_tostring(sb2ctx->lua, -2);
	if (host_path && (*host_path != '/')) {
		SB_LOG(SB_LOGLEVEL_ERROR,
			"Mapping failed: Result is not absolute ('%s'->'%s')",
			abs_clean_virtual_path, host_path);
		host_path = NULL;
	} else if (host_path) {
		host_path = strdup(host_path);
	}
	flags = lua_tointeger(sb2ctx->lua, -1);
	check_mapping_flags(flags, "sbox_translate_path");
	if (flagsp) *flagsp = flags;

	if (exec_policy_name_ptr) {
		char *exec_policy_name;

		if (*exec_policy_name_ptr) {
			free(*exec_policy_name_ptr);
			*exec_policy_name_ptr = NULL;
		}
		exec_policy_name = (char *)lua_tostring(sb2ctx->lua, -3);
		if (exec_policy_name) {
			*exec_policy_name_ptr = strdup(exec_policy_name);
		}
	}

	lua_pop(sb2ctx->lua, 3); /* leave the rule to the stack */

	if (host_path) {
		char *new_host_path = clean_and_log_fs_mapping_result(ctx,
			abs_clean_virtual_path, result_log_level, host_path, flags);
		free(host_path);
		host_path = new_host_path;
	}
	if (!host_path) {
		SB_LOG(SB_LOGLEVEL_ERROR,
			"No result from sbox_translate_path for: %s '%s'",
			ctx->pmc_func_name, abs_clean_virtual_path);
	}
	SB_LOG(SB_LOGLEVEL_NOISE,
		"call_lua_function_sbox_translate_path: at exit, gettop=%d",
		lua_gettop(sb2ctx->lua));
	if(SB_LOG_IS_ACTIVE(SB_LOGLEVEL_NOISE3)) {
		dump_lua_stack("call_lua_function_sbox_translate_path exit",
			sb2ctx->lua);
	}
	return(host_path);
}
/**
**  Change the shared vision from ThisPlayer to another player.
**
**  @param l  Lua state.
*/
static int CclSharedVision(lua_State *l)
{
	lua_pushnumber(l, ThisPlayer->Index);
	lua_insert(l, 1);
	return CclSetSharedVision(l);
}
Beispiel #23
0
/**
  * wifi.sta.listap()
  * Description:
  * 	scan and get ap list as a lua table into callback function.
  * Syntax:
  * 	wifi.sta.getap(function(table))
  * 	wifi.sta.getap(format, function(table))
  * 	wifi.sta.getap(cfg, function(table))
  * 	wifi.sta.getap(cfg, format, function(table))
  * Parameters:
  * 	cfg: table that contains scan configuration
  * 	Format:Select output table format.
  * 		0 for the old format (SSID : Authmode, RSSI, BSSID, Channel) (Default)
  * 		1 for the new format (BSSID : SSID, RSSI, Authmode, Channel)
  * 	function(table): a callback function to receive ap table when scan is done
			this function receive a table, the key is the ssid,
			value is other info in format: authmode,rssi,bssid,channel
  * Returns:
  * 	nil
  *
  * Example:
  	  --original function left intact to preserve backward compatibility
  	  wifi.sta.getap(function(T) for k,v in pairs(T) do print(k..":"..v) end end)

  	  --if no scan configuration is desired cfg can be set to nil or previous example can be used
  	  wifi.sta.getap(nil, function(T) for k,v in pairs(T) do print(k..":"..v) end end)

  	  --scan configuration
  	  scan_cfg={}
	  scan_cfg.ssid="myssid"  			 --if set to nil, ssid is not filtered
	  scan_cfg.bssid="AA:AA:AA:AA:AA:AA" --if set to nil, MAC address is not filtered
	  scan_cfg.channel=0  				 --if set to nil, channel will default to 0(scans all channels), if set scan will be faster
	  scan_cfg.show_hidden=1			 --if set to nil, show_hidden will default to 0
  	  wifi.sta.getap(scan_cfg, function(T) for k,v in pairs(T) do print(k..":"..v) end end)

  */
static int wifi_station_listap( lua_State* L )
{
  if(wifi_get_opmode() == SOFTAP_MODE)
  {
    return luaL_error( L, "Can't list ap in SOFTAP mode" );
  }
  gL = L;
  struct scan_config scan_cfg;
  getap_output_format=0;

  if (lua_type(L, 1)==LUA_TTABLE)
  {
	  char ssid[32];
	  char bssid[6];
	  uint8 channel=0;
	  uint8 show_hidden=0;
	  size_t len;

	  lua_getfield(L, 1, "ssid");
	  if (!lua_isnil(L, -1)){  /* found? */
	    if( lua_isstring(L, -1) )   // deal with the ssid string
	    {
	      const char *ssidstr = luaL_checklstring( L, -1, &len );
	      if(len>32)
	        return luaL_error( L, "ssid:<32" );
	      c_memset(ssid, 0, 32);
	      c_memcpy(ssid, ssidstr, len);
	      scan_cfg.ssid=ssid;
	      NODE_DBG(scan_cfg.ssid);
	      NODE_DBG("\n");
	    }
	    else
	      return luaL_error( L, "wrong arg type" );
	  }
	  else
		  scan_cfg.ssid=NULL;

	  lua_getfield(L, 1, "bssid");
	  if (!lua_isnil(L, -1)){  /* found? */
	    if( lua_isstring(L, -1) )   // deal with the ssid string
	    {
	      const char *macaddr = luaL_checklstring( L, -1, &len );
	      if(len!=17)
	        return luaL_error( L, "bssid: FF:FF:FF:FF:FF:FF" );
	      c_memset(bssid, 0, 6);
	      os_str2macaddr(bssid, macaddr);
	      scan_cfg.bssid=bssid;
	      NODE_DBG(MACSTR, MAC2STR(scan_cfg.bssid));
	      NODE_DBG("\n");

	    }
	    else
	      return luaL_error( L, "wrong arg type" );
	  }
	  else
		  scan_cfg.bssid=NULL;


	  lua_getfield(L, 1, "channel");
	  if (!lua_isnil(L, -1)){  /* found? */
	    if( lua_isnumber(L, -1) )   // deal with the ssid string
	    {
	      channel = luaL_checknumber( L, -1);
	      if(!(channel>=0 && channel<=13))
	        return luaL_error( L, "channel: 0 or 1-13" );
	      scan_cfg.channel=channel;
	      NODE_DBG("%d\n", scan_cfg.channel);
	    }
	    else
	      return luaL_error( L, "wrong arg type" );
	  }
	  else
		  scan_cfg.channel=0;

	  lua_getfield(L, 1, "show_hidden");
	  if (!lua_isnil(L, -1)){  /* found? */
	    if( lua_isnumber(L, -1) )   // deal with the ssid string
	    {
	      show_hidden = luaL_checknumber( L, -1);
	      if(show_hidden!=0 && show_hidden!=1)
	        return luaL_error( L, "show_hidden: 0 or 1" );
	      scan_cfg.show_hidden=show_hidden;
	      NODE_DBG("%d\n", scan_cfg.show_hidden);

	    }
	    else
	      return luaL_error( L, "wrong arg type" );
	  }
	  else
		  scan_cfg.show_hidden=0;
	  if (lua_type(L, 2) == LUA_TFUNCTION || lua_type(L, 2) == LUA_TLIGHTFUNCTION)
	  {
		  lua_pushnil(L);
		  lua_insert(L, 2);
	  }
	  lua_pop(L, -4);
  }
  else  if (lua_type(L, 1) == LUA_TNUMBER)
  {
	  lua_pushnil(L);
	  lua_insert(L, 1);
  }
  else  if (lua_type(L, 1) == LUA_TFUNCTION || lua_type(L, 1) == LUA_TLIGHTFUNCTION)
  {
	  lua_pushnil(L);
	  lua_insert(L, 1);
	  lua_pushnil(L);
	  lua_insert(L, 1);
  }
  else if(lua_isnil(L, 1))
  {
	  if (lua_type(L, 2) == LUA_TFUNCTION || lua_type(L, 2) == LUA_TLIGHTFUNCTION)
	  {
		  lua_pushnil(L);
		  lua_insert(L, 2);
	  }
  }
  else
  {
	  return luaL_error( L, "wrong arg type" );
  }


  if (lua_type(L, 2) == LUA_TNUMBER) //this section changes the output format
    {
	  getap_output_format=luaL_checkinteger( L, 2 );
	  if ( getap_output_format != 0 && getap_output_format != 1)
		  return luaL_error( L, "wrong arg type" );
    }
  NODE_DBG("Use alternate output format: %d\n", getap_output_format);
  if (lua_type(L, 3) == LUA_TFUNCTION || lua_type(L, 3) == LUA_TLIGHTFUNCTION)
  {
    lua_pushvalue(L, 3);  // copy argument (func) to the top of stack
    if(wifi_scan_succeed != LUA_NOREF)
      luaL_unref(L, LUA_REGISTRYINDEX, wifi_scan_succeed);
    wifi_scan_succeed = luaL_ref(L, LUA_REGISTRYINDEX);
    if (lua_type(L, 1)==LUA_TTABLE)
    {
    	wifi_station_scan(&scan_cfg,wifi_scan_done);
    }
    else
    {
    	wifi_station_scan(NULL,wifi_scan_done);
    }
  }
  else
  {
    if(wifi_scan_succeed != LUA_NOREF)
      luaL_unref(L, LUA_REGISTRYINDEX, wifi_scan_succeed);
    wifi_scan_succeed = LUA_NOREF;
  }
}
Beispiel #24
0
const char *LuaSerializer::unpickle(lua_State *l, const char *pos)
{
	LUA_DEBUG_START(l);

	char type = *pos++;

	switch (type) {

		case 'f': {
			char *end;
			double f = strtod(pos, &end);
			if (pos == end) throw SavedGameCorruptException();
			lua_pushnumber(l, f);
			pos = end+1; // skip newline
			break;
		}

		case 'b': {
			if (*pos != '0' && *pos != '1') throw SavedGameCorruptException();
			bool b = (*pos == '0') ? false : true;
			lua_pushboolean(l, b);
			pos++;
			break;
		}

		case 's': {
			char *end;
			int len = strtol(pos, const_cast<char**>(&end), 0);
			if (pos == end) throw SavedGameCorruptException();
			end++; // skip newline
			lua_pushlstring(l, end, len);
			pos = end + len;
			break;
		}

		case 't': {
			lua_newtable(l);

			lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs");
			pos = unpickle(l, pos);
			lua_pushvalue(l, -3);
			lua_rawset(l, -3);
			lua_pop(l, 1);

			while (*pos != 'n') {
				pos = unpickle(l, pos);
				pos = unpickle(l, pos);
				lua_rawset(l, -3);
			}
			pos++;

			break;
		}

		case 'r': {
			pos = unpickle(l, pos);

			lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs");
			lua_pushvalue(l, -2);
			lua_rawget(l, -2);

			if (lua_isnil(l, -1))
				throw SavedGameCorruptException();

			lua_insert(l, -3);
			lua_pop(l, 2);

			break;
		}

		case 'u': {
			const char *end = strchr(pos, '\n');
			if (!end) throw SavedGameCorruptException();
			int len = end - pos;
			end++; // skip newline

			if (len == 10 && strncmp(pos, "SystemPath", 10) == 0) {
				pos = end;

				Sint32 sectorX = strtol(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Sint32 sectorY = strtol(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Sint32 sectorZ = strtol(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Uint32 systemNum = strtoul(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Uint32 sbodyId = strtoul(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				SystemPath *sbp = new SystemPath(sectorX, sectorY, sectorZ, systemNum, sbodyId);
				LuaSystemPath::PushToLuaGC(sbp);

				break;
			}

			if (len == 4 && strncmp(pos, "Body", 4) == 0) {
				pos = end;

				Uint32 n = strtoul(pos, const_cast<char**>(&end), 0);
				if (pos == end) throw SavedGameCorruptException();
				pos = end+1; // skip newline

				Body *body = Pi::game->GetSpace()->GetBodyByIndex(n);
				if (pos == end) throw SavedGameCorruptException();

				switch (body->GetType()) {
					case Object::BODY:
						LuaBody::PushToLua(body);
						break;
					case Object::SHIP:
						LuaShip::PushToLua(dynamic_cast<Ship*>(body));
						break;
					case Object::SPACESTATION:
						LuaSpaceStation::PushToLua(dynamic_cast<SpaceStation*>(body));
						break;
					case Object::PLANET:
						LuaPlanet::PushToLua(dynamic_cast<Planet*>(body));
						break;
					case Object::STAR:
						LuaStar::PushToLua(dynamic_cast<Star*>(body));
						break;
					case Object::PLAYER:
						LuaPlayer::PushToLua(dynamic_cast<Player*>(body));
						break;
					default:
						throw SavedGameCorruptException();
				}

				break;
			}

			throw SavedGameCorruptException();
		}

		case 'o': {
			const char *end = strchr(pos, '\n');
			if (!end) throw SavedGameCorruptException();
			int len = end - pos;
			end++; // skip newline

			const char *cl = pos;

			// unpickle the object, and insert it beneath the method table value
			pos = unpickle(l, end);

			// get _G[typename]
			lua_rawgeti(l, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS);
			lua_pushlstring(l, cl, len);
			lua_gettable(l, -2);
			lua_remove(l, -2);

			if (lua_isnil(l, -1)) {
				lua_pop(l, 2);
				break;
			}

			lua_getfield(l, -1, "Unserialize");
			if (lua_isnil(l, -1)) {
				lua_pushlstring(l, cl, len);
				luaL_error(l, "No Unserialize method found for class '%s'\n", lua_tostring(l, -1));
			}

			lua_insert(l, -3);
			lua_pop(l, 1);

			pi_lua_protected_call(l, 1, 1);

			break;
		}

		default:
			throw SavedGameCorruptException();
	}

	LUA_DEBUG_END(l, 1);

	return pos;
}
Beispiel #25
0
static void
nlua_thread(int pin, int pout, char *project, char *filename)
{
    char cmd[4096];
    int cmd_size;

    fprintf(stderr, "[err] Starting up Lua interpreter...\n");
    fprintf(stdout, "[out] Starting up Lua interpreter...\n");

    lua_State *L;
    L = lua_open();

    if (!L) {
        cmd[0] = LC_ERROR;
        cmd_size = snprintf(cmd+1, sizeof(cmd)-2, "Unable to open lua") + 1;
        write(1, cmd, cmd_size);
        exit(0);
    }

    luaL_openlibs(L);
    lua_sethook(L, nlua_interpret_hook, LUA_MASKLINE, 0);

    /* If a filename was specified, load it in and run it */
    if (project && *project) {
        char full_filename[2048];
        if (filename && *filename)
            snprintf(full_filename, sizeof(full_filename)-1,
                    "%s/%s/%s", PROJECT_DIR, project, filename);
        else
            snprintf(full_filename, sizeof(full_filename)-1,
                    "%s/%s", PROJECT_DIR, project);

        if (luaL_dofile(L, full_filename)) {
            cmd[0] = LC_ERROR;
            cmd_size = snprintf(cmd+1, sizeof(cmd)-2, "Error: %s",
                    lua_tostring(L, 1)) + 1;
            write(1, cmd, cmd_size);
        }
    }

    /* If no file was specified, enter REPL mode */
    else {
        printf("Entering REPL mode...\n");
        int status;
        while ((status = loadline(L)) != -1) {
            if (status == 0)
                status = docall(L, 0, 0);
            report(L, status);
            if (status == 0 && lua_gettop(L) > 0) {  /* any result to print? */
                lua_getglobal(L, "print");
                lua_insert(L, 1);
                if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0)
                    l_message(progname,
                        lua_pushfstring(L, "error calling " LUA_QL("print") " (%s)",
                        lua_tostring(L, -1)));
            }
        }
        lua_settop(L, 0);
        fputs("\n", stdout);
        fflush(stdout);
    }

    lua_close(L);
    close(pin);
    close(pout);
    exit(0);

    return;
}
Beispiel #26
0
void LuaSerializer::pickle(lua_State *l, int idx, std::string &out, const char *key = NULL)
{
	static char buf[256];

	LUA_DEBUG_START(l);

	idx = lua_absindex(l, idx);

	if (lua_getmetatable(l, idx)) {
		lua_getfield(l, -1, "class");
		if (lua_isnil(l, -1))
			lua_pop(l, 2);

		else {
			const char *cl = lua_tostring(l, -1);
			snprintf(buf, sizeof(buf), "o%s\n", cl);

			lua_getglobal(l, cl);
			if (lua_isnil(l, -1))
				luaL_error(l, "No Serialize method found for class '%s'\n", cl);

			lua_getfield(l, -1, "Serialize");
			if (lua_isnil(l, -1))
				luaL_error(l, "No Serialize method found for class '%s'\n", cl);

			lua_pushvalue(l, idx);
			pi_lua_protected_call(l, 1, 1);

			lua_remove(l, idx);
			lua_insert(l, idx);

			lua_pop(l, 3);

			if (lua_isnil(l, idx)) {
				LUA_DEBUG_END(l, 0);
				return;
			}

			out += buf;
		}
	}

	switch (lua_type(l, idx)) {
		case LUA_TNIL:
			break;

		case LUA_TNUMBER: {
			snprintf(buf, sizeof(buf), "f%f\n", lua_tonumber(l, idx));
			out += buf;
			break;
		}

		case LUA_TBOOLEAN: {
			snprintf(buf, sizeof(buf), "b%d", lua_toboolean(l, idx) ? 1 : 0);
			out += buf;
			break;
		}

		case LUA_TSTRING: {
			lua_pushvalue(l, idx);
			const char *str = lua_tostring(l, -1);
			snprintf(buf, sizeof(buf), "s" SIZET_FMT "\n", strlen(str));
			out += buf;
			out += str;
			lua_pop(l, 1);
			break;
		}

		case LUA_TTABLE: {
			lua_pushinteger(l, lua_Integer(lua_topointer(l, idx)));         // ptr

			lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs");    // ptr reftable
			lua_pushvalue(l, -2);                                           // ptr reftable ptr
			lua_rawget(l, -2);                                              // ptr reftable ???

			if (!lua_isnil(l, -1)) {
				out += "r";
				pickle(l, -3, out, key);
				lua_pop(l, 3);                                              // [empty]
			}

			else {
				out += "t";

				lua_pushvalue(l, -3);                                       // ptr reftable nil ptr
				lua_pushvalue(l, idx);                                      // ptr reftable nil ptr table
				lua_rawset(l, -4);                                          // ptr reftable nil
				pickle(l, -3, out, key);
				lua_pop(l, 3);                                              // [empty]

				lua_pushvalue(l, idx);
				lua_pushnil(l);
				while (lua_next(l, -2)) {
					if (key) {
						pickle(l, -2, out, key);
						pickle(l, -1, out, key);
					}
					else {
						lua_pushvalue(l, -2);
						const char *k = lua_tostring(l, -1);
						pickle(l, -3, out, k);
						pickle(l, -2, out, k);
						lua_pop(l, 1);
					}
					lua_pop(l, 1);
				}
				lua_pop(l, 1);
				out += "n";
			}

			break;
		}

		case LUA_TUSERDATA: {
			out += "u";
			lid *idp = static_cast<lid*>(lua_touserdata(l, idx));
			LuaObjectBase *lo = LuaObjectBase::Lookup(*idp);
			if (!lo)
				Error("Lua serializer '%s' tried to serialize object with id 0x%08x, but it no longer exists", key, *idp);

			// XXX object wrappers should really have Serialize/Unserialize
			// methods to deal with this
			if (lo->Isa("SystemPath")) {
				SystemPath *sbp = dynamic_cast<SystemPath*>(lo->m_object);
				snprintf(buf, sizeof(buf), "SystemPath\n%d\n%d\n%d\n%u\n%u\n",
					sbp->sectorX, sbp->sectorY, sbp->sectorZ, sbp->systemIndex, sbp->bodyIndex);
				out += buf;
				break;
			}

			if (lo->Isa("Body")) {
				Body *b = dynamic_cast<Body*>(lo->m_object);
				snprintf(buf, sizeof(buf), "Body\n%u\n", Pi::game->GetSpace()->GetIndexForBody(b));
				out += buf;
				break;
			}

			Error("Lua serializer '%s' tried to serialize unsupported userdata value", key);
			break;
		}

		default:
			Error("Lua serializer '%s' tried to serialize %s value", key, lua_typename(l, lua_type(l, idx)));
			break;
	}

	LUA_DEBUG_END(l, 0);
}
ngx_int_t
ngx_http_lua_body_filter_by_chunk(lua_State *L, ngx_http_request_t *r,
    ngx_chain_t *in)
{
    ngx_int_t        rc;
    u_char          *err_msg;
    size_t           len;
#if (NGX_PCRE)
    ngx_pool_t      *old_pool;
#endif

    dd("initialize nginx context in Lua VM, code chunk at stack top  sp = 1");
    ngx_http_lua_body_filter_by_lua_env(L, r, in);

#if (NGX_PCRE)
    /* XXX: work-around to nginx regex subsystem */
    old_pool = ngx_http_lua_pcre_malloc_init(r->pool);
#endif

    lua_pushcfunction(L, ngx_http_lua_traceback);
    lua_insert(L, 1);  /* put it under chunk and args */

    dd("protected call user code");
    rc = lua_pcall(L, 0, 1, 1);

    lua_remove(L, 1);  /* remove traceback function */

#if (NGX_PCRE)
    /* XXX: work-around to nginx regex subsystem */
    ngx_http_lua_pcre_malloc_done(old_pool);
#endif

    if (rc != 0) {

        /*  error occured */
        err_msg = (u_char *) lua_tolstring(L, -1, &len);

        if (err_msg == NULL) {
            err_msg = (u_char *) "unknown reason";
            len = sizeof("unknown reason") - 1;
        }

        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                      "failed to run body_filter_by_lua*: %*s", len, err_msg);

        lua_settop(L, 0);    /*  clear remaining elems on stack */

        return NGX_ERROR;
    }

    /* rc == 0 */

    rc = (ngx_int_t) lua_tointeger(L, -1);

    dd("got return value: %d", (int) rc);

    lua_settop(L, 0);

    if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
        return NGX_ERROR;
    }

    return NGX_OK;
}
Beispiel #28
0
// in: linda_ud [, key [, ...]]
int keepercall_count( lua_State* L)
{
	int top;
	push_table( L, 1);                                   // ud keys fifos
	switch( lua_gettop( L))
	{
		// no key is specified: return a table giving the count of all known keys
		case 2:                                            // ud fifos
		lua_newtable( L);                                  // ud fifos out
		lua_replace( L, 1);                                // out fifos
		lua_pushnil( L);                                   // out fifos nil
		while( lua_next( L, 2))                            // out fifos key fifo
		{
			keeper_fifo* fifo = prepare_fifo_access( L, -1); // out fifos key fifo
			lua_pop( L, 1);                                  // out fifos key
			lua_pushvalue( L, -1);                           // out fifos key key
			lua_pushinteger( L, fifo->count);                // out fifos key key count
			lua_rawset( L, -5);                              // out fifos key
		}
		lua_pop( L, 1);                                    // out
		break;

		// 1 key is specified: return its count
		case 3:                                            // ud key fifos
		{
			keeper_fifo* fifo;
			lua_replace( L, 1);                              // fifos key
			lua_rawget( L, -2);                              // fifos fifo
			fifo = prepare_fifo_access( L, -1);              // fifos fifo
			lua_pushinteger( L, fifo->count);                // fifos fifo count
			lua_replace( L, -3);                             // count fifo
			lua_pop( L, 1);                                  // count
		}
		break;

		// a variable number of keys is specified: return a table of their counts
		default:                                           // ud keys fifos
		lua_newtable( L);                                  // ud keys fifos out
		lua_replace( L, 1);                                // out keys fifos
		// shifts all keys up in the stack. potentially slow if there are a lot of them, but then it should be bearable
		lua_insert( L, 2);                                 // out fifos keys
		while( (top = lua_gettop( L)) > 2)
		{
			keeper_fifo* fifo;
			lua_pushvalue( L, -1);                           // out fifos keys key
			lua_rawget( L, 2);                               // out fifos keys fifo
			fifo = prepare_fifo_access( L, -1);              // out fifos keys fifo
			lua_pop( L, 1);                                  // out fifos keys
			if( fifo)
			{
				lua_pushinteger( L, fifo->count);              // out fifos keys count
				lua_rawset( L, 1);                             // out fifos keys
			}
			else
			{
				lua_pop( L, 1);                                // out fifos keys
			}
		}
		lua_pop( L, 1);                                    // out
	}
	return 1;
}
Beispiel #29
0
/*!
 * \brief Store the sort order of each context
 
 * In the event of an error, an error string will be pushed onto the lua stack.
 *
 * \retval 0 success
 * \retval 1 failure
 */
static int lua_sort_extensions(lua_State *L)
{
	int extensions, extensions_order;

	/* create the extensions_order table */
	lua_newtable(L);
	lua_setfield(L, LUA_REGISTRYINDEX, "extensions_order");
	lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order");
	extensions_order = lua_gettop(L);

	/* sort each context in the extensions table */
	/* load the 'extensions' table */
	lua_getglobal(L, "extensions");
	extensions = lua_gettop(L);
	if (lua_isnil(L, -1)) {
		lua_pop(L, 1);
		lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n");
		return 1;
	}

	/* iterate through the extensions table and create a
	 * matching table (holding the sort order) in the
	 * extensions_order table for each context that is found
	 */
	for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) {
		int context = lua_gettop(L);
		int context_name = context - 1;
		int context_order;

		/* copy the context_name to be used as the key for the
		 * context_order table in the extensions_order table later */
		lua_pushvalue(L, context_name);

		/* create the context_order table */
		lua_newtable(L);
		context_order = lua_gettop(L);

		/* iterate through this context an popluate the corrisponding
		 * table in the extensions_order table */
		for (lua_pushnil(L); lua_next(L, context); lua_pop(L, 1)) {
			int exten = lua_gettop(L) - 1;

			lua_pushinteger(L, lua_objlen(L, context_order) + 1);
			lua_pushvalue(L, exten);
			lua_settable(L, context_order);
		}
		lua_settable(L, extensions_order); /* put the context_order table in the extensions_order table */

		/* now sort the new table */

		/* push the table.sort function */
		lua_getglobal(L, "table");
		lua_getfield(L, -1, "sort");
		lua_remove(L, -2); /* remove the 'table' table */

		/* push the context_order table */
		lua_pushvalue(L, context_name);
		lua_gettable(L, extensions_order);

		/* push the comp function */
		lua_pushcfunction(L, &lua_extension_cmp);

		if (lua_pcall(L, 2, 0, 0)) {
			lua_insert(L, -5);
			lua_pop(L, 4);
			return 1;
		}
	}
	
	/* remove the extensions table and the extensions_order table */
	lua_pop(L, 2);
	return 0;
}
Beispiel #30
0
/*
| The effective main for one run.
|
| HUP signals may cause several runs of the one main.
*/
int
main1( int argc, char *argv[] )
{
	// the Lua interpreter
	lua_State * L;

	// the runner file
	char * lsyncd_runner_file = NULL;

	int argp = 1;

	// load Lua
	L = luaL_newstate( );

	luaL_openlibs( L );
	{
		// checks the lua version
		const char * version;
		int major, minor;
		lua_getglobal( L, "_VERSION" );
		version = luaL_checkstring( L, -1 );

		if(
			sscanf(
				version,
				"Lua %d.%d",
				&major, &minor
			) != 2
		)
		{
			fprintf(
				stderr,
				"cannot parse lua library version!\n"
			);
			exit (-1 );
		}

		if(
			major < 5 ||
			(major == 5 && minor < 1)
		) {
			fprintf(
				stderr,
				"Lua library is too old. Needs 5.1 at least"
			);
			exit( -1 );
		}

		lua_pop( L, 1 );
	}

	{
		// logging is prepared quite early
		int i = 1;
		add_logcat( "Normal", LOG_NOTICE  );
		add_logcat( "Warn",   LOG_WARNING );
		add_logcat( "Error",  LOG_ERR     );

		while( i < argc )
		{
			if(
				strcmp( argv[ i ], "-log"  ) &&
				strcmp( argv[ i ], "--log" )
			)
			{
				// arg is neither -log or --log
				i++;
				continue;
			}

			if( ++i >= argc )
			{
				// -(-)log was last argument
				break;
			}

			if( !add_logcat( argv[ i ], LOG_NOTICE ) )
			{
				printlogf(
					L, "Error",
					"'%s' is not a valid logging category",
					argv[ i ]
				);
				exit( -1 );
			}
		}
	}

	// registers Lsycnd's core library
	register_lsyncd( L );

	if( check_logcat( "Debug" ) <= settings.log_level )
	{
		// printlogf doesnt support %ld :-(
		printf(
			"kernels clocks_per_sec=%ld\n",
			clocks_per_sec
		);
	}

	// checks if the user overrode the default runner file
	if(
		argp < argc &&
		!strcmp( argv[ argp ], "--runner" )
	)
	{
		if (argp + 1 >= argc)
		{
			logstring(
				"Error",
				"Lsyncd Lua-runner file missing after --runner "
			);

			exit( -1 );
		}

		lsyncd_runner_file = argv[ argp + 1 ];
		argp += 2;
	}

	if( lsyncd_runner_file )
	{
		// checks if the runner file exists
		struct stat st;

		if( stat( lsyncd_runner_file, &st ) )
		{
			printlogf(
				L, "Error",
				"Cannot see a runner at '%s'.",
				lsyncd_runner_file
			);
			exit( -1 );
		}

		// loads the runner file
		if( luaL_loadfile(L, lsyncd_runner_file ) )
		{
			printlogf(
				L, "Error",
				"error loading '%s': %s",
				lsyncd_runner_file,
				lua_tostring( L, -1 )
			);

			exit( -1 );
		}

	}
	else
	{
		// loads the runner from binary
		if( luaL_loadbuffer( L, runner_out, runner_size, "runner" ) )
		{
			printlogf(
				L, "Error",
				"error loading precompiled runner: %s",
				lua_tostring( L, -1 )
			);

			exit( -1 );
		}
	}

	// prepares the runner executing the script
	{
		if( lua_pcall( L, 0, LUA_MULTRET, 0 ) )
		{
			printlogf(
				L, "Error",
				"preparing runner: %s",
				lua_tostring( L, -1 )
			);

			exit( -1 );
		}

		lua_pushlightuserdata( L, (void *) & runner );

		// switches the value ( result of preparing ) and the key &runner
		lua_insert( L, 1 );

		// saves the table of the runners functions in the lua registry
		lua_settable( L, LUA_REGISTRYINDEX );

		// saves the error function extras

		// &callError is the key
		lua_pushlightuserdata ( L, (void *) &callError );

		// &runner[ callError ] the value
		lua_pushlightuserdata ( L, (void *) &runner    );
		lua_gettable          ( L, LUA_REGISTRYINDEX   );
		lua_pushstring        ( L, "callError"         );
		lua_gettable          ( L, -2                  );
		lua_remove            ( L, -2                  );

		lua_settable          ( L, LUA_REGISTRYINDEX   );
	}

	// asserts the Lsyncd's version matches
	// between runner and core
	{
		const char *lversion;

		lua_getglobal( L, "lsyncd_version" );
		lversion = luaL_checkstring( L, -1 );

		if( strcmp( lversion, PACKAGE_VERSION ) )
		{
			printlogf(
				L, "Error",
				"Version mismatch '%s' is '%s', but core is '%s'",
				lsyncd_runner_file ? lsyncd_runner_file : "( internal runner )",
				lversion, PACKAGE_VERSION
			);

			exit( -1 );
		}

		lua_pop( L, 1 );
	}

	// loads the defaults from binary
	{
		if( luaL_loadbuffer( L, defaults_out, defaults_size, "defaults" ) )
		{
			printlogf(
				L, "Error",
				"loading defaults: %s",
				lua_tostring( L, -1 )
			);

			exit( -1 );
		}

		// prepares the defaults
		if( lua_pcall( L, 0, 0, 0 ) )
		{
			printlogf(
				L, "Error",
				"preparing defaults: %s",
				lua_tostring( L, -1 )
			);
			exit( -1 );
		}
	}

	// checks if there is a "-help" or "--help"
	{
		int i;
		for( i = argp; i < argc; i++ )
		{
			if (
				!strcmp( argv[ i ],  "-help" ) ||
				!strcmp( argv[ i ], "--help" )
			)
			{
				load_runner_func( L, "help" );

				if( lua_pcall( L, 0, 0, -2 ) )
				{
					exit( -1 );
				}

				lua_pop( L, 1 );
				exit( 0 );
			}
		}
	}

	// starts the option parser in Lua script
	{
		int idx = 1;
		const char *s;

		// creates a table with all remaining argv option arguments
		load_runner_func( L, "configure" );
		lua_newtable( L );

		while( argp < argc )
		{
			lua_pushnumber ( L, idx++          );
			lua_pushstring ( L, argv[ argp++ ] );
			lua_settable   ( L, -3             );
		}

		// creates a table with the cores event monitor interfaces
		idx = 0;
		lua_newtable( L );

		while( monitors[ idx ] )
		{
			lua_pushnumber ( L, idx + 1           );
			lua_pushstring ( L, monitors[ idx++ ] );
			lua_settable   ( L, -3                );
		}

		if( lua_pcall( L, 2, 1, -4 ) )
		{
			exit( -1 );
		}

		if( first_time )
		{
			// If not first time, simply retains the config file given
			s = lua_tostring(L, -1);
			if( s )
			{
				lsyncd_config_file = s_strdup( s );
			}
		}
		lua_pop( L, 2 );
	}

	// checks existence of the config file
	if( lsyncd_config_file )
	{
		struct stat st;

		// gets the absolute path to the config file
		// so in case of HUPing the daemon, it finds it again
		char * apath = get_realpath( lsyncd_config_file );
		if( !apath )
		{
			printlogf(
				L, "Error",
				"Cannot find config file at '%s'.",
				lsyncd_config_file
			);

			exit( -1 );
		}

		free( lsyncd_config_file );
		lsyncd_config_file = apath;

		if( stat( lsyncd_config_file, &st ) )
		{
			printlogf(
				L, "Error",
				"Cannot find config file at '%s'.",
				lsyncd_config_file
			);

			exit( -1 );
		}

		// loads and executes the config file
		if( luaL_loadfile( L, lsyncd_config_file ) )
		{
			printlogf(
				L, "Error",
				"error loading %s: %s",
				lsyncd_config_file,
				lua_tostring( L, -1 )
			);

			exit( -1 );
		}

		if( lua_pcall( L, 0, LUA_MULTRET, 0) )
		{
			printlogf(
				L, "Error",
				"error preparing %s: %s",
				lsyncd_config_file,
				lua_tostring( L, -1 )
			);

			exit( -1 );
		}
	}

#ifdef WITH_INOTIFY
	open_inotify( L );
#endif

#ifdef WITH_FSEVENTS
	open_fsevents( L );
#endif

	// adds signal handlers
	// listens to SIGCHLD, but blocks it until pselect( )
	// opens the signal handler up
	{
		sigset_t set;
		sigemptyset( &set );
		sigaddset( &set, SIGCHLD );
		signal( SIGCHLD, sig_child );
		sigprocmask( SIG_BLOCK, &set, NULL );

		signal( SIGHUP,  sig_handler );
		signal( SIGTERM, sig_handler );
		signal( SIGINT,  sig_handler );
	}

	// runs initializations from runner
	// it will set the configuration and add watches
	{
		load_runner_func( L, "initialize" );
		lua_pushboolean( L, first_time );

		if( lua_pcall( L, 1, 0, -3 ) )
		{
			exit( -1 );
		}

		lua_pop( L, 1 );
	}

	//
	// enters the master loop
	//
	masterloop( L );

	//
	// cleanup
	//

	// tidies up all observances
	{
		int i;
		for( i = 0; i < observances_len; i++ )
		{
			struct observance *obs = observances + i;
			obs->tidy( obs );
		}

		observances_len    = 0;
		nonobservances_len = 0;
	}

	// frees logging categories
	{
		int ci;
		struct logcat *lc;
		for( ci = 'A'; ci <= 'Z'; ci++ )
		{
			for( lc = logcats[ ci - 'A' ]; lc && lc->name; lc++)
			{
				free( lc->name );
				lc->name = NULL;
			}

			if( logcats[ci - 'A' ] )
			{
				free( logcats[ ci - 'A' ] );
				logcats[ ci - 'A' ] = NULL;
			}
		}
	}

	lua_close( L );
	return 0;
}