Index: libroar/basic.c
===================================================================
--- libroar/basic.c	(revision 5365)
+++ libroar/basic.c	(revision 5368)
@@ -36,5 +36,112 @@
 #include "libroar.h"
 
-int roar_connect_raw (const char * server, int flags, uint_least32_t timeout) {
+static int _connect_server(struct roar_connection * con, const char * server, int type, int flags, uint_least32_t timeout) {
+#if defined(ROAR_HAVE_STAT) && defined(ROAR_HAVE_H_SYS_STAT)
+ struct stat sockstat;
+#endif
+ const char * obj = NULL;
+ char user_sock[128];
+ int is_decnet = 0;
+ int port = 0;
+ int i = 0;
+ int fh = -1;
+ int err;
+
+ if ( con == NULL || server == NULL ) {
+  roar_err_set(ROAR_ERROR_FAULT);
+  return -1;
+ }
+
+ if ( !strcmp(server, "+invalid") ) {
+  roar_err_set(ROAR_ERROR_CANCELED);
+  return -1;
+ } else if ( !strncmp(server, "+dstr=", 6) ) {
+  if ( roar_vio_open_dstr_simple(con->viocon, server+6, ROAR_VIOF_READWRITE) == -1 )
+   return -1;
+  con->flags |= ROAR_CON_FLAGS_VIO;
+  return 0;
+ }
+
+ strncpy(user_sock, server, sizeof(user_sock)-1);
+ user_sock[sizeof(user_sock)-1] = 0;
+
+
+ if ( *user_sock != '/' ) { // don't test AF_UNIX sockets for ports
+  for (i = 0; user_sock[i] != 0; i++) {
+   if ( user_sock[i] == ':' ) {
+    if ( user_sock[i+1] == ':' ) { // DECnet, leave unchanged
+     is_decnet = 1;
+     obj = &user_sock[i+2];
+     break;
+    }
+
+    port = atoi(&(user_sock[i+1]));
+    user_sock[i] = 0;
+    break;
+   }
+  }
+ }
+
+ if ( is_decnet ) {
+  if ( *user_sock == ':' ) {
+   if ( roar_socket_get_local_nodename() != NULL ) {
+    strncpy(user_sock, roar_socket_get_local_nodename(), sizeof(user_sock)-1);
+    user_sock[sizeof(user_sock)-1] = 0;
+    roar_mm_strlcat(user_sock, server, sizeof(user_sock)-1);
+    user_sock[sizeof(user_sock)-1] = 0;
+    obj  = strstr(user_sock, "::");
+    obj += 2;
+   }
+  }
+
+  if ( *obj == 0 ) {
+#ifdef DN_MAXOBJL
+   roar_mm_strlcat(user_sock, ROAR_DEFAULT_OBJECT, sizeof(user_sock)-1);
+   user_sock[sizeof(user_sock)-1] = 0;
+#else
+   ROAR_ERR("roar_connect_raw(*): size of DECnet object unknown.");
+#endif
+  }
+   ROAR_DBG("roar_connect_raw(*): user_sock='%s'", user_sock);
+ }
+
+ if ( port || is_decnet ) {
+  fh = roar_socket_connect(user_sock, port);
+  // restore the original string
+  user_sock[i] = ':';
+ } else {
+#if defined(ROAR_HAVE_STAT) && defined(ROAR_HAVE_H_SYS_STAT)
+  if ( user_sock[0] == '/' ) {
+   if ( stat(user_sock, &sockstat) == 0 ) {
+    if ( S_ISCHR(sockstat.st_mode) ) {
+     return open(user_sock, O_RDWR|O_NOCTTY, 0666);
+    }
+   }
+  }
+#endif
+  fh = roar_socket_connect(user_sock, ROAR_DEFAULT_PORT);
+ }
+
+ if ( fh == -1 )
+  return -1;
+
+ if ( roar_vio_open_fh_socket(con->viocon, fh) == -1 ) {
+  err = roar_error;
+#ifdef ROAR_TARGET_WIN32
+  closesocket(fh);
+#else
+  close(fh);
+#endif
+  roar_error = err;
+  return -1;
+ } else {
+  con->flags |= ROAR_CON_FLAGS_VIO;
+ }
+
+ roar_err_set(ROAR_ERROR_NONE);
+ return 0;
+}
+
+static int roar_connect_raw (struct roar_connection * con, const char * server, int flags, uint_least32_t timeout) {
 #ifdef ROAR_HAVE_LIBSLP
  struct roar_libroar_config * config = roar_libroar_get_config();
@@ -43,8 +150,4 @@
  char * roar_server;
  int i = 0;
- int port = 0;
- int fh = -1;
- int is_decnet = 0;
- const char * obj = NULL;
 #if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER)
  struct passwd * pwd;
@@ -60,7 +163,4 @@
  int workarounds_store;
 #endif
-#if defined(ROAR_HAVE_STAT) && defined(ROAR_HAVE_H_SYS_STAT)
- struct stat sockstat;
-#endif
 
  roar_err_set(ROAR_ERROR_UNKNOWN);
@@ -75,12 +175,12 @@
 
 
- if ( server == NULL )
+ if ( server == NULL || *server == 0 )
   server = roar_libroar_get_server();
 
- if ( server == NULL && (roar_server = getenv("ROAR_SERVER")) != NULL )
-  server = roar_server;
+ if ( server == NULL || *server == 0 )
+  server = getenv("ROAR_SERVER");
 
 #ifdef ROAR_HAVE_LIBX11
- if ( server == NULL ) {
+ if ( server == NULL || *server == 0 ) {
   if ( (x11con = roar_x11_connect(NULL)) != NULL ) {
    server = roar_x11_get_prop(x11con, "ROAR_SERVER");
@@ -91,5 +191,5 @@
 
 #if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER)
- if ( server == NULL && (i = readlink("/etc/roarserver", user_sock, sizeof(user_sock)-1)) != -1 ) {
+ if ( (server == NULL || *server == 0) && (i = readlink("/etc/roarserver", user_sock, sizeof(user_sock)-1)) != -1 ) {
    user_sock[i] = 0;
    server = user_sock;
@@ -129,13 +229,13 @@
   user_sock[sizeof(user_sock)-1] = 0;
 
-  if ( (fh = roar_socket_connect(user_sock, 0)) != -1 )
-   return fh;
-
-  if ( (fh = roar_socket_connect(ROAR_DEFAULT_SOCK_GLOBAL, 0)) != -1 )
-   return fh;
-#endif
-
-  if ( (fh = roar_socket_connect(ROAR_DEFAULT_HOST, ROAR_DEFAULT_PORT)) != -1 )
-   return fh;
+  if ( _connect_server(con, user_sock, ROAR_SOCKET_TYPE_UNIX, flags, timeout) == 0 )
+   return 0;
+
+  if ( _connect_server(con, ROAR_DEFAULT_SOCK_GLOBAL, ROAR_SOCKET_TYPE_UNIX, flags, timeout) == 0 )
+   return 0;
+#endif
+
+  if ( _connect_server(con, ROAR_DEFAULT_HOSTPORT, ROAR_SOCKET_TYPE_TCP, flags, timeout) == 0 )
+   return 0;
 
 #ifdef ROAR_HAVE_LIBDNET
@@ -143,12 +243,12 @@
    if ( roar_socket_get_local_nodename() ) {
     snprintf(user_sock, 79, "%s::%s", roar_socket_get_local_nodename(), ROAR_DEFAULT_OBJECT);
-    if ( (fh = roar_socket_connect(user_sock, ROAR_DEFAULT_NUM)) != -1 )
-     return fh;
+    if ( _connect_server(con, user_sock, ROAR_SOCKET_TYPE_DECNET, flags, timeout) == 0 )
+     return 0;
    }
   }
 #endif
 
-  if ( (fh = roar_socket_connect("+abstract", 0)) != -1 )
-   return fh;
+  if ( _connect_server(con, "+abstract", -1, flags, timeout) == 0 )
+   return 0;
 
 #ifdef ROAR_HAVE_LIBSLP
@@ -157,6 +257,6 @@
     ) {
   if ( (server = roar_slp_find_roard(0)) != NULL ) {
-   if ( (fh = roar_connect_raw(server, 0, 0)) != -1 )
-    return fh;
+   if ( _connect_server(con, server, -1, 0, 0) == 0 )
+    return 0;
 
    /* in case we can not connect to the server given this may be a cache problem,
@@ -164,6 +264,6 @@
    ROAR_WARN("roar_connect_raw(*): Can not connect to SLP located server, disabling cache");
    if ( (server = roar_slp_find_roard(1)) != NULL )
-    if ( (fh = roar_connect_raw(server, 0, 0)) != -1 )
-     return fh;
+    if ( _connect_server(con, server, -1, 0, 0) == 0 )
+     return 0;
   }
  }
@@ -175,7 +275,7 @@
  if ( list != NULL ) {
   for (i = 0; list[i].server != NULL; i++) {
-   if ( (fh = roar_connect_raw(list[i].server, 0, 0)) != -1 ) {
+   if ( _connect_server(con, list[i].server, -1, 0, 0) == 0 ) {
     roar_enum_servers_free(list);
-    return fh;
+    return 0;
    }
   }
@@ -188,80 +288,14 @@
  } else {
   /* connect via (char*)server */
-  // find a port:
-
-  if ( !strcmp(server, "+invalid") ) {
-   roar_err_set(ROAR_ERROR_CANCELED);
-   return -1;
-  }
-
-  strncpy(user_sock, server, sizeof(user_sock)-1);
-  user_sock[sizeof(user_sock)-1] = 0;
-
-  if ( *user_sock != '/' ) { // don't test AF_UNIX sockets for ports
-   for (i = 0; user_sock[i] != 0; i++) {
-    if ( user_sock[i] == ':' ) {
-     if ( user_sock[i+1] == ':' ) { // DECnet, leave unchanged
-      is_decnet = 1;
-      obj = &user_sock[i+2];
-      break;
-     }
-
-     port = atoi(&(user_sock[i+1]));
-     user_sock[i] = 0;
-     break;
-    }
-   }
-  }
-
-  if ( is_decnet ) {
-   if ( *user_sock == ':' ) {
-    if ( roar_socket_get_local_nodename() != NULL ) {
-     strncpy(user_sock, roar_socket_get_local_nodename(), sizeof(user_sock)-1);
-     user_sock[sizeof(user_sock)-1] = 0;
-     roar_mm_strlcat(user_sock, server, sizeof(user_sock)-1);
-     user_sock[sizeof(user_sock)-1] = 0;
-     obj  = strstr(user_sock, "::");
-     obj += 2;
-    }
-   }
-
-   if ( *obj == 0 ) {
-#ifdef DN_MAXOBJL
-    roar_mm_strlcat(user_sock, ROAR_DEFAULT_OBJECT, sizeof(user_sock)-1);
-    user_sock[sizeof(user_sock)-1] = 0;
-#else
-    ROAR_ERR("roar_connect_raw(*): size of DECnet object unknown.");
-#endif
-   }
-    ROAR_DBG("roar_connect_raw(*): user_sock='%s'", user_sock);
-  }
-
-  if ( port || is_decnet ) {
-   fh = roar_socket_connect(user_sock, port);
-   // restore the original string
-   user_sock[i] = ':';
-  } else {
-#if defined(ROAR_HAVE_STAT) && defined(ROAR_HAVE_H_SYS_STAT)
-   if ( user_sock[0] == '/' ) {
-    if ( stat(user_sock, &sockstat) == 0 ) {
-     if ( S_ISCHR(sockstat.st_mode) ) {
-      return open(user_sock, O_RDWR|O_NOCTTY, 0666);
-     }
-    }
-   }
-#endif
-   fh = roar_socket_connect(user_sock, ROAR_DEFAULT_PORT);
-  }
- }
-
- ROAR_DBG("roar_connect_raw(*) = %i", fh);
-
- return fh;
+  if ( _connect_server(con, server, -1, flags, timeout) == 0 )
+   return 0;
+ }
+
+ roar_err_set(ROAR_ERROR_NODEV);
+ ROAR_DBG("roar_connect_raw(*) = -1 // error=NODEV");
+ return -1;
 }
 
 int roar_connect     (struct roar_connection * con, const char * server, int flags, uint_least32_t timeout) {
- int fh;
- int err;
-
  if ( con == NULL ) {
   roar_err_set(ROAR_ERROR_FAULT);
@@ -269,20 +303,10 @@
  }
 
+ if ( roar_connect_none(con) == -1 )
+  return -1;
+
  roar_err_set(ROAR_ERROR_UNKNOWN);
- fh = roar_connect_raw(server, flags, timeout);
-
- if ( fh == -1 )
-  return -1;
-
- if ( roar_connect_fh(con, fh) == -1 ) {
-  err = roar_error;
-#ifdef ROAR_TARGET_WIN32
-  closesocket(fh);
-#else
-  close(fh);
-#endif
-  roar_error = err;
-  return -1;
- }
+ if ( roar_connect_raw(con, server, flags, timeout) == -1 )
+  return -1;
 
  if ( server != NULL ) {
