diff src/inet.c @ 0:4b915342e2a8

LuaSocket 2.0.2 + CMake build description.
author Eric Wing <ewing . public |-at-| gmail . com>
date Tue, 26 Aug 2008 18:40:01 -0700
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/inet.c	Tue Aug 26 18:40:01 2008 -0700
@@ -0,0 +1,281 @@
+/*=========================================================================*\
+* Internet domain functions
+* LuaSocket toolkit
+*
+* RCS ID: $Id: inet.c,v 1.28 2005/10/07 04:40:59 diego Exp $
+\*=========================================================================*/
+#include <stdio.h>
+#include <string.h>
+
+#include "lua.h"
+#include "lauxlib.h"
+
+#include "inet.h"
+
+/*=========================================================================*\
+* Internal function prototypes.
+\*=========================================================================*/
+static int inet_global_toip(lua_State *L);
+static int inet_global_tohostname(lua_State *L);
+static void inet_pushresolved(lua_State *L, struct hostent *hp);
+static int inet_global_gethostname(lua_State *L);
+
+/* DNS functions */
+static luaL_reg func[] = {
+    { "toip", inet_global_toip },
+    { "tohostname", inet_global_tohostname },
+    { "gethostname", inet_global_gethostname},
+    { NULL, NULL}
+};
+
+/*=========================================================================*\
+* Exported functions
+\*=========================================================================*/
+/*-------------------------------------------------------------------------*\
+* Initializes module
+\*-------------------------------------------------------------------------*/
+int inet_open(lua_State *L)
+{
+    lua_pushstring(L, "dns");
+    lua_newtable(L);
+    luaL_openlib(L, NULL, func, 0);
+    lua_settable(L, -3);
+    return 0;
+}
+
+/*=========================================================================*\
+* Global Lua functions
+\*=========================================================================*/
+/*-------------------------------------------------------------------------*\
+* Returns all information provided by the resolver given a host name
+* or ip address
+\*-------------------------------------------------------------------------*/
+static int inet_gethost(const char *address, struct hostent **hp) {
+    struct in_addr addr;
+    if (inet_aton(address, &addr))
+        return socket_gethostbyaddr((char *) &addr, sizeof(addr), hp);
+    else 
+        return socket_gethostbyname(address, hp);
+}
+
+/*-------------------------------------------------------------------------*\
+* Returns all information provided by the resolver given a host name
+* or ip address
+\*-------------------------------------------------------------------------*/
+static int inet_global_tohostname(lua_State *L) {
+    const char *address = luaL_checkstring(L, 1);
+    struct hostent *hp = NULL; 
+    int err = inet_gethost(address, &hp);
+    if (err != IO_DONE) {
+        lua_pushnil(L);
+        lua_pushstring(L, socket_hoststrerror(err));
+        return 2;
+    }
+    lua_pushstring(L, hp->h_name);
+    inet_pushresolved(L, hp);
+    return 2;
+}
+
+/*-------------------------------------------------------------------------*\
+* Returns all information provided by the resolver given a host name
+* or ip address
+\*-------------------------------------------------------------------------*/
+static int inet_global_toip(lua_State *L)
+{
+    const char *address = luaL_checkstring(L, 1);
+    struct hostent *hp = NULL; 
+    int err = inet_gethost(address, &hp);
+    if (err != IO_DONE) {
+        lua_pushnil(L);
+        lua_pushstring(L, socket_hoststrerror(err));
+        return 2;
+    }
+    lua_pushstring(L, inet_ntoa(*((struct in_addr *) hp->h_addr)));
+    inet_pushresolved(L, hp);
+    return 2;
+}
+
+
+/*-------------------------------------------------------------------------*\
+* Gets the host name
+\*-------------------------------------------------------------------------*/
+static int inet_global_gethostname(lua_State *L)
+{
+    char name[257];
+    name[256] = '\0';
+    if (gethostname(name, 256) < 0) {
+        lua_pushnil(L);
+        lua_pushstring(L, "gethostname failed");
+        return 2;
+    } else {
+        lua_pushstring(L, name);
+        return 1;
+    }
+}
+
+
+
+/*=========================================================================*\
+* Lua methods
+\*=========================================================================*/
+/*-------------------------------------------------------------------------*\
+* Retrieves socket peer name
+\*-------------------------------------------------------------------------*/
+int inet_meth_getpeername(lua_State *L, p_socket ps)
+{
+    struct sockaddr_in peer;
+    socklen_t peer_len = sizeof(peer);
+    if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) {
+        lua_pushnil(L);
+        lua_pushstring(L, "getpeername failed");
+    } else {
+        lua_pushstring(L, inet_ntoa(peer.sin_addr));
+        lua_pushnumber(L, ntohs(peer.sin_port));
+    }
+    return 2;
+}
+
+/*-------------------------------------------------------------------------*\
+* Retrieves socket local name
+\*-------------------------------------------------------------------------*/
+int inet_meth_getsockname(lua_State *L, p_socket ps)
+{
+    struct sockaddr_in local;
+    socklen_t local_len = sizeof(local);
+    if (getsockname(*ps, (SA *) &local, &local_len) < 0) {
+        lua_pushnil(L);
+        lua_pushstring(L, "getsockname failed");
+    } else {
+        lua_pushstring(L, inet_ntoa(local.sin_addr));
+        lua_pushnumber(L, ntohs(local.sin_port));
+    }
+    return 2;
+}
+
+/*=========================================================================*\
+* Internal functions
+\*=========================================================================*/
+/*-------------------------------------------------------------------------*\
+* Passes all resolver information to Lua as a table
+\*-------------------------------------------------------------------------*/
+static void inet_pushresolved(lua_State *L, struct hostent *hp)
+{
+    char **alias;
+    struct in_addr **addr;
+    int i, resolved;
+    lua_newtable(L); resolved = lua_gettop(L);
+    lua_pushstring(L, "name");
+    lua_pushstring(L, hp->h_name);
+    lua_settable(L, resolved);
+    lua_pushstring(L, "ip");
+    lua_pushstring(L, "alias");
+    i = 1;
+    alias = hp->h_aliases;
+    lua_newtable(L);
+    if (alias) {
+        while (*alias) {
+            lua_pushnumber(L, i);
+            lua_pushstring(L, *alias);
+            lua_settable(L, -3);
+            i++; alias++;
+        }
+    }
+    lua_settable(L, resolved);
+    i = 1;
+    lua_newtable(L);
+    addr = (struct in_addr **) hp->h_addr_list;
+    if (addr) {
+        while (*addr) {
+            lua_pushnumber(L, i);
+            lua_pushstring(L, inet_ntoa(**addr));
+            lua_settable(L, -3);
+            i++; addr++;
+        }
+    }
+    lua_settable(L, resolved);
+}
+
+/*-------------------------------------------------------------------------*\
+* Tries to create a new inet socket
+\*-------------------------------------------------------------------------*/
+const char *inet_trycreate(p_socket ps, int type) {
+    return socket_strerror(socket_create(ps, AF_INET, type, 0));
+}
+
+/*-------------------------------------------------------------------------*\
+* Tries to connect to remote address (address, port)
+\*-------------------------------------------------------------------------*/
+const char *inet_tryconnect(p_socket ps, const char *address, 
+        unsigned short port, p_timeout tm)
+{
+    struct sockaddr_in remote;
+    int err;
+    memset(&remote, 0, sizeof(remote));
+    remote.sin_family = AF_INET;
+    remote.sin_port = htons(port);
+	if (strcmp(address, "*")) {
+        if (!inet_aton(address, &remote.sin_addr)) {
+            struct hostent *hp = NULL;
+            struct in_addr **addr;
+            err = socket_gethostbyname(address, &hp);
+            if (err != IO_DONE) return socket_hoststrerror(err);
+            addr = (struct in_addr **) hp->h_addr_list;
+            memcpy(&remote.sin_addr, *addr, sizeof(struct in_addr));
+        }
+    } else remote.sin_family = AF_UNSPEC;
+    err = socket_connect(ps, (SA *) &remote, sizeof(remote), tm);
+    return socket_strerror(err);
+}
+
+/*-------------------------------------------------------------------------*\
+* Tries to bind socket to (address, port)
+\*-------------------------------------------------------------------------*/
+const char *inet_trybind(p_socket ps, const char *address, unsigned short port)
+{
+    struct sockaddr_in local;
+    int err;
+    memset(&local, 0, sizeof(local));
+    /* address is either wildcard or a valid ip address */
+    local.sin_addr.s_addr = htonl(INADDR_ANY);
+    local.sin_port = htons(port);
+    local.sin_family = AF_INET;
+    if (strcmp(address, "*") && !inet_aton(address, &local.sin_addr)) {
+        struct hostent *hp = NULL;
+        struct in_addr **addr;
+        err = socket_gethostbyname(address, &hp);
+        if (err != IO_DONE) return socket_hoststrerror(err);
+        addr = (struct in_addr **) hp->h_addr_list;
+        memcpy(&local.sin_addr, *addr, sizeof(struct in_addr));
+    }
+    err = socket_bind(ps, (SA *) &local, sizeof(local));
+    if (err != IO_DONE) socket_destroy(ps);
+    return socket_strerror(err); 
+}
+
+/*-------------------------------------------------------------------------*\
+* Some systems do not provide this so that we provide our own. It's not
+* marvelously fast, but it works just fine.
+\*-------------------------------------------------------------------------*/
+#ifdef INET_ATON
+int inet_aton(const char *cp, struct in_addr *inp)
+{
+    unsigned int a = 0, b = 0, c = 0, d = 0;
+    int n = 0, r;
+    unsigned long int addr = 0;
+    r = sscanf(cp, "%u.%u.%u.%u%n", &a, &b, &c, &d, &n);
+    if (r == 0 || n == 0) return 0;
+    cp += n;
+    if (*cp) return 0;
+    if (a > 255 || b > 255 || c > 255 || d > 255) return 0;
+    if (inp) {
+        addr += a; addr <<= 8;
+        addr += b; addr <<= 8;
+        addr += c; addr <<= 8;
+        addr += d;
+        inp->s_addr = htonl(addr);
+    }
+    return 1;
+}
+#endif
+
+