From 9f014d5b9735a63da0e7d783f4c67a984140f7ab Mon Sep 17 00:00:00 2001
From: Christian Pointner <equinox@helsinki.at>
Date: Tue, 8 Mar 2011 21:36:45 +0000
Subject: client handling at tcpserver


diff --git a/nopsyncd/tcpserver.lua b/nopsyncd/tcpserver.lua
index ff338ac..972603d 100755
--- a/nopsyncd/tcpserver.lua
+++ b/nopsyncd/tcpserver.lua
@@ -18,32 +18,116 @@
 --  You should have received a copy of the GNU General Public License
 --  along with rhnop. If not, see <http://www.gnu.org/licenses/>.
 --
+
 require "socket"
 
+function init_server()
+   local server = assert(socket.tcp())
+   
+   assert(server:setoption('reuseaddr', true))
+   assert(server:bind("*", 2342))
+   assert(server:listen(5))
+
+   return server
+end
+
+local clients = {}
+
+function add_client(hdl)
+   print("new client(" .. hdl:getfd() .. ") from " .. hdl:getpeername())
+   local client = {}
+   client.buffer = ""
+   client.hdl = hdl
+   client.getfd = function() return hdl:getfd() end
+   client.dirty = function() return hdl:dirty() end
+   table.insert(clients, client)
+end
+
+function remove_client(c)
+   local idx = 0
+   for idx, client in ipairs(clients) do
+      if client == c then
+         break
+      end
+   end
+
+   print("removing client(" .. c.hdl:getfd() .. ")")
+   c.hdl:close()
+   table.remove(clients, idx)
+end
+
+function cleanup_clients()
+   for _, client in ipairs(clients) do
+      client:close()
+   end
+end
+
+function clients_get_writeables()
+   local fds = {}
+   
+   for _, client in ipairs(clients) do
+      if client.buffer ~= "" then
+         table.insert(fds, client)
+      end
+   end
+
+   return fds
+end
+
+function clients_senddata()
+   -- TODO: fetch data from SQL and send it out to all clients
+
+   for _, client in ipairs(clients) do
+      client.buffer  = client.buffer .. "hello world\n"
+   end
+end
 
 function main_loop()
    local pipefd = pipe.getreadfd()
 
+   server = init_server()
+
    while true do
-      local readable, _, err = socket.select({ pipefd } , nil)
-      if(err) then
+      local readables, writeables, err = socket.select({ pipefd , server , unpack(clients) } , clients_get_writeables())
+      if err then
          print("select returned with error: " .. err)
          return -1
       else
-         for _, input in ipairs(readable) do
-            if(input == pipefd) then
+         for _, input in ipairs(readables) do
+            if input == pipefd then
                local ret = pipe.consume()
                if ret == 1 then
                   print("pipe was signaled")
+                  clients_senddata()
                else
                   return ret
                end
+            elseif input == server then
+               local client = assert(server:accept())
+               add_client(client)
             else
-               print("select returned unknown file descriptor!?")
+               if input.hdl then
+                  -- receive is insanely stupid, therefore we must always read one byte only
+                  local tmp, err, part = input.hdl:receive(1)
+                  if err then
+                     remove_client(input)
+                  end
+
+                  -- TODO: receive timestamp of last received entry
+                  --       send out (enqueue in buffer) all entrys since this timestamp
+               end
             end
          end
+
+         for _, output in ipairs(writeables) do
+            local ret = assert(output.hdl:send(output.buffer))
+            output.buffer = string.sub(output.buffer, ret+1)
+         end
       end
    end
 
+   server:close()
+   cleanup_clients()
+
    return 0
-end
\ No newline at end of file
+end
-- 
cgit v0.10.2