Index: include/libroar/vio_dstr.h
===================================================================
--- include/libroar/vio_dstr.h	(revision 1323)
+++ include/libroar/vio_dstr.h	(revision 1325)
@@ -98,5 +98,5 @@
 #define ROAR_VIO_DSTR_OBJT_PGP            (0x10|ROAR_VIO_DSTR_OBJGT_CRYPT)
 #define ROAR_VIO_DSTR_OBJT_PGP_ENC        (0x11|ROAR_VIO_DSTR_OBJGT_CRYPT)
-#define ROAR_VIO_DSTR_OBJT_PGP_STORE      (0x11|ROAR_VIO_DSTR_OBJGT_CRYPT)
+#define ROAR_VIO_DSTR_OBJT_PGP_STORE      (0x12|ROAR_VIO_DSTR_OBJGT_CRYPT)
 #define ROAR_VIO_DSTR_OBJT_SSL1           (0x21|ROAR_VIO_DSTR_OBJGT_CRYPT)
 #define ROAR_VIO_DSTR_OBJT_SSL2           (0x22|ROAR_VIO_DSTR_OBJGT_CRYPT)
@@ -127,4 +127,6 @@
 };
 
+#define ROAR_VIO_DSTR_MAX_OBJ_PER_CHAIN 16
+
 struct roar_vio_dstr_chain {
  int    type;
@@ -134,4 +136,5 @@
  struct roar_vio_defaults * def;
  struct roar_vio_calls    * vio;
+ struct roar_vio_defaults   store_def;
 };
 
@@ -145,5 +148,5 @@
 
 int     roar_vio_dstr_parse_opts(struct roar_vio_dstr_chain * chain);
-int     roar_vio_dstr_set_defaults(struct roar_vio_dstr_chain * chain);
+int     roar_vio_dstr_set_defaults(struct roar_vio_dstr_chain * chain, int len, struct roar_vio_defaults * def, int dnum);
 int     roar_vio_dstr_build_chain(struct roar_vio_dstr_chain * chain, struct roar_vio_calls * calls, struct roar_vio_calls * vio);
 
Index: libroar/vio_dstr.c
===================================================================
--- libroar/vio_dstr.c	(revision 1323)
+++ libroar/vio_dstr.c	(revision 1325)
@@ -145,4 +145,7 @@
  }
 
+ if ( type == ROAR_VIO_DSTR_OBJT_EOL )
+  return "<<EOL>>";
+
  return NULL;
 }
@@ -170,4 +173,5 @@
                                char * dstr, struct roar_vio_defaults * def, int dnum,
                                struct roar_vio_calls * vio) {
+ struct roar_vio_dstr_chain chain[ROAR_VIO_DSTR_MAX_OBJ_PER_CHAIN];
  char * next;
  char * this;
@@ -178,4 +182,5 @@
  int    inopts;
  int    type;
+ int    cc = 0; // current chain element
 
  if ( calls == NULL || dstr == NULL )
@@ -185,13 +190,16 @@
   return -1;
 
- if ( dnum > 1 )
-  return -1;
-
  if ( (dstr = strdup(dstr)) == NULL )
   return -1;
 
+ memset(chain, 0, sizeof(chain));
+
  next = dstr;
 
  while (next != NULL) {
+  if ( (cc+1) == ROAR_VIO_DSTR_MAX_OBJ_PER_CHAIN ) {
+   _ret(-1);
+  }
+
   this = next;
   next = strstr(next, "##");
@@ -239,7 +247,125 @@
   ROAR_WARN("roar_vio_open_dstr_vio(*): type=0x%.4x(%s)", type, roar_vio_dstr_get_name(type));
 
- }
-
- _ret(-1);
+  chain[cc].type     = type;
+  chain[cc].opts     = opts;
+  chain[cc].dst      = dst;
+  chain[cc].def      = NULL;
+  chain[cc].vio      = NULL;
+  chain[cc].need_vio = -1;
+  cc++;
+
+ }
+
+ chain[cc].type = ROAR_VIO_DSTR_OBJT_EOL;
+
+ if ( roar_vio_dstr_parse_opts(chain) == -1 ) {
+  _ret(-1);
+ }
+
+ if ( roar_vio_dstr_set_defaults(chain, cc, def, dnum) == -1 ) {
+  _ret(-1);
+ }
+
+ if ( roar_vio_dstr_build_chain(chain, calls, vio) == -1 ) {
+  _ret(-1);
+ }
+
+ _ret(0);
+}
+
+#undef _ret
+
+int     roar_vio_dstr_parse_opts(struct roar_vio_dstr_chain * chain) {
+ if ( chain == NULL )
+  return -1;
+
+ // TODO: we should add some code here later...
+
+ return 0;
+}
+
+#define _toggle(x) ((x) = ((x) ? 0 : 1))
+
+int     roar_vio_dstr_set_defaults(struct roar_vio_dstr_chain * chain, int len, struct roar_vio_defaults * def, int dnum) {
+ struct roar_vio_dstr_chain * c, * next;
+ int i;
+
+ if ( chain == NULL )
+  return -1;
+
+ if ( def == NULL && dnum != 0 )
+  return -1;
+
+ if ( dnum > 1 ) /* currently not supported */
+  return -1;
+
+ if ( dnum == 0 )
+  def = NULL;
+
+ chain[len].def = def;
+
+ for (i = len; i >= 0; i--) {
+  c    = &chain[i];
+  next = &chain[i-1];
+
+  ROAR_WARN("roar_vio_dstr_set_defaults(*): i=%i, c->type=0x%.4x(%s)", i, c->type & 0xFFFF, roar_vio_dstr_get_name(c->type));
+  ROAR_WARN("roar_vio_dstr_set_defaults(*): i=%i, c->type=0x%.4x(%s): c->def=%p, c->def->type=%i", i, c->type & 0xFFFF,
+                   roar_vio_dstr_get_name(c->type), c->def, c->def == NULL ? -1 : c->def->type);
+
+  c->need_vio = 1;
+
+  switch (c->type) {
+   case ROAR_VIO_DSTR_OBJT_PASS:
+   case ROAR_VIO_DSTR_OBJT_RE:
+   case ROAR_VIO_DSTR_OBJT_GZIP:
+   case ROAR_VIO_DSTR_OBJT_BZIP2:
+   case ROAR_VIO_DSTR_OBJT_PGP:
+   case ROAR_VIO_DSTR_OBJT_PGP_ENC:
+   case ROAR_VIO_DSTR_OBJT_PGP_STORE:
+   case ROAR_VIO_DSTR_OBJT_SSL1:
+   case ROAR_VIO_DSTR_OBJT_SSL2:
+   case ROAR_VIO_DSTR_OBJT_SSL3:
+   case ROAR_VIO_DSTR_OBJT_TLS:
+   case ROAR_VIO_DSTR_OBJT_MAGIC:
+    _toggle(c->need_vio);
+   case ROAR_VIO_DSTR_OBJT_EOL:
+    _toggle(c->need_vio);
+     next->def = c->def;
+    break;
+   case ROAR_VIO_DSTR_OBJT_FILE:
+     if ( c->dst == NULL ) /* should we allow multible cascaed file: objects? */
+      return -1;
+
+     c->need_vio = 0;
+     next->def = &(next->store_def);
+     if ( c->def != NULL ) {
+      roar_vio_dstr_init_defaults(next->def, ROAR_VIO_DEF_TYPE_FILE, c->def->o_flags, c->def->o_mode);
+     } else {
+      roar_vio_dstr_init_defaults(next->def, ROAR_VIO_DEF_TYPE_FILE, O_RDONLY, 0644);
+     }
+
+     if ( c->dst[0] == '/' && c->dst[1] == '/' ) {
+      next->def->d.file = c->dst + 1;
+     } else {
+      next->def->d.file = c->dst;
+     }
+    break;
+   default:
+    return -1;
+  }
+
+  ROAR_WARN("roar_vio_dstr_set_defaults(*): i=%i, c->type=0x%.4x(%s): next->def=%p, next->def->type=%i", i,
+                   c->type & 0xFFFF, roar_vio_dstr_get_name(c->type),
+                   next->def, next->def == NULL ? -1 : next->def->type);
+ }
+
+ return 0;
+}
+
+int     roar_vio_dstr_build_chain(struct roar_vio_dstr_chain * chain, struct roar_vio_calls * calls, struct roar_vio_calls * vio) {
+ if ( chain == NULL || calls == NULL )
+  return -1;
+
+ return -1;
 }
 
