Commit 77a1a1c4 authored by Marek Vavruša's avatar Marek Vavruša

daemon: ‘net’ package, implemented ‘net.interfaces’

lists available interfaces
parent 06adb891
......@@ -14,6 +14,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <uv.h>
#include "lib/cache.h"
#include "daemon/bindings.h"
......@@ -59,8 +61,19 @@ static int mod_load(lua_State *L)
/** Unload module. */
static int mod_unload(lua_State *L)
{
lua_pushstring(L, "not implemented");
lua_error(L);
/* Check parameters */
int n = lua_gettop(L);
if (n != 1 || !lua_isstring(L, 1)) {
lua_pushstring(L, "expected module name");
lua_error(L);
}
/* Unload engine module */
struct engine *engine = engine_luaget(L);
int ret = engine_unregister(engine, lua_tostring(L, 1));
if (ret != 0) {
lua_pushstring(L, kr_strerror(ret));
lua_error(L);
}
return 0;
}
......@@ -77,11 +90,93 @@ int lib_modules(lua_State *L)
return 1;
}
int lib_config(lua_State *L)
/** List active endpoints. */
static int net_list(lua_State *L)
{
lua_pushstring(L, "not implemented");
lua_error(L);
return 0;
}
/** Listen on endpoint. */
static int net_listen(lua_State *L)
{
lua_pushstring(L, "not implemented");
lua_error(L);
return 0;
}
/** Close endpoint. */
static int net_close(lua_State *L)
{
lua_pushstring(L, "not implemented");
lua_error(L);
return 0;
}
/** List available interfaces.
* @TODO: Implement as a map {name: { addr: [], mac: "" }}
*/
static int net_interfaces(lua_State *L)
{
/* Retrieve interface list */
int count = 0;
char buf[INET6_ADDRSTRLEN]; /* http://tools.ietf.org/html/rfc4291 */
uv_interface_address_t *info = NULL;
uv_interface_addresses(&info, &count);
/* Fill table. */
lua_newtable(L);
for (int i = count; i--; ) {
uv_interface_address_t iface = info[i];
lua_newtable(L);
lua_pushstring(L, iface.name);
lua_setfield(L, -2, "id");
/* Address */
buf[0] = '\0';
switch(iface.address.address4.sin_family) {
case AF_INET:
uv_ip4_name(&iface.address.address4, buf, sizeof(buf));
break;
case AF_INET6:
uv_ip6_name(&iface.address.address6, buf, sizeof(buf));
break;
}
lua_pushstring(L, buf);
lua_setfield(L, -2, "addr");
/* Hardware address. */
char *p = buf;
memset(buf, 0, sizeof(buf));
for (unsigned k = 0; k < sizeof(iface.phys_addr); ++k) {
sprintf(p, "%0x", iface.phys_addr[k] & 0xff);
p += 2;
}
lua_pushstring(L, buf);
lua_setfield(L, -2, "mac");
/* Push table */
lua_rawseti(L, -2, i);
}
uv_free_interface_addresses(info, count);
return 1;
}
int lib_net(lua_State *L)
{
static const luaL_Reg lib[] = {
{ "list", net_list },
{ "listen", net_listen },
{ "close", net_close },
{ "interfaces", net_interfaces },
{ NULL, NULL }
};
register_lib(L, "net", lib);
return 1;
}
/** Open cache */
static int cache_open(lua_State *L)
{
......
......@@ -33,11 +33,11 @@
int lib_modules(lua_State *L);
/**
* Load 'config' package.
* Load 'net' package.
* @param L scriptable
* @return number of packages to load
*/
int lib_config(lua_State *L);
int lib_net(lua_State *L);
/**
* Load 'cache' package.
......
......@@ -27,6 +27,13 @@
* Global bindings.
*/
/** Register module callback into Lua world. */
#define REGISTER_MODULE_CALL(L, module, cb, name) \
lua_pushlightuserdata((L), (module)); \
lua_pushlightuserdata((L), (cb)); \
lua_pushcclosure((L), l_trampoline, 2); \
lua_setfield((L), -2, (name))
/** Print help and available commands. */
static int l_help(lua_State *L)
{
......@@ -56,26 +63,23 @@ static int l_quit(lua_State *L)
/** Trampoline function for module properties. */
static int l_trampoline(lua_State *L)
{
const char *name = lua_tostring(L, lua_upvalueindex(1));
const char *property = lua_tostring(L, lua_upvalueindex(2));
struct kr_module *module = lua_touserdata(L, lua_upvalueindex(1));
void* callback = lua_touserdata(L, lua_upvalueindex(2));
struct engine *engine = engine_luaget(L);
/* Find module. */
for (unsigned i = 0; i < engine->modules.len; ++i) {
struct kr_module *module = &engine->modules.at[i];
if (strcmp(module->name, name) != 0) {
continue;
}
/* Find property. */
for (struct kr_prop *p = module->props; p && p->name; ++p) {
if (strcmp(p->name, property) == 0) {
auto_free char *ret = p->cb(engine, module, NULL);
lua_pushstring(L, ret);
return 1;
}
}
break;
/* Now we only have property callback or config,
* if we expand the callables, we might need a callback_type.
*/
if (callback == module->config) {
const char *param = lua_tostring(L, 1);
module->config(module, param);
} else {
kr_prop_cb *prop = (kr_prop_cb *)callback;
auto_free char *ret = prop(engine, module, lua_tostring(L, 1));
lua_pushstring(L, ret);
return 1;
}
/* No results */
return 0;
}
......@@ -186,6 +190,14 @@ int engine_cmd(struct engine *engine, const char *str)
static int engine_loadconf(struct engine *engine)
{
/* Init environment */
static const char l_init[] = {
#include "daemon/lua/init.inc"
};
if (luaL_dostring(engine->L, l_init) != 0) {
return kr_error(ENOEXEC);
}
/* Load config file */
int ret = 0;
if(access("config", F_OK ) != -1 ) {
......@@ -193,7 +205,7 @@ static int engine_loadconf(struct engine *engine)
} else {
/* Load defaults */
static const char config_init[] = {
#include "daemon/lua/init.inc"
#include "daemon/lua/config.inc"
};
ret = luaL_dostring(engine->L, config_init);
}
......@@ -244,11 +256,13 @@ int engine_register(struct engine *engine, const char *name)
/* Register properties */
if (module->props) {
lua_newtable(engine->L);
if (module->config != NULL) {
REGISTER_MODULE_CALL(engine->L, module, module->config, "config");
}
for (struct kr_prop *p = module->props; p->name; ++p) {
lua_pushstring(engine->L, module->name);
lua_pushstring(engine->L, p->name);
lua_pushcclosure(engine->L, l_trampoline, 2);
lua_setfield(engine->L, -2, p->name);
if (p->cb != NULL && p->name != NULL) {
REGISTER_MODULE_CALL(engine->L, module, p->cb, p->name);
}
}
lua_setglobal(engine->L, module->name);
}
......
......@@ -20,7 +20,6 @@
* @internal These are forward decls to allow building modules with engine but without Lua.
*/
struct lua_State;
typedef int (*lua_CFunction) (struct lua_State *L);
#include "lib/resolve.h"
#include "lib/generic/array.h"
......@@ -40,5 +39,5 @@ void engine_stop(struct engine *engine);
int engine_register(struct engine *engine, const char *module);
int engine_unregister(struct engine *engine, const char *module);
/** Return engine light userdata. */
void engine_lualib(struct engine *engine, const char *name, lua_CFunction lib_cb);
void engine_lualib(struct engine *engine, const char *name, int (*lib_cb) (struct lua_State *));
struct engine *engine_luaget(struct lua_State *L);
\ No newline at end of file
......@@ -144,8 +144,8 @@ int main(int argc, char **argv)
/* Load bindings */
engine_lualib(&engine, "modules", lib_modules);
engine_lualib(&engine, "config", lib_config);
engine_lualib(&engine, "cache", lib_cache);
engine_lualib(&engine, "net", lib_net);
engine_lualib(&engine, "cache", lib_cache);
/* Create main worker. */
struct worker_ctx worker = {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment