From 0c3e067af17a21338e8aa3240b61d40934373939 Mon Sep 17 00:00:00 2001 From: Florian Zeitz Date: Sat, 5 May 2012 02:13:56 +0200 Subject: [PATCH] Add a getnameinfo() wrapper This wrapper takes a domain name or an IP as first argument and a service name or port as second argument. Either argument may be nil. It returns a list of names (always only one in the IP case) and a service name. --- src/inet.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/inet.c b/src/inet.c index 5823c36..55e89d7 100644 --- a/src/inet.c +++ b/src/inet.c @@ -16,6 +16,7 @@ static int inet_global_toip(lua_State *L); static int inet_global_getaddrinfo(lua_State *L); static int inet_global_tohostname(lua_State *L); +static int inet_global_getnameinfo(lua_State *L); static void inet_pushresolved(lua_State *L, struct hostent *hp); static int inet_global_gethostname(lua_State *L); @@ -24,6 +25,7 @@ static luaL_Reg func[] = { { "toip", inet_global_toip}, { "getaddrinfo", inet_global_getaddrinfo}, { "tohostname", inet_global_tohostname}, + { "getnameinfo", inet_global_getnameinfo}, { "gethostname", inet_global_gethostname}, { NULL, NULL} }; @@ -76,6 +78,52 @@ static int inet_global_tohostname(lua_State *L) { return 2; } +static int inet_global_getnameinfo(lua_State *L) { + int i, ret; + char host[1024]; + char serv[32]; + struct addrinfo hints; + struct addrinfo *resolved, *iter; + const char *node = luaL_optstring(L, 1, NULL); + const char *service = luaL_optstring(L, 2, NULL); + + if (!(node || service)) + luaL_error(L, "You have to specify a hostname, a service, or both"); + + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = SOCK_STREAM; + hints.ai_family = PF_UNSPEC; + + /* getaddrinfo must get a node and a service argument */ + ret = getaddrinfo(node ? node : "127.0.0.1", service ? service : "7", + &hints, &resolved); + if (ret != 0) { + lua_pushnil(L); + lua_pushstring(L, socket_gaistrerror(ret)); + return 2; + } + + lua_newtable(L); + for (i = 1, iter = resolved; iter; i++, iter = iter->ai_next) { + getnameinfo(iter->ai_addr, iter->ai_addrlen, host, + node ? sizeof(host) : 0, serv, service ? sizeof(serv) : 0, 0); + + if (node) { + lua_pushnumber(L, i); + lua_pushstring(L, host); + lua_settable(L, -3); + } + } + freeaddrinfo(resolved); + + if (service) { + lua_pushstring(L, serv); + return 2; + } else { + return 1; + } +} + /*-------------------------------------------------------------------------*\ * Returns all information provided by the resolver given a host name * or ip address