Index: include/libroar/error.h
===================================================================
--- include/libroar/error.h	(revision 5286)
+++ include/libroar/error.h	(revision 5312)
@@ -113,4 +113,8 @@
 void   roar_err_to_errno(void);
 
+// Resets the stored state to 'no error' state. This can be used
+// to init the state.
+int    roar_err_initstore(struct roar_error_state * state);
+
 // store a error state (both libroar and system)
 // returnes the error or ROAR_ERROR_NONE on success so it does not alter gloabl error state.
Index: include/libroar/roardl.h
===================================================================
--- include/libroar/roardl.h	(revision 5275)
+++ include/libroar/roardl.h	(revision 5312)
@@ -148,6 +148,10 @@
  int    (*func[ROAR_DL_FN_MAX])(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib);
  struct roar_dl_libraryname * libname;
+ size_t  global_data_len;
+ void *  global_data_init;
+ void ** global_data_pointer;
 };
 
+// parameter functions:
 struct roar_dl_librarypara * roar_dl_para_new(const char * args, void * binargv,
                                               const char * appname, const char * abiversion);
@@ -157,4 +161,5 @@
                                          const char * appname, const char * abiversion);
 
+// 'core' dynamic loader functions.
 struct roar_dl_lhandle * roar_dl_open   (const char * filename, int flags,
                                          int ra_init, struct roar_dl_librarypara * para);
@@ -169,6 +174,13 @@
 const char *             roar_dl_errstr (struct roar_dl_lhandle * lhandle);
 
+// getting meta data:
 struct roar_dl_librarypara       * roar_dl_getpara(struct roar_dl_lhandle * lhandle);
 const struct roar_dl_libraryname * roar_dl_getlibname(struct roar_dl_lhandle * lhandle);
+
+// context switching:
+// _restore() is to switch from main to library context. _store() is to store library context
+// and switch back to main context.
+int                      roar_dl_context_restore(struct roar_dl_lhandle * lhandle);
+int                      roar_dl_context_store(struct roar_dl_lhandle * lhandle);
 
 #endif
Index: libroar/error.c
===================================================================
--- libroar/error.c	(revision 5295)
+++ libroar/error.c	(revision 5312)
@@ -866,4 +866,21 @@
 }
 
+// Resets the stored state to 'no error' state. This can be used
+// to init the state.
+int    roar_err_initstore(struct roar_error_state * state) {
+ struct roar_error_state curstate;
+
+ if ( state == NULL ) {
+  roar_err_set(ROAR_ERROR_FAULT);
+  return -1;
+ }
+
+ roar_err_store(&curstate);
+ roar_err_clear_all();
+ roar_err_store(state);
+ roar_err_restore(&curstate);
+
+ return -1;
+}
 
 // store a error state (both libroar and system)
Index: libroar/roardl.c
===================================================================
--- libroar/roardl.c	(revision 5275)
+++ libroar/roardl.c	(revision 5312)
@@ -43,4 +43,9 @@
  struct roar_dl_librarypara * para;
  struct roar_dl_libraryinst * lib;
+ struct {
+  struct roar_error_state error_state;
+  void *  global_data;
+  void *  global_data_state;
+ } context;
 #if defined(ROAR_HAVE_LIBDL)
  void * handle;
@@ -187,4 +192,6 @@
  memset(ret, 0, sizeof(struct roar_dl_lhandle));
 
+ roar_err_initstore(&(ret->context.error_state));
+
 #if defined(ROAR_HAVE_LIBDL)
  flags  = RTLD_NOW;
@@ -243,4 +250,7 @@
  ret = -1;
 #endif
+
+ if ( lhandle->context.global_data != NULL )
+  roar_mm_free(lhandle->context.global_data);
 
  if ( lhandle->para != NULL )
@@ -273,4 +283,5 @@
  struct roar_dl_libraryinst * (*func)(struct roar_dl_librarypara * para);
  struct roar_dl_libraryinst * lib;
+ void * global_data_state = NULL;
  int i;
 
@@ -310,4 +321,25 @@
  if ( !((void*)lhandle < (void*)128) ) {
   lhandle->lib = lib;
+
+  if ( lib->global_data_len ) {
+   lhandle->context.global_data = roar_mm_malloc(lib->global_data_len);
+   if ( lhandle->context.global_data == NULL )
+    return -1;
+
+   if ( lib->global_data_init == NULL ) {
+    memset(lhandle->context.global_data, 0, lib->global_data_len);
+   } else {
+    memcpy(lhandle->context.global_data, lib->global_data_init, lib->global_data_len);
+   }
+  }
+ }
+
+ if ( lib->global_data_pointer != NULL ) {
+  global_data_state = *(lib->global_data_pointer);
+  if ( !((void*)lhandle < (void*)128) ) {
+   *(lib->global_data_pointer) = lib->global_data_init;
+  } else {
+   *(lib->global_data_pointer) = lhandle->context.global_data;
+  }
  }
 
@@ -315,4 +347,8 @@
   if ( lib->func[i] != NULL )
    lib->func[i](para, lib);
+ }
+
+ if ( lib->global_data_pointer != NULL ) {
+  *(lib->global_data_pointer) = global_data_state;
  }
 
@@ -375,3 +411,42 @@
 }
 
+int                      roar_dl_context_restore(struct roar_dl_lhandle * lhandle) {
+ struct roar_error_state error_state;
+
+ if ( (void*)lhandle < (void*)128 ) {
+  roar_err_set(ROAR_ERROR_NOTSUP);
+  return -1;
+ }
+
+ roar_err_store(&error_state);
+ roar_err_restore(&(lhandle->context.error_state));
+ lhandle->context.error_state = error_state;
+
+ if ( lhandle->lib->global_data_pointer != NULL ) {
+  lhandle->context.global_data_state = *(lhandle->lib->global_data_pointer);
+  *(lhandle->lib->global_data_pointer) = lhandle->context.global_data;
+ }
+
+ return 0;
+}
+
+int                      roar_dl_context_store(struct roar_dl_lhandle * lhandle) {
+ struct roar_error_state error_state;
+
+ if ( (void*)lhandle < (void*)128 ) {
+  roar_err_set(ROAR_ERROR_NOTSUP);
+  return -1;
+ }
+
+ if ( lhandle->lib->global_data_pointer != NULL ) {
+  *(lhandle->lib->global_data_pointer) = lhandle->context.global_data_state;
+ }
+
+ roar_err_store(&error_state);
+ roar_err_restore(&(lhandle->context.error_state));
+ lhandle->context.error_state = error_state;
+
+ return 0;
+}
+
 //ll
Index: plugins/roard/protocol-irc.c
===================================================================
--- plugins/roard/protocol-irc.c	(revision 5310)
+++ plugins/roard/protocol-irc.c	(revision 5312)
@@ -865,5 +865,5 @@
 
 static struct roard_proto proto[1] = {
- {ROAR_PROTO_IRC, ROAR_SUBSYS_NONE, "Internet Relay Chat", new_client, check_client, NULL, NULL}
+ {ROAR_PROTO_IRC, ROAR_SUBSYS_NONE, "Internet Relay Chat", NULL, new_client, check_client, NULL, NULL}
 };
 
Index: plugins/universal/protocol-daytime.c
===================================================================
--- plugins/universal/protocol-daytime.c	(revision 5303)
+++ plugins/universal/protocol-daytime.c	(revision 5312)
@@ -59,5 +59,5 @@
 
 static struct roard_proto proto[1] = {
- {ROAR_PROTO_DAYTIME, ROAR_SUBSYS_NONE, "The Internet daytime protocol", new_client, NULL, NULL, flushed_client}
+ {ROAR_PROTO_DAYTIME, ROAR_SUBSYS_NONE, "The Internet daytime protocol", NULL, new_client, NULL, NULL, flushed_client}
 };
 
Index: plugins/universal/protocol-discard.c
===================================================================
--- plugins/universal/protocol-discard.c	(revision 5275)
+++ plugins/universal/protocol-discard.c	(revision 5312)
@@ -42,5 +42,5 @@
 
 static struct roard_proto proto[1] = {
- {ROAR_PROTO_DISCARD, ROAR_SUBSYS_NONE, "Discard all data send to the server", NULL, check_client, NULL, NULL}
+ {ROAR_PROTO_DISCARD, ROAR_SUBSYS_NONE, "Discard all data send to the server", NULL, NULL, check_client, NULL, NULL}
 };
 
Index: plugins/universal/protocol-echo.c
===================================================================
--- plugins/universal/protocol-echo.c	(revision 5303)
+++ plugins/universal/protocol-echo.c	(revision 5312)
@@ -57,5 +57,5 @@
 
 static struct roard_proto proto[1] = {
- {ROAR_PROTO_ECHO, ROAR_SUBSYS_NONE, "Send all data send to the server back to the client", NULL, check_client, NULL, NULL}
+ {ROAR_PROTO_ECHO, ROAR_SUBSYS_NONE, "Send all data send to the server back to the client", NULL, NULL, check_client, NULL, NULL}
 };
 
Index: roard/clients.c
===================================================================
--- roard/clients.c	(revision 5304)
+++ roard/clients.c	(revision 5312)
@@ -38,14 +38,14 @@
 #ifndef ROAR_WITHOUT_DCOMP_EMUL_ESD
 #ifdef ROAR_HAVE_H_ESD
- {ROAR_PROTO_ESOUND, ROAR_SUBSYS_WAVEFORM, "EsounD emulation", NULL, emul_esd_check_client, NULL, NULL},
+ {ROAR_PROTO_ESOUND, ROAR_SUBSYS_WAVEFORM, "EsounD emulation", NULL, NULL, emul_esd_check_client, NULL, NULL},
 #endif
 #endif
 #ifndef ROAR_WITHOUT_DCOMP_EMUL_RPLAY
- {ROAR_PROTO_RPLAY, ROAR_SUBSYS_WAVEFORM, "RPlay emulation", NULL, emul_rplay_check_client, NULL, NULL},
+ {ROAR_PROTO_RPLAY, ROAR_SUBSYS_WAVEFORM, "RPlay emulation", NULL, NULL, emul_rplay_check_client, NULL, NULL},
 #endif
 #ifndef ROAR_WITHOUT_DCOMP_EMUL_GOPHER
- {ROAR_PROTO_GOPHER, ROAR_SUBSYS_WAVEFORM, "The Internet Gopher Protocol", NULL, emul_gopher_check_client, NULL, emul_gopher_flushed_client},
-#endif
- {-1, 0, NULL, NULL, NULL, NULL, NULL}
+ {ROAR_PROTO_GOPHER, ROAR_SUBSYS_WAVEFORM, "The Internet Gopher Protocol", NULL, NULL, emul_gopher_check_client, NULL, emul_gopher_flushed_client},
+#endif
+ {-1, 0, NULL, NULL, NULL, NULL, NULL, NULL}
 };
 
@@ -647,5 +647,9 @@
      if ( g_proto[i].proto == c->proto ) {
       roar_vio_open_fh_socket(&vio, clients_get_fh(id));
+      if ( g_proto[i].lhandle != NULL )
+       roar_dl_context_restore(g_proto[i].lhandle);
       rv = g_proto[i].check_client(id, &vio);
+      if ( g_proto[i].lhandle != NULL )
+       roar_dl_context_store(g_proto[i].lhandle);
      }
     }
@@ -686,5 +690,9 @@
 
  if ( p->flush_client != NULL ) {
+  if ( p->lhandle != NULL )
+   roar_dl_context_restore(p->lhandle);
   return p->flush_client(id, &vio);
+  if ( p->lhandle != NULL )
+   roar_dl_context_store(p->lhandle);
  }
 
@@ -716,5 +724,9 @@
  if ( cs->outbuf == NULL ) {
   if ( p->flushed_client != NULL ) {
+   if ( p->lhandle != NULL )
+    roar_dl_context_restore(p->lhandle);
    return p->flushed_client(id, &vio);
+   if ( p->lhandle != NULL )
+    roar_dl_context_store(p->lhandle);
   }
  }
@@ -813,5 +825,5 @@
 
 // proto support
-int clients_register_proto(struct roard_proto * proto) {
+int clients_register_proto(struct roard_proto * proto, struct roar_dl_lhandle * lhandle) {
  const size_t len = sizeof(g_proto)/sizeof(*g_proto);
  size_t i;
@@ -829,4 +841,6 @@
 
  memcpy(&(g_proto[i]), proto, sizeof(*g_proto));
+
+ g_proto[i].lhandle = lhandle;
 
  return 0;
Index: roard/include/client.h
===================================================================
--- roard/include/client.h	(revision 5301)
+++ roard/include/client.h	(revision 5312)
@@ -78,4 +78,5 @@
  int subsystems;
  const char * description;
+ struct roar_dl_lhandle * lhandle;
  int (*new_client)(int client, struct roar_vio_calls * vio, struct roard_listen * lsock);
  int (*check_client)(int client, struct roar_vio_calls * vio);
@@ -116,5 +117,5 @@
 
 // proto support
-int clients_register_proto  (struct roard_proto * proto);
+int clients_register_proto  (struct roard_proto * proto, struct roar_dl_lhandle * lhandle);
 int clients_unregister_proto(int proto);
 void print_protolist        (enum output_format format);
Index: roard/plugins.c
===================================================================
--- roard/plugins.c	(revision 5275)
+++ roard/plugins.c	(revision 5312)
@@ -57,7 +57,11 @@
  int i;
 
- if ( plugin->sched != NULL )
-  if ( plugin->sched->free != NULL )
+ if ( plugin->sched != NULL ) {
+  if ( plugin->sched->free != NULL ) {
+   roar_dl_context_restore(plugin->lhandle);
    plugin->sched->free();
+   roar_dl_context_store(plugin->lhandle);
+  }
+ }
 
  for (i = 0; i < MAX_PROTOS; i++) {
@@ -87,7 +91,11 @@
    }
 
-   if ( g_plugins[i].sched != NULL )
-    if ( g_plugins[i].sched->init != NULL )
+   if ( g_plugins[i].sched != NULL ) {
+    if ( g_plugins[i].sched->init != NULL ) {
+     roar_dl_context_restore(g_plugins[i].lhandle);
      g_plugins[i].sched->init();
+     roar_dl_context_store(g_plugins[i].lhandle);
+    }
+   }
 
    _pp = NULL;
@@ -114,10 +122,16 @@
  int i;
 
- for (i = 0; i < MAX_PLUGINS; i++)
-  if ( g_plugins[i].lhandle != NULL )
-   if ( g_plugins[i].sched != NULL )
-    if ( g_plugins[i].sched->update != NULL )
+ for (i = 0; i < MAX_PLUGINS; i++) {
+  if ( g_plugins[i].lhandle != NULL ) {
+   if ( g_plugins[i].sched != NULL ) {
+    if ( g_plugins[i].sched->update != NULL ) {
+     roar_dl_context_restore(g_plugins[i].lhandle);
      if ( g_plugins[i].sched->update() == -1 )
       ret = -1;
+     roar_dl_context_store(g_plugins[i].lhandle);
+    }
+   }
+  }
+ }
 
  return ret;
@@ -178,5 +192,5 @@
  }
 
- return clients_register_proto(proto);
+ return clients_register_proto(proto, _pp->lhandle);
 }
 
