aboutsummaryrefslogtreecommitdiff
path: root/src/util/configuration.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-12-08 20:19:08 +0000
committerChristian Grothoff <christian@grothoff.org>2012-12-08 20:19:08 +0000
commit99c8e541e650a32caee7862989e6741509640755 (patch)
treea95c096644928eab2fc0e9ae00ea0203a73f9724 /src/util/configuration.c
parent33ead6c4ef534690c738a16f5467f2e4fa1ed9c9 (diff)
downloadgnunet-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.c141
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