Index: roarclients/roarpluginrunner.c
===================================================================
--- roarclients/roarpluginrunner.c	(revision 5712)
+++ roarclients/roarpluginrunner.c	(revision 5715)
@@ -55,4 +55,16 @@
                  "    --args ARGS          - Set plugin arguments.\n"
         );
+
+ fprintf(stderr, "\nCPI Options:\n\n");
+ fprintf(stderr, " -t --tcp                - Use TCP listen socket\n"
+                 " -u --unix               - Use UNIX Domain listen socket (default)\n"
+                 " -n --decnet             - use DECnet listen socket\n"
+                 "    --port PORT          - TCP Port to bind to\n"
+                 "    --bind ADDR          - Node/Hostname/Path to bind to\n"
+                 "    --proto PROTO        - Use PROTO as protocol on Socket\n"
+                 "    --new-sock           - Parameters for new socket follow\n"
+                 "    --client-fh FH       - Comunicate with a client over this handle\n"
+                 "\n"
+        );
 }
 
@@ -72,4 +84,5 @@
  if ( roar_plugincontainer_load(cont, name, NULL) == -1 ) {
   err = roar_error;
+  roar_scheduler_source_del(g_sched, &s_container);
   roar_plugincontainer_unref(cont);
   roar_error = err;
@@ -425,4 +438,115 @@
 }
 
+static struct roar_scheduler_source * add_cpi_common(int proto) {
+ struct roar_scheduler_source * source;
+ int err;
+
+ if ( proto == -1 ) {
+  roar_err_set(ROAR_ERROR_INVAL);
+  return NULL;
+ }
+
+ source = roar_mm_malloc(sizeof(struct roar_scheduler_source));
+ if ( source == NULL )
+  return NULL;
+
+ memset(source, 0, sizeof(struct roar_scheduler_source));
+
+ source->vio   = roar_mm_malloc(sizeof(struct roar_vio_calls));
+ if ( source->vio == NULL ) {
+  err = roar_error;
+  roar_mm_free(source);
+  roar_error = err;
+  return NULL;
+ }
+
+ source->flags = ROAR_SCHEDULER_FLAG_FREE;
+ source->handle.cpi.proto = proto;
+
+ return source;
+}
+
+static int add_cpi_listen(int proto, int type, const char * host, int port) {
+ struct roar_scheduler_source * source = add_cpi_common(proto);
+ int err;
+
+ if ( source == NULL )
+  return -1;
+
+ if ( roar_vio_open_socket_listen(source->vio, type, host, port) == -1 ) {
+  err = roar_error;
+  roar_mm_free(source->vio);
+  roar_mm_free(source);
+  roar_error = err;
+  return -1;
+ }
+
+ source->type  = ROAR_SCHEDULER_CPI_LISTEN;
+
+ source->vio->flags |= ROAR_VIO_FLAGS_FREESELF;
+
+ if ( roar_scheduler_source_add(g_sched, source) == -1 ) {
+  err = roar_error;
+  roar_vio_close(source->vio);
+  roar_mm_free(source);
+  roar_error = err;
+  return -1;
+ }
+
+ return 0;
+}
+
+static int add_cpi_client(int proto, int fh) {
+ struct roar_scheduler_source * source = add_cpi_common(proto);
+ struct roar_dl_librarypara * para;
+ int err;
+
+ if ( source == NULL )
+  return -1;
+
+ if ( roar_vio_open_fh(source->vio, fh) == -1 ) {
+  err = roar_error;
+  roar_mm_free(source->vio);
+  roar_mm_free(source);
+  roar_error = err;
+  return -1;
+ }
+
+ source->type  = ROAR_SCHEDULER_CPI_CLIENT;
+
+ source->vio->flags |= ROAR_VIO_FLAGS_FREESELF;
+
+ if ( roar_scheduler_source_add(g_sched, source) == -1 ) {
+  err = roar_error;
+  roar_vio_close(source->vio);
+  roar_mm_free(source);
+  roar_error = err;
+  return -1;
+ }
+
+ if ( source->flags & ROAR_SCHEDULER_FLAG_STUB ) {
+  ROAR_ERR("Can not handle proto STUB clients. Try to use --client-fh as last argument.");
+
+  roar_scheduler_source_del(g_sched, source);
+
+  return -1;
+ }
+
+ if ( source->handle.cpi.impl->set_proto != NULL ) {
+  para = roar_dl_getpara(source->lhandle);
+
+  if ( source->lhandle != NULL )
+   roar_dl_context_restore(source->lhandle);
+  source->handle.cpi.impl->set_proto(source->handle.cpi.client, source->vio, &(source->handle.cpi.obuffer), &(source->handle.cpi.userdata), source->handle.cpi.protopara, source->handle.cpi.protoparalen, para);
+  if ( source->lhandle != NULL )
+   roar_dl_context_store(source->lhandle);
+
+  if ( para != NULL )
+   roar_dl_para_unref(para);
+ }
+
+ return 0;
+}
+
 int main (int argc, char * argv[]) {
  const char * appname    = "roarpluginrunner " ROAR_VSTR_ROARAUDIO;
@@ -433,4 +557,9 @@
  int i;
  const char * k;
+ int cpi_type = ROAR_SOCKET_TYPE_UNKNOWN;
+ int cpi_proto = -1;
+ int cpi_port = 0;
+ int cpi_touched = 0;
+ const char * cpi_host = NULL;
 
  g_sched = roar_scheduler_new(ROAR_SCHEDULER_FLAG_NONE, ROAR_SCHEDULER_STRATEGY_DEFAULT);
@@ -459,4 +588,38 @@
   } else if ( !strcmp(k, "--server") ) {
    roar_libroar_set_server(argv[++i]);
+
+  } else if ( !strcmp(k, "--tcp") || !strcmp(k, "-t") ) {
+   cpi_type = ROAR_SOCKET_TYPE_TCP;
+   cpi_touched++;
+  } else if ( !strcmp(k, "--unix") || !strcmp(k, "-u") ) {
+   cpi_type = ROAR_SOCKET_TYPE_UNIX;
+   cpi_touched++;
+  } else if ( !strcmp(k, "--decnet") || !strcmp(k, "-n") ) {
+   cpi_type = ROAR_SOCKET_TYPE_DECNET;
+   cpi_touched++;
+  } else if ( !strcmp(k, "--port") ) {
+   cpi_port = atoi(argv[++i]);
+   cpi_touched++;
+  } else if ( !strcmp(k, "--bind") ) {
+   cpi_host = argv[++i];
+   cpi_touched++;
+  } else if ( !strcmp(k, "--proto") ) {
+   cpi_proto = roar_str2proto(argv[++i]);
+   if ( cpi_proto == -1 ) {
+    fprintf(stderr, "Unknown protocol: %s: %s\n", argv[i], roar_error2str(roar_error));
+    return 1;
+   }
+  } else if ( !strcmp(k, "--new-sock") ) {
+   if ( cpi_touched && add_cpi_listen(cpi_proto, cpi_type, cpi_host, cpi_port) == -1 ) {
+    fprintf(stderr, "Can not open socket for CPI: %s\n", roar_error2str(roar_error));
+    return 1;
+   }
+   cpi_touched = 0;
+  } else if ( !strcmp(k, "--client-fh") ) {
+   if ( add_cpi_client(cpi_proto, atoi(argv[++i])) == -1 ) {
+    fprintf(stderr, "Can not add CPI client: %s\n", roar_error2str(roar_error));
+    return 1;
+   }
+
   } else if ( !strcmp(k, "--appname") ) {
    appname = argv[++i];
@@ -469,4 +632,10 @@
    _clear_para();
   } else {
+   if ( cpi_touched && add_cpi_listen(cpi_proto, cpi_type, cpi_host, cpi_port) == -1 ) {
+    fprintf(stderr, "Can not open socket for CPI: %s\n", roar_error2str(roar_error));
+    return 1;
+   }
+   cpi_touched = 0;
+
    if ( g_para == NULL )
     g_para = roar_dl_para_new(action == RUN_AS_APPLICATION ? NULL : pluginargs, NULL, appname, abiversion);
