- Allocate buffer large enough to contain UNIX_PATH_MAX size pathnames in case of...
[oweals/gnunet.git] / src / util / configuration.c
index 6176b173451982f85327896b5cad94040813aeae..3d9281e8d2d87fdb07773451685e159baa8d9449 100644 (file)
@@ -145,7 +145,7 @@ GNUNET_CONFIGURATION_destroy (struct GNUNET_CONFIGURATION_Handle *cfg)
  * @param allow_inline set to #GNUNET_YES if we recursively load configuration
  *          from inlined configurations; #GNUNET_NO if not and raise warnings
  *          when we come across them
- * @return #GNUNET_OK on success, #GNUNET_ERROR on error
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
  */
 int
 GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg,
@@ -328,7 +328,7 @@ GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg,
     return GNUNET_SYSERR;
   dirty = cfg->dirty;           /* back up value! */
   if (GNUNET_SYSERR ==
-       GNUNET_DISK_file_size (fn, &fs64, GNUNET_YES, GNUNET_YES))
+      GNUNET_DISK_file_size (fn, &fs64, GNUNET_YES, GNUNET_YES))
   {
     LOG (GNUNET_ERROR_TYPE_WARNING,
         "Error while determining the file size of %s\n", fn);
@@ -1054,6 +1054,9 @@ expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cfg,
   char *def;
   char *end;
   unsigned int lopen;
+  char erased_char;
+  char *erased_pos;
+  size_t len;
 
   if (NULL == orig)
     return NULL;
@@ -1072,6 +1075,8 @@ expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cfg,
          "Doesn't start with $ - not expanding\n");
     return orig;
   }
+  erased_char = 0;
+  erased_pos = NULL;
   if ('{' == orig[1])
   {
     start = &orig[2];
@@ -1098,6 +1103,8 @@ expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cfg,
         break;
       }
     }
+    erased_char = *end;
+    erased_pos = end;
     *end = '\0';
     post = end + 1;
     def = strchr (orig, ':');
@@ -1118,7 +1125,8 @@ expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cfg,
     i = 0;
     while ( (orig[i] != '/') &&
             (orig[i] != '\\') &&
-            (orig[i] != '\0') )
+            (orig[i] != '\0')  &&
+            (orig[i] != ' ') )
       i++;
     if (orig[i] == '\0')
     {
@@ -1126,6 +1134,8 @@ expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cfg,
     }
     else
     {
+      erased_char = orig[i];
+      erased_pos = &orig[i];
       orig[i] = '\0';
       post = &orig[i + 1];
     }
@@ -1136,10 +1146,10 @@ expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cfg,
        post,
        def);
   if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_filename (cfg,
-                                               "PATHS",
-                                               start,
-                                               &prefix))
+      GNUNET_CONFIGURATION_get_value_string (cfg,
+                                             "PATHS",
+                                             start,
+                                             &prefix))
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG,
          "Filename for `%s' is not in PATHS config section\n",
@@ -1155,23 +1165,30 @@ expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cfg,
     }
     if (NULL == env)
     {
-      orig[strlen (orig)] = DIR_SEPARATOR;
-      LOG (GNUNET_ERROR_TYPE_DEBUG,
-           "Expanded to `%s' (returning orig)\n",
-           orig);
+      start = GNUNET_strdup (start);
+      if (erased_pos)
+        *erased_pos = erased_char;
+      LOG (GNUNET_ERROR_TYPE_WARNING,
+           _("Failed to expand `%s' in `%s' as it is neither found in [PATHS] nor defined as an environmental variable\n"),
+           start, orig);
+      GNUNET_free (start);
       return orig;
     }
     prefix = GNUNET_strdup (env);
   }
+  prefix = GNUNET_CONFIGURATION_expand_dollar (cfg, prefix);
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Prefix is `%s'\n",
        prefix);
-  result = GNUNET_malloc (strlen (prefix) + strlen (post) + 2);
+  if ( (erased_pos) && ('}' != erased_char) )
+  {
+    len = strlen (prefix) + 1;
+    prefix = GNUNET_realloc (prefix, len + 1);
+    prefix[len - 1] = erased_char;
+    prefix[len] = '\0';
+  }
+  result = GNUNET_malloc (strlen (prefix) + strlen (post) + 1);
   strcpy (result, prefix);
-  if ( (0 == strlen (prefix)) ||
-       ( (prefix[strlen (prefix) - 1] != DIR_SEPARATOR) &&
-         (strlen (post) > 0) ) )
-    strcat (result, DIR_SEPARATOR_STR);
   strcat (result, post);
   GNUNET_free_non_null (def);
   GNUNET_free (prefix);
@@ -1194,14 +1211,31 @@ expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cfg,
  * to VAR2.
  *
  * @param cfg configuration to use for path expansion
- * @param orig string to $-expand (will be freed!)
+ * @param orig string to $-expand (will be freed!).  Note that multiple
+ *          $-expressions can be present in this string.  They will all be
+ *          $-expanded.
  * @return $-expanded string
  */
 char *
 GNUNET_CONFIGURATION_expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cfg,
                                     char *orig)
 {
-  return expand_dollar (cfg, orig, 0);
+  char *dup;
+  size_t i;
+  size_t len;
+
+  for (i = 0; '\0' != orig[i]; i++)
+  {
+    if ('$' != orig[i])
+      continue;
+    dup = GNUNET_strdup (orig + i);
+    dup = expand_dollar (cfg, dup, 0);
+    len = strlen (dup) + 1;
+    orig = GNUNET_realloc (orig, i + len);
+    memcpy (orig + i, dup, len);
+    GNUNET_free (dup);
+  }
+  return orig;
 }
 
 
@@ -1598,7 +1632,7 @@ GNUNET_CONFIGURATION_load (struct GNUNET_CONFIGURATION_Handle *cfg,
   char *ipath;
 
   ipath = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_DATADIR);
-  if (ipath == NULL)
+  if (NULL == ipath)
     return GNUNET_SYSERR;
   baseconfig = NULL;
   GNUNET_asprintf (&baseconfig, "%s%s", ipath, "config.d");
@@ -1610,7 +1644,7 @@ GNUNET_CONFIGURATION_load (struct GNUNET_CONFIGURATION_Handle *cfg,
     return GNUNET_SYSERR;       /* no configuration at all found */
   }
   GNUNET_free (baseconfig);
-  if ((filename != NULL) &&
+  if ((NULL != filename) &&
       (GNUNET_OK != GNUNET_CONFIGURATION_parse (cfg, filename)))
   {
     /* specified configuration not found */