diff options
Diffstat (limited to 'src/util/configuration.c')
-rw-r--r-- | src/util/configuration.c | 174 |
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 | */ |
998 | int | 998 | int |
999 | GNUNET_CONFIGURATION_have_value (const struct GNUNET_CONFIGURATION_Handle *cfg, | 999 | GNUNET_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 | */ |
1019 | char * | 1025 | static char * |
1020 | GNUNET_CONFIGURATION_expand_dollar (const struct GNUNET_CONFIGURATION_Handle | 1026 | expand_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 | */ | ||
1180 | char * | ||
1181 | GNUNET_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 |