Index: trunk/src/sh_extern.c
===================================================================
--- trunk/src/sh_extern.c	(revision 210)
+++ trunk/src/sh_extern.c	(revision 211)
@@ -31,6 +31,6 @@
  * for debugging
  */
-#if 0
-#define PDGBFILE "/pdbg."
+#if 1
+#define PDGBFILE "/home/rainer/PROJECTS/samhain/devel/pdbg."
 #endif
 
@@ -532,5 +532,5 @@
   SL_ENTER(_("sh_ext_pclose"));
 
-  PDBGC_OPEN;
+  PDBG_OPEN;
   PDBG_S(" -> pclose");
   (void) fflush(task->pipe);
@@ -773,4 +773,91 @@
 }
 
+/* Execute command, return first line of output
+ * ifconfig | grep -1 lo | tail -n 1 | sed s/.*inet addr:\([0-9.]*\)\(.*\)/\1/
+ */
+char * sh_ext_popen_str (char * command)
+{
+  sh_tas_t task;
+  struct  sigaction  new_act;
+  struct  sigaction  old_act;
+  char  dir[SH_PATHBUF];
+  char * p;
+  char * out = NULL;
+  int    status;
+
+  SL_ENTER(_("sh_ext_popen_str"));
+
+  sh_ext_tas_init(&task);
+
+  (void) sh_ext_tas_add_envv (&task, _("SHELL"), 
+			      _("/bin/sh")); 
+  (void) sh_ext_tas_add_envv (&task, _("PATH"),  
+			      _("/sbin:/bin:/usr/sbin:/usr/bin:/usr/ucb")); 
+  (void) sh_ext_tas_add_envv (&task, _("IFS"), " \n\t"); 
+  if (sh.timezone != NULL)
+    {
+      (void) sh_ext_tas_add_envv(&task,  "TZ", sh.timezone);
+    }
+  
+  sh_ext_tas_command(&task,  _("/bin/sh"));
+
+  (void) sh_ext_tas_add_argv(&task,  _("/bin/sh"));
+  (void) sh_ext_tas_add_argv(&task,  _("-c"));
+  (void) sh_ext_tas_add_argv(&task,  command);
+  
+  task.rw = 'r';
+  task.fork_twice = S_FALSE;
+
+  status = sh_ext_popen(&task);
+
+  if (status != 0)
+    {
+      sh_error_handle(SH_ERR_ALL, FIL__, __LINE__, status, MSG_E_SUBGEN, 
+		      _("Could not open pipe"), _("sh_ext_popen_str"));
+      SL_RETURN ((NULL), _("sh_ext_popen_str"));
+    }
+
+  /* ignore SIGPIPE (instead get EPIPE if connection is closed)
+   */
+  new_act.sa_handler = SIG_IGN;
+  (void) retry_sigaction (FIL__, __LINE__, SIGPIPE, &new_act, &old_act);
+
+  /* read from the open pipe
+   */
+  if (task.pipe != NULL)
+    {
+      int try = 1200; /* 1000 * 0.1 = 120 sec */
+      sh_string * s = sh_string_new(0);
+      do {
+	sh_string_read(s, task.pipe, 0);
+	if (sh_string_len(s) == 0)
+	  {
+	    --try; retry_msleep(0, 100);
+	  }
+      } while (sh_string_len(s) == 0 && try != 0);
+
+      if (sh_string_len(s) == 0)
+	{
+	  sh_error_handle(SH_ERR_ALL, FIL__, __LINE__, status, MSG_E_SUBGEN, 
+			  _("No output from command"), _("sh_ext_popen_str"));
+	}
+
+      out = sh_util_strdup(sh_string_str(s));
+      sh_string_destroy(&s);
+    }
+
+  /* restore old signal handler
+   */
+  (void) retry_sigaction (FIL__, __LINE__, SIGPIPE, &old_act, NULL);
+
+  /* close pipe and return exit status
+   */
+  (void) sh_ext_pclose(&task);
+  sh_ext_tas_free (&task);
+  SL_RETURN ((out), _("sh_ext_popen_str"));
+}
+
+
+
 
 /* ---------------  EXTERN STUFF ------------------- */
@@ -1141,5 +1228,6 @@
     (void) sh_ext_add_envv (_("HOME"), p);
   (void) sh_ext_add_envv (_("SHELL"), _("/bin/sh")); 
-  (void) sh_ext_add_envv (_("PATH"),  _("/sbin:/usr/sbin:/bin:/usr/bin")); 
+  (void) sh_ext_add_envv (_("PATH"),  _("/sbin:/bin:/usr/sbin:/usr/bin")); 
+  (void) sh_ext_add_envv (_("IFS"), " \n\t"); 
   i = (p == NULL ? (-1) :  0);
   SL_RETURN(i, _("sh_ext_add_default"));
Index: trunk/src/sh_readconf.c
===================================================================
--- trunk/src/sh_readconf.c	(revision 210)
+++ trunk/src/sh_readconf.c	(revision 211)
@@ -135,4 +135,25 @@
   { NULL,                     SH_SECTION_NONE}
 };
+
+static char * sh_readconf_expand_value (const char * str)
+{
+  char * tmp = (char*)str;
+  char * out;
+
+  while (tmp && isspace((int)*tmp)) ++tmp;
+  
+  if (tmp[0] == '$' && tmp[1] == '(')
+    {
+      size_t len = strlen(tmp);
+      while (isspace((int) tmp[len-1])) { tmp[len-1] = '\0'; --len; }
+      if (tmp[len-1] == ')')
+	{
+	  tmp[len-1] = '\0';
+	  out = sh_ext_popen_str(&tmp[2]);
+	  return out;
+	}
+    }
+  return sh_util_strdup(str);
+}
 
 enum {
@@ -1297,4 +1318,14 @@
     }
 
+  /* Expand shell expressions. This return allocated memory which we must free.
+   */
+  value = sh_readconf_expand_value(value);
+
+  if (!value || (*value) == '\0')
+    {
+      TPT(( 0, FIL__, __LINE__, _("msg=<ConfigFile: empty after shell expansion: %s>\n"),
+	    line));
+      SL_RETURN(good_opt, _("sh_readconf_line"));
+    }
 
 #if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE) 
@@ -1362,4 +1393,6 @@
     }
 
+  SH_FREE((char*)value);
+
   SL_RETURN(good_opt, _("sh_readconf_line"));
 }
Index: trunk/src/trustfile.c
===================================================================
--- trunk/src/trustfile.c	(revision 210)
+++ trunk/src/trustfile.c	(revision 211)
@@ -827,7 +827,7 @@
 	      /* smack on the /../ 
 	       */
-	      t_const = "/../";
+	      t_const = "/../"; t = (char *)t_const;
 	      while(*t && b < end)
-		*b++ = *t_const++;
+		*b++ = *t++;
 
 	      /* append the symlink referent 
