aboutsummaryrefslogtreecommitdiff
path: root/src/util/configuration.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/configuration.c')
-rw-r--r--src/util/configuration.c174
1 files changed, 143 insertions, 31 deletions
diff --git a/src/util/configuration.c b/src/util/configuration.c
index 1b600b4c8..d7076fac1 100644
--- a/src/util/configuration.c
+++ b/src/util/configuration.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2006, 2007, 2008, 2009 Christian Grothoff (and other contributing authors) 3 (C) 2006, 2007, 2008, 2009, 2013 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -414,7 +414,7 @@ GNUNET_CONFIGURATION_serialize (const struct GNUNET_CONFIGURATION_Handle *cfg,
414 } 414 }
415 /* For each key = value pair we need to add 4 characters (2 415 /* For each key = value pair we need to add 4 characters (2
416 spaces and 1 equal-to character and 1 new line) */ 416 spaces and 1 equal-to character and 1 new line) */
417 m_size += strlen (ent->key) + strlen (ent->val) + 4; 417 m_size += strlen (ent->key) + strlen (ent->val) + 4;
418 } 418 }
419 } 419 }
420 /* A new line after section end */ 420 /* A new line after section end */
@@ -449,7 +449,7 @@ GNUNET_CONFIGURATION_serialize (const struct GNUNET_CONFIGURATION_Handle *cfg,
449 GNUNET_free (val); 449 GNUNET_free (val);
450 memcpy (mem + c_size, cbuf, len); 450 memcpy (mem + c_size, cbuf, len);
451 c_size += len; 451 c_size += len;
452 GNUNET_free (cbuf); 452 GNUNET_free (cbuf);
453 } 453 }
454 } 454 }
455 memcpy (mem + c_size, "\n", 1); 455 memcpy (mem + c_size, "\n", 1);
@@ -993,7 +993,7 @@ GNUNET_CONFIGURATION_get_value_choice (const struct GNUNET_CONFIGURATION_Handle
993 * @param cfg configuration to inspect 993 * @param cfg configuration to inspect
994 * @param section section of interest 994 * @param section section of interest
995 * @param option option of interest 995 * @param option option of interest
996 * @return GNUNET_YES if so, GNUNET_NO if not. 996 * @return #GNUNET_YES if so, #GNUNET_NO if not.
997 */ 997 */
998int 998int
999GNUNET_CONFIGURATION_have_value (const struct GNUNET_CONFIGURATION_Handle *cfg, 999GNUNET_CONFIGURATION_have_value (const struct GNUNET_CONFIGURATION_Handle *cfg,
@@ -1009,71 +1009,183 @@ GNUNET_CONFIGURATION_have_value (const struct GNUNET_CONFIGURATION_Handle *cfg,
1009 1009
1010/** 1010/**
1011 * Expand an expression of the form "$FOO/BAR" to "DIRECTORY/BAR" 1011 * Expand an expression of the form "$FOO/BAR" to "DIRECTORY/BAR"
1012 * where either in the "PATHS" section or the environtment 1012 * where either in the "PATHS" section or the environtment "FOO" is
1013 * "FOO" is set to "DIRECTORY". 1013 * set to "DIRECTORY". We also support default expansion,
1014 * i.e. ${VARIABLE:-default} will expand to $VARIABLE if VARIABLE is
1015 * set in PATHS or the environment, and otherwise to "default". Note
1016 * that "default" itself can also be a $-expression, thus
1017 * "${VAR1:-{$VAR2}}" will expand to VAR1 and if that is not defined
1018 * to VAR2.
1014 * 1019 *
1015 * @param cfg configuration to use for path expansion 1020 * @param cfg configuration to use for path expansion
1016 * @param orig string to $-expand (will be freed!) 1021 * @param orig string to $-expand (will be freed!)
1022 * @param depth recursion depth, used to detect recursive expansions
1017 * @return $-expanded string 1023 * @return $-expanded string
1018 */ 1024 */
1019char * 1025static char *
1020GNUNET_CONFIGURATION_expand_dollar (const struct GNUNET_CONFIGURATION_Handle 1026expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cfg,
1021 *cfg, char *orig) 1027 char *orig,
1028 unsigned int depth)
1022{ 1029{
1023 int i; 1030 int i;
1024 char *prefix; 1031 char *prefix;
1025 char *result; 1032 char *result;
1033 char *start;
1026 const char *post; 1034 const char *post;
1027 const char *env; 1035 const char *env;
1036 char *def;
1037 char *end;
1038 unsigned int lopen;
1028 1039
1029 LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to $-expand %s\n", orig); 1040 if (depth > 128)
1030 1041 {
1031 if (orig[0] != '$') 1042 LOG (GNUNET_ERROR_TYPE_WARNING,
1043 _("Recursive expansion suspected, aborting $-expansion for term `%s'\n"),
1044 orig);
1045 return orig;
1046 }
1047 LOG (GNUNET_ERROR_TYPE_DEBUG,
1048 "Asked to $-expand %s\n", orig);
1049 if ('$' != orig[0])
1032 { 1050 {
1033 LOG (GNUNET_ERROR_TYPE_DEBUG, "Doesn't start with $ - not expanding\n"); 1051 LOG (GNUNET_ERROR_TYPE_DEBUG,
1052 "Doesn't start with $ - not expanding\n");
1034 return orig; 1053 return orig;
1035 } 1054 }
1036 i = 0; 1055 if ('{' == orig[1])
1037 while ((orig[i] != '/') && (orig[i] != '\\') && (orig[i] != '\0'))
1038 i++;
1039 if (orig[i] == '\0')
1040 { 1056 {
1041 post = ""; 1057 start = &orig[2];
1058 lopen = 1;
1059 end = &orig[1];
1060 while (lopen > 0)
1061 {
1062 end++;
1063 switch (*end)
1064 {
1065 case '}':
1066 lopen--;
1067 break;
1068 case '{':
1069 lopen++;
1070 break;
1071 case '\0':
1072 LOG (GNUNET_ERROR_TYPE_WARNING,
1073 _("Missing closing `%s' in option `%s'\n"),
1074 "}",
1075 orig);
1076 return orig;
1077 default:
1078 break;
1079 }
1080 }
1081 *end = '\0';
1082 post = end + 1;
1083 def = strchr (orig, ':');
1084 if (NULL != def)
1085 {
1086 *def = '\0';
1087 def++;
1088 if ( ('-' == *def) ||
1089 ('=' == *def) )
1090 def++;
1091 def = GNUNET_strdup (def);
1092 }
1042 } 1093 }
1043 else 1094 else
1044 { 1095 {
1045 orig[i] = '\0'; 1096 start = &orig[1];
1046 post = &orig[i + 1]; 1097 def = NULL;
1098 i = 0;
1099 while ( (orig[i] != '/') &&
1100 (orig[i] != '\\') &&
1101 (orig[i] != '\0') )
1102 i++;
1103 if (orig[i] == '\0')
1104 {
1105 post = "";
1106 }
1107 else
1108 {
1109 orig[i] = '\0';
1110 post = &orig[i + 1];
1111 }
1047 } 1112 }
1048 LOG (GNUNET_ERROR_TYPE_DEBUG, "Split into `%s' and `%s'\n", orig, post); 1113 LOG (GNUNET_ERROR_TYPE_DEBUG,
1114 "Split into `%s' and `%s' with default %s\n",
1115 start,
1116 post,
1117 def);
1049 if (GNUNET_OK != 1118 if (GNUNET_OK !=
1050 GNUNET_CONFIGURATION_get_value_filename (cfg, "PATHS", &orig[1], &prefix)) 1119 GNUNET_CONFIGURATION_get_value_filename (cfg,
1120 "PATHS",
1121 start,
1122 &prefix))
1051 { 1123 {
1052 LOG (GNUNET_ERROR_TYPE_DEBUG, "Filename for `%s' is not in PATHS config section\n", &orig[1]); 1124 LOG (GNUNET_ERROR_TYPE_DEBUG,
1053 if (NULL == (env = getenv (&orig[1]))) 1125 "Filename for `%s' is not in PATHS config section\n",
1126 start);
1127 if (NULL == (env = getenv (start)))
1128 {
1129 LOG (GNUNET_ERROR_TYPE_DEBUG,
1130 "`%s' is not an environment variable\n",
1131 start);
1132 /* try default */
1133 def = expand_dollar (cfg, def, depth + 1);
1134 env = def;
1135 }
1136 if (NULL == env)
1054 { 1137 {
1055 LOG (GNUNET_ERROR_TYPE_DEBUG, "`%s' is not an environment variable\n", &orig[1]); 1138 orig[strlen (orig)] = DIR_SEPARATOR;
1056 orig[i] = DIR_SEPARATOR; 1139 LOG (GNUNET_ERROR_TYPE_DEBUG,
1057 LOG (GNUNET_ERROR_TYPE_DEBUG, "Expanded to `%s' (returning orig)\n", orig); 1140 "Expanded to `%s' (returning orig)\n",
1141 orig);
1058 return orig; 1142 return orig;
1059 } 1143 }
1060 prefix = GNUNET_strdup (env); 1144 prefix = GNUNET_strdup (env);
1061 } 1145 }
1062 LOG (GNUNET_ERROR_TYPE_DEBUG, "Prefix is `%s'\n", prefix); 1146 LOG (GNUNET_ERROR_TYPE_DEBUG,
1147 "Prefix is `%s'\n",
1148 prefix);
1063 result = GNUNET_malloc (strlen (prefix) + strlen (post) + 2); 1149 result = GNUNET_malloc (strlen (prefix) + strlen (post) + 2);
1064 strcpy (result, prefix); 1150 strcpy (result, prefix);
1065 if ((strlen (prefix) == 0) || 1151 if ( (0 == strlen (prefix)) ||
1066 ((prefix[strlen (prefix) - 1] != DIR_SEPARATOR) && (strlen (post) > 0))) 1152 ( (prefix[strlen (prefix) - 1] != DIR_SEPARATOR) &&
1153 (strlen (post) > 0) ) )
1067 strcat (result, DIR_SEPARATOR_STR); 1154 strcat (result, DIR_SEPARATOR_STR);
1068 strcat (result, post); 1155 strcat (result, post);
1156 GNUNET_free_non_null (def);
1069 GNUNET_free (prefix); 1157 GNUNET_free (prefix);
1070 GNUNET_free (orig); 1158 GNUNET_free (orig);
1071 LOG (GNUNET_ERROR_TYPE_DEBUG, "Expanded to `%s'\n", result); 1159 LOG (GNUNET_ERROR_TYPE_DEBUG,
1160 "Expanded to `%s'\n",
1161 result);
1072 return result; 1162 return result;
1073} 1163}
1074 1164
1075 1165
1076/** 1166/**
1167 * Expand an expression of the form "$FOO/BAR" to "DIRECTORY/BAR"
1168 * where either in the "PATHS" section or the environtment "FOO" is
1169 * set to "DIRECTORY". We also support default expansion,
1170 * i.e. ${VARIABLE:-default} will expand to $VARIABLE if VARIABLE is
1171 * set in PATHS or the environment, and otherwise to "default". Note
1172 * that "default" itself can also be a $-expression, thus
1173 * "${VAR1:-{$VAR2}}" will expand to VAR1 and if that is not defined
1174 * to VAR2.
1175 *
1176 * @param cfg configuration to use for path expansion
1177 * @param orig string to $-expand (will be freed!)
1178 * @return $-expanded string
1179 */
1180char *
1181GNUNET_CONFIGURATION_expand_dollar (const struct GNUNET_CONFIGURATION_Handle *cfg,
1182 char *orig)
1183{
1184 return expand_dollar (cfg, orig, 0);
1185}
1186
1187
1188/**
1077 * Get a configuration value that should be a string. 1189 * Get a configuration value that should be a string.
1078 * 1190 *
1079 * @param cfg configuration to inspect 1191 * @param cfg configuration to inspect