1/*
2 * Copyright © 2010 Codethink Limited
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16 *
17 * Author: Ryan Lortie <desrt@desrt.ca>
18 */
19
20#include "config.h"
21
22#include <gio/gio.h>
23#include <gi18n.h>
24#include <locale.h>
25#include <string.h>
26#include <stdlib.h>
27
28#include "glib/glib-private.h"
29
30static GSettingsSchemaSource *global_schema_source;
31static GSettings *global_settings;
32static GSettingsSchema *global_schema;
33static GSettingsSchemaKey *global_schema_key;
34const gchar *global_key;
35const gchar *global_value;
36
37static gboolean
38is_relocatable_schema (GSettingsSchema *schema)
39{
40 return g_settings_schema_get_path (schema) == NULL;
41}
42
43static gboolean
44check_relocatable_schema (GSettingsSchema *schema,
45 const gchar *schema_id)
46{
47 if (schema == NULL)
48 {
49 g_printerr (_("No such schema “%s”\n"), schema_id);
50 return FALSE;
51 }
52
53 if (!is_relocatable_schema (schema))
54 {
55 g_printerr (_("Schema “%s” is not relocatable "
56 "(path must not be specified)\n"),
57 schema_id);
58 return FALSE;
59 }
60
61 return TRUE;
62}
63
64static gboolean
65check_schema (GSettingsSchema *schema,
66 const gchar *schema_id)
67{
68 if (schema == NULL)
69 {
70 g_printerr (_("No such schema “%s”\n"), schema_id);
71 return FALSE;
72 }
73
74 if (is_relocatable_schema (schema))
75 {
76 g_printerr (_("Schema “%s” is relocatable "
77 "(path must be specified)\n"),
78 schema_id);
79 return FALSE;
80 }
81
82 return TRUE;
83}
84
85static gboolean
86check_path (const gchar *path)
87{
88 if (path[0] == '\0')
89 {
90 g_printerr (_("Empty path given.\n"));
91 return FALSE;
92 }
93
94 if (path[0] != '/')
95 {
96 g_printerr (_("Path must begin with a slash (/)\n"));
97 return FALSE;
98 }
99
100 if (!g_str_has_suffix (str: path, suffix: "/"))
101 {
102 g_printerr (_("Path must end with a slash (/)\n"));
103 return FALSE;
104 }
105
106 if (strstr (haystack: path, needle: "//"))
107 {
108 g_printerr (_("Path must not contain two adjacent slashes (//)\n"));
109 return FALSE;
110 }
111
112 return TRUE;
113}
114
115static void
116output_list (gchar **list)
117{
118 gint i;
119
120 for (i = 0; list[i]; i++)
121 g_print (format: "%s\n", list[i]);
122}
123
124static void
125gsettings_print_version (void)
126{
127 g_print (format: "%d.%d.%d\n", glib_major_version, glib_minor_version,
128 glib_micro_version);
129}
130
131static void
132gsettings_list_schemas (void)
133{
134 gchar **schemas;
135
136 g_settings_schema_source_list_schemas (source: global_schema_source, TRUE, non_relocatable: &schemas, NULL);
137 output_list (list: schemas);
138 g_strfreev (str_array: schemas);
139}
140
141static void
142gsettings_list_schemas_with_paths (void)
143{
144 gchar **schemas;
145 gsize i;
146
147 g_settings_schema_source_list_schemas (source: global_schema_source, TRUE, non_relocatable: &schemas, NULL);
148
149 for (i = 0; schemas[i] != NULL; i++)
150 {
151 GSettingsSchema *schema;
152 gchar *schema_name;
153 const gchar *schema_path;
154
155 schema_name = g_steal_pointer (&schemas[i]);
156
157 schema = g_settings_schema_source_lookup (source: global_schema_source, schema_id: schema_name, TRUE);
158 schema_path = g_settings_schema_get_path (schema);
159
160 schemas[i] = g_strconcat (string1: schema_name, " ", schema_path, NULL);
161
162 g_settings_schema_unref (schema);
163 g_free (mem: schema_name);
164 }
165
166 output_list (list: schemas);
167 g_strfreev (str_array: schemas);
168}
169
170static void
171gsettings_list_relocatable_schemas (void)
172{
173 gchar **schemas;
174
175 g_settings_schema_source_list_schemas (source: global_schema_source, TRUE, NULL, relocatable: &schemas);
176 output_list (list: schemas);
177 g_strfreev (str_array: schemas);
178}
179
180static void
181gsettings_list_keys (void)
182{
183 gchar **keys;
184
185 keys = g_settings_schema_list_keys (schema: global_schema);
186 output_list (list: keys);
187 g_strfreev (str_array: keys);
188}
189
190static void
191gsettings_list_children (void)
192{
193 gchar **children;
194 gint max = 0;
195 gint i;
196
197 children = g_settings_list_children (settings: global_settings);
198 for (i = 0; children[i]; i++)
199 if (strlen (s: children[i]) > max)
200 max = strlen (s: children[i]);
201
202 for (i = 0; children[i]; i++)
203 {
204 GSettings *child;
205 GSettingsSchema *schema;
206 gchar *path;
207
208 child = g_settings_get_child (settings: global_settings, name: children[i]);
209 g_object_get (object: child,
210 first_property_name: "settings-schema", &schema,
211 "path", &path,
212 NULL);
213
214 if (g_settings_schema_get_path (schema) != NULL)
215 g_print (format: "%-*s %s\n", max, children[i], g_settings_schema_get_id (schema));
216 else
217 g_print (format: "%-*s %s:%s\n", max, children[i], g_settings_schema_get_id (schema), path);
218
219 g_object_unref (object: child);
220 g_settings_schema_unref (schema);
221 g_free (mem: path);
222 }
223
224 g_strfreev (str_array: children);
225}
226
227static void
228enumerate (GSettings *settings)
229{
230 gchar **keys;
231 GSettingsSchema *schema;
232 gint i;
233
234 g_object_get (object: settings, first_property_name: "settings-schema", &schema, NULL);
235
236 keys = g_settings_schema_list_keys (schema);
237 for (i = 0; keys[i]; i++)
238 {
239 GVariant *value;
240 gchar *printed;
241
242 value = g_settings_get_value (settings, key: keys[i]);
243 printed = g_variant_print (value, TRUE);
244 g_print (format: "%s %s %s\n", g_settings_schema_get_id (schema), keys[i], printed);
245 g_variant_unref (value);
246 g_free (mem: printed);
247 }
248
249 g_settings_schema_unref (schema);
250 g_strfreev (str_array: keys);
251}
252
253static void
254list_recursively (GSettings *settings)
255{
256 gchar **children;
257 gint i;
258
259 enumerate (settings);
260 children = g_settings_list_children (settings);
261 for (i = 0; children[i]; i++)
262 {
263 gboolean will_see_elsewhere = FALSE;
264 GSettings *child;
265
266 child = g_settings_get_child (settings, name: children[i]);
267
268 if (global_settings == NULL)
269 {
270 /* we're listing all non-relocatable settings objects from the
271 * top-level, so if this one is non-relocatable, don't recurse,
272 * because we will pick it up later on.
273 */
274
275 GSettingsSchema *child_schema;
276
277 g_object_get (object: child, first_property_name: "settings-schema", &child_schema, NULL);
278 will_see_elsewhere = !is_relocatable_schema (schema: child_schema);
279 g_settings_schema_unref (schema: child_schema);
280 }
281
282 if (!will_see_elsewhere)
283 list_recursively (settings: child);
284
285 g_object_unref (object: child);
286 }
287
288 g_strfreev (str_array: children);
289}
290
291static void
292gsettings_list_recursively (void)
293{
294 if (global_settings)
295 {
296 list_recursively (settings: global_settings);
297 }
298 else
299 {
300 gchar **schemas;
301 gint i;
302
303 g_settings_schema_source_list_schemas (source: global_schema_source, TRUE, non_relocatable: &schemas, NULL);
304
305 for (i = 0; schemas[i]; i++)
306 {
307 GSettings *settings;
308
309 settings = g_settings_new (schema_id: schemas[i]);
310 list_recursively (settings);
311 g_object_unref (object: settings);
312 }
313
314 g_strfreev (str_array: schemas);
315 }
316}
317
318static void
319gsettings_description (void)
320{
321 const gchar *description;
322 description = g_settings_schema_key_get_description (key: global_schema_key);
323 if (description == NULL)
324 description = g_settings_schema_key_get_summary (key: global_schema_key);
325 g_print (format: "%s\n", description);
326}
327
328static void
329gsettings_range (void)
330{
331 GVariant *range, *detail;
332 const gchar *type;
333
334 range = g_settings_schema_key_get_range (key: global_schema_key);
335 g_variant_get (value: range, format_string: "(&sv)", &type, &detail);
336
337 if (strcmp (s1: type, s2: "type") == 0)
338 g_print (format: "type %s\n", g_variant_get_type_string (value: detail) + 1);
339
340 else if (strcmp (s1: type, s2: "range") == 0)
341 {
342 GVariant *min, *max;
343 gchar *smin, *smax;
344
345 g_variant_get (value: detail, format_string: "(**)", &min, &max);
346 smin = g_variant_print (value: min, FALSE);
347 smax = g_variant_print (value: max, FALSE);
348
349 g_print (format: "range %s %s %s\n",
350 g_variant_get_type_string (value: min), smin, smax);
351 g_variant_unref (value: min);
352 g_variant_unref (value: max);
353 g_free (mem: smin);
354 g_free (mem: smax);
355 }
356
357 else if (strcmp (s1: type, s2: "enum") == 0 || strcmp (s1: type, s2: "flags") == 0)
358 {
359 GVariantIter iter;
360 GVariant *item;
361
362 g_print (format: "%s\n", type);
363
364 g_variant_iter_init (iter: &iter, value: detail);
365 while (g_variant_iter_loop (iter: &iter, format_string: "*", &item))
366 {
367 gchar *printed;
368
369 printed = g_variant_print (value: item, FALSE);
370 g_print (format: "%s\n", printed);
371 g_free (mem: printed);
372 }
373 }
374
375 g_variant_unref (value: detail);
376 g_variant_unref (value: range);
377}
378
379static void
380gsettings_get (void)
381{
382 GVariant *value;
383 gchar *printed;
384
385 value = g_settings_get_value (settings: global_settings, key: global_key);
386 printed = g_variant_print (value, TRUE);
387 g_print (format: "%s\n", printed);
388 g_variant_unref (value);
389 g_free (mem: printed);
390}
391
392static void
393gsettings_reset (void)
394{
395 g_settings_reset (settings: global_settings, key: global_key);
396 g_settings_sync ();
397}
398
399static void
400reset_all_keys (GSettings *settings)
401{
402 GSettingsSchema *schema;
403 gchar **keys;
404 gint i;
405
406 g_object_get (object: settings, first_property_name: "settings-schema", &schema, NULL);
407
408 keys = g_settings_schema_list_keys (schema);
409 for (i = 0; keys[i]; i++)
410 {
411 g_settings_reset (settings, key: keys[i]);
412 }
413
414 g_settings_schema_unref (schema);
415 g_strfreev (str_array: keys);
416}
417
418static void
419gsettings_reset_recursively (void)
420{
421 gchar **children;
422 gint i;
423
424 g_settings_delay (settings: global_settings);
425
426 reset_all_keys (settings: global_settings);
427 children = g_settings_list_children (settings: global_settings);
428 for (i = 0; children[i]; i++)
429 {
430 GSettings *child;
431 child = g_settings_get_child (settings: global_settings, name: children[i]);
432
433 reset_all_keys (settings: child);
434
435 g_object_unref (object: child);
436 }
437
438 g_strfreev (str_array: children);
439
440 g_settings_apply (settings: global_settings);
441 g_settings_sync ();
442}
443
444static void
445gsettings_writable (void)
446{
447 g_print (format: "%s\n",
448 g_settings_is_writable (settings: global_settings, name: global_key) ?
449 "true" : "false");
450}
451
452static void
453value_changed (GSettings *settings,
454 const gchar *key,
455 gpointer user_data)
456{
457 GVariant *value;
458 gchar *printed;
459
460 value = g_settings_get_value (settings, key);
461 printed = g_variant_print (value, TRUE);
462 g_print (format: "%s: %s\n", key, printed);
463 g_variant_unref (value);
464 g_free (mem: printed);
465}
466
467static void
468gsettings_monitor (void)
469{
470 if (global_key)
471 {
472 gchar *name;
473
474 name = g_strdup_printf (format: "changed::%s", global_key);
475 g_signal_connect (global_settings, name, G_CALLBACK (value_changed), NULL);
476 }
477 else
478 g_signal_connect (global_settings, "changed", G_CALLBACK (value_changed), NULL);
479
480 for (;;)
481 g_main_context_iteration (NULL, TRUE);
482}
483
484static void
485gsettings_set (void)
486{
487 const GVariantType *type;
488 GError *error = NULL;
489 GVariant *new;
490 gchar *freeme = NULL;
491
492 type = g_settings_schema_key_get_value_type (key: global_schema_key);
493
494 new = g_variant_parse (type, text: global_value, NULL, NULL, error: &error);
495
496 /* If that didn't work and the type is string then we should assume
497 * that the user is just trying to set a string directly and forgot
498 * the quotes (or had them consumed by the shell).
499 *
500 * If the user started with a quote then we assume that some deeper
501 * problem is at play and we want the failure in that case.
502 *
503 * Consider:
504 *
505 * gsettings set x.y.z key "'i don't expect this to work'"
506 *
507 * Note that we should not just add quotes and try parsing again, but
508 * rather assume that the user is providing us with a bare string.
509 * Assume we added single quotes, then consider this case:
510 *
511 * gsettings set x.y.z key "i'd expect this to work"
512 *
513 * A similar example could be given for double quotes.
514 *
515 * Avoid that whole mess by just using g_variant_new_string().
516 */
517 if (new == NULL &&
518 g_variant_type_equal (type1: type, G_VARIANT_TYPE_STRING) &&
519 global_value[0] != '\'' && global_value[0] != '"')
520 {
521 g_clear_error (err: &error);
522 new = g_variant_new_string (string: global_value);
523 }
524
525 if (new == NULL)
526 {
527 gchar *context;
528
529 context = g_variant_parse_error_print_context (error, source_str: global_value);
530 g_printerr (format: "%s", context);
531 exit (status: 1);
532 }
533
534 if (!g_settings_schema_key_range_check (key: global_schema_key, value: new))
535 {
536 g_printerr (_("The provided value is outside of the valid range\n"));
537 g_variant_unref (value: new);
538 exit (status: 1);
539 }
540
541 if (!g_settings_set_value (settings: global_settings, key: global_key, value: new))
542 {
543 g_printerr (_("The key is not writable\n"));
544 exit (status: 1);
545 }
546
547 g_settings_sync ();
548
549 g_free (mem: freeme);
550}
551
552static int
553gsettings_help (gboolean requested,
554 const gchar *command)
555{
556 const gchar *description;
557 const gchar *synopsis;
558 GString *string;
559
560 string = g_string_new (NULL);
561
562 if (command == NULL)
563 ;
564
565 else if (strcmp (s1: command, s2: "help") == 0)
566 {
567 description = _("Print help");
568 synopsis = "[COMMAND]";
569 }
570
571 else if (strcmp (s1: command, s2: "--version") == 0)
572 {
573 description = _("Print version information and exit");
574 synopsis = "";
575 }
576
577 else if (strcmp (s1: command, s2: "list-schemas") == 0)
578 {
579 description = _("List the installed (non-relocatable) schemas");
580 synopsis = "[--print-paths]";
581 }
582
583 else if (strcmp (s1: command, s2: "list-relocatable-schemas") == 0)
584 {
585 description = _("List the installed relocatable schemas");
586 synopsis = "";
587 }
588
589 else if (strcmp (s1: command, s2: "list-keys") == 0)
590 {
591 description = _("List the keys in SCHEMA");
592 synopsis = N_("SCHEMA[:PATH]");
593 }
594
595 else if (strcmp (s1: command, s2: "list-children") == 0)
596 {
597 description = _("List the children of SCHEMA");
598 synopsis = N_("SCHEMA[:PATH]");
599 }
600
601 else if (strcmp (s1: command, s2: "list-recursively") == 0)
602 {
603 description = _("List keys and values, recursively\n"
604 "If no SCHEMA is given, list all keys\n");
605 synopsis = N_("[SCHEMA[:PATH]]");
606 }
607
608 else if (strcmp (s1: command, s2: "get") == 0)
609 {
610 description = _("Get the value of KEY");
611 synopsis = N_("SCHEMA[:PATH] KEY");
612 }
613
614 else if (strcmp (s1: command, s2: "range") == 0)
615 {
616 description = _("Query the range of valid values for KEY");
617 synopsis = N_("SCHEMA[:PATH] KEY");
618 }
619
620 else if (strcmp (s1: command, s2: "describe") == 0)
621 {
622 description = _("Query the description for KEY");
623 synopsis = N_("SCHEMA[:PATH] KEY");
624 }
625
626 else if (strcmp (s1: command, s2: "set") == 0)
627 {
628 description = _("Set the value of KEY to VALUE");
629 synopsis = N_("SCHEMA[:PATH] KEY VALUE");
630 }
631
632 else if (strcmp (s1: command, s2: "reset") == 0)
633 {
634 description = _("Reset KEY to its default value");
635 synopsis = N_("SCHEMA[:PATH] KEY");
636 }
637
638 else if (strcmp (s1: command, s2: "reset-recursively") == 0)
639 {
640 description = _("Reset all keys in SCHEMA to their defaults");
641 synopsis = N_("SCHEMA[:PATH]");
642 }
643
644 else if (strcmp (s1: command, s2: "writable") == 0)
645 {
646 description = _("Check if KEY is writable");
647 synopsis = N_("SCHEMA[:PATH] KEY");
648 }
649
650 else if (strcmp (s1: command, s2: "monitor") == 0)
651 {
652 description = _("Monitor KEY for changes.\n"
653 "If no KEY is specified, monitor all keys in SCHEMA.\n"
654 "Use ^C to stop monitoring.\n");
655 synopsis = N_("SCHEMA[:PATH] [KEY]");
656 }
657 else
658 {
659 g_string_printf (string, _("Unknown command %s\n\n"), command);
660 requested = FALSE;
661 command = NULL;
662 }
663
664 if (command == NULL)
665 {
666 g_string_append (string,
667 _("Usage:\n"
668 " gsettings --version\n"
669 " gsettings [--schemadir SCHEMADIR] COMMAND [ARGS…]\n"
670 "\n"
671 "Commands:\n"
672 " help Show this information\n"
673 " list-schemas List installed schemas\n"
674 " list-relocatable-schemas List relocatable schemas\n"
675 " list-keys List keys in a schema\n"
676 " list-children List children of a schema\n"
677 " list-recursively List keys and values, recursively\n"
678 " range Queries the range of a key\n"
679 " describe Queries the description of a key\n"
680 " get Get the value of a key\n"
681 " set Set the value of a key\n"
682 " reset Reset the value of a key\n"
683 " reset-recursively Reset all values in a given schema\n"
684 " writable Check if a key is writable\n"
685 " monitor Watch for changes\n"
686 "\n"
687 "Use “gsettings help COMMAND” to get detailed help.\n\n"));
688 }
689 else
690 {
691 g_string_append_printf (string, _("Usage:\n gsettings [--schemadir SCHEMADIR] %s %s\n\n%s\n\n"),
692 command, synopsis[0] ? _(synopsis) : "", description);
693
694 g_string_append (string, _("Arguments:\n"));
695
696 g_string_append (string,
697 _(" SCHEMADIR A directory to search for additional schemas\n"));
698
699 if (strstr (haystack: synopsis, needle: "[COMMAND]"))
700 g_string_append (string,
701 _(" COMMAND The (optional) command to explain\n"));
702
703 else if (strstr (haystack: synopsis, needle: "SCHEMA"))
704 g_string_append (string,
705 _(" SCHEMA The name of the schema\n"
706 " PATH The path, for relocatable schemas\n"));
707
708 if (strstr (haystack: synopsis, needle: "[KEY]"))
709 g_string_append (string,
710 _(" KEY The (optional) key within the schema\n"));
711
712 else if (strstr (haystack: synopsis, needle: "KEY"))
713 g_string_append (string,
714 _(" KEY The key within the schema\n"));
715
716 if (strstr (haystack: synopsis, needle: "VALUE"))
717 g_string_append (string,
718 _(" VALUE The value to set\n"));
719
720 g_string_append (string, val: "\n");
721 }
722
723 if (requested)
724 g_print (format: "%s", string->str);
725 else
726 g_printerr (format: "%s\n", string->str);
727
728 g_string_free (string, TRUE);
729
730 return requested ? 0 : 1;
731}
732
733
734int
735main (int argc, char **argv)
736{
737 void (* function) (void);
738 gboolean need_settings, skip_third_arg_test;
739
740#ifdef G_OS_WIN32
741 gchar *tmp;
742#endif
743
744 setlocale (LC_ALL, GLIB_DEFAULT_LOCALE);
745 textdomain (GETTEXT_PACKAGE);
746
747#ifdef G_OS_WIN32
748 tmp = _glib_get_locale_dir ();
749 bindtextdomain (GETTEXT_PACKAGE, tmp);
750 g_free (tmp);
751#else
752 bindtextdomain (GETTEXT_PACKAGE, GLIB_LOCALE_DIR);
753#endif
754
755#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
756 bind_textdomain_codeset (GETTEXT_PACKAGE, codeset: "UTF-8");
757#endif
758
759 if (argc < 2)
760 return gsettings_help (FALSE, NULL);
761
762 global_schema_source = g_settings_schema_source_get_default ();
763
764 if (argc > 3 && g_str_equal (v1: argv[1], v2: "--schemadir"))
765 {
766 GSettingsSchemaSource *parent = global_schema_source;
767 GError *error = NULL;
768
769 global_schema_source = g_settings_schema_source_new_from_directory (directory: argv[2], parent, FALSE, error: &error);
770
771 if (global_schema_source == NULL)
772 {
773 g_printerr (_("Could not load schemas from %s: %s\n"), argv[2], error->message);
774 g_clear_error (err: &error);
775
776 return 1;
777 }
778
779 /* shift remaining arguments (not correct wrt argv[0], but doesn't matter) */
780 argv = argv + 2;
781 argc -= 2;
782 }
783 else if (global_schema_source == NULL)
784 {
785 g_printerr (_("No schemas installed\n"));
786 return 1;
787 }
788 else
789 g_settings_schema_source_ref (source: global_schema_source);
790
791 need_settings = TRUE;
792 skip_third_arg_test = FALSE;
793
794 if (strcmp (s1: argv[1], s2: "help") == 0)
795 return gsettings_help (TRUE, command: argv[2]);
796
797 else if (argc == 2 && strcmp (s1: argv[1], s2: "--version") == 0)
798 function = gsettings_print_version;
799
800 else if (argc == 2 && strcmp (s1: argv[1], s2: "list-schemas") == 0)
801 function = gsettings_list_schemas;
802
803 else if (argc == 3 && strcmp (s1: argv[1], s2: "list-schemas") == 0
804 && strcmp (s1: argv[2], s2: "--print-paths") == 0)
805 {
806 skip_third_arg_test = TRUE;
807 function = gsettings_list_schemas_with_paths;
808 }
809
810 else if (argc == 2 && strcmp (s1: argv[1], s2: "list-relocatable-schemas") == 0)
811 function = gsettings_list_relocatable_schemas;
812
813 else if (argc == 3 && strcmp (s1: argv[1], s2: "list-keys") == 0)
814 {
815 need_settings = FALSE;
816 function = gsettings_list_keys;
817 }
818
819 else if (argc == 3 && strcmp (s1: argv[1], s2: "list-children") == 0)
820 function = gsettings_list_children;
821
822 else if ((argc == 2 || argc == 3) && strcmp (s1: argv[1], s2: "list-recursively") == 0)
823 function = gsettings_list_recursively;
824
825 else if (argc == 4 && strcmp (s1: argv[1], s2: "describe") == 0)
826 {
827 need_settings = FALSE;
828 function = gsettings_description;
829 }
830
831 else if (argc == 4 && strcmp (s1: argv[1], s2: "range") == 0)
832 {
833 need_settings = FALSE;
834 function = gsettings_range;
835 }
836
837 else if (argc == 4 && strcmp (s1: argv[1], s2: "get") == 0)
838 function = gsettings_get;
839
840 else if (argc == 5 && strcmp (s1: argv[1], s2: "set") == 0)
841 function = gsettings_set;
842
843 else if (argc == 4 && strcmp (s1: argv[1], s2: "reset") == 0)
844 function = gsettings_reset;
845
846 else if (argc == 3 && strcmp (s1: argv[1], s2: "reset-recursively") == 0)
847 function = gsettings_reset_recursively;
848
849 else if (argc == 4 && strcmp (s1: argv[1], s2: "writable") == 0)
850 function = gsettings_writable;
851
852 else if ((argc == 3 || argc == 4) && strcmp (s1: argv[1], s2: "monitor") == 0)
853 function = gsettings_monitor;
854
855 else
856 return gsettings_help (FALSE, command: argv[1]);
857
858 if (argc > 2 && !skip_third_arg_test)
859 {
860 gchar **parts;
861
862 if (argv[2][0] == '\0')
863 {
864 g_printerr (_("Empty schema name given\n"));
865 return 1;
866 }
867
868 parts = g_strsplit (string: argv[2], delimiter: ":", max_tokens: 2);
869
870 global_schema = g_settings_schema_source_lookup (source: global_schema_source, schema_id: parts[0], TRUE);
871
872 if (need_settings)
873 {
874 if (parts[1])
875 {
876 if (!check_relocatable_schema (schema: global_schema, schema_id: parts[0]) || !check_path (path: parts[1]))
877 return 1;
878
879 global_settings = g_settings_new_full (schema: global_schema, NULL, path: parts[1]);
880 }
881 else
882 {
883 if (!check_schema (schema: global_schema, schema_id: parts[0]))
884 return 1;
885
886 global_settings = g_settings_new_full (schema: global_schema, NULL, NULL);
887 }
888 }
889 else
890 {
891 /* If the user has given a path then we enforce that we have a
892 * relocatable schema, but if they didn't give a path then it
893 * doesn't matter what type of schema we have (since it's
894 * reasonable to ask for introspection information on a
895 * relocatable schema without having to give the path).
896 */
897 if (parts[1])
898 {
899 if (!check_relocatable_schema (schema: global_schema, schema_id: parts[0]) || !check_path (path: parts[1]))
900 return 1;
901 }
902 else
903 {
904 if (global_schema == NULL)
905 {
906 g_printerr (_("No such schema “%s”\n"), parts[0]);
907 return 1;
908 }
909 }
910 }
911
912 g_strfreev (str_array: parts);
913 }
914
915 if (argc > 3)
916 {
917 if (!g_settings_schema_has_key (schema: global_schema, name: argv[3]))
918 {
919 g_printerr (_("No such key “%s”\n"), argv[3]);
920 return 1;
921 }
922
923 global_key = argv[3];
924 global_schema_key = g_settings_schema_get_key (schema: global_schema, name: global_key);
925 }
926
927 if (argc > 4)
928 global_value = argv[4];
929
930 (* function) ();
931
932
933 g_clear_pointer (&global_schema_source, g_settings_schema_source_unref);
934 g_clear_pointer (&global_schema_key, g_settings_schema_key_unref);
935 g_clear_pointer (&global_schema, g_settings_schema_unref);
936 g_clear_object (&global_settings);
937
938 return 0;
939}
940

source code of gtk/subprojects/glib/gio/gsettings-tool.c