+ GNUNET_free_non_null (line_orig);
+ GNUNET_free (section);
+ GNUNET_assert ((GNUNET_OK != ret) || (r_bytes == size));
+ return ret;
+}
+
+
+/**
+ * Parse a configuration file, add all of the options in the
+ * file to the configuration environment.
+ *
+ * @param cfg configuration to update
+ * @param filename name of the configuration file
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+ */
+int
+GNUNET_CONFIGURATION_parse (struct GNUNET_CONFIGURATION_Handle *cfg,
+ const char *filename)
+{
+ uint64_t fs64;
+ size_t fs;
+ char *fn;
+ char *mem;
+ char *endsep;
+ int dirty;
+ int ret;
+ ssize_t sret;
+
+ fn = GNUNET_STRINGS_filename_expand (filename);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Asked to parse config file `%s'\n", fn);
+ if (NULL == fn)
+ return GNUNET_SYSERR;
+ dirty = cfg->dirty; /* back up value! */
+ if (GNUNET_SYSERR ==
+ 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);
+ GNUNET_free (fn);
+ return GNUNET_SYSERR;
+ }
+ if (fs64 > SIZE_MAX)
+ {
+ GNUNET_break (0); /* File size is more than the heap size */
+ GNUNET_free (fn);
+ return GNUNET_SYSERR;
+ }
+ fs = fs64;
+ mem = GNUNET_malloc (fs);
+ sret = GNUNET_DISK_fn_read (fn, mem, fs);
+ if ((sret < 0) || (fs != (size_t) sret))
+ {
+ LOG (GNUNET_ERROR_TYPE_WARNING, _ ("Error while reading file `%s'\n"), fn);
+ GNUNET_free (fn);
+ GNUNET_free (mem);
+ return GNUNET_SYSERR;
+ }
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Deserializing contents of file `%s'\n", fn);
+ endsep = strrchr (fn, (int) '/');
+ if (NULL != endsep)
+ *endsep = '\0';
+ ret = GNUNET_CONFIGURATION_deserialize (cfg, mem, fs, fn);
+ GNUNET_free (fn);
+ GNUNET_free (mem);