Index: roard/clients.c
===================================================================
--- roard/clients.c	(revision 5567)
+++ roard/clients.c	(revision 5571)
@@ -136,19 +136,66 @@
 
 int clients_new_from_fh(int fh, int proto, int byteorder, int update_nnode) {
+ return clients_new_from_fh2(fh, proto, byteorder, update_nnode, NULL, NULL, 0);
+}
+
+int clients_new_from_fh2(int fh, int proto, int byteorder,
+                         int update_nnode,
+                         struct roard_listen * lsock, struct sockaddr * sockaddr, socklen_t addrlen) {
+ const struct roard_proto_handle * protohandle;
+ struct roar_vio_calls    vio;
  struct roar_client * c;
+ int supported = 0;
  int client;
 
- if ( fh == -1 )
-  return -1;
-
- if ( proto != ROAR_PROTO_ROARAUDIO || byteorder != ROAR_BYTEORDER_NETWORK )
-  return -1;
-
- if ( (client = clients_new()) == -1 )
-  return -1;
-
- if ( clients_set_fh(client, fh) == -1 ) {
-  clients_delete(client);
-  return -1;
+ if ( fh == -1 ) {
+  roar_err_set(ROAR_ERROR_BADFH);
+  return -1;
+ }
+
+ if ( lsock == NULL ) {
+  switch (proto) {
+   case ROAR_PROTO_RSOUND:
+   case ROAR_PROTO_SIMPLE:
+     roar_err_set(ROAR_ERROR_FAULT);
+     return -1;
+    break;
+  }
+ }
+
+ if ( byteorder != ROAR_BYTEORDER_NETWORK )
+  return -1;
+
+
+ if ( proto == ROAR_PROTO_RSOUND ) {
+#ifndef ROAR_WITHOUT_DCOMP_EMUL_RSOUND
+  client = emul_rsound_on_connect(fh, lsock);
+  switch (client) {
+   case -1: return -1; break;
+   case -2: return  0; break;
+   default: // TODO: write error handling
+     clients_get(client, &c);
+     fh = c->fh;
+    break;
+  }
+#else
+  roar_err_set(ROAR_ERROR_PROTONOSUP);
+  return -1;
+#endif
+ } else {
+  client = clients_new();
+
+  if ( client == -1 ) {
+   ROAR_DBG("clients_new_from_fh2(*) = -1 // can not create new client");
+   return -1;
+  }
+
+  if ( clients_set_fh(client, fh) == -1 ) {
+   ROAR_ERR("clients_new_from_fh2(*): Can not set client's fh");
+
+   clients_delete(client);
+
+   ROAR_DBG("clients_new_from_fh2(*) = -1");
+   return -1;
+  }
  }
 
@@ -156,8 +203,92 @@
   if ( clients_get(client, &c) != -1 ) {
    if ( roar_nnode_free(&(c->nnode)) != -1 ) {
-    roar_nnode_new_from_fh(&(c->nnode), fh, 1);
+    if ( sockaddr != NULL && addrlen != 0 ) {
+     roar_nnode_new_from_sockaddr(&(c->nnode), sockaddr, addrlen);
+    } else {
+     roar_nnode_new_from_fh(&(c->nnode), fh, 1);
+    }
    }
   }
  }
+
+ if ( clients_set_proto(client, proto) == -1 ) {
+  ROAR_WARN("clients_new_from_fh2(*): Setting proto(0x%.4x) of client %i failed.", proto, client);
+  clients_delete(client);
+  return -1;
+ }
+
+ switch (proto) {
+  case ROAR_PROTO_ROARAUDIO:
+    // nothing needed to be done here
+   break;
+#ifndef ROAR_WITHOUT_DCOMP_EMUL_ESD
+#ifdef ROAR_HAVE_H_ESD
+  case ROAR_PROTO_ESOUND:
+    ROAR_DBG("net_get_new_client(*): execing ESD CONNECT command");
+
+    if ( roar_vio_open_fh_socket(&vio, fh) == -1 )
+     return -1;
+
+    ROAR_DBG("net_get_new_client(*): creating VIO OK");
+
+    if ( emul_esd_exec_command(client, ESD_PROTO_CONNECT, &vio) == -1 )
+     return -1;
+
+    ROAR_DBG("net_get_new_client(*): CONNECT execed sucessfully");
+   break;
+#endif
+#endif
+#ifndef ROAR_WITHOUT_DCOMP_EMUL_SIMPLE
+  case ROAR_PROTO_SIMPLE:
+    if ( emul_simple_on_connect(client, lsock) == -1 )
+     return -1;
+   break;
+#endif
+#ifndef ROAR_WITHOUT_DCOMP_EMUL_RSOUND
+  case ROAR_PROTO_RSOUND: // nothing to do here.
+   break;
+#endif
+#ifndef ROAR_WITHOUT_DCOMP_EMUL_RPLAY
+  case ROAR_PROTO_RPLAY:
+    if ( roar_vio_open_fh_socket(&vio, fh) == -1 )
+     return -1;
+
+    if ( emul_rplay_on_status(client, NULL, &vio, NULL, 0) == -1 )
+     return -1;
+   break;
+#endif
+  default:
+    // OS independiend code to close the socket:
+    if ( roar_vio_open_fh_socket(&vio, fh) == -1 )
+     return -1;
+
+    protohandle = clients_get_protohandle(proto);
+    supported = 0;
+    if ( protohandle != NULL ) {
+     switch (protohandle->type) {
+      case ROARD_PROTO_TYPE_BUILDIN:
+        //this should not end up here.
+        ROAR_WARN("net_get_new_client(lsock=%p): proto(%i) marked as buildin but isn't. BAD.", lsock, proto);
+        supported = 0;
+       break;
+      case ROARD_PROTO_TYPE_ROARDPROTO:
+        supported = 1;
+        if ( protohandle->impl.roardproto.new_client != NULL ) {
+         if ( protohandle->impl.roardproto.new_client(client, &vio, lsock) == -1 ) {
+          supported = 0;
+         }
+        }
+       break;
+     }
+    }
+
+    if ( !supported ) {
+     clients_delete(client);
+     //roar_vio_close(&vio);
+     return -1;
+    }
+   break;
+ }
+
 
  return 0;
Index: roard/include/client.h
===================================================================
--- roard/include/client.h	(revision 5567)
+++ roard/include/client.h	(revision 5571)
@@ -111,4 +111,7 @@
 int clients_new        (void);
 int clients_new_from_fh(int fh, int proto, int byteorder, int update_nnode);
+int clients_new_from_fh2(int fh, int proto, int byteorder,
+                         int update_nnode,
+                         struct roard_listen * lsock, struct sockaddr * sockaddr, socklen_t addrlen);
 int clients_delete     (int id);
 int clients_close      (int id, int nocheck_exec);
Index: roard/network.c
===================================================================
--- roard/network.c	(revision 5567)
+++ roard/network.c	(revision 5571)
@@ -70,5 +70,5 @@
 
 int net_get_new_client (struct roard_listen * lsock) {
- const struct roard_proto_handle * proto;
+ const struct roard_proto_handle * protohandle;
  int fh;
  int client;
@@ -79,4 +79,5 @@
  socklen_t                addrlen = sizeof(addr);
  int supported = 0;
+ int proto = lsock->proto;
 
  if ( roar_vio_ctl(&(lsock->sock), ROAR_VIO_CTL_GET_FH, &socket) == -1 ) {
@@ -95,129 +96,12 @@
   return -1;
 
-#ifndef ROAR_WITHOUT_DCOMP_EMUL_RSOUND
- if ( lsock->proto == ROAR_PROTO_RSOUND ) {
-  client = emul_rsound_on_connect(fh, lsock);
-  switch (client) {
-   case -1: return -1; break;
-   case -2: return  0; break;
-   default: // TODO: write error handling
-     clients_get(client, &c);
-     fh = c->fh;
-    break;
+ if ( clients_new_from_fh2(fh, lsock->proto, ROAR_BYTEORDER_NETWORK, 1, lsock, (struct sockaddr*)&addr, &addrlen) == -1 ) {
+  if ( roar_vio_open_fh_socket(&vio, fh) == -1 ) {
+   close(fh);
+   return -1;
   }
- } else {
-#endif
-
- client = clients_new();
-
- if ( client == -1 ) {
-  ROAR_DBG("net_get_new_client(void) = -1 // can not create new client");
-  close(fh);
+  roar_vio_close(&vio);
   return -1;
  }
-
- if ( clients_set_fh(client, fh) == -1 ) {
-  ROAR_ERR("net_get_new_client(void): Can not set client's fh");
-
-  clients_delete(client);
-  close(fh);
-
-  ROAR_DBG("net_get_new_client(void) = -1");
-  return -1;
- }
-#ifndef ROAR_WITHOUT_DCOMP_EMUL_RSOUND
- }
-#endif
-
- if ( clients_get(client, &c) != -1 ) {
-  if ( roar_nnode_free(&(c->nnode)) == -1 )
-   return -1;
-
-  if ( roar_nnode_new_from_sockaddr(&(c->nnode), (struct sockaddr*)&addr, addrlen) == -1 )
-   return -1;
- }
-
- ROAR_DBG("net_get_new_client(*): proto=0x%.4x", lsock->proto);
-
- if ( clients_set_proto(client, lsock->proto) == -1 ) {
-  ROAR_WARN("net_get_new_client(*): Setting proto(0x%.4x) of client %i failed.", lsock->proto, client);
-  return -1;
- }
-
- switch (lsock->proto) {
-  case ROAR_PROTO_ROARAUDIO:
-    // nothing needed to be done here
-   break;
-#ifndef ROAR_WITHOUT_DCOMP_EMUL_ESD
-#ifdef ROAR_HAVE_H_ESD
-  case ROAR_PROTO_ESOUND:
-    ROAR_DBG("net_get_new_client(*): execing ESD CONNECT command");
-
-    if ( roar_vio_open_fh_socket(&vio, fh) == -1 )
-     return -1;
-
-    ROAR_DBG("net_get_new_client(*): creating VIO OK");
-
-    if ( emul_esd_exec_command(client, ESD_PROTO_CONNECT, &vio) == -1 )
-     return -1;
-
-    ROAR_DBG("net_get_new_client(*): CONNECT execed sucessfully");
-   break;
-#endif
-#endif
-#ifndef ROAR_WITHOUT_DCOMP_EMUL_SIMPLE
-  case ROAR_PROTO_SIMPLE:
-    if ( emul_simple_on_connect(client, lsock) == -1 )
-     return -1;
-   break;
-#endif
-#ifndef ROAR_WITHOUT_DCOMP_EMUL_RSOUND
-  case ROAR_PROTO_RSOUND: // nothing to do here.
-   break;
-#endif
-#ifndef ROAR_WITHOUT_DCOMP_EMUL_RPLAY
-  case ROAR_PROTO_RPLAY: // nothing to do here.
-
-    if ( roar_vio_open_fh_socket(&vio, fh) == -1 )
-     return -1;
-
-    if ( emul_rplay_on_status(client, NULL, &vio, NULL, 0) == -1 )
-     return -1;
-   break;
-#endif
-  default:
-    // OS independiend code to close the socket:
-    if ( roar_vio_open_fh_socket(&vio, fh) == -1 )
-     return -1;
-
-    proto = clients_get_protohandle(lsock->proto);
-    supported = 0;
-    if ( proto != NULL ) {
-     switch (proto->type) {
-      case ROARD_PROTO_TYPE_BUILDIN:
-        //this should not end up here.
-        ROAR_WARN("net_get_new_client(lsock=%p): proto(%i) marked as buildin but isn't. BAD.", lsock, lsock->proto);
-        supported = 0;
-       break;
-      case ROARD_PROTO_TYPE_ROARDPROTO:
-        supported = 1;
-        if ( proto->impl.roardproto.new_client != NULL ) {
-         if ( proto->impl.roardproto.new_client(client, &vio, lsock) == -1 ) {
-          supported = 0;
-         }
-        }
-       break;
-     }
-    }
-
-    if ( !supported ) {
-     clients_delete(client);
-     //roar_vio_close(&vio);
-     return -1;
-    }
-   break;
- }
-
-// close(fh);
 
  return 0;
