Merge remote branch 'gvdb/master'
[platform/upstream/glib.git] / gio / gsettings-tool.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 2010 Red Hat, Inc.
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 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, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  *
19  * Author: Matthias Clasen
20  */
21
22 #include "config.h"
23
24 #include <locale.h>
25 #include <gi18n.h>
26 #include <gio.h>
27
28 static gint
29 usage (gint      *argc,
30        gchar    **argv[],
31        gboolean   use_stdout)
32 {
33   GOptionContext *context;
34   gchar *s;
35
36   g_set_prgname (g_path_get_basename ((*argv)[0]));
37
38   context = g_option_context_new (_("COMMAND"));
39   g_option_context_set_help_enabled (context, FALSE);
40   s = g_strdup_printf (
41     _("Commands:\n"
42       "  help        Show this information\n"
43       "  get         Get the value of a key\n"
44       "  set         Set the value of a key\n"
45       "  monitor     Monitor a key for changes\n"
46       "  writable    Check if a key is writable\n"
47       "\n"
48       "Use '%s COMMAND --help' to get help for individual commands.\n"),
49       g_get_prgname ());
50   g_option_context_set_description (context, s);
51   g_free (s);
52   s = g_option_context_get_help (context, FALSE, NULL);
53   if (use_stdout)
54     g_print ("%s", s);
55   else
56     g_printerr ("%s", s);
57   g_free (s);
58   g_option_context_free (context);
59
60   return use_stdout ? 0 : 1;
61 }
62
63 static void
64 remove_arg (gint num, gint *argc, gchar **argv[])
65 {
66   gint n;
67
68   g_assert (num <= (*argc));
69
70   for (n = num; (*argv)[n] != NULL; n++)
71     (*argv)[n] = (*argv)[n+1];
72   (*argv)[n] = NULL;
73   (*argc) = (*argc) - 1;
74 }
75
76 static void
77 modify_argv0_for_command (gint         *argc,
78                           gchar       **argv[],
79                           const gchar  *command)
80 {
81   gchar *s;
82
83   g_assert (g_strcmp0 ((*argv)[1], command) == 0);
84   remove_arg (1, argc, argv);
85
86   s = g_strdup_printf ("%s %s", (*argv)[0], command);
87   (*argv)[0] = s;
88 }
89
90
91 static gint
92 handle_get (gint   *argc,
93             gchar **argv[])
94 {
95   gchar *schema;
96   gchar *path;
97   gchar *key;
98   GSettings *settings;
99   GVariant *v;
100   GOptionContext *context;
101   GOptionEntry entries[] = {
102     { "path", 'p', 0, G_OPTION_ARG_STRING, &path, N_("Specify the path for the schema"), N_("PATH") },
103     { NULL }
104   };
105   GError *error;
106   gint ret = 1;
107
108   modify_argv0_for_command (argc, argv, "get");
109
110   context = g_option_context_new (_("SCHEMA KEY"));
111   g_option_context_set_help_enabled (context, FALSE);
112   g_option_context_set_summary (context, _("Get the value of KEY"));
113   g_option_context_set_description (context,
114     _("Arguments:\n"
115       "  SCHEMA      The id of the schema\n"
116       "  KEY         The name of the key\n"));
117   g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
118
119   path = NULL;
120
121   error = NULL;
122   if (!g_option_context_parse (context, argc, argv, NULL) || *argc != 3)
123     {
124       gchar *s;
125       s = g_option_context_get_help (context, FALSE, NULL);
126       g_printerr ("%s", s);
127       g_free (s);
128
129       goto out;
130     }
131
132   schema = (*argv)[1];
133   key = (*argv)[2];
134
135   settings = g_settings_new_with_path (schema, path);
136
137   v = g_settings_get_value (settings, key);
138   g_print ("%s\n", g_variant_print (v, FALSE));
139   g_variant_unref (v);
140   ret = 0;
141
142  out:
143   g_option_context_free (context);
144
145   return ret;
146 }
147
148 static gint
149 handle_set (gint   *argc,
150             gchar **argv[])
151 {
152   gchar *schema;
153   gchar *path;
154   gchar *key;
155   gchar *value;
156   GSettings *settings;
157   GVariant *v;
158   const GVariantType *type;
159   GOptionContext *context;
160   GOptionEntry entries[] = {
161     { "path", 'p', 0, G_OPTION_ARG_STRING, &path, N_("Specify the path for the schema"), N_("PATH") },
162     { NULL }
163   };
164   GError *error;
165   gint ret = 1;
166
167   modify_argv0_for_command (argc, argv, "set");
168
169   context = g_option_context_new (_("SCHEMA KEY VALUE"));
170   g_option_context_set_help_enabled (context, FALSE);
171   g_option_context_set_summary (context, _("Set the value of KEY"));
172   g_option_context_set_description (context,
173     _("Arguments:\n"
174       "  SCHEMA      The id of the schema\n"
175       "  KEY         The name of the key\n"
176       "  VALUE       The value to set key to, as a serialized GVariant\n"));
177   g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
178
179   path = NULL;
180
181   error = NULL;
182   if (!g_option_context_parse (context, argc, argv, NULL) || *argc != 4)
183     {
184       gchar *s;
185       s = g_option_context_get_help (context, FALSE, NULL);
186       g_printerr ("%s", s);
187       g_free (s);
188
189       goto out;
190     }
191
192   schema = (*argv)[1];
193   key = (*argv)[2];
194   value = (*argv)[3];
195
196   settings = g_settings_new_with_path (schema, path);
197
198   v = g_settings_get_value (settings, key);
199   type = g_variant_get_type (v);
200   g_variant_unref (v);
201
202   error = NULL;
203   v = g_variant_parse (type, value, NULL, NULL, &error);
204   if (v == NULL)
205     {
206       g_printerr ("%s\n", error->message);
207       goto out;
208     }
209
210   if (!g_settings_set_value (settings, key, v))
211     {
212       g_printerr (_("Key %s is not writable\n"), key);
213       goto out;
214     }
215
216   ret = 0;
217
218   /* XXX: workaround for now
219    *
220    * if we exit() so quickly, GDBus may not have had a chance to
221    * actually send the message (since we're using it async).
222    *
223    * GDBusConnection has no API to sync or wait for messages to be sent,
224    * so we send a meaningless message and wait for the reply to ensure
225    * that all messages that came before must have been sent.
226    */
227   {
228     GDBusConnection *session;
229
230     session = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
231     g_dbus_connection_call_sync (session, "org.gtk.DoesNotExist", "/",
232                                  "org.gtk.DoesNotExist", "Workaround",
233                                  g_variant_new ("()"), NULL, 0, -1, NULL, NULL);
234   }
235
236  out:
237   g_option_context_free (context);
238
239   return ret;
240 }
241
242 static gint
243 handle_writable (gint   *argc,
244                  gchar **argv[])
245 {
246   gchar *schema;
247   gchar *path;
248   gchar *key;
249   GSettings *settings;
250   GOptionContext *context;
251   GOptionEntry entries[] = {
252     { "path", 'p', 0, G_OPTION_ARG_STRING, &path, N_("Specify the path for the schema"), N_("PATH") },
253     { NULL }
254   };
255   GError *error;
256   gint ret = 1;
257
258   modify_argv0_for_command (argc, argv, "writable");
259
260   context = g_option_context_new (_("SCHEMA KEY"));
261   g_option_context_set_help_enabled (context, FALSE);
262   g_option_context_set_summary (context, _("Find out whether KEY is writable"));
263   g_option_context_set_description (context,
264     _("Arguments:\n"
265       "  SCHEMA      The id of the schema\n"
266       "  KEY         The name of the key\n"));
267   g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
268
269   path = NULL;
270
271   error = NULL;
272   if (!g_option_context_parse (context, argc, argv, NULL) || *argc != 3)
273     {
274       gchar *s;
275       s = g_option_context_get_help (context, FALSE, NULL);
276       g_printerr ("%s", s);
277       g_free (s);
278
279       goto out;
280     }
281
282   schema = (*argv)[1];
283   key = (*argv)[2];
284
285   settings = g_settings_new_with_path (schema, path);
286
287   if (g_settings_is_writable (settings, key))
288     g_print ("true\n");
289   else
290     g_print ("false\n");
291   ret = 0;
292
293  out:
294   g_option_context_free (context);
295
296   return ret;
297 }
298
299 static void
300 key_changed (GSettings   *settings,
301              const gchar *key)
302 {
303   GVariant *v;
304   gchar *value;
305
306   v = g_settings_get_value (settings, key);
307   value = g_variant_print (v, FALSE);
308   g_print ("%s\n", value);
309   g_free (value);
310   g_variant_unref (v);
311 }
312
313 static gint
314 handle_monitor (gint   *argc,
315                 gchar **argv[])
316 {
317   gchar *schema;
318   gchar *path;
319   gchar *key;
320   GSettings *settings;
321   gchar *detailed_signal;
322   GMainLoop *loop;
323   GOptionContext *context;
324   GOptionEntry entries[] = {
325     { "path", 'p', 0, G_OPTION_ARG_STRING, &path, N_("Specify the path for the schema"), N_("PATH") },
326     { NULL }
327   };
328   GError *error;
329   gint ret = 1;
330
331   modify_argv0_for_command (argc, argv, "monitor");
332
333   context = g_option_context_new (_("SCHEMA KEY"));
334   g_option_context_set_help_enabled (context, FALSE);
335   g_option_context_set_summary (context,
336     _("Monitor KEY for changes and print the changed values.\n"
337       "Monitoring will continue until the process is terminated."));
338
339   g_option_context_set_description (context,
340     _("Arguments:\n"
341       "  SCHEMA      The id of the schema\n"
342       "  KEY         The name of the key\n"));
343   g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
344
345   path = NULL;
346
347   error = NULL;
348   if (!g_option_context_parse (context, argc, argv, NULL) || *argc != 3)
349     {
350       gchar *s;
351       s = g_option_context_get_help (context, FALSE, NULL);
352       g_printerr ("%s", s);
353       g_free (s);
354
355       goto out;
356     }
357
358   schema = (*argv)[1];
359   key = (*argv)[2];
360
361   settings = g_settings_new_with_path (schema, path);
362
363   detailed_signal = g_strdup_printf ("changed::%s", key);
364   g_signal_connect (settings, detailed_signal,
365                     G_CALLBACK (key_changed), NULL);
366
367   loop = g_main_loop_new (NULL, FALSE);
368   g_main_loop_run (loop);
369   g_main_loop_unref (loop);
370
371  out:
372   g_option_context_free (context);
373
374   return ret;
375 }
376 int
377 main (int argc, char *argv[])
378 {
379   gboolean ret = 1;
380
381   setlocale (LC_ALL, "");
382
383   g_type_init ();
384
385   if (argc < 2)
386     ret = usage (&argc, &argv, FALSE);
387   else if (g_strcmp0 (argv[1], "help") == 0)
388     ret = usage (&argc, &argv, TRUE);
389   else if (g_strcmp0 (argv[1], "get") == 0)
390     ret = handle_get (&argc, &argv);
391   else if (g_strcmp0 (argv[1], "set") == 0)
392     ret = handle_set (&argc, &argv);
393   else if (g_strcmp0 (argv[1], "monitor") == 0)
394     ret = handle_monitor (&argc, &argv);
395   else if (g_strcmp0 (argv[1], "writable") == 0)
396     ret = handle_writable (&argc, &argv);
397   else
398     {
399       g_printerr (_("Unknown command '%s'\n"), argv[1]);
400       ret = usage (&argc, &argv, FALSE);
401     }
402
403   return ret;
404 }