diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-12-08 20:19:08 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-12-08 20:19:08 +0000 |
commit | 99c8e541e650a32caee7862989e6741509640755 (patch) | |
tree | a95c096644928eab2fc0e9ae00ea0203a73f9724 /src/util/configuration.c | |
parent | 33ead6c4ef534690c738a16f5467f2e4fa1ed9c9 (diff) | |
download | gnunet-99c8e541e650a32caee7862989e6741509640755.tar.gz gnunet-99c8e541e650a32caee7862989e6741509640755.zip |
fixing #2680 -- config file lines can now have any length
Diffstat (limited to 'src/util/configuration.c')
-rw-r--r-- | src/util/configuration.c | 141 |
1 files changed, 80 insertions, 61 deletions
diff --git a/src/util/configuration.c b/src/util/configuration.c index 5ce6db269..7d5dc10c1 100644 --- a/src/util/configuration.c +++ b/src/util/configuration.c | |||
@@ -156,118 +156,137 @@ GNUNET_CONFIGURATION_deserialize (struct GNUNET_CONFIGURATION_Handle *cfg, | |||
156 | const size_t size, | 156 | const size_t size, |
157 | int allow_inline) | 157 | int allow_inline) |
158 | { | 158 | { |
159 | char line[256]; | 159 | char *line; |
160 | char tag[64]; | 160 | size_t line_size; |
161 | char value[192]; | ||
162 | char *pos; | 161 | char *pos; |
163 | unsigned int nr; | 162 | unsigned int nr; |
164 | size_t r_bytes; | 163 | size_t r_bytes; |
165 | size_t to_read; | 164 | size_t to_read; |
166 | int i; | 165 | size_t i; |
167 | int emptyline; | 166 | int emptyline; |
168 | int ret; | 167 | int ret; |
169 | char *section; | 168 | char *section; |
169 | char *eq; | ||
170 | char *tag; | ||
171 | char *value; | ||
170 | 172 | ||
171 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Deserializing config file\n"); | 173 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Deserializing config file\n"); |
172 | ret = GNUNET_OK; | 174 | ret = GNUNET_OK; |
173 | section = GNUNET_strdup (""); | 175 | section = GNUNET_strdup (""); |
174 | nr = 0; | 176 | nr = 0; |
175 | r_bytes = 0; | 177 | r_bytes = 0; |
176 | memset (line, 0, 256); | ||
177 | while (r_bytes < size) | 178 | while (r_bytes < size) |
178 | { | 179 | { |
179 | /* fgets-like behaviour on buffer. read size is 255 bytes */ | 180 | /* fgets-like behaviour on buffer */ |
180 | to_read = size - r_bytes; | 181 | to_read = size - r_bytes; |
181 | if (to_read > 255) | 182 | pos = memchr (&mem[r_bytes], '\n', to_read); |
182 | to_read = 255; | 183 | if (NULL == pos) |
183 | memcpy (line, mem + r_bytes, to_read); | ||
184 | line[to_read] = '\0'; | ||
185 | if (NULL != (pos = strstr (line, "\n"))) | ||
186 | { | 184 | { |
187 | pos[1] = '\0'; | 185 | line = GNUNET_strndup (&mem[r_bytes], line_size = to_read); |
188 | r_bytes += (pos - line) + 1; | 186 | r_bytes += line_size; |
189 | } | 187 | } |
190 | else | 188 | else |
191 | r_bytes += to_read; | 189 | { |
192 | /* fgets-like behaviour end */ | 190 | line = GNUNET_strndup (&mem[r_bytes], line_size = (pos - &mem[r_bytes])); |
191 | r_bytes += line_size + 1; | ||
192 | } | ||
193 | /* increment line number */ | ||
193 | nr++; | 194 | nr++; |
194 | for (i = 0; i < 255; i++) | 195 | /* ignore comments */ |
196 | if ( ('#' == line[0]) || ('%' == line[0]) ) | ||
197 | continue; | ||
198 | /* tabs and '\r' are whitespace */ | ||
199 | emptyline = GNUNET_YES; | ||
200 | for (i = 0; i < line_size; i++) | ||
201 | { | ||
195 | if (line[i] == '\t') | 202 | if (line[i] == '\t') |
196 | line[i] = ' '; | 203 | line[i] = ' '; |
197 | if (line[0] == '\n' || line[0] == '#' || line[0] == '%' || line[0] == '\r') | 204 | if (line[i] == '\r') |
198 | continue; | 205 | line[i] = ' '; |
199 | emptyline = 1; | 206 | if (' ' != line[i]) |
200 | for (i = 0; (i < 255 && line[i] != 0); i++) | 207 | emptyline = GNUNET_NO; |
201 | if (line[i] != ' ' && line[i] != '\n' && line[i] != '\r') | 208 | } |
202 | emptyline = 0; | 209 | /* ignore empty lines */ |
203 | if (emptyline == 1) | 210 | if (GNUNET_YES == emptyline) |
204 | continue; | 211 | continue; |
212 | |||
205 | /* remove tailing whitespace */ | 213 | /* remove tailing whitespace */ |
206 | for (i = strlen (line) - 1; (i >= 0) && (isspace ((unsigned char) line[i])); | 214 | for (i = line_size - 1; (i >= 1) && (isspace ((unsigned char) line[i]));i--) |
207 | i--) | ||
208 | line[i] = '\0'; | 215 | line[i] = '\0'; |
209 | if (1 == SSCANF (line, "@INLINE@ %191[^\n]", value)) | 216 | |
217 | /* handle special "@INLINE@" directive */ | ||
218 | if (0 == strncasecmp (line, | ||
219 | "@INLINE@ ", | ||
220 | strlen ("@INLINE@ "))) | ||
210 | { | 221 | { |
211 | /* @INLINE@ value */ | 222 | /* @INLINE@ value */ |
223 | value = &line[strlen ("@INLINE@ ")]; | ||
212 | if (GNUNET_YES == allow_inline) | 224 | if (GNUNET_YES == allow_inline) |
213 | { | 225 | { |
214 | if (GNUNET_OK != GNUNET_CONFIGURATION_parse (cfg, value)) | 226 | if (GNUNET_OK != GNUNET_CONFIGURATION_parse (cfg, value)) |
227 | { | ||
215 | ret = GNUNET_SYSERR; /* failed to parse included config */ | 228 | ret = GNUNET_SYSERR; /* failed to parse included config */ |
229 | break; | ||
230 | } | ||
216 | } | 231 | } |
217 | else | 232 | else |
233 | { | ||
218 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 234 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
219 | "Ignoring parsing INLINE configurations as allow_inline is false\n"); | 235 | "Ignoring parsing @INLINE@ configurations, not allowed!\n"); |
236 | ret = GNUNET_SYSERR; | ||
237 | break; | ||
238 | } | ||
239 | continue; | ||
220 | } | 240 | } |
221 | else if (1 == SSCANF (line, "[%99[^]]]", value)) | 241 | if ( ('[' == line[0]) && (']' == line[line_size - 1]) ) |
222 | { | 242 | { |
223 | /* [value] */ | 243 | /* [value] */ |
244 | line[line_size - 1] = '\0'; | ||
245 | value = &line[1]; | ||
224 | GNUNET_free (section); | 246 | GNUNET_free (section); |
225 | section = GNUNET_strdup (value); | 247 | section = GNUNET_strdup (value); |
226 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Config section `%s'\n", section); | 248 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
249 | "Config section `%s'\n", | ||
250 | section); | ||
251 | continue; | ||
227 | } | 252 | } |
228 | else if (2 == SSCANF (line, " %63[^= ] = %191[^\n]", tag, value)) | 253 | if (NULL != (eq = strchr (line, '='))) |
229 | { | 254 | { |
230 | /* tag = value */ | 255 | /* tag = value */ |
231 | /* Strip LF */ | 256 | tag = GNUNET_strndup (line, eq - line); |
232 | i = strlen (value) - 1; | 257 | /* remove tailing whitespace */ |
233 | while ((i >= 0) && (isspace ((unsigned char) value[i]))) | 258 | for (i = strlen (tag) - 1; (i >= 1) && (isspace ((unsigned char) tag[i]));i--) |
234 | value[i--] = '\0'; | 259 | tag[i] = '\0'; |
260 | |||
261 | /* Strip whitespace */ | ||
262 | value = eq + 1; | ||
263 | while (isspace ((unsigned char) value[0])) | ||
264 | value++; | ||
265 | for (i = strlen (value) - 1; (i >= 1) && (isspace ((unsigned char) value[i]));i--) | ||
266 | value[i] = '\0'; | ||
267 | |||
235 | /* remove quotes */ | 268 | /* remove quotes */ |
236 | i = 0; | 269 | i = 0; |
237 | if (value[0] == '"') | 270 | if ( ('"' == value[0]) && |
271 | ('"' == value[strlen (value) - 1]) ) | ||
238 | { | 272 | { |
239 | i = 1; | 273 | value[strlen (value) - 1] = '\0'; |
240 | while ((value[i] != '\0') && (value[i] != '"')) | 274 | value++; |
241 | i++; | ||
242 | if (value[i] == '"') | ||
243 | { | ||
244 | value[i] = '\0'; | ||
245 | i = 1; | ||
246 | } | ||
247 | else | ||
248 | i = 0; | ||
249 | } | 275 | } |
250 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Config value %s=%s\n", tag, value); | 276 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Config value %s=\"%s\"\n", tag, value); |
251 | GNUNET_CONFIGURATION_set_value_string (cfg, section, tag, &value[i]); | 277 | GNUNET_CONFIGURATION_set_value_string (cfg, section, tag, &value[i]); |
278 | continue; | ||
252 | } | 279 | } |
253 | else if (1 == SSCANF (line, " %63[^= ] =[^\n]", tag)) | 280 | /* parse error */ |
254 | { | 281 | LOG (GNUNET_ERROR_TYPE_WARNING, |
255 | /* tag = */ | 282 | _("Syntax error while deserializing in line %u\n"), |
256 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Config value %s is empty\n", tag); | 283 | nr); |
257 | GNUNET_CONFIGURATION_set_value_string (cfg, section, tag, ""); | 284 | ret = GNUNET_SYSERR; |
258 | } | 285 | break; |
259 | else | ||
260 | { | ||
261 | /* parse error */ | ||
262 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
263 | _("Syntax error while deserializing operation at line %u\n"), nr); | ||
264 | ret = GNUNET_SYSERR; | ||
265 | break; | ||
266 | } | ||
267 | } | 286 | } |
268 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Finished deserializing config\n", tag); | 287 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Finished deserializing config\n", tag); |
269 | GNUNET_free (section); | 288 | GNUNET_free (section); |
270 | GNUNET_assert (r_bytes == size); | 289 | GNUNET_assert ( (GNUNET_OK != ret) || (r_bytes == size) ); |
271 | return ret; | 290 | return ret; |
272 | } | 291 | } |
273 | 292 | ||