Index: libroar/roardl.c
===================================================================
--- libroar/roardl.c	(revision 5381)
+++ libroar/roardl.c	(revision 5427)
@@ -36,4 +36,8 @@
 #include "libroar.h"
 
+#ifdef ROAR_HAVE_H_DIRENT
+#include <dirent.h>
+#endif
+
 #if defined(ROAR_HAVE_LIBDL) && !defined(RTLD_NEXT)
 #define RTLD_NEXT ((void *) -1L)
@@ -191,4 +195,128 @@
 #endif
 
+#ifdef ROAR_HAVE_H_DIRENT
+// pvn = prefix, host vendor, host name
+static struct roar_dl_lhandle * _load_from_path_pvn(const char * name,
+                                                    int flags, int ra_init,
+                                                    struct roar_dl_librarypara * para,
+                                                    const char * prefix,
+                                                    const char * hostvendor,
+                                                    const char * hostname) {
+ struct roar_dl_lhandle * ret = NULL;
+ int i, j;
+ char path[1024];
+ const char * path_format[] = {"%s/%s/%s", "%s/%s/universal", "%s/universal/universal"};
+ DIR * dir;
+ struct dirent * dirent;
+ char file[1024];
+ const char * file_format[] = {"%s/%s/%s", "%s/%s/%s" ROAR_SHARED_SUFFIX, "%s/%s/lib%s" ROAR_SHARED_SUFFIX};
+//  cont->handle[idx] = roar_dl_open(name, ROAR_DL_FLAG_DEFAULTS, 1, para);
+//#vars: $PREFIX_PLUGINS, $hostvendor, $hostname, $name
+//#search order: $PREFIX_PLUGINS/{$hostvendor/{$hostname,universal},universal/universal}/*/{,lib}$name.so
+
+ for (i = 0; i < 3; i++) {
+  snprintf(path, sizeof(path), path_format[i], prefix, hostvendor, hostname);
+  dir = opendir(path);
+  if ( dir == NULL )
+   continue;
+
+  while ((dirent = readdir(dir)) != NULL) {
+   if ( !strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, "..") )
+    continue;
+
+   for (j = 0; j < 3; j++) {
+    snprintf(file, sizeof(file), file_format[j], path, dirent->d_name, name);
+    ret = roar_dl_open(file, flags, ra_init, para);
+    if ( ret != NULL ) {
+     closedir(dir);
+     return ret;
+    }
+   }
+  }
+
+  closedir(dir);
+ }
+
+ return NULL;
+}
+
+static struct roar_dl_lhandle * _load_from_path(const char * name, int flags, int ra_init,
+                                                struct roar_dl_librarypara * para) {
+ struct roar_dl_lhandle * ret = NULL;
+ char * host = NULL;
+ char * hostvendor_buffer = NULL;
+ char * hostvendor = NULL;
+ char * hostname = NULL;
+ char * c, * d;
+
+ if ( para != NULL && para->appname != NULL && para->appname[0] != 0 ) {
+  host = roar_mm_strdup(para->appname);
+
+  // if we are out of memory we will likely not pass the rest, so just return in error.
+  if ( host == NULL )
+   return NULL;
+
+  hostname = host;
+  c = strstr(host, "<");
+  if ( c != NULL ) {
+   while (c[-1] == ' ') c--;
+   *c = 0;
+   c++;
+   while (*c == ' ' || *c == '<') c++;
+   if ( *c ) {
+    d = strstr(c, ">");
+    if ( d != NULL )
+     *d = 0;
+
+    d = strstr(c, "/");
+    if ( d != NULL ) {
+     *d = '-';
+     hostvendor = c;
+    } else {
+     hostvendor_buffer = roar_mm_malloc(roar_mm_strlen(c) + 1 /* tailing \0 */ + 6 /* "unreg-" */);
+
+     // see above
+     if ( hostvendor_buffer == NULL ) {
+      roar_mm_free(host);
+      return NULL;
+     }
+
+     strcpy(hostvendor_buffer, "unreg-");
+     strcat(hostvendor_buffer, c);
+     hostvendor = hostvendor_buffer;
+    }
+   }
+  }
+ }
+
+ if ( hostvendor == NULL )
+  hostvendor = "universal";
+
+ if ( hostname == NULL )
+  hostname = "universal";
+
+ ret = _load_from_path_pvn(name, flags, ra_init, para, ROAR_PREFIX_PLUGINS, hostvendor, hostname);
+
+ if ( host != NULL )
+  roar_mm_free(host);
+ if ( hostvendor_buffer != NULL )
+  roar_mm_free(hostvendor_buffer);
+ return ret;
+}
+#endif
+
+static struct roar_dl_lhandle * _roar_dl_open_pluginpath(const char * filename, int flags,
+                                      int ra_init, struct roar_dl_librarypara * para) {
+ flags |= ROAR_DL_FLAG_PLUGINPATH;
+ flags -= ROAR_DL_FLAG_PLUGINPATH;
+
+#ifdef ROAR_HAVE_H_DIRENT
+ return _load_from_path(filename, flags, ra_init, para);
+#else
+ // fall back to system open function.
+ return roar_dl_open(filename, flags, ra_init, para);
+#endif
+}
+
 struct roar_dl_lhandle * roar_dl_open(const char * filename, int flags,
                                       int ra_init, struct roar_dl_librarypara * para) {
@@ -203,6 +331,11 @@
  int err;
 
- if ( flags == ROAR_DL_FLAG_DEFAULTS )
-  flags = ROAR_DL_FLAG_NONE;
+ switch (flags) {
+  case ROAR_DL_FLAG_DEFAULTS: flags = ROAR_DL_FLAG_NONE;       break;
+  case ROAR_DL_FLAG_PLUGIN:   flags = ROAR_DL_FLAG_PLUGINPATH; break;
+ }
+
+ if ( flags & ROAR_DL_FLAG_PLUGINPATH )
+  return _roar_dl_open_pluginpath(filename, flags, ra_init, para);
 
 #if defined(ROAR_HAVE_LIBDL)
