| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright © 2010 Codethink Limited | 
					
						
							|  |  |  |  * Copyright © 2010 Novell, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2022-05-18 09:12:45 +01:00
										 |  |  |  * SPDX-License-Identifier: LGPL-2.1-or-later | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  |  * This library is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU Lesser General Public | 
					
						
							|  |  |  |  * License as published by the Free Software Foundation; either | 
					
						
							| 
									
										
										
										
											2017-05-27 18:21:30 +02:00
										 |  |  |  * version 2.1 of the License, or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  |  * | 
					
						
							|  |  |  |  * This library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
					
						
							|  |  |  |  * Lesser General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Lesser General Public | 
					
						
							| 
									
										
										
										
											2014-01-23 12:58:29 +01:00
										 |  |  |  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Authors: Vincent Untz <vuntz@gnome.org> | 
					
						
							|  |  |  |  *          Ryan Lortie <desrt@desrt.ca> | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "config.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  | #include <glib.h>
 | 
					
						
							|  |  |  | #include <glibintl.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "gfile.h"
 | 
					
						
							|  |  |  | #include "gfileinfo.h"
 | 
					
						
							| 
									
										
										
										
											2018-11-05 16:07:55 -05:00
										 |  |  | #include "gfileenumerator.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | #include "gfilemonitor.h"
 | 
					
						
							| 
									
										
										
										
											2010-06-04 23:07:40 +02:00
										 |  |  | #include "gsimplepermission.h"
 | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  | #include "gsettingsbackendinternal.h"
 | 
					
						
							| 
									
										
										
										
											2018-12-19 20:03:29 -05:00
										 |  |  | #include "giomodule-priv.h"
 | 
					
						
							| 
									
										
										
										
											2018-11-02 23:00:49 -04:00
										 |  |  | #include "gportalsupport.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | #define G_TYPE_KEYFILE_SETTINGS_BACKEND      (g_keyfile_settings_backend_get_type ())
 | 
					
						
							|  |  |  | #define G_KEYFILE_SETTINGS_BACKEND(inst)     (G_TYPE_CHECK_INSTANCE_CAST ((inst),      \
 | 
					
						
							|  |  |  |                                               G_TYPE_KEYFILE_SETTINGS_BACKEND,         \ | 
					
						
							|  |  |  |                                               GKeyfileSettingsBackend)) | 
					
						
							|  |  |  | #define G_IS_KEYFILE_SETTINGS_BACKEND(inst)  (G_TYPE_CHECK_INSTANCE_TYPE ((inst),      \
 | 
					
						
							|  |  |  |                                               G_TYPE_KEYFILE_SETTINGS_BACKEND)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef GSettingsBackendClass GKeyfileSettingsBackendClass; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-05 16:07:55 -05:00
										 |  |  | typedef enum { | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  |   PROP_FILENAME = 1, | 
					
						
							|  |  |  |   PROP_ROOT_PATH, | 
					
						
							| 
									
										
										
										
											2018-11-05 16:07:55 -05:00
										 |  |  |   PROP_ROOT_GROUP, | 
					
						
							|  |  |  |   PROP_DEFAULTS_DIR | 
					
						
							|  |  |  | } GKeyfileSettingsBackendProperty; | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | typedef struct | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GSettingsBackend   parent_instance; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   GKeyFile          *keyfile; | 
					
						
							|  |  |  |   GPermission       *permission; | 
					
						
							|  |  |  |   gboolean           writable; | 
					
						
							| 
									
										
										
										
											2018-11-05 16:07:55 -05:00
										 |  |  |   char              *defaults_dir; | 
					
						
							|  |  |  |   GKeyFile          *system_keyfile; | 
					
						
							|  |  |  |   GHashTable        *system_locks; /* Used as a set, owning the strings it contains */ | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   gchar             *prefix; | 
					
						
							| 
									
										
										
										
											2021-04-15 11:00:18 +02:00
										 |  |  |   gsize              prefix_len; | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   gchar             *root_group; | 
					
						
							| 
									
										
										
										
											2021-04-15 11:00:18 +02:00
										 |  |  |   gsize              root_group_len; | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   GFile             *file; | 
					
						
							|  |  |  |   GFileMonitor      *file_monitor; | 
					
						
							|  |  |  |   guint8             digest[32]; | 
					
						
							|  |  |  |   GFile             *dir; | 
					
						
							|  |  |  |   GFileMonitor      *dir_monitor; | 
					
						
							|  |  |  | } GKeyfileSettingsBackend; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-02 23:00:49 -04:00
										 |  |  | #ifdef G_OS_WIN32
 | 
					
						
							|  |  |  | #define EXTENSION_PRIORITY 10
 | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2019-07-12 11:31:37 -04:00
										 |  |  | #define EXTENSION_PRIORITY (glib_should_use_portal () && !glib_has_dconf_access_in_sandbox () ? 110 : 10)
 | 
					
						
							| 
									
										
										
										
											2018-11-02 23:00:49 -04:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-19 20:03:29 -05:00
										 |  |  | G_DEFINE_TYPE_WITH_CODE (GKeyfileSettingsBackend, | 
					
						
							|  |  |  |                          g_keyfile_settings_backend, | 
					
						
							|  |  |  |                          G_TYPE_SETTINGS_BACKEND, | 
					
						
							|  |  |  |                          _g_io_modules_ensure_extension_points_registered (); | 
					
						
							|  |  |  |                          g_io_extension_point_implement (G_SETTINGS_BACKEND_EXTENSION_POINT_NAME, | 
					
						
							| 
									
										
										
										
											2018-11-02 23:00:49 -04:00
										 |  |  |                                                          g_define_type_id, "keyfile", EXTENSION_PRIORITY)) | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | static void | 
					
						
							|  |  |  | compute_checksum (guint8        *digest, | 
					
						
							|  |  |  |                   gconstpointer  contents, | 
					
						
							|  |  |  |                   gsize          length) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GChecksum *checksum; | 
					
						
							|  |  |  |   gsize len = 32; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   checksum = g_checksum_new (G_CHECKSUM_SHA256); | 
					
						
							|  |  |  |   g_checksum_update (checksum, contents, length); | 
					
						
							|  |  |  |   g_checksum_get_digest (checksum, digest, &len); | 
					
						
							|  |  |  |   g_checksum_free (checksum); | 
					
						
							|  |  |  |   g_assert (len == 32); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-23 16:43:12 -06:00
										 |  |  | static gboolean | 
					
						
							|  |  |  | g_keyfile_settings_backend_keyfile_write (GKeyfileSettingsBackend  *kfsb, | 
					
						
							|  |  |  |                                           GError                  **error) | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | { | 
					
						
							|  |  |  |   gchar *contents; | 
					
						
							|  |  |  |   gsize length; | 
					
						
							| 
									
										
										
										
											2020-11-23 16:43:12 -06:00
										 |  |  |   gboolean success; | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   contents = g_key_file_to_data (kfsb->keyfile, &length, NULL); | 
					
						
							| 
									
										
										
										
											2020-11-23 16:43:12 -06:00
										 |  |  |   success = g_file_replace_contents (kfsb->file, contents, length, NULL, FALSE, | 
					
						
							|  |  |  |                                      G_FILE_CREATE_REPLACE_DESTINATION | | 
					
						
							|  |  |  |                                      G_FILE_CREATE_PRIVATE, | 
					
						
							|  |  |  |                                      NULL, NULL, error); | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   compute_checksum (kfsb->digest, contents, length); | 
					
						
							|  |  |  |   g_free (contents); | 
					
						
							| 
									
										
										
										
											2020-11-23 16:43:12 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return success; | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static gboolean | 
					
						
							|  |  |  | group_name_matches (const gchar *group_name, | 
					
						
							|  |  |  |                     const gchar *prefix) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   /* sort of like g_str_has_prefix() except that it must be an exact
 | 
					
						
							|  |  |  |    * match or the prefix followed by '/'. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * for example 'a' is a prefix of 'a' and 'a/b' but not 'ab'. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   gint i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (i = 0; prefix[i]; i++) | 
					
						
							|  |  |  |     if (prefix[i] != group_name[i]) | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return group_name[i] == '\0' || group_name[i] == '/'; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static gboolean | 
					
						
							|  |  |  | convert_path (GKeyfileSettingsBackend  *kfsb, | 
					
						
							|  |  |  |               const gchar              *key, | 
					
						
							|  |  |  |               gchar                   **group, | 
					
						
							|  |  |  |               gchar                   **basename) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-04 13:58:32 +00:00
										 |  |  |   gsize key_len = strlen (key); | 
					
						
							|  |  |  |   const gchar *last_slash; | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (key_len < kfsb->prefix_len || | 
					
						
							|  |  |  |       memcmp (key, kfsb->prefix, kfsb->prefix_len) != 0) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   key_len -= kfsb->prefix_len; | 
					
						
							|  |  |  |   key += kfsb->prefix_len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-04 13:58:32 +00:00
										 |  |  |   last_slash = strrchr (key, '/'); | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-10 21:19:30 +00:00
										 |  |  |   /* Disallow empty group names or key names */ | 
					
						
							|  |  |  |   if (key_len == 0 || | 
					
						
							|  |  |  |       (last_slash != NULL && | 
					
						
							|  |  |  |        (*(last_slash + 1) == '\0' || | 
					
						
							|  |  |  |         last_slash == key))) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   if (kfsb->root_group) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       /* if a root_group was specified, make sure the user hasn't given
 | 
					
						
							|  |  |  |        * a path that ghosts that group name | 
					
						
							|  |  |  |        */ | 
					
						
							| 
									
										
										
										
											2021-04-15 11:00:18 +02:00
										 |  |  |       if (last_slash != NULL && last_slash - key >= 0 && | 
					
						
							|  |  |  |           (gsize) (last_slash - key) == kfsb->root_group_len && | 
					
						
							|  |  |  |           memcmp (key, kfsb->root_group, last_slash - key) == 0) | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |         return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       /* if no root_group was given, ensure that the user gave a path */ | 
					
						
							| 
									
										
										
										
											2021-02-04 13:58:32 +00:00
										 |  |  |       if (last_slash == NULL) | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |         return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (group) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-02-04 13:58:32 +00:00
										 |  |  |       if (last_slash != NULL) | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2021-02-04 13:58:32 +00:00
										 |  |  |           *group = g_memdup2 (key, (last_slash - key) + 1); | 
					
						
							|  |  |  |           (*group)[(last_slash - key)] = '\0'; | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |         } | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         *group = g_strdup (kfsb->root_group); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (basename) | 
					
						
							| 
									
										
										
										
											2021-02-10 21:16:39 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |       if (last_slash != NULL) | 
					
						
							|  |  |  |         *basename = g_memdup2 (last_slash + 1, key_len - (last_slash - key)); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         *basename = g_strdup (key); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-16 21:24:45 -04:00
										 |  |  | static gboolean | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | path_is_valid (GKeyfileSettingsBackend *kfsb, | 
					
						
							|  |  |  |                const gchar             *path) | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   return convert_path (kfsb, path, NULL, NULL); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | static GVariant * | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | get_from_keyfile (GKeyfileSettingsBackend *kfsb, | 
					
						
							|  |  |  |                   const GVariantType      *type, | 
					
						
							|  |  |  |                   const gchar             *key) | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   GVariant *return_value = NULL; | 
					
						
							|  |  |  |   gchar *group, *name; | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   if (convert_path (kfsb, key, &group, &name)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       gchar *str; | 
					
						
							| 
									
										
										
										
											2018-11-05 16:07:55 -05:00
										 |  |  |       gchar *sysstr; | 
					
						
							| 
									
										
										
										
											2010-04-25 22:00:28 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |       g_assert (*name); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-05 16:07:55 -05:00
										 |  |  |       sysstr = g_key_file_get_value (kfsb->system_keyfile, group, name, NULL); | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |       str = g_key_file_get_value (kfsb->keyfile, group, name, NULL); | 
					
						
							| 
									
										
										
										
											2018-11-05 16:07:55 -05:00
										 |  |  |       if (sysstr && | 
					
						
							|  |  |  |           (g_hash_table_contains (kfsb->system_locks, key) || | 
					
						
							|  |  |  |            str == NULL)) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           g_free (str); | 
					
						
							|  |  |  |           str = g_steal_pointer (&sysstr); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |       if (str) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           return_value = g_variant_parse (type, str, NULL, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2019-01-23 15:14:58 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |           /* As a special case, support values of type %G_VARIANT_TYPE_STRING
 | 
					
						
							|  |  |  |            * not being quoted, since users keep forgetting to do it and then | 
					
						
							|  |  |  |            * getting confused. */ | 
					
						
							| 
									
										
										
										
											2019-01-21 22:55:45 -05:00
										 |  |  |           if (return_value == NULL && | 
					
						
							|  |  |  |               g_variant_type_equal (type, G_VARIANT_TYPE_STRING) && | 
					
						
							|  |  |  |               str[0] != '\"') | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |               GString *s = g_string_sized_new (strlen (str) + 2); | 
					
						
							|  |  |  |               char *p = str; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               g_string_append_c (s, '\"'); | 
					
						
							|  |  |  |               while (*p) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                   if (*p == '\"') | 
					
						
							|  |  |  |                     g_string_append_c (s, '\\'); | 
					
						
							|  |  |  |                   g_string_append_c (s, *p); | 
					
						
							|  |  |  |                   p++; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |               g_string_append_c (s, '\"'); | 
					
						
							|  |  |  |               return_value = g_variant_parse (type, s->str, NULL, NULL, NULL); | 
					
						
							|  |  |  |               g_string_free (s, TRUE); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |           g_free (str); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-05 16:07:55 -05:00
										 |  |  |       g_free (sysstr); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |       g_free (group); | 
					
						
							|  |  |  |       g_free (name); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return return_value; | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static gboolean | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | set_to_keyfile (GKeyfileSettingsBackend *kfsb, | 
					
						
							|  |  |  |                 const gchar             *key, | 
					
						
							|  |  |  |                 GVariant                *value) | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   gchar *group, *name; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-05 16:07:55 -05:00
										 |  |  |   if (g_hash_table_contains (kfsb->system_locks, key)) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   if (convert_path (kfsb, key, &group, &name)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (value) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           gchar *str = g_variant_print (value, FALSE); | 
					
						
							|  |  |  |           g_key_file_set_value (kfsb->keyfile, group, name, str); | 
					
						
							|  |  |  |           g_variant_unref (g_variant_ref_sink (value)); | 
					
						
							|  |  |  |           g_free (str); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           if (*name == '\0') | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |               gchar **groups; | 
					
						
							|  |  |  |               gint i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               groups = g_key_file_get_groups (kfsb->keyfile, NULL); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |               for (i = 0; groups[i]; i++) | 
					
						
							|  |  |  |                 if (group_name_matches (groups[i], group)) | 
					
						
							|  |  |  |                   g_key_file_remove_group (kfsb->keyfile, groups[i], NULL); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |               g_strfreev (groups); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           else | 
					
						
							|  |  |  |             g_key_file_remove_key (kfsb->keyfile, group, name, NULL); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |       g_free (group); | 
					
						
							|  |  |  |       g_free (name); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |       return TRUE; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | static GVariant * | 
					
						
							|  |  |  | g_keyfile_settings_backend_read (GSettingsBackend   *backend, | 
					
						
							|  |  |  |                                  const gchar        *key, | 
					
						
							|  |  |  |                                  const GVariantType *expected_type, | 
					
						
							|  |  |  |                                  gboolean            default_value) | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (backend); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (default_value) | 
					
						
							|  |  |  |     return NULL; | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   return get_from_keyfile (kfsb, expected_type, key); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | typedef struct | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GKeyfileSettingsBackend *kfsb; | 
					
						
							|  |  |  |   gboolean failed; | 
					
						
							|  |  |  | } WriteManyData; | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | static gboolean | 
					
						
							|  |  |  | g_keyfile_settings_backend_write_one (gpointer key, | 
					
						
							|  |  |  |                                       gpointer value, | 
					
						
							|  |  |  |                                       gpointer user_data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   WriteManyData *data = user_data; | 
					
						
							| 
									
										
										
										
											2019-03-05 12:22:51 +00:00
										 |  |  |   gboolean success G_GNUC_UNUSED  /* when compiling with G_DISABLE_ASSERT */; | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   success = set_to_keyfile (data->kfsb, key, value); | 
					
						
							|  |  |  |   g_assert (success); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   return FALSE; | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static gboolean | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | g_keyfile_settings_backend_check_one (gpointer key, | 
					
						
							|  |  |  |                                       gpointer value, | 
					
						
							|  |  |  |                                       gpointer user_data) | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   WriteManyData *data = user_data; | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  |   return data->failed = g_hash_table_contains (data->kfsb->system_locks, key) || | 
					
						
							|  |  |  |                         !path_is_valid (data->kfsb, key); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static gboolean | 
					
						
							| 
									
										
										
										
											2010-07-22 18:39:50 -04:00
										 |  |  | g_keyfile_settings_backend_write_tree (GSettingsBackend *backend, | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  |                                        GTree            *tree, | 
					
						
							|  |  |  |                                        gpointer          origin_tag) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-11-17 12:29:48 +01:00
										 |  |  |   WriteManyData data = { G_KEYFILE_SETTINGS_BACKEND (backend), 0 }; | 
					
						
							| 
									
										
										
										
											2020-11-23 16:43:12 -06:00
										 |  |  |   gboolean success; | 
					
						
							|  |  |  |   GError *error = NULL; | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (!data.kfsb->writable) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   g_tree_foreach (tree, g_keyfile_settings_backend_check_one, &data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (data.failed) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   g_tree_foreach (tree, g_keyfile_settings_backend_write_one, &data); | 
					
						
							| 
									
										
										
										
											2020-11-23 16:43:12 -06:00
										 |  |  |   success = g_keyfile_settings_backend_keyfile_write (data.kfsb, &error); | 
					
						
							|  |  |  |   if (error) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       g_warning ("Failed to write keyfile to %s: %s", g_file_peek_path (data.kfsb->file), error->message); | 
					
						
							|  |  |  |       g_error_free (error); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   g_settings_backend_changed_tree (backend, tree, origin_tag); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-23 16:43:12 -06:00
										 |  |  |   return success; | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | static gboolean | 
					
						
							|  |  |  | g_keyfile_settings_backend_write (GSettingsBackend *backend, | 
					
						
							|  |  |  |                                   const gchar      *key, | 
					
						
							|  |  |  |                                   GVariant         *value, | 
					
						
							|  |  |  |                                   gpointer          origin_tag) | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (backend); | 
					
						
							|  |  |  |   gboolean success; | 
					
						
							| 
									
										
										
										
											2020-11-23 16:43:12 -06:00
										 |  |  |   GError *error = NULL; | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   if (!kfsb->writable) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   success = set_to_keyfile (kfsb, key, value); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   if (success) | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |       g_settings_backend_changed (backend, key, origin_tag); | 
					
						
							| 
									
										
										
										
											2020-11-23 16:43:12 -06:00
										 |  |  |       success = g_keyfile_settings_backend_keyfile_write (kfsb, &error); | 
					
						
							|  |  |  |       if (error) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           g_warning ("Failed to write keyfile to %s: %s", g_file_peek_path (kfsb->file), error->message); | 
					
						
							|  |  |  |           g_error_free (error); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   return success; | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | static void | 
					
						
							|  |  |  | g_keyfile_settings_backend_reset (GSettingsBackend *backend, | 
					
						
							|  |  |  |                                   const gchar      *key, | 
					
						
							|  |  |  |                                   gpointer          origin_tag) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (backend); | 
					
						
							| 
									
										
										
										
											2020-11-23 16:43:12 -06:00
										 |  |  |   GError *error = NULL; | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   if (set_to_keyfile (kfsb, key, NULL)) | 
					
						
							| 
									
										
										
										
											2020-11-23 16:43:12 -06:00
										 |  |  |     { | 
					
						
							|  |  |  |       g_keyfile_settings_backend_keyfile_write (kfsb, &error); | 
					
						
							|  |  |  |       if (error) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           g_warning ("Failed to write keyfile to %s: %s", g_file_peek_path (kfsb->file), error->message); | 
					
						
							|  |  |  |           g_error_free (error); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   g_settings_backend_changed (backend, key, origin_tag); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static gboolean | 
					
						
							|  |  |  | g_keyfile_settings_backend_get_writable (GSettingsBackend *backend, | 
					
						
							|  |  |  |                                          const gchar      *name) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (backend); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-05 16:07:55 -05:00
										 |  |  |   return kfsb->writable && | 
					
						
							|  |  |  |          !g_hash_table_contains (kfsb->system_locks, name) && | 
					
						
							|  |  |  |          path_is_valid (kfsb, name); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-04 23:07:40 +02:00
										 |  |  | static GPermission * | 
					
						
							|  |  |  | g_keyfile_settings_backend_get_permission (GSettingsBackend *backend, | 
					
						
							|  |  |  |                                            const gchar      *path) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (backend); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return g_object_ref (kfsb->permission); | 
					
						
							| 
									
										
										
										
											2010-06-04 23:07:40 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | static void | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | keyfile_to_tree (GKeyfileSettingsBackend *kfsb, | 
					
						
							|  |  |  |                  GTree                   *tree, | 
					
						
							|  |  |  |                  GKeyFile                *keyfile, | 
					
						
							|  |  |  |                  gboolean                 dup_check) | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   gchar **groups; | 
					
						
							|  |  |  |   gint i; | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   groups = g_key_file_get_groups (keyfile, NULL); | 
					
						
							|  |  |  |   for (i = 0; groups[i]; i++) | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |       gboolean is_root_group; | 
					
						
							|  |  |  |       gchar **keys; | 
					
						
							|  |  |  |       gint j; | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |       is_root_group = g_strcmp0 (kfsb->root_group, groups[i]) == 0; | 
					
						
							| 
									
										
										
										
											2010-07-02 11:35:43 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |       /* reject group names that will form invalid key names */ | 
					
						
							|  |  |  |       if (!is_root_group && | 
					
						
							|  |  |  |           (g_str_has_prefix (groups[i], "/") || | 
					
						
							|  |  |  |            g_str_has_suffix (groups[i], "/") || strstr (groups[i], "//"))) | 
					
						
							|  |  |  |         continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |       keys = g_key_file_get_keys (keyfile, groups[i], NULL, NULL); | 
					
						
							| 
									
										
										
										
											2014-07-22 14:23:47 -04:00
										 |  |  |       g_assert (keys != NULL); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |       for (j = 0; keys[j]; j++) | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |           gchar *path, *value; | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-02 11:35:43 -04:00
										 |  |  |           /* reject key names with slashes in them */ | 
					
						
							|  |  |  |           if (strchr (keys[j], '/')) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |           if (is_root_group) | 
					
						
							|  |  |  |             path = g_strdup_printf ("%s%s", kfsb->prefix, keys[j]); | 
					
						
							|  |  |  |           else | 
					
						
							|  |  |  |             path = g_strdup_printf ("%s%s/%s", kfsb->prefix, groups[i], keys[j]); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |           value = g_key_file_get_value (keyfile, groups[i], keys[j], NULL); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |           if (dup_check && g_strcmp0 (g_tree_lookup (tree, path), value) == 0) | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |               g_tree_remove (tree, path); | 
					
						
							|  |  |  |               g_free (value); | 
					
						
							|  |  |  |               g_free (path); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  |             } | 
					
						
							|  |  |  |           else | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |             g_tree_insert (tree, path, value); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       g_strfreev (keys); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   g_strfreev (groups); | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | static void | 
					
						
							|  |  |  | g_keyfile_settings_backend_keyfile_reload (GKeyfileSettingsBackend *kfsb) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   guint8 digest[32]; | 
					
						
							|  |  |  |   gchar *contents; | 
					
						
							|  |  |  |   gsize length; | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   contents = NULL; | 
					
						
							|  |  |  |   length = 0; | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   g_file_load_contents (kfsb->file, NULL, &contents, &length, NULL, NULL); | 
					
						
							|  |  |  |   compute_checksum (digest, contents, length); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   if (memcmp (kfsb->digest, digest, sizeof digest) != 0) | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |       GKeyFile *keyfiles[2]; | 
					
						
							|  |  |  |       GTree *tree; | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |       tree = g_tree_new_full ((GCompareDataFunc) strcmp, NULL, | 
					
						
							|  |  |  |                               g_free, g_free); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |       keyfiles[0] = kfsb->keyfile; | 
					
						
							|  |  |  |       keyfiles[1] = g_key_file_new (); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |       if (length > 0) | 
					
						
							|  |  |  |         g_key_file_load_from_data (keyfiles[1], contents, length, | 
					
						
							|  |  |  |                                    G_KEY_FILE_KEEP_COMMENTS | | 
					
						
							|  |  |  |                                    G_KEY_FILE_KEEP_TRANSLATIONS, NULL); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |       keyfile_to_tree (kfsb, tree, keyfiles[0], FALSE); | 
					
						
							|  |  |  |       keyfile_to_tree (kfsb, tree, keyfiles[1], TRUE); | 
					
						
							|  |  |  |       g_key_file_free (keyfiles[0]); | 
					
						
							|  |  |  |       kfsb->keyfile = keyfiles[1]; | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |       if (g_tree_nnodes (tree) > 0) | 
					
						
							|  |  |  |         g_settings_backend_changed_tree (&kfsb->parent_instance, tree, NULL); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |       g_tree_unref (tree); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |       memcpy (kfsb->digest, digest, sizeof digest); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   g_free (contents); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | g_keyfile_settings_backend_keyfile_writable (GKeyfileSettingsBackend *kfsb) | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   GFileInfo *fileinfo; | 
					
						
							|  |  |  |   gboolean writable; | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   fileinfo = g_file_query_info (kfsb->dir, "access::*", 0, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   if (fileinfo) | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |       writable = | 
					
						
							|  |  |  |         g_file_info_get_attribute_boolean (fileinfo, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE) && | 
					
						
							|  |  |  |         g_file_info_get_attribute_boolean (fileinfo, G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE); | 
					
						
							|  |  |  |       g_object_unref (fileinfo); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   else | 
					
						
							|  |  |  |     writable = FALSE; | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   if (writable != kfsb->writable) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       kfsb->writable = writable; | 
					
						
							|  |  |  |       g_settings_backend_path_writable_changed (&kfsb->parent_instance, "/"); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_keyfile_settings_backend_finalize (GObject *object) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   g_key_file_free (kfsb->keyfile); | 
					
						
							|  |  |  |   g_object_unref (kfsb->permission); | 
					
						
							| 
									
										
										
										
											2018-11-05 16:07:55 -05:00
										 |  |  |   g_key_file_unref (kfsb->system_keyfile); | 
					
						
							|  |  |  |   g_hash_table_unref (kfsb->system_locks); | 
					
						
							|  |  |  |   g_free (kfsb->defaults_dir); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-23 16:31:26 -06:00
										 |  |  |   if (kfsb->file_monitor) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       g_file_monitor_cancel (kfsb->file_monitor); | 
					
						
							|  |  |  |       g_object_unref (kfsb->file_monitor); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   g_object_unref (kfsb->file); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-23 16:31:26 -06:00
										 |  |  |   if (kfsb->dir_monitor) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       g_file_monitor_cancel (kfsb->dir_monitor); | 
					
						
							|  |  |  |       g_object_unref (kfsb->dir_monitor); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   g_object_unref (kfsb->dir); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   g_free (kfsb->root_group); | 
					
						
							|  |  |  |   g_free (kfsb->prefix); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-23 16:31:26 -06:00
										 |  |  |   G_OBJECT_CLASS (g_keyfile_settings_backend_parent_class)->finalize (object); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | g_keyfile_settings_backend_init (GKeyfileSettingsBackend *kfsb) | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | static void | 
					
						
							|  |  |  | file_changed (GFileMonitor      *monitor, | 
					
						
							|  |  |  |               GFile             *file, | 
					
						
							|  |  |  |               GFile             *other_file, | 
					
						
							|  |  |  |               GFileMonitorEvent  event_type, | 
					
						
							|  |  |  |               gpointer           user_data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GKeyfileSettingsBackend *kfsb = user_data; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-27 17:26:33 -07:00
										 |  |  |   /* Ignore file deletions, let the GKeyFile content remain in tact. */ | 
					
						
							|  |  |  |   if (event_type != G_FILE_MONITOR_EVENT_DELETED) | 
					
						
							|  |  |  |     g_keyfile_settings_backend_keyfile_reload (kfsb); | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | static void | 
					
						
							|  |  |  | dir_changed (GFileMonitor       *monitor, | 
					
						
							|  |  |  |               GFile             *file, | 
					
						
							|  |  |  |               GFile             *other_file, | 
					
						
							|  |  |  |               GFileMonitorEvent  event_type, | 
					
						
							|  |  |  |               gpointer           user_data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GKeyfileSettingsBackend *kfsb = user_data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   g_keyfile_settings_backend_keyfile_writable (kfsb); | 
					
						
							| 
									
										
										
										
											2010-04-16 23:57:26 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-04-17 10:26:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-05 16:07:55 -05:00
										 |  |  | static void | 
					
						
							|  |  |  | load_system_settings (GKeyfileSettingsBackend *kfsb) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GError *error = NULL; | 
					
						
							|  |  |  |   const char *dir = "/etc/glib-2.0/settings"; | 
					
						
							|  |  |  |   char *path; | 
					
						
							|  |  |  |   char *contents; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   kfsb->system_keyfile = g_key_file_new (); | 
					
						
							|  |  |  |   kfsb->system_locks = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (kfsb->defaults_dir) | 
					
						
							|  |  |  |     dir = kfsb->defaults_dir; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   path = g_build_filename (dir, "defaults", NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* The defaults are in the same keyfile format that we use for the settings.
 | 
					
						
							|  |  |  |    * It can be produced from a dconf database using: dconf dump | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   if (!g_key_file_load_from_file (kfsb->system_keyfile, path, G_KEY_FILE_NONE, &error)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) | 
					
						
							|  |  |  |         g_warning ("Failed to read %s: %s", path, error->message); | 
					
						
							|  |  |  |       g_clear_error (&error); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     g_debug ("Loading default settings from %s", path); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   g_free (path); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   path = g_build_filename (dir, "locks", NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* The locks file is a text file containing a list paths to lock, one per line.
 | 
					
						
							|  |  |  |    * It can be produced from a dconf database using: dconf list-locks | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   if (!g_file_get_contents (path, &contents, NULL, &error)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) | 
					
						
							|  |  |  |         g_warning ("Failed to read %s: %s", path, error->message); | 
					
						
							|  |  |  |       g_clear_error (&error); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       char **lines; | 
					
						
							|  |  |  |       gsize i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       g_debug ("Loading locks from %s", path); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       lines = g_strsplit (contents, "\n", 0); | 
					
						
							|  |  |  |       for (i = 0; lines[i]; i++) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           char *line = lines[i]; | 
					
						
							|  |  |  |           if (line[0] == '#' || line[0] == '\0') | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |               g_free (line); | 
					
						
							|  |  |  |               continue; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           g_debug ("Locking key %s", line); | 
					
						
							|  |  |  |           g_hash_table_add (kfsb->system_locks, g_steal_pointer (&line)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       g_free (lines); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   g_free (contents); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   g_free (path); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  | static void | 
					
						
							|  |  |  | g_keyfile_settings_backend_constructed (GObject *object) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object); | 
					
						
							| 
									
										
										
										
											2021-02-23 16:31:26 -06:00
										 |  |  |   GError *error = NULL; | 
					
						
							| 
									
										
										
										
											2020-11-23 16:43:12 -06:00
										 |  |  |   const char *path; | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (kfsb->file == NULL) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       char *filename = g_build_filename (g_get_user_config_dir (), | 
					
						
							|  |  |  |                                          "glib-2.0", "settings", "keyfile", | 
					
						
							|  |  |  |                                          NULL); | 
					
						
							|  |  |  |       kfsb->file = g_file_new_for_path (filename); | 
					
						
							|  |  |  |       g_free (filename); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (kfsb->prefix == NULL) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       kfsb->prefix = g_strdup ("/"); | 
					
						
							|  |  |  |       kfsb->prefix_len = 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   kfsb->keyfile = g_key_file_new (); | 
					
						
							|  |  |  |   kfsb->permission = g_simple_permission_new (TRUE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   kfsb->dir = g_file_get_parent (kfsb->file); | 
					
						
							| 
									
										
										
										
											2020-11-23 16:43:12 -06:00
										 |  |  |   path = g_file_peek_path (kfsb->dir); | 
					
						
							|  |  |  |   if (g_mkdir_with_parents (path, 0700) == -1) | 
					
						
							|  |  |  |     g_warning ("Failed to create %s: %s", path, g_strerror (errno)); | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-23 16:31:26 -06:00
										 |  |  |   kfsb->file_monitor = g_file_monitor (kfsb->file, G_FILE_MONITOR_NONE, NULL, &error); | 
					
						
							|  |  |  |   if (!kfsb->file_monitor) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       g_warning ("Failed to create file monitor for %s: %s", g_file_peek_path (kfsb->file), error->message); | 
					
						
							|  |  |  |       g_clear_error (&error); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       g_signal_connect (kfsb->file_monitor, "changed", | 
					
						
							|  |  |  |                         G_CALLBACK (file_changed), kfsb); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-23 16:31:26 -06:00
										 |  |  |   kfsb->dir_monitor = g_file_monitor (kfsb->dir, G_FILE_MONITOR_NONE, NULL, &error); | 
					
						
							|  |  |  |   if (!kfsb->dir_monitor) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       g_warning ("Failed to create file monitor for %s: %s", g_file_peek_path (kfsb->file), error->message); | 
					
						
							|  |  |  |       g_clear_error (&error); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       g_signal_connect (kfsb->dir_monitor, "changed", | 
					
						
							|  |  |  |                         G_CALLBACK (dir_changed), kfsb); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-23 16:31:26 -06:00
										 |  |  |   compute_checksum (kfsb->digest, NULL, 0); | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |   g_keyfile_settings_backend_keyfile_writable (kfsb); | 
					
						
							|  |  |  |   g_keyfile_settings_backend_keyfile_reload (kfsb); | 
					
						
							| 
									
										
										
										
											2018-11-05 16:07:55 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |   load_system_settings (kfsb); | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_keyfile_settings_backend_set_property (GObject      *object, | 
					
						
							|  |  |  |                                          guint         prop_id, | 
					
						
							|  |  |  |                                          const GValue *value, | 
					
						
							|  |  |  |                                          GParamSpec   *pspec) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-05 16:07:55 -05:00
										 |  |  |   switch ((GKeyfileSettingsBackendProperty)prop_id) | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  |     { | 
					
						
							|  |  |  |     case PROP_FILENAME: | 
					
						
							|  |  |  |       /* Construct only. */ | 
					
						
							|  |  |  |       g_assert (kfsb->file == NULL); | 
					
						
							| 
									
										
										
										
											2019-07-10 11:14:03 -04:00
										 |  |  |       if (g_value_get_string (value)) | 
					
						
							|  |  |  |         kfsb->file = g_file_new_for_path (g_value_get_string (value)); | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case PROP_ROOT_PATH: | 
					
						
							|  |  |  |       /* Construct only. */ | 
					
						
							|  |  |  |       g_assert (kfsb->prefix == NULL); | 
					
						
							|  |  |  |       kfsb->prefix = g_value_dup_string (value); | 
					
						
							|  |  |  |       if (kfsb->prefix) | 
					
						
							|  |  |  |         kfsb->prefix_len = strlen (kfsb->prefix); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case PROP_ROOT_GROUP: | 
					
						
							|  |  |  |       /* Construct only. */ | 
					
						
							|  |  |  |       g_assert (kfsb->root_group == NULL); | 
					
						
							|  |  |  |       kfsb->root_group = g_value_dup_string (value); | 
					
						
							|  |  |  |       if (kfsb->root_group) | 
					
						
							|  |  |  |         kfsb->root_group_len = strlen (kfsb->root_group); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-05 16:07:55 -05:00
										 |  |  |     case PROP_DEFAULTS_DIR: | 
					
						
							|  |  |  |       /* Construct only. */ | 
					
						
							|  |  |  |       g_assert (kfsb->defaults_dir == NULL); | 
					
						
							|  |  |  |       kfsb->defaults_dir = g_value_dup_string (value); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  |     default: | 
					
						
							|  |  |  |       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_keyfile_settings_backend_get_property (GObject    *object, | 
					
						
							|  |  |  |                                          guint       prop_id, | 
					
						
							|  |  |  |                                          GValue     *value, | 
					
						
							|  |  |  |                                          GParamSpec *pspec) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GKeyfileSettingsBackend *kfsb = G_KEYFILE_SETTINGS_BACKEND (object); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-05 16:07:55 -05:00
										 |  |  |   switch ((GKeyfileSettingsBackendProperty)prop_id) | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  |     { | 
					
						
							|  |  |  |     case PROP_FILENAME: | 
					
						
							|  |  |  |       g_value_set_string (value, g_file_peek_path (kfsb->file)); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case PROP_ROOT_PATH: | 
					
						
							|  |  |  |       g_value_set_string (value, kfsb->prefix); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case PROP_ROOT_GROUP: | 
					
						
							|  |  |  |       g_value_set_string (value, kfsb->root_group); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-05 16:07:55 -05:00
										 |  |  |     case PROP_DEFAULTS_DIR: | 
					
						
							|  |  |  |       g_value_set_string (value, kfsb->defaults_dir); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  |     default: | 
					
						
							|  |  |  |       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | g_keyfile_settings_backend_class_init (GKeyfileSettingsBackendClass *class) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   GObjectClass *object_class = G_OBJECT_CLASS (class); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   object_class->finalize = g_keyfile_settings_backend_finalize; | 
					
						
							|  |  |  |   object_class->constructed = g_keyfile_settings_backend_constructed; | 
					
						
							|  |  |  |   object_class->get_property = g_keyfile_settings_backend_get_property; | 
					
						
							|  |  |  |   object_class->set_property = g_keyfile_settings_backend_set_property; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   class->read = g_keyfile_settings_backend_read; | 
					
						
							|  |  |  |   class->write = g_keyfile_settings_backend_write; | 
					
						
							|  |  |  |   class->write_tree = g_keyfile_settings_backend_write_tree; | 
					
						
							|  |  |  |   class->reset = g_keyfile_settings_backend_reset; | 
					
						
							|  |  |  |   class->get_writable = g_keyfile_settings_backend_get_writable; | 
					
						
							|  |  |  |   class->get_permission = g_keyfile_settings_backend_get_permission; | 
					
						
							|  |  |  |   /* No need to implement subscribed/unsubscribe: the only point would be to
 | 
					
						
							|  |  |  |    * stop monitoring the file when there's no GSettings anymore, which is no | 
					
						
							|  |  |  |    * big win. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * GKeyfileSettingsBackend:filename: | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * The location where the settings are stored on disk. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * Defaults to `$XDG_CONFIG_HOME/glib-2.0/settings/keyfile`. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   g_object_class_install_property (object_class, | 
					
						
							|  |  |  |                                    PROP_FILENAME, | 
					
						
							| 
									
										
										
										
											2023-04-28 01:59:26 +02:00
										 |  |  |                                    g_param_spec_string ("filename", NULL, NULL, | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  |                                                         NULL, | 
					
						
							|  |  |  |                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | | 
					
						
							|  |  |  |                                                         G_PARAM_STATIC_STRINGS)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * GKeyfileSettingsBackend:root-path: | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * All settings read to or written from the backend must fall under the | 
					
						
							| 
									
										
										
										
											2025-02-04 14:24:57 +00:00
										 |  |  |    * path given in @root_path. | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  |    *  | 
					
						
							| 
									
										
										
										
											2025-02-04 14:24:57 +00:00
										 |  |  |    * The path must start and end with a slash and not contain two consecutive | 
					
						
							|  |  |  |    * slashes. It may be `"/"`. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * Defaults to `"/"`. | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  |    */ | 
					
						
							|  |  |  |   g_object_class_install_property (object_class, | 
					
						
							|  |  |  |                                    PROP_ROOT_PATH, | 
					
						
							| 
									
										
										
										
											2023-04-28 01:59:26 +02:00
										 |  |  |                                    g_param_spec_string ("root-path", NULL, NULL, | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  |                                                         NULL, | 
					
						
							|  |  |  |                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | | 
					
						
							|  |  |  |                                                         G_PARAM_STATIC_STRINGS)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * GKeyfileSettingsBackend:root-group: | 
					
						
							|  |  |  |    * | 
					
						
							| 
									
										
										
										
											2025-02-04 14:24:57 +00:00
										 |  |  |    * If @root_group is non-`NULL` then it specifies the name of the keyfile | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  |    * group used for keys that are written directly below the root path. | 
					
						
							|  |  |  |    * | 
					
						
							| 
									
										
										
										
											2025-02-04 14:24:57 +00:00
										 |  |  |    * Defaults to `NULL`. | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  |    */ | 
					
						
							|  |  |  |   g_object_class_install_property (object_class, | 
					
						
							|  |  |  |                                    PROP_ROOT_GROUP, | 
					
						
							| 
									
										
										
										
											2023-04-28 01:59:26 +02:00
										 |  |  |                                    g_param_spec_string ("root-group", NULL, NULL, | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  |                                                         NULL, | 
					
						
							|  |  |  |                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | | 
					
						
							|  |  |  |                                                         G_PARAM_STATIC_STRINGS)); | 
					
						
							| 
									
										
										
										
											2018-11-05 16:07:55 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    * GKeyfileSettingsBackend:default-dir: | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * The directory where the system defaults and locks are located. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * Defaults to `/etc/glib-2.0/settings`. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   g_object_class_install_property (object_class, | 
					
						
							|  |  |  |                                    PROP_DEFAULTS_DIR, | 
					
						
							| 
									
										
										
										
											2023-04-28 01:59:26 +02:00
										 |  |  |                                    g_param_spec_string ("defaults-dir", NULL, NULL, | 
					
						
							| 
									
										
										
										
											2018-11-05 16:07:55 -05:00
										 |  |  |                                                         NULL, | 
					
						
							|  |  |  |                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | | 
					
						
							|  |  |  |                                                         G_PARAM_STATIC_STRINGS)); | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * g_keyfile_settings_backend_new: | 
					
						
							|  |  |  |  * @filename: the filename of the keyfile | 
					
						
							|  |  |  |  * @root_path: the path under which all settings keys appear | 
					
						
							| 
									
										
										
										
											2025-02-04 14:24:57 +00:00
										 |  |  |  * @root_group: (nullable): the group name corresponding to @root_path, or | 
					
						
							|  |  |  |  *    `NULL` to disallow storing keys directly beneath @root_path | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2025-02-04 14:24:57 +00:00
										 |  |  |  * Creates a keyfile-backed [class@Gio.SettingsBackend]. | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |  * | 
					
						
							|  |  |  |  * The filename of the keyfile to use is given by @filename. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * All settings read to or written from the backend must fall under the | 
					
						
							|  |  |  |  * path given in @root_path (which must start and end with a slash and | 
					
						
							| 
									
										
										
										
											2025-02-04 14:24:57 +00:00
										 |  |  |  * not contain two consecutive slashes).  @root_path may be `"/"`. | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2025-02-04 14:24:57 +00:00
										 |  |  |  * If @root_group is non-`NULL` then it specifies the name of the keyfile | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |  * group used for keys that are written directly below @root_path.  For | 
					
						
							| 
									
										
										
										
											2025-02-04 14:24:57 +00:00
										 |  |  |  * example, if @root_path is `"/apps/example/"` and @root_group is | 
					
						
							|  |  |  |  * `"toplevel"`, then setting the key `"/apps/example/enabled"` to true will | 
					
						
							|  |  |  |  * cause the following to appear in the keyfile: | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2025-02-04 14:24:57 +00:00
										 |  |  |  * ``` | 
					
						
							|  |  |  |  * [toplevel] | 
					
						
							|  |  |  |  * enabled=true | 
					
						
							|  |  |  |  * ``` | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2025-02-04 14:24:57 +00:00
										 |  |  |  * If @root_group is `NULL` then it is not permitted to store keys | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |  * directly below the @root_path. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * For keys not stored directly below @root_path (ie: in a sub-path), | 
					
						
							|  |  |  |  * the name of the subpath (with the final slash stripped) is used as | 
					
						
							|  |  |  |  * the name of the keyfile group.  To continue the example, if | 
					
						
							| 
									
										
										
										
											2025-02-04 14:24:57 +00:00
										 |  |  |  * `"/apps/example/profiles/default/font-size"` were set to | 
					
						
							|  |  |  |  * `12` then the following would appear in the keyfile: | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2025-02-04 14:24:57 +00:00
										 |  |  |  * ``` | 
					
						
							|  |  |  |  * [profiles/default] | 
					
						
							|  |  |  |  * font-size=12 | 
					
						
							|  |  |  |  * ``` | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |  * | 
					
						
							|  |  |  |  * The backend will refuse writes (and return writability as being | 
					
						
							| 
									
										
										
										
											2025-02-04 14:24:57 +00:00
										 |  |  |  * false) for keys outside of @root_path and, in the event that | 
					
						
							|  |  |  |  * @root_group is `NULL`, also for keys directly under @root_path. | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |  * Writes will also be refused if the backend detects that it has the | 
					
						
							|  |  |  |  * inability to rewrite the keyfile (ie: the containing directory is not | 
					
						
							|  |  |  |  * writable). | 
					
						
							| 
									
										
										
										
											2010-06-24 02:21:58 -04:00
										 |  |  |  * | 
					
						
							|  |  |  |  * There is no checking done for your key namespace clashing with the | 
					
						
							| 
									
										
										
										
											2025-02-04 14:24:57 +00:00
										 |  |  |  * syntax of the key file format.  For example, if you have `[` or `]` | 
					
						
							|  |  |  |  * characters in your path names or `=` in your key names you may be in | 
					
						
							| 
									
										
										
										
											2010-06-24 02:21:58 -04:00
										 |  |  |  * trouble. | 
					
						
							| 
									
										
										
										
											2011-11-21 12:02:02 -05:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-11-05 16:07:55 -05:00
										 |  |  |  * The backend reads default values from a keyfile called `defaults` in | 
					
						
							| 
									
										
										
										
											2025-02-04 14:24:57 +00:00
										 |  |  |  * the directory specified by the `GKeyfileSettingsBackend:defaults-dir` | 
					
						
							|  |  |  |  * property, and a list of locked keys from a text file with the name `locks` in | 
					
						
							| 
									
										
										
										
											2018-11-05 16:07:55 -05:00
										 |  |  |  * the same location. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2025-02-04 14:24:57 +00:00
										 |  |  |  * Returns: (transfer full): a keyfile-backed [class@Gio.SettingsBackend] | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |  **/ | 
					
						
							| 
									
										
										
										
											2010-06-17 14:05:40 -04:00
										 |  |  | GSettingsBackend * | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  | g_keyfile_settings_backend_new (const gchar *filename, | 
					
						
							|  |  |  |                                 const gchar *root_path, | 
					
						
							|  |  |  |                                 const gchar *root_group) | 
					
						
							| 
									
										
										
										
											2010-04-17 10:26:10 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-06-22 08:12:04 -04:00
										 |  |  |   g_return_val_if_fail (filename != NULL, NULL); | 
					
						
							|  |  |  |   g_return_val_if_fail (root_path != NULL, NULL); | 
					
						
							|  |  |  |   g_return_val_if_fail (g_str_has_prefix (root_path, "/"), NULL); | 
					
						
							|  |  |  |   g_return_val_if_fail (g_str_has_suffix (root_path, "/"), NULL); | 
					
						
							|  |  |  |   g_return_val_if_fail (strstr (root_path, "//") == NULL, NULL); | 
					
						
							| 
									
										
										
										
											2010-04-17 10:26:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-19 19:58:16 -05:00
										 |  |  |   return G_SETTINGS_BACKEND (g_object_new (G_TYPE_KEYFILE_SETTINGS_BACKEND, | 
					
						
							|  |  |  |                                            "filename", filename, | 
					
						
							|  |  |  |                                            "root-path", root_path, | 
					
						
							|  |  |  |                                            "root-group", root_group, | 
					
						
							|  |  |  |                                            NULL)); | 
					
						
							| 
									
										
										
										
											2010-04-17 10:26:10 -04:00
										 |  |  | } |