+
+/**
+ * A callback function, compares entries from two configurations
+ * (default against a new configuration) and write the diffs in a
+ * diff-configuration object (the callback object).
+ *
+ * @param cls the diff configuration (`struct DiffHandle *`)
+ * @param section section for the value (of the default conf.)
+ * @param option option name of the value (of the default conf.)
+ * @param value value to copy (of the default conf.)
+ */
+static void
+compare_entries (void *cls,
+ const char *section,
+ const char *option,
+ const char *value)
+{
+ struct DiffHandle *dh = cls;
+ struct ConfigEntry *entNew;
+
+ entNew = find_entry (dh->cfg_default, section, option);
+ if ( (NULL != entNew) &&
+ (NULL != entNew->val) &&
+ (0 == strcmp (entNew->val, value)) )
+ return;
+ GNUNET_CONFIGURATION_set_value_string (dh->cfgDiff, section, option, value);
+}
+
+
+/**
+ * Compute configuration with only entries that have been changed
+ *
+ * @param cfg_default original configuration
+ * @param cfg_new new configuration
+ * @return configuration with only the differences, never NULL
+ */
+struct GNUNET_CONFIGURATION_Handle *
+GNUNET_CONFIGURATION_get_diff (const struct GNUNET_CONFIGURATION_Handle *cfg_default,
+ const struct GNUNET_CONFIGURATION_Handle *cfg_new)
+{
+ struct DiffHandle diffHandle;
+
+ diffHandle.cfgDiff = GNUNET_CONFIGURATION_create ();
+ diffHandle.cfg_default = cfg_default;
+ GNUNET_CONFIGURATION_iterate (cfg_new, &compare_entries, &diffHandle);
+ return diffHandle.cfgDiff;
+}
+
+
+/**
+ * Write only configuration entries that have been changed to configuration file
+ *
+ * @param cfg_default default configuration
+ * @param cfg_new new configuration
+ * @param filename where to write the configuration diff between default and new
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+ */
+int
+GNUNET_CONFIGURATION_write_diffs (const struct GNUNET_CONFIGURATION_Handle
+ *cfg_default,
+ const struct GNUNET_CONFIGURATION_Handle
+ *cfg_new, const char *filename)
+{
+ int ret;
+ struct GNUNET_CONFIGURATION_Handle *diff;
+
+ diff = GNUNET_CONFIGURATION_get_diff (cfg_default, cfg_new);
+ ret = GNUNET_CONFIGURATION_write (diff, filename);
+ GNUNET_CONFIGURATION_destroy (diff);
+ return ret;
+}
+
+
+/**
+ * Set a configuration value that should be a string.
+ *
+ * @param cfg configuration to update
+ * @param section section of interest
+ * @param option option of interest
+ * @param value value to set
+ */