Consistently use readonly_config_filename for loading

This commit is contained in:
Christian Dywan 2012-09-18 00:13:15 +02:00
parent 13b735e382
commit d88b9776f2
4 changed files with 76 additions and 77 deletions

View file

@ -45,7 +45,7 @@ namespace Midori {
public HSTS (owned string filename) { public HSTS (owned string filename) {
whitelist = new HashTable<string, Directive> (str_hash, str_equal); whitelist = new HashTable<string, Directive> (str_hash, str_equal);
read_cache (File.new_for_path (Paths.get_config_filename (null, "hsts"))); read_cache (File.new_for_path (Paths.get_preset_filename (null, "hsts")));
file = File.new_for_path (filename); file = File.new_for_path (filename);
read_cache (file); read_cache (file);
if (strcmp (Environment.get_variable ("MIDORI_DEBUG"), "hsts") == 0) if (strcmp (Environment.get_variable ("MIDORI_DEBUG"), "hsts") == 0)

View file

@ -19,6 +19,7 @@ extern const string LIBDIR;
extern const string MDATADIR; extern const string MDATADIR;
extern const string PACKAGE_NAME; extern const string PACKAGE_NAME;
extern const string SYSCONFDIR; extern const string SYSCONFDIR;
extern const string MIDORI_VERSION_SUFFIX;
namespace Midori { namespace Midori {
public enum RuntimeMode { public enum RuntimeMode {
@ -35,18 +36,25 @@ namespace Midori {
static RuntimeMode mode = RuntimeMode.UNDEFINED; static RuntimeMode mode = RuntimeMode.UNDEFINED;
static string? config_dir = null; static string? config_dir = null;
static string? readonly_dir = null;
static string? cache_dir = null; static string? cache_dir = null;
static string? user_data_dir = null; static string? user_data_dir = null;
static string? tmp_dir = null; static string? tmp_dir = null;
public static string get_readonly_config_dir (RuntimeMode new_mode) { public static string get_readonly_config_dir () {
assert (mode == RuntimeMode.UNDEFINED); assert (mode != RuntimeMode.UNDEFINED);
if (new_mode == RuntimeMode.PORTABLE) { return readonly_dir ?? config_dir;
return Path.build_path (Path.DIR_SEPARATOR_S, }
exec_path, "profile", "config");
} public static string get_readonly_config_filename (string filename) {
assert (mode != RuntimeMode.UNDEFINED);
return Path.build_path (Path.DIR_SEPARATOR_S, return Path.build_path (Path.DIR_SEPARATOR_S,
Environment.get_user_config_dir (), PACKAGE_NAME); readonly_dir ?? config_dir, filename);
}
public bool is_readonly () {
assert (mode != RuntimeMode.UNDEFINED);
return readonly_dir != null;
} }
public static void init (RuntimeMode new_mode, string? config_base) { public static void init (RuntimeMode new_mode, string? config_base) {
@ -64,18 +72,19 @@ namespace Midori {
exec_path, "profile", "tmp"); exec_path, "profile", "tmp");
} }
else if (mode == RuntimeMode.PRIVATE || mode == RuntimeMode.APP) { else if (mode == RuntimeMode.PRIVATE || mode == RuntimeMode.APP) {
config_dir = "private-or-app://"; /* Use mock folders in development builds */
cache_dir = "private-or-app://"; if ("." in MIDORI_VERSION_SUFFIX)
user_data_dir = "private-or-app://"; config_dir = cache_dir = user_data_dir = config_base;
else
config_dir = cache_dir = user_data_dir = "/";
readonly_dir = config_base ?? Path.build_path (Path.DIR_SEPARATOR_S,
Environment.get_user_config_dir (), PACKAGE_NAME);
tmp_dir = Path.build_path (Path.DIR_SEPARATOR_S, tmp_dir = Path.build_path (Path.DIR_SEPARATOR_S,
Environment.get_tmp_dir (), "midori-" + Environment.get_user_name ()); Environment.get_tmp_dir (), "midori-" + Environment.get_user_name ());
} }
else { else {
if (config_base != null) config_dir = config_base ?? Path.build_path (Path.DIR_SEPARATOR_S,
config_dir = config_base; Environment.get_user_config_dir (), PACKAGE_NAME);
else
config_dir = Path.build_path (Path.DIR_SEPARATOR_S,
Environment.get_user_config_dir (), PACKAGE_NAME);
cache_dir = Path.build_path (Path.DIR_SEPARATOR_S, cache_dir = Path.build_path (Path.DIR_SEPARATOR_S,
Environment.get_user_cache_dir (), PACKAGE_NAME); Environment.get_user_cache_dir (), PACKAGE_NAME);
user_data_dir = Environment.get_user_data_dir (); user_data_dir = Environment.get_user_data_dir ();
@ -88,15 +97,17 @@ namespace Midori {
} }
} }
public bool is_readonly () {
return mode == RuntimeMode.APP || mode == RuntimeMode.PRIVATE;
}
public static unowned string get_config_dir () { public static unowned string get_config_dir () {
assert (config_dir != null); assert (config_dir != null);
return config_dir; return config_dir;
} }
public static string get_config_filename (string filename) {
assert (mode != RuntimeMode.UNDEFINED);
assert (config_dir != null);
return Path.build_path (Path.DIR_SEPARATOR_S, config_dir, filename);
}
public static unowned string get_cache_dir () { public static unowned string get_cache_dir () {
assert (cache_dir != null); assert (cache_dir != null);
return cache_dir; return cache_dir;
@ -214,7 +225,7 @@ namespace Midori {
#endif #endif
} }
public static string get_config_filename (string? folder, string filename) { public static string get_preset_filename (string? folder, string filename) {
assert (config_dir != null); assert (config_dir != null);
#if HAVE_WIN32 #if HAVE_WIN32

View file

@ -52,18 +52,11 @@
#include <gdk/gdkx.h> #include <gdk/gdkx.h>
#endif #endif
static gchar*
build_config_filename (const gchar* filename)
{
return g_build_filename (midori_paths_get_config_dir (), filename, NULL);
}
static MidoriWebSettings* static MidoriWebSettings*
settings_and_accels_new (const gchar* config, settings_and_accels_new (gchar*** extensions)
gchar*** extensions)
{ {
MidoriWebSettings* settings = midori_web_settings_new (); MidoriWebSettings* settings = midori_web_settings_new ();
gchar* config_file = g_build_filename (config, "config", NULL); gchar* config_file = midori_paths_get_readonly_config_filename ("config");
GKeyFile* key_file = g_key_file_new (); GKeyFile* key_file = g_key_file_new ();
GError* error = NULL; GError* error = NULL;
GObjectClass* class; GObjectClass* class;
@ -83,7 +76,7 @@ settings_and_accels_new (const gchar* config,
if (error->code == G_FILE_ERROR_NOENT) if (error->code == G_FILE_ERROR_NOENT)
{ {
GError* inner_error = NULL; GError* inner_error = NULL;
katze_assign (config_file, midori_paths_get_config_filename (NULL, "config")); katze_assign (config_file, midori_paths_get_preset_filename (NULL, "config"));
g_key_file_load_from_file (key_file, config_file, g_key_file_load_from_file (key_file, config_file,
G_KEY_FILE_KEEP_COMMENTS, &inner_error); G_KEY_FILE_KEEP_COMMENTS, &inner_error);
if (inner_error != NULL) if (inner_error != NULL)
@ -156,9 +149,9 @@ settings_and_accels_new (const gchar* config,
g_key_file_free (key_file); g_key_file_free (key_file);
/* Load accelerators */ /* Load accelerators */
katze_assign (config_file, g_build_filename (config, "accels", NULL)); katze_assign (config_file, midori_paths_get_config_filename ("accels"));
if (g_access (config_file, F_OK) != 0) if (g_access (config_file, F_OK) != 0)
katze_assign (config_file, midori_paths_get_config_filename (NULL, "accels")); katze_assign (config_file, midori_paths_get_preset_filename (NULL, "accels"));
gtk_accel_map_load (config_file); gtk_accel_map_load (config_file);
g_free (config_file); g_free (config_file);
@ -336,10 +329,9 @@ search_engines_new_from_file (const gchar* filename,
} }
static KatzeArray* static KatzeArray*
search_engines_new_from_folder (const gchar* config, search_engines_new_from_folder (GString* error_messages)
GString* error_messages)
{ {
gchar* config_file = g_build_filename (config, "search", NULL); gchar* config_file = midori_paths_get_config_filename ("search");
GError* error = NULL; GError* error = NULL;
KatzeArray* search_engines; KatzeArray* search_engines;
@ -354,7 +346,7 @@ search_engines_new_from_folder (const gchar* config,
if (!error && katze_array_is_empty (search_engines)) if (!error && katze_array_is_empty (search_engines))
{ {
katze_assign (config_file, katze_assign (config_file,
midori_paths_get_config_filename (NULL, "search")); midori_paths_get_preset_filename (NULL, "search"));
katze_object_assign (search_engines, katze_object_assign (search_engines,
search_engines_new_from_file (config_file, NULL)); search_engines_new_from_file (config_file, NULL));
} }
@ -485,7 +477,7 @@ midori_history_initialize (KatzeArray* array,
"COMMIT;", "COMMIT;",
NULL, NULL, errmsg); NULL, NULL, errmsg);
bookmarks_filename = build_config_filename ("bookmarks_v2.db"); bookmarks_filename = midori_paths_get_config_filename ("bookmarks_v2.db");
sql = g_strdup_printf ("ATTACH DATABASE '%s' AS bookmarks", bookmarks_filename); sql = g_strdup_printf ("ATTACH DATABASE '%s' AS bookmarks", bookmarks_filename);
g_free (bookmarks_filename); g_free (bookmarks_filename);
sqlite3_exec (db, sql, NULL, NULL, errmsg); sqlite3_exec (db, sql, NULL, NULL, errmsg);
@ -529,7 +521,7 @@ settings_notify_cb (MidoriWebSettings* settings,
if (pspec && midori_settings_delay_saving (MIDORI_SETTINGS (settings), pspec->name)) if (pspec && midori_settings_delay_saving (MIDORI_SETTINGS (settings), pspec->name))
return; return;
config_file = build_config_filename ("config"); config_file = midori_paths_get_config_filename ("config");
if (!settings_save_to_file (settings, app, config_file, &error)) if (!settings_save_to_file (settings, app, config_file, &error))
{ {
g_warning (_("The configuration couldn't be saved. %s"), error->message); g_warning (_("The configuration couldn't be saved. %s"), error->message);
@ -544,7 +536,7 @@ accel_map_changed_cb (GtkAccelMap* accel_map,
guint accel_key, guint accel_key,
GdkModifierType accel_mods) GdkModifierType accel_mods)
{ {
gchar* config_file = build_config_filename ("accels"); gchar* config_file = midori_paths_get_config_filename ("accels");
gtk_accel_map_save (config_file); gtk_accel_map_save (config_file);
g_free (config_file); g_free (config_file);
} }
@ -554,7 +546,7 @@ midori_search_engines_modify_cb (KatzeArray* array,
gpointer item, gpointer item,
KatzeArray* search_engines) KatzeArray* search_engines)
{ {
gchar* config_file = build_config_filename ("search"); gchar* config_file = midori_paths_get_config_filename ("search");
GError* error = NULL; GError* error = NULL;
if (!search_engines_save_to_file (search_engines, config_file, &error)) if (!search_engines_save_to_file (search_engines, config_file, &error))
{ {
@ -589,7 +581,7 @@ static void
midori_trash_remove_item_cb (KatzeArray* trash, midori_trash_remove_item_cb (KatzeArray* trash,
GObject* item) GObject* item)
{ {
gchar* config_file = build_config_filename ("tabtrash.xbel"); gchar* config_file = midori_paths_get_config_filename ("tabtrash.xbel");
GError* error = NULL; GError* error = NULL;
midori_trash_add_item_no_save_cb (trash, item); midori_trash_add_item_no_save_cb (trash, item);
if (!midori_array_to_file (trash, config_file, "xbel", &error)) if (!midori_array_to_file (trash, config_file, "xbel", &error))
@ -760,7 +752,7 @@ static guint save_timeout = 0;
static gboolean static gboolean
midori_session_save_timeout_cb (KatzeArray* session) midori_session_save_timeout_cb (KatzeArray* session)
{ {
gchar* config_file = build_config_filename ("session.xbel"); gchar* config_file = midori_paths_get_config_filename ("session.xbel");
GError* error = NULL; GError* error = NULL;
if (!midori_array_to_file (session, config_file, "xbel", &error)) if (!midori_array_to_file (session, config_file, "xbel", &error))
{ {
@ -792,7 +784,7 @@ static void
midori_app_quit_cb (MidoriBrowser* browser, midori_app_quit_cb (MidoriBrowser* browser,
KatzeArray* session) KatzeArray* session)
{ {
gchar* config_file = build_config_filename ("running"); gchar* config_file = midori_paths_get_config_filename ("running");
g_unlink (config_file); g_unlink (config_file);
g_free (config_file); g_free (config_file);
@ -1035,8 +1027,8 @@ midori_load_soup_session (gpointer settings)
g_signal_connect (session, "request-queued", g_signal_connect (session, "request-queued",
G_CALLBACK (midori_soup_session_settings_accept_language_cb), settings); G_CALLBACK (midori_soup_session_settings_accept_language_cb), settings);
soup_session_add_feature (session, soup_session_add_feature (session, SOUP_SESSION_FEATURE (
SOUP_SESSION_FEATURE (midori_hsts_new (build_config_filename ("hsts")))); midori_hsts_new (midori_paths_get_readonly_config_filename ("hsts"))));
midori_soup_session_debug (session); midori_soup_session_debug (session);
@ -1169,7 +1161,7 @@ midori_load_soup_session_full (gpointer settings)
midori_load_soup_session (settings); midori_load_soup_session (settings);
config_file = build_config_filename ("logins"); config_file = midori_paths_get_config_filename ("logins");
feature = g_object_new (KATZE_TYPE_HTTP_AUTH, "filename", config_file, NULL); feature = g_object_new (KATZE_TYPE_HTTP_AUTH, "filename", config_file, NULL);
soup_session_add_feature (session, feature); soup_session_add_feature (session, feature);
g_object_unref (feature); g_object_unref (feature);
@ -1179,7 +1171,7 @@ midori_load_soup_session_full (gpointer settings)
soup_session_add_feature (session, SOUP_SESSION_FEATURE (jar)); soup_session_add_feature (session, SOUP_SESSION_FEATURE (jar));
g_object_unref (jar); g_object_unref (jar);
katze_assign (config_file, build_config_filename ("cookies.db")); katze_assign (config_file, midori_paths_get_config_filename ("cookies.db"));
have_new_cookies = g_access (config_file, F_OK) == 0; have_new_cookies = g_access (config_file, F_OK) == 0;
feature = g_object_new (KATZE_TYPE_HTTP_COOKIES_SQLITE, NULL); feature = g_object_new (KATZE_TYPE_HTTP_COOKIES_SQLITE, NULL);
g_object_set_data_full (G_OBJECT (feature), "filename", g_object_set_data_full (G_OBJECT (feature), "filename",
@ -1189,7 +1181,7 @@ midori_load_soup_session_full (gpointer settings)
if (!have_new_cookies) if (!have_new_cookies)
{ {
katze_assign (config_file, build_config_filename ("cookies.txt")); katze_assign (config_file, midori_paths_get_config_filename ("cookies.txt"));
if (g_access (config_file, F_OK) == 0) if (g_access (config_file, F_OK) == 0)
{ {
g_message ("Importing cookies from txt to sqlite3"); g_message ("Importing cookies from txt to sqlite3");
@ -1357,7 +1349,7 @@ midori_browser_action_last_session_activate_cb (GtkAction* action,
MidoriBrowser* browser) MidoriBrowser* browser)
{ {
KatzeArray* old_session = katze_array_new (KATZE_TYPE_ITEM); KatzeArray* old_session = katze_array_new (KATZE_TYPE_ITEM);
gchar* config_file = build_config_filename ("session.old.xbel"); gchar* config_file = midori_paths_get_readonly_config_filename ("session.old.xbel");
GError* error = NULL; GError* error = NULL;
if (midori_array_from_file (old_session, config_file, "xbel", &error)) if (midori_array_from_file (old_session, config_file, "xbel", &error))
{ {
@ -1399,7 +1391,7 @@ midori_load_session (gpointer data)
g_signal_connect_after (katze_object_get_object (app, "settings"), "notify", g_signal_connect_after (katze_object_get_object (app, "settings"), "notify",
G_CALLBACK (settings_notify_cb), app); G_CALLBACK (settings_notify_cb), app);
config_file = build_config_filename ("session.old.xbel"); config_file = midori_paths_get_readonly_config_filename ("session.old.xbel");
if (g_access (config_file, F_OK) == 0) if (g_access (config_file, F_OK) == 0)
{ {
GtkActionGroup* action_group = midori_browser_get_action_group (browser); GtkActionGroup* action_group = midori_browser_get_action_group (browser);
@ -1411,7 +1403,7 @@ midori_load_session (gpointer data)
midori_app_add_browser (app, browser); midori_app_add_browser (app, browser);
gtk_widget_show (GTK_WIDGET (browser)); gtk_widget_show (GTK_WIDGET (browser));
katze_assign (config_file, build_config_filename ("accels")); katze_assign (config_file, midori_paths_get_readonly_config_filename ("accels"));
g_signal_connect_after (gtk_accel_map_get (), "changed", g_signal_connect_after (gtk_accel_map_get (), "changed",
G_CALLBACK (accel_map_changed_cb), NULL); G_CALLBACK (accel_map_changed_cb), NULL);
@ -1455,7 +1447,7 @@ midori_load_session (gpointer data)
g_object_unref (settings); g_object_unref (settings);
g_object_unref (_session); g_object_unref (_session);
katze_assign (config_file, build_config_filename ("session.xbel")); katze_assign (config_file, midori_paths_get_readonly_config_filename ("session.xbel"));
g_signal_connect_after (browser, "add-tab", g_signal_connect_after (browser, "add-tab",
G_CALLBACK (midori_browser_session_cb), session); G_CALLBACK (midori_browser_session_cb), session);
g_signal_connect_after (browser, "remove-tab", g_signal_connect_after (browser, "remove-tab",
@ -1530,7 +1522,7 @@ midori_remove_config_file (gint clear_prefs,
{ {
if ((clear_prefs & flag) == flag) if ((clear_prefs & flag) == flag)
{ {
gchar* config_file = build_config_filename (filename); gchar* config_file = midori_paths_get_config_filename (filename);
g_unlink (config_file); g_unlink (config_file);
g_free (config_file); g_free (config_file);
} }
@ -1934,17 +1926,7 @@ main (int argc,
g_free (old_config); g_free (old_config);
} }
/* Private browsing, window title, default config folder */ g_set_application_name (_("Midori"));
if (private)
{
if (!config && !webapp)
config = midori_paths_get_readonly_config_dir (MIDORI_RUNTIME_MODE_PRIVATE);
/* Mask the timezone, which can be read by Javascript */
g_setenv ("TZ", "UTC", TRUE);
}
else
g_set_application_name (_("Midori"));
/* Versioned prgname to override menuproxy blacklist */ /* Versioned prgname to override menuproxy blacklist */
g_set_prgname (PACKAGE_NAME "4"); g_set_prgname (PACKAGE_NAME "4");
@ -2123,11 +2105,18 @@ main (int argc,
midori_startup_timer ("Browser: \t%f"); midori_startup_timer ("Browser: \t%f");
if (config) if (private)
midori_paths_init (MIDORI_RUNTIME_MODE_PRIVATE, config);
else if (webapp)
midori_paths_init (MIDORI_RUNTIME_MODE_APP, config);
else
midori_paths_init (MIDORI_RUNTIME_MODE_NORMAL, config);
if (private || !webapp)
{ {
settings = settings_and_accels_new (config, &extensions); settings = settings_and_accels_new (&extensions);
g_strfreev (extensions); g_strfreev (extensions);
search_engines = search_engines_new_from_folder (config, NULL); search_engines = search_engines_new_from_folder (NULL);
g_object_set (browser, "search-engines", search_engines, NULL); g_object_set (browser, "search-engines", search_engines, NULL);
g_object_unref (search_engines); g_object_unref (search_engines);
} }
@ -2136,6 +2125,8 @@ main (int argc,
if (private) if (private)
{ {
/* Mask the timezone, which can be read by Javascript */
g_setenv ("TZ", "UTC", TRUE);
/* In-memory trash for re-opening closed tabs */ /* In-memory trash for re-opening closed tabs */
trash = katze_array_new (KATZE_TYPE_ITEM); trash = katze_array_new (KATZE_TYPE_ITEM);
g_signal_connect_after (trash, "add-item", g_signal_connect_after (trash, "add-item",
@ -2167,10 +2158,7 @@ main (int argc,
g_object_set (gtk_settings_get_default (), g_object_set (gtk_settings_get_default (),
"gtk-recent-files-max-age", 0, NULL); "gtk-recent-files-max-age", 0, NULL);
midori_paths_init (MIDORI_RUNTIME_MODE_PRIVATE, "private://");
} }
else if (webapp)
midori_paths_init (MIDORI_RUNTIME_MODE_APP, config ? config : "app://");
midori_load_soup_session (settings); midori_load_soup_session (settings);
if (block_uris) if (block_uris)
@ -2287,7 +2275,7 @@ main (int argc,
{ {
g_object_set (gtk_settings_get_default (), g_object_set (gtk_settings_get_default (),
"gtk-recent-files-max-age", 0, NULL); "gtk-recent-files-max-age", 0, NULL);
midori_paths_init (MIDORI_RUNTIME_MODE_PORTABLE, "portable://"); midori_paths_init (MIDORI_RUNTIME_MODE_PORTABLE, config);
} }
else else
midori_paths_init (MIDORI_RUNTIME_MODE_NORMAL, config); midori_paths_init (MIDORI_RUNTIME_MODE_NORMAL, config);
@ -2338,13 +2326,13 @@ main (int argc,
/* Load configuration file */ /* Load configuration file */
error_messages = g_string_new (NULL); error_messages = g_string_new (NULL);
error = NULL; error = NULL;
settings = settings_and_accels_new (config, &extensions); settings = settings_and_accels_new (&extensions);
g_object_set (settings, "enable-developer-extras", TRUE, NULL); g_object_set (settings, "enable-developer-extras", TRUE, NULL);
g_object_set (settings, "enable-html5-database", TRUE, NULL); g_object_set (settings, "enable-html5-database", TRUE, NULL);
midori_startup_timer ("Config and accels read: \t%f"); midori_startup_timer ("Config and accels read: \t%f");
/* Load search engines */ /* Load search engines */
search_engines = search_engines_new_from_folder (config, error_messages); search_engines = search_engines_new_from_folder (error_messages);
/* Pick first search engine as default if not set */ /* Pick first search engine as default if not set */
g_object_get (settings, "location-entry-search", &uri, NULL); g_object_get (settings, "location-entry-search", &uri, NULL);
if (!(uri && *uri) && !katze_array_is_empty (search_engines)) if (!(uri && *uri) && !katze_array_is_empty (search_engines))
@ -2373,7 +2361,7 @@ main (int argc,
#if HAVE_LIBXML #if HAVE_LIBXML
if (load_on_startup >= MIDORI_STARTUP_LAST_OPEN_PAGES) if (load_on_startup >= MIDORI_STARTUP_LAST_OPEN_PAGES)
{ {
katze_assign (config_file, build_config_filename ("session.xbel")); katze_assign (config_file, midori_paths_get_readonly_config_filename ("session.xbel"));
error = NULL; error = NULL;
if (!midori_array_from_file (_session, config_file, "xbel", &error)) if (!midori_array_from_file (_session, config_file, "xbel", &error))
{ {
@ -2588,7 +2576,7 @@ main (int argc,
load_on_startup = katze_object_get_int (settings, "load-on-startup"); load_on_startup = katze_object_get_int (settings, "load-on-startup");
if (load_on_startup < MIDORI_STARTUP_LAST_OPEN_PAGES) if (load_on_startup < MIDORI_STARTUP_LAST_OPEN_PAGES)
{ {
katze_assign (config_file, g_build_filename (config, "session.xbel", NULL)); katze_assign (config_file, midori_paths_get_config_filename ("session.xbel"));
g_unlink (config_file); g_unlink (config_file);
} }

View file

@ -321,7 +321,7 @@ midori_extension_activate_cb (MidoriExtension* extension,
folder = g_build_filename ("extensions", filename, NULL); folder = g_build_filename ("extensions", filename, NULL);
g_free (filename); g_free (filename);
katze_assign (config_file, katze_assign (config_file,
midori_paths_get_config_filename (folder, "config")); midori_paths_get_preset_filename (folder, "config"));
g_free (folder); g_free (folder);
g_key_file_load_from_file (extension->priv->key_file, config_file, g_key_file_load_from_file (extension->priv->key_file, config_file,
G_KEY_FILE_KEEP_COMMENTS, NULL); G_KEY_FILE_KEEP_COMMENTS, NULL);