Author: titmuss
Date: Wed Feb 13 09:27:48 2008
New Revision: 1935

URL: http://svn.slimdevices.com?rev=1935&root=Jive&view=rev
Log:
 [EMAIL PROTECTED] (orig r1921):  titmuss | 2008-02-13 15:52:01 +0000
 Bug: 7086
 Description:
 Added non-block dns lookups for http connections.
 
 

Added:
    trunk/jive/src/pkg/jive/share/jive/net/DNS.lua
    trunk/jive/src/pkg/jive/src/net/
    trunk/jive/src/pkg/jive/src/net/jive_dns.c
Modified:
    trunk/   (props changed)
    trunk/jive/src/pkg/jive/Makefile.am
    trunk/jive/src/pkg/jive/Makefile.in
    trunk/jive/src/pkg/jive/share/jive/net/NetworkThread.lua
    trunk/jive/src/pkg/jive/share/jive/net/SocketHttp.lua
    trunk/jive/src/pkg/jive/share/jive/net/SocketTcp.lua
    trunk/jive/src/pkg/jive/src/common.h
    trunk/jive/src/pkg/jive/src/jive.c

Propchange: trunk/
------------------------------------------------------------------------------
--- svk:merge (original)
+++ svk:merge Wed Feb 13 09:27:48 2008
@@ -1,3 +1,3 @@
-bbe22326-0783-4b3a-ac2b-7ab96b24c8d9:/branches/7.0:1920
+bbe22326-0783-4b3a-ac2b-7ab96b24c8d9:/branches/7.0:1921
 bbe22326-0783-4b3a-ac2b-7ab96b24c8d9:/branches/SN:1083
 bbe22326-0783-4b3a-ac2b-7ab96b24c8d9:/branches/scrolling:1378

Modified: trunk/jive/src/pkg/jive/Makefile.am
URL: 
http://svn.slimdevices.com/trunk/jive/src/pkg/jive/Makefile.am?rev=1935&root=Jive&r1=1934&r2=1935&view=diff
==============================================================================
--- trunk/jive/src/pkg/jive/Makefile.am (original)
+++ trunk/jive/src/pkg/jive/Makefile.am Wed Feb 13 09:27:48 2008
@@ -17,8 +17,8 @@
 #      @rm -f badsyntax
 
 
-# Convenience library: libui.la
-noinst_LTLIBRARIES = libjiveui.la
+# Convenience library:
+noinst_LTLIBRARIES = libjiveui.la libjivenet.la
 
 BUILT_SOURCES = \
        src/ui/lua_jiveui.c \
@@ -55,8 +55,13 @@
        src/ui/jive_window.c \
        src/ui/lua_jiveui.c
 
-
 libjiveui_la_LIBADD = -ltolua++ -llua -lSDL_image -lSDL_ttf -lSDL_gfx -lSDL
+
+
+libjivenet_la_SOURCES = \
+       src/net/jive_dns.c
+
+libjivenet_la_LIBADD = -lSDL
 
 
 # Program: jivebrowser
@@ -76,7 +81,7 @@
        src/jive.c \
        src/jive_debug.c
 
-jive_LDADD = libjiveui.la -llua
+jive_LDADD = libjiveui.la libjivenet.la -llua
 #jive_DEPENDENCIES = check_lua
 
 

Modified: trunk/jive/src/pkg/jive/Makefile.in
URL: 
http://svn.slimdevices.com/trunk/jive/src/pkg/jive/Makefile.in?rev=1935&root=Jive&r1=1934&r2=1935&view=diff
==============================================================================
--- trunk/jive/src/pkg/jive/Makefile.in (original)
+++ trunk/jive/src/pkg/jive/Makefile.in Wed Feb 13 09:27:48 2008
@@ -79,6 +79,9 @@
 CONFIG_HEADER = $(top_builddir)/src/config.h
 CONFIG_CLEAN_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
+libjivenet_la_DEPENDENCIES =
+am_libjivenet_la_OBJECTS = jive_dns.lo
+libjivenet_la_OBJECTS = $(am_libjivenet_la_OBJECTS)
 libjiveui_la_DEPENDENCIES =
 am_libjiveui_la_OBJECTS = jive_audio.lo jive_event.lo jive_font.lo \
        jive_framework.lo jive_group.lo jive_icon.lo jive_label.lo \
@@ -118,7 +121,7 @@
 PROGRAMS = $(bin_PROGRAMS) $(test_PROGRAMS)
 am_jive_OBJECTS = jive.$(OBJEXT) jive_debug.$(OBJEXT)
 jive_OBJECTS = $(am_jive_OBJECTS)
-jive_DEPENDENCIES = libjiveui.la
+jive_DEPENDENCIES = libjiveui.la libjivenet.la
 am_jiveblit_OBJECTS = jiveblit.$(OBJEXT)
 jiveblit_OBJECTS = $(am_jiveblit_OBJECTS)
 jiveblit_DEPENDENCIES =
@@ -133,9 +136,10 @@
 CCLD = $(CC)
 LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
        $(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = $(libjiveui_la_SOURCES) $(jive_SOURCES) $(jiveblit_SOURCES)
-DIST_SOURCES = $(libjiveui_la_SOURCES) $(jive_SOURCES) \
-       $(jiveblit_SOURCES)
+SOURCES = $(libjivenet_la_SOURCES) $(libjiveui_la_SOURCES) \
+       $(jive_SOURCES) $(jiveblit_SOURCES)
+DIST_SOURCES = $(libjivenet_la_SOURCES) $(libjiveui_la_SOURCES) \
+       $(jive_SOURCES) $(jiveblit_SOURCES)
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
     $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -323,8 +327,8 @@
 #      @test \! -s badsyntax
 #      @rm -f badsyntax
 
-# Convenience library: libui.la
-noinst_LTLIBRARIES = libjiveui.la
+# Convenience library:
+noinst_LTLIBRARIES = libjiveui.la libjivenet.la
 BUILT_SOURCES = \
        src/ui/lua_jiveui.c \
        src/version.h
@@ -351,6 +355,10 @@
        src/ui/lua_jiveui.c
 
 libjiveui_la_LIBADD = -ltolua++ -llua -lSDL_image -lSDL_ttf -lSDL_gfx -lSDL
+libjivenet_la_SOURCES = \
+       src/net/jive_dns.c
+
+libjivenet_la_LIBADD = -lSDL
 
 # Test programs: jiveblit
 testdir = $(bindir)
@@ -358,7 +366,7 @@
        src/jive.c \
        src/jive_debug.c
 
-jive_LDADD = libjiveui.la -llua
+jive_LDADD = libjiveui.la libjivenet.la -llua
 #jive_DEPENDENCIES = check_lua
 
 # Test program: jiveblit
@@ -860,6 +868,8 @@
          echo "rm -f \"$${dir}/so_locations\""; \
          rm -f "$${dir}/so_locations"; \
        done
+libjivenet.la: $(libjivenet_la_OBJECTS) $(libjivenet_la_DEPENDENCIES) 
+       $(LINK)  $(libjivenet_la_LDFLAGS) $(libjivenet_la_OBJECTS) 
$(libjivenet_la_LIBADD) $(LIBS)
 libjiveui.la: $(libjiveui_la_OBJECTS) $(libjiveui_la_DEPENDENCIES) 
        $(LINK)  $(libjiveui_la_LDFLAGS) $(libjiveui_la_OBJECTS) 
$(libjiveui_la_LIBADD) $(LIBS)
 install-binPROGRAMS: $(bin_PROGRAMS)
@@ -934,6 +944,7 @@
 @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
 @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
 @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
[EMAIL PROTECTED]@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
 @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
 @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
 @AMDEP_TRUE@@am__include@ @[EMAIL PROTECTED]/$(DEPDIR)/[EMAIL PROTECTED]@
@@ -974,6 +985,13 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes 
@AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) 
$(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
+
+jive_dns.lo: src/net/jive_dns.c
[EMAIL PROTECTED]@      if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) 
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) 
$(CFLAGS) -MT jive_dns.lo -MD -MP -MF "$(DEPDIR)/jive_dns.Tpo" -c -o 
jive_dns.lo `test -f 'src/net/jive_dns.c' || echo 
'$(srcdir)/'`src/net/jive_dns.c; \
[EMAIL PROTECTED]@      then mv -f "$(DEPDIR)/jive_dns.Tpo" 
"$(DEPDIR)/jive_dns.Plo"; else rm -f "$(DEPDIR)/jive_dns.Tpo"; exit 1; fi
[EMAIL PROTECTED]@@am__fastdepCC_FALSE@ source='src/net/jive_dns.c' 
object='jive_dns.lo' libtool=yes @AMDEPBACKSLASH@
[EMAIL PROTECTED]@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) 
$(depcomp) @AMDEPBACKSLASH@
[EMAIL PROTECTED]@      $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) 
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) 
$(CFLAGS) -c -o jive_dns.lo `test -f 'src/net/jive_dns.c' || echo 
'$(srcdir)/'`src/net/jive_dns.c
 
 jive_audio.lo: src/ui/jive_audio.c
 @am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) 
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) 
$(CFLAGS) -MT jive_audio.lo -MD -MP -MF "$(DEPDIR)/jive_audio.Tpo" -c -o 
jive_audio.lo `test -f 'src/ui/jive_audio.c' || echo 
'$(srcdir)/'`src/ui/jive_audio.c; \

Added: trunk/jive/src/pkg/jive/share/jive/net/DNS.lua
URL: 
http://svn.slimdevices.com/trunk/jive/src/pkg/jive/share/jive/net/DNS.lua?rev=1935&root=Jive&view=auto
==============================================================================
--- trunk/jive/src/pkg/jive/share/jive/net/DNS.lua (added)
+++ trunk/jive/src/pkg/jive/share/jive/net/DNS.lua Wed Feb 13 09:27:48 2008
@@ -1,0 +1,114 @@
+--[[
+=head1 NAME
+
+jive.net.DNS - non-blocking dns queries.
+
+=head1 DESCRIPTION
+
+Implements non-block dns queries using the same api a luasocket. These
+functions must be called in a Task.
+
+--]]
+
+
+local assert = assert
+
+local oo          = require("loop.base")
+local table       = require("table")
+local string      = require("string")
+
+local Framework   = require("jive.ui.Framework")
+local Task        = require("jive.ui.Task")
+
+local debug       = require("jive.utils.debug")
+local log         = require("jive.utils.log").logger("net.socket")
+
+local jive_dns    = require("jive.dns")
+
+
+-- jive.net.DNS is a base class
+module(..., oo.class)
+
+
+-- singleton instance
+local _instance = false
+
+
+function __init(self, jnt)
+       if _instance then
+               return _instance
+       end
+
+       local obj = oo.rawnew(self, {})
+       obj.sock = jive_dns:open()
+       obj.dnsQueue = {}
+
+       jnt:t_addRead(obj.sock,
+               Task("DNS",
+                    obj,
+                    function()
+                            while true do
+                                    Task:yield(false)
+
+                                    -- read host entry
+                                    local hostent, err = obj.sock:read()
+
+                                    -- wake up requesting task
+                                    local task = table.remove(obj.dnsQueue, 1)
+                                    if task then
+                                            task:addTask(hostent, err)
+                                    end
+                            end
+                    end),
+               0) -- no timeout
+
+       _instance = obj
+       return obj
+end
+
+
+function isip(self, address)
+       -- XXXX crude check
+       return string.match(address, "%d+%.%d+%.%d+%.%d+")
+end
+
+
+-- Converts from IP address to host name. See socket.dns.tohostname.
+function tohostname(self, address)
+       local task = Task:running()
+       assert(task, "DNS:tohostname must be called in a Task")
+
+       -- queue request
+       _instance.sock:write(address)
+
+       -- wait for reply
+       table.insert(_instance.dnsQueue, task)
+       local _, hostent, err = Task:yield(false)
+
+       if err then
+               return nil, err
+       else
+               return hostent.name, hostent
+       end
+end
+
+
+-- Coverts from host name to IP address. See socket.dns.toip.
+function toip(self, address)
+       local task = Task:running()
+       assert(task, "DNS:toip must be called in a Task")
+
+       -- queue request
+       _instance.sock:write(address)
+
+       -- wait for reply
+       table.insert(_instance.dnsQueue, task)
+       local _, hostent, err = Task:yield(false)
+
+       if err then
+               return nil, err
+       else
+               return hostent.ip[1], hostent
+       end
+end
+

Modified: trunk/jive/src/pkg/jive/share/jive/net/NetworkThread.lua
URL: 
http://svn.slimdevices.com/trunk/jive/src/pkg/jive/share/jive/net/NetworkThread.lua?rev=1935&root=Jive&r1=1934&r2=1935&view=diff
==============================================================================
--- trunk/jive/src/pkg/jive/share/jive/net/NetworkThread.lua (original)
+++ trunk/jive/src/pkg/jive/share/jive/net/NetworkThread.lua Wed Feb 13 
09:27:48 2008
@@ -40,6 +40,7 @@
 local Event             = require("jive.ui.Event")
 local Framework         = require("jive.ui.Framework")
 local Task              = require("jive.ui.Task")
+local DNS               = require("jive.net.DNS")
 
 local log               = require("jive.utils.log").logger("net.thread")
 
@@ -312,6 +313,9 @@
                subscribers = {},
        })
 
+       -- create dns resolver
+       DNS(obj)
+
        return obj
 end
 

Modified: trunk/jive/src/pkg/jive/share/jive/net/SocketHttp.lua
URL: 
http://svn.slimdevices.com/trunk/jive/src/pkg/jive/share/jive/net/SocketHttp.lua?rev=1935&root=Jive&r1=1934&r2=1935&view=diff
==============================================================================
--- trunk/jive/src/pkg/jive/share/jive/net/SocketHttp.lua (original)
+++ trunk/jive/src/pkg/jive/share/jive/net/SocketHttp.lua Wed Feb 13 09:27:48 
2008
@@ -42,6 +42,9 @@
 local socketHttp  = require("socket.http")
 local ltn12       = require("ltn12")
 
+local Task        = require("jive.ui.Task")
+
+local DNS         = require("jive.net.DNS")
 local SocketTcp   = require("jive.net.SocketTcp")
 local RequestHttp = require("jive.net.RequestHttp")
 
@@ -76,6 +79,9 @@
 
        -- init superclass
        local obj = oo.rawnew(self, SocketTcp(jnt, address, port, name))
+
+       -- hostname
+       obj.address = address
 
        -- init states
        obj.t_httpSendState = 't_sendDequeue'
@@ -155,7 +161,7 @@
 
        if self.t_httpSendRequest then
                log:debug(self, " send processing ", self.t_httpSendRequest)
-               self:t_nextSendState(true, 't_sendConnect')
+               self:t_nextSendState(true, 't_sendResolve')
                return
        end
 end
@@ -172,11 +178,42 @@
 end
 
 
+-- t_sendResolve
+-- resolve the hostname to an ip address
+function t_sendResolve(self)
+       log:debug(self, ":t_sendResolve()")
+
+       if DNS:isip(self.address) then
+               -- don't lookup an ip address
+               self.t_tcp.address = self.address
+               self:t_nextSendState(true, 't_sendConnect')
+               return
+       end
+
+       local t = Task(tostring(self) .. "(D)",
+                      self,
+                      function()
+                              log:debug(self, " DNS loopup for ", self.address)
+                              local ip, err = DNS:toip(self.address)
+
+                              log:debug(self, " IP=", ip)
+                              if not ip then
+                                      self:close(self.address .. " " .. err)
+                                      return
+                              end
+
+                              self.t_tcp.address = ip
+                              self:t_nextSendState(true, 't_sendConnect')
+                      end)
+       t:addTask()
+end
+
+
 -- t_sendConnect
 -- open our socket
 function t_sendConnect(self)
        log:debug(self, ":t_sendConnect()")
-       
+
        if not self:connected() then
                local err = socket.skip(1, self:t_connect())
        

Modified: trunk/jive/src/pkg/jive/share/jive/net/SocketTcp.lua
URL: 
http://svn.slimdevices.com/trunk/jive/src/pkg/jive/share/jive/net/SocketTcp.lua?rev=1935&root=Jive&r1=1934&r2=1935&view=diff
==============================================================================
--- trunk/jive/src/pkg/jive/share/jive/net/SocketTcp.lua (original)
+++ trunk/jive/src/pkg/jive/share/jive/net/SocketTcp.lua Wed Feb 13 09:27:48 
2008
@@ -49,14 +49,6 @@
 oo.class(_M, Socket)
 
 
--- _createTcpSocket
-local _createTcpSocket = socket.protect(function()
-       --log:debug("_createTcpSocket()")
-       
-       return socket.try(socket.tcp())
-end)
-
-
 --[[
 
 =head2 jive.net.SocketTcp(jnt, address, port, name)
@@ -93,8 +85,6 @@
        --log:debug(self, ":t_connect()")
        
        -- create a tcp socket
-       local sock, err = _createTcpSocket()
-       
        self.t_sock = socket.tcp()
 
        -- set a long timeout for connection

Modified: trunk/jive/src/pkg/jive/src/common.h
URL: 
http://svn.slimdevices.com/trunk/jive/src/pkg/jive/src/common.h?rev=1935&root=Jive&r1=1934&r2=1935&view=diff
==============================================================================
--- trunk/jive/src/pkg/jive/src/common.h (original)
+++ trunk/jive/src/pkg/jive/src/common.h Wed Feb 13 09:27:48 2008
@@ -45,6 +45,9 @@
 #include <unistd.h>
 #endif
 
+#include <netdb.h>
+#include <arpa/inet.h>
+
 
 #ifndef PATH_MAX
 /* Default POSIX maximum path length */

Modified: trunk/jive/src/pkg/jive/src/jive.c
URL: 
http://svn.slimdevices.com/trunk/jive/src/pkg/jive/src/jive.c?rev=1935&root=Jive&r1=1934&r2=1935&view=diff
==============================================================================
--- trunk/jive/src/pkg/jive/src/jive.c (original)
+++ trunk/jive/src/pkg/jive/src/jive.c Wed Feb 13 09:27:48 2008
@@ -33,9 +33,10 @@
 #include <lualib.h>
 
 /* Module initialization functions */
-int luaopen_jive(lua_State *L);
-int luaopen_jive_ui_framework(lua_State *L);
-int luaopen_jive_debug(lua_State *L);
+extern int luaopen_jive(lua_State *L);
+extern int luaopen_jive_ui_framework(lua_State *L);
+extern int luaopen_jive_net_dns(lua_State *L);
+extern int luaopen_jive_debug(lua_State *L);
 
 
 /* OPEN_ALL_STDLIBS
@@ -127,6 +128,9 @@
        lua_call(L, 0, 0);
 
        lua_pushcfunction(L, luaopen_jive_ui_framework);
+       lua_call(L, 0, 0);
+
+       lua_pushcfunction(L, luaopen_jive_net_dns);
        lua_call(L, 0, 0);
 
        lua_pushcfunction(L, luaopen_jive_debug);

Added: trunk/jive/src/pkg/jive/src/net/jive_dns.c
URL: 
http://svn.slimdevices.com/trunk/jive/src/pkg/jive/src/net/jive_dns.c?rev=1935&root=Jive&view=auto
==============================================================================
--- trunk/jive/src/pkg/jive/src/net/jive_dns.c (added)
+++ trunk/jive/src/pkg/jive/src/net/jive_dns.c Wed Feb 13 09:27:48 2008
@@ -1,0 +1,265 @@
+/*
+** Copyright 2007 Logitech. All Rights Reserved.
+**
+** This file is subject to the Logitech Public Source License Version 1.0. 
Please see the LICENCE file for details.
+*/
+
+#include "common.h"
+
+#define RESOLV_TIMEOUT (2 * 60 * 1000) /* 2 minutes */
+
+
+/* write a string to the pipe fd */
+static void write_str(int fd, char *str) {
+       size_t len;
+
+       len = strlen(str);
+       write(fd, &len, sizeof(len));
+       write(fd, str, len);
+}
+
+
+/* read a string to the lua stack from the pipe fd */
+static void read_pushstring(lua_State *L, int fd) {
+       size_t len;
+       char *buf;
+
+       read(fd, &len, sizeof(len));
+
+       if (len == 0) {
+               lua_pushnil(L);
+       }
+       else {
+               buf = malloc(len);
+
+               read(fd, buf, len);
+               lua_pushlstring(L, buf, len);
+
+               free(buf);
+       }
+}
+
+
+/* dns resolver thread */
+static int dns_resolver_thread(void *p) {
+       int fd = (int) p;
+       struct hostent *hostent;
+       struct in_addr **addr, byaddr;
+       char **alias;
+       size_t len;
+       char *buf;
+       char *failed_error = NULL;
+       Uint32 failed_timeout = 0;
+
+       while (1) {
+               if (read(fd, &len, sizeof(len)) < 0) {
+                       /* broken pipe */
+                       return 0;
+               }
+               
+               buf = malloc(len + 1);
+               if (read(fd, buf, len) < 0) {
+                       /* broken pipe */
+                       free(buf);
+                       return 0;
+               }
+               buf[len] = '\0';
+
+               if (failed_error) {
+                       Uint32 now = SDL_GetTicks();
+                       
+                       if (now - failed_timeout < RESOLV_TIMEOUT) {
+                               write_str(fd, failed_error);
+                               continue;
+                       }
+
+                       failed_error = NULL;
+               }
+
+               if (inet_aton(buf, &byaddr)) {
+                       hostent = gethostbyaddr((char *) &byaddr, sizeof(addr), 
AF_INET);
+               }
+               else {
+                       hostent = gethostbyname(buf);
+               }
+               free(buf);
+
+               if (hostent == NULL) {
+                       /* error */
+                       switch (h_errno) {
+                       case HOST_NOT_FOUND:
+                               write_str(fd, "Not found");
+                               break;
+                       case NO_DATA:
+                               write_str(fd, "No data");
+                               break;
+                       case NO_RECOVERY:
+                               failed_error = "No recovery";
+                               failed_timeout = SDL_GetTicks();
+                               write_str(fd, failed_error);
+                               break;
+                       case TRY_AGAIN:
+                               failed_error = "Try again"; 
+                               failed_timeout = SDL_GetTicks();
+                               write_str(fd, failed_error);
+                               break;
+                       }
+               }
+               else {
+                       write_str(fd, ""); // no error
+                       write_str(fd, hostent->h_name);
+
+                       alias = hostent->h_aliases;
+                       while (*alias) {
+                               write_str(fd, *alias);
+                               alias++;
+                       }
+                       write_str(fd, ""); // end of aliases
+
+                       addr = (struct in_addr **) hostent->h_addr_list;
+                       while (*addr) {
+                               write_str(fd, inet_ntoa(**addr));
+                               addr++;
+                       }
+                       write_str(fd, ""); // end if addrs
+               }
+       }
+}
+
+
+struct dns_userdata {
+       int fd[2];
+       SDL_Thread *t;
+};
+
+
+static int jiveL_dns_open(lua_State *L) {
+       struct dns_userdata *u;
+       int r;
+
+       u = lua_newuserdata(L, sizeof(struct dns_userdata));
+
+       r = socketpair(AF_UNIX, SOCK_STREAM, 0, u->fd);
+       if (r < 0) {
+               return luaL_error(L, "socketpair failed: %s", strerror(r));
+       }
+
+       u->t = SDL_CreateThread(dns_resolver_thread, (void *)(u->fd[1]));
+
+       luaL_getmetatable(L, "jive.dns");
+       lua_setmetatable(L, -2);
+
+       return 1;
+}
+
+
+static int jiveL_dns_gc(lua_State *L) {
+       struct dns_userdata *u;
+
+       u = lua_touserdata(L, 1);
+       close(u->fd[0]);
+       close(u->fd[1]);
+
+       return 0;
+}
+
+
+static int jiveL_dns_getfd(lua_State *L) {
+       struct dns_userdata *u;
+
+       u = lua_touserdata(L, 1);
+       lua_pushinteger(L, u->fd[0]);
+
+       return 1;
+}
+
+
+static int jiveL_dns_read(lua_State *L) {
+       struct dns_userdata *u;
+       int i, resolved;
+
+       u = lua_touserdata(L, 1);
+
+       /* error? */
+       read_pushstring(L, u->fd[0]);
+       if (!lua_isnil(L, -1)) {
+               lua_pushnil(L);
+               lua_insert(L, -2);
+               return 2;
+       }
+
+       /* read hostent table */
+       lua_newtable(L);
+       resolved = lua_gettop(L);
+
+       lua_pushstring(L, "name");
+       read_pushstring(L, u->fd[0]);
+       lua_settable(L, resolved);
+
+       i = 1;
+       lua_newtable(L);
+       read_pushstring(L, u->fd[0]);
+       while (!lua_isnil(L, -1)) {
+               lua_rawseti(L, -2, i++);
+               read_pushstring(L, u->fd[0]);
+       }
+       lua_pop(L, 1);
+       lua_setfield(L, resolved, "alias");
+
+       i = 1;
+       lua_newtable(L);
+       read_pushstring(L, u->fd[0]);
+       while (!lua_isnil(L, -1)) {
+               lua_rawseti(L, -2, i++);
+               read_pushstring(L, u->fd[0]);
+       }
+       lua_pop(L, 1);
+       lua_setfield(L, resolved, "ip");
+
+       return 1;
+}
+
+
+static int jiveL_dns_write(lua_State *L) {
+       struct dns_userdata *u;
+       const char *buf;
+       size_t len;
+
+       u = lua_touserdata(L, 1);
+       buf = lua_tolstring(L, 2, &len);
+
+       write(u->fd[0], &len, sizeof(len));
+       write(u->fd[0], buf, len);
+
+       return 0;
+}
+
+
+static const struct luaL_Reg dns_lib[] = {
+       { "open", jiveL_dns_open },
+       { NULL, NULL }
+};
+
+
+int luaopen_jive_net_dns(lua_State *L) {
+       luaL_newmetatable(L, "jive.dns");
+
+       lua_pushcfunction(L, jiveL_dns_gc);
+       lua_setfield(L, -2, "__gc");
+
+       lua_pushcfunction(L, jiveL_dns_read);
+       lua_setfield(L, -2, "read");
+
+       lua_pushcfunction(L, jiveL_dns_write);
+       lua_setfield(L, -2, "write");
+
+       lua_pushcfunction(L, jiveL_dns_getfd);
+       lua_setfield(L, -2, "getfd");
+
+       lua_pushvalue(L, -1);
+       lua_setfield(L, -2, "__index");
+
+       luaL_register(L, "jive.dns", dns_lib);
+
+       return 0;
+}

_______________________________________________
Jive-checkins mailing list
[email protected]
http://lists.slimdevices.com/cgi-bin/mailman/listinfo/jive-checkins

Reply via email to