aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am6
-rw-r--r--src/bus-utils.c109
-rw-r--r--src/bus-utils.h11
-rw-r--r--src/hostnamed.c47
-rw-r--r--src/localed.c59
-rw-r--r--src/main.c6
-rw-r--r--src/shell-utils.h86
-rw-r--r--src/timedated.c9
-rw-r--r--src/utils.c (renamed from src/shell-utils.c)308
-rw-r--r--src/utils.h102
10 files changed, 378 insertions, 365 deletions
diff --git a/Makefile.am b/Makefile.am
index 32890fb..e12c3d7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -59,10 +59,8 @@ openrc_settingsd_SOURCES = \
src/localed.h \
src/timedated.c \
src/timedated.h \
- src/bus-utils.c \
- src/bus-utils.h \
- src/shell-utils.c \
- src/shell-utils.h \
+ src/utils.c \
+ src/utils.h \
src/main.c \
$(NULL)
diff --git a/src/bus-utils.c b/src/bus-utils.c
index f78f8f2..8db9bb4 100644
--- a/src/bus-utils.c
+++ b/src/bus-utils.c
@@ -22,113 +22,4 @@
#include "bus-utils.h"
-struct check_polkit_data {
- const gchar *unique_name;
- const gchar *action_id;
- gboolean user_interaction;
- GAsyncReadyCallback callback;
- gpointer user_data;
- PolkitAuthority *authority;
- PolkitSubject *subject;
-};
-
-void
-check_polkit_data_free (struct check_polkit_data *data)
-{
- if (data == NULL)
- return;
-
- if (data->subject != NULL)
- g_object_unref (data->subject);
- if (data->authority != NULL)
- g_object_unref (data->authority);
-
- g_free (data);
-}
-
-gboolean
-check_polkit_finish (GAsyncResult *res,
- GError **error)
-{
- GSimpleAsyncResult *simple;
-
- simple = G_SIMPLE_ASYNC_RESULT (res);
- if (g_simple_async_result_propagate_error (simple, error))
- return FALSE;
-
- return g_simple_async_result_get_op_res_gboolean (simple);
-}
-
-static void
-check_polkit_authorization_cb (GObject *source_object,
- GAsyncResult *res,
- gpointer _data)
-{
- struct check_polkit_data *data;
- PolkitAuthorizationResult *result;
- GSimpleAsyncResult *simple;
- GError *err = NULL;
-
- data = (struct check_polkit_data *) _data;
- if ((result = polkit_authority_check_authorization_finish (data->authority, res, &err)) == NULL) {
- g_simple_async_report_take_gerror_in_idle (NULL, data->callback, data->user_data, err);
- goto out;
- }
-
- if (!polkit_authorization_result_get_is_authorized (result)) {
- g_simple_async_report_error_in_idle (NULL, data->callback, data->user_data, POLKIT_ERROR, POLKIT_ERROR_NOT_AUTHORIZED, "Authorizing for '%s': not authorized", data->action_id);
- goto out;
- }
- simple = g_simple_async_result_new (NULL, data->callback, data->user_data, check_polkit_async);
- g_simple_async_result_set_op_res_gboolean (simple, TRUE);
- g_simple_async_result_complete_in_idle (simple);
- g_object_unref (simple);
-
- out:
- check_polkit_data_free (data);
- if (result != NULL)
- g_object_unref (result);
-}
-
-static void
-check_polkit_authority_cb (GObject *source_object,
- GAsyncResult *res,
- gpointer _data)
-{
- struct check_polkit_data *data;
- GError *err = NULL;
-
- data = (struct check_polkit_data *) _data;
- if ((data->authority = polkit_authority_get_finish (res, &err)) == NULL) {
- g_simple_async_report_take_gerror_in_idle (NULL, data->callback, data->user_data, err);
- check_polkit_data_free (data);
- return;
- }
- if (data->unique_name == NULL || data->action_id == NULL ||
- (data->subject = polkit_system_bus_name_new (data->unique_name)) == NULL) {
- g_simple_async_report_error_in_idle (NULL, data->callback, data->user_data, POLKIT_ERROR, POLKIT_ERROR_FAILED, "Authorizing for '%s': failed sanity check", data->action_id);
- check_polkit_data_free (data);
- return;
- }
- polkit_authority_check_authorization (data->authority, data->subject, data->action_id, NULL, (PolkitCheckAuthorizationFlags) data->user_interaction, NULL, check_polkit_authorization_cb, data);
-}
-
-void
-check_polkit_async (const gchar *unique_name,
- const gchar *action_id,
- const gboolean user_interaction,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- struct check_polkit_data *data;
-
- data = g_new0 (struct check_polkit_data, 1);
- data->unique_name = unique_name;
- data->action_id = action_id;
- data->user_interaction = user_interaction;
- data->callback = callback;
- data->user_data = user_data;
-
- polkit_authority_get_async (NULL, check_polkit_authority_cb, data);
-}
diff --git a/src/bus-utils.h b/src/bus-utils.h
index 4a57bb5..282a63e 100644
--- a/src/bus-utils.h
+++ b/src/bus-utils.h
@@ -21,15 +21,6 @@
#include <glib.h>
-void
-check_polkit_async (const gchar *unique_name,
- const gchar *action_id,
- const gboolean user_interaction,
- GAsyncReadyCallback callback,
- gpointer user_data);
-
-gboolean
-check_polkit_finish (GAsyncResult *res,
- GError **error);
+
#endif
diff --git a/src/hostnamed.c b/src/hostnamed.c
index f0992bd..1fb14c0 100644
--- a/src/hostnamed.c
+++ b/src/hostnamed.c
@@ -28,8 +28,7 @@
#include "hostnamed.h"
#include "hostname1-generated.h"
-#include "bus-utils.h"
-#include "shell-utils.h"
+#include "utils.h"
#include "config.h"
@@ -66,10 +65,12 @@ hostname_is_valid (const gchar *name)
name, G_REGEX_MULTILINE, 0);
}
-static void
+static gchar *
guess_icon_name ()
{
/* TODO: detect virtualization by reading rc_sys */
+ gchar *filebuf = NULL;
+ gchar *ret = NULL;
#if defined(__i386__) || defined(__x86_64__)
/*
@@ -80,32 +81,34 @@ guess_icon_name ()
http://www.dmtf.org/sites/default/files/standards/documents/DSP0134_2.7.1.pdf
*/
- gchar *contents;
- if (g_file_get_contents ("/sys/class/dmi/id/chassis_type", &contents, NULL, NULL)) {
- switch (g_ascii_strtoull (contents, NULL, 10)) {
+ if (g_file_get_contents ("/sys/class/dmi/id/chassis_type", &filebuf, NULL, NULL)) {
+ switch (g_ascii_strtoull (filebuf, NULL, 10)) {
case 0x3:
case 0x4:
case 0x5:
case 0x6:
case 0x7:
- icon_name = g_strdup ("computer-desktop");
- return;
+ ret = g_strdup ("computer-desktop");
+ goto out;
case 0x9:
case 0xA:
case 0xE:
- icon_name = g_strdup ("computer-laptop");
- return;
+ ret = g_strdup ("computer-laptop");
+ goto out;
case 0x11:
case 0x17:
case 0x1C:
case 0x1D:
- icon_name = g_strdup ("computer-server");
- return;
+ ret = g_strdup ("computer-server");
+ goto out;
}
}
#endif
- icon_name = g_strdup ("computer");
+ ret = g_strdup ("computer");
+ out:
+ g_free (filebuf);
+ return ret;
}
static void
@@ -198,7 +201,7 @@ on_handle_set_static_hostname_authorized_cb (GObject *source_object,
data->name = g_strdup ("localhost");
}
- if (!shell_utils_trivial_set_and_save (static_hostname_file, &err, "hostname", "HOSTNAME", data->name, NULL)) {
+ if (!shell_parser_set_and_save (static_hostname_file, &err, "hostname", "HOSTNAME", data->name, NULL)) {
g_dbus_method_invocation_return_gerror (data->invocation, err);
G_UNLOCK (static_hostname);
goto out;
@@ -257,7 +260,7 @@ on_handle_set_pretty_hostname_authorized_cb (GObject *source_object,
if (data->name == NULL)
data->name = g_strdup ("");
- if (!shell_utils_trivial_set_and_save (machine_info_file, &err, "PRETTY_HOSTNAME", NULL, data->name, NULL)) {
+ if (!shell_parser_set_and_save (machine_info_file, &err, "PRETTY_HOSTNAME", NULL, data->name, NULL)) {
g_dbus_method_invocation_return_gerror (data->invocation, err);
G_UNLOCK (machine_info);
goto out;
@@ -316,7 +319,7 @@ on_handle_set_icon_name_authorized_cb (GObject *source_object,
if (data->name == NULL)
data->name = g_strdup ("");
- if (!shell_utils_trivial_set_and_save (machine_info_file, &err, "ICON_NAME", NULL, data->name, NULL)) {
+ if (!shell_parser_set_and_save (machine_info_file, &err, "ICON_NAME", NULL, data->name, NULL)) {
g_dbus_method_invocation_return_gerror (data->invocation, err);
G_UNLOCK (machine_info);
goto out;
@@ -425,13 +428,13 @@ hostnamed_init (gboolean _read_only)
static_hostname_file = g_file_new_for_path (SYSCONFDIR "/conf.d/hostname");
machine_info_file = g_file_new_for_path (SYSCONFDIR "/machine-info");
- static_hostname = shell_utils_source_var (static_hostname_file, "${hostname-${HOSTNAME-localhost}}", &err);
+ static_hostname = shell_source_var (static_hostname_file, "${hostname-${HOSTNAME-localhost}}", &err);
if (err != NULL) {
g_debug ("%s", err->message);
g_error_free (err);
err = NULL;
}
- pretty_hostname = shell_utils_source_var (machine_info_file, "${PRETTY_HOSTNAME}", &err);
+ pretty_hostname = shell_source_var (machine_info_file, "${PRETTY_HOSTNAME}", &err);
if (pretty_hostname == NULL)
pretty_hostname = g_strdup ("");
if (err != NULL) {
@@ -439,7 +442,7 @@ hostnamed_init (gboolean _read_only)
g_error_free (err);
err = NULL;
}
- icon_name = shell_utils_source_var (machine_info_file, "${ICON_NAME}", &err);
+ icon_name = shell_source_var (machine_info_file, "${ICON_NAME}", &err);
if (icon_name == NULL)
icon_name = g_strdup ("");
if (err != NULL) {
@@ -448,8 +451,10 @@ hostnamed_init (gboolean _read_only)
err = NULL;
}
- if (icon_name == NULL || strlen (icon_name) == 0)
- guess_icon_name ();
+ if (icon_name == NULL || *icon_name == 0) {
+ g_free (icon_name);
+ icon_name = guess_icon_name ();
+ }
read_only = _read_only;
diff --git a/src/localed.c b/src/localed.c
index 2e8e44e..0cb4404 100644
--- a/src/localed.c
+++ b/src/localed.c
@@ -26,8 +26,7 @@
#include "localed.h"
#include "locale1-generated.h"
-#include "bus-utils.h"
-#include "shell-utils.h"
+#include "utils.h"
#include "config.h"
@@ -215,16 +214,17 @@ kbd_model_map_load (GError **error)
for (line = filebuf; *line != 0; line = newline + 1) {
struct kbd_model_map_entry *entry = NULL;
GMatchInfo *match_info = NULL;
+ gboolean m = FALSE;
if ((newline = strstr (line, "\n")) != NULL)
*newline = 0;
else
newline = line + strlen (line) - 1;
- if (g_regex_match (kbd_model_map_line_comment_re, line, 0, &match_info)) {
- g_match_info_free (match_info);
+ m = g_regex_match (kbd_model_map_line_comment_re, line, 0, &match_info);
+ _g_match_info_clear (&match_info);
+ if (m)
continue;
- }
if (!g_regex_match (kbd_model_map_line_re, line, 0, &match_info)) {
g_propagate_error (error,
@@ -253,7 +253,7 @@ kbd_model_map_load (GError **error)
entry->x11_options[0] = 0;
ret = g_list_prepend (ret, entry);
- g_match_info_free (match_info);
+ _g_match_info_clear (&match_info);
}
out:
if (ret != NULL)
@@ -452,6 +452,7 @@ xorg_confd_parser_new (GFile *xorg_confd_file,
struct xorg_confd_line_entry *entry = NULL;
GMatchInfo *match_info = NULL;
gboolean matched = FALSE;
+ gboolean m = FALSE;
if ((newline = strstr (line, "\n")) != NULL)
*newline = 0;
@@ -463,48 +464,48 @@ xorg_confd_parser_new (GFile *xorg_confd_file,
if (g_regex_match (xorg_confd_line_comment_re, line, 0, &match_info)) {
g_debug ("Parsed line '%s' as comment", line);
entry->type = XORG_CONFD_LINE_TYPE_COMMENT;
- } else if (g_regex_match (xorg_confd_line_section_input_class_re, line, 0, &match_info)) {
+ } else if (_g_match_info_clear (&match_info) && g_regex_match (xorg_confd_line_section_input_class_re, line, 0, &match_info)) {
g_debug ("Parsed line '%s' as InputClass section", line);
if (in_section)
goto no_match;
in_section = TRUE;
entry->type = XORG_CONFD_LINE_TYPE_SECTION_INPUT_CLASS;
- } else if (g_regex_match (xorg_confd_line_section_re, line, 0, &match_info)) {
+ } else if (_g_match_info_clear (&match_info) && g_regex_match (xorg_confd_line_section_re, line, 0, &match_info)) {
g_debug ("Parsed line '%s' as non-InputClass section", line);
if (in_section)
goto no_match;
in_section = TRUE;
entry->type = XORG_CONFD_LINE_TYPE_SECTION_OTHER;
- } else if (g_regex_match (xorg_confd_line_end_section_re, line, 0, &match_info)) {
+ } else if (_g_match_info_clear (&match_info) && g_regex_match (xorg_confd_line_end_section_re, line, 0, &match_info)) {
g_debug ("Parsed line '%s' as end of section", line);
if (!in_section)
goto no_match;
entry->type = XORG_CONFD_LINE_TYPE_END_SECTION;
- } else if (g_regex_match (xorg_confd_line_match_is_keyboard_re, line, 0, &match_info)) {
+ } else if (_g_match_info_clear (&match_info) && g_regex_match (xorg_confd_line_match_is_keyboard_re, line, 0, &match_info)) {
g_debug ("Parsed line '%s' as MatchIsKeyboard declaration", line);
if (!in_section)
goto no_match;
entry->type = XORG_CONFD_LINE_TYPE_MATCH_IS_KEYBOARD;
in_xkb_section = TRUE;
- } else if (g_regex_match (xorg_confd_line_xkb_layout_re, line, 0, &match_info)) {
+ } else if (_g_match_info_clear (&match_info) && g_regex_match (xorg_confd_line_xkb_layout_re, line, 0, &match_info)) {
g_debug ("Parsed line '%s' as XkbLayout option", line);
if (!in_section)
goto no_match;
entry->type = XORG_CONFD_LINE_TYPE_XKB_LAYOUT;
entry->value = g_match_info_fetch (match_info, 2);
- } else if (g_regex_match (xorg_confd_line_xkb_model_re, line, 0, &match_info)) {
+ } else if (_g_match_info_clear (&match_info) && g_regex_match (xorg_confd_line_xkb_model_re, line, 0, &match_info)) {
g_debug ("Parsed line '%s' as XkbModel option", line);
if (!in_section)
goto no_match;
entry->type = XORG_CONFD_LINE_TYPE_XKB_MODEL;
entry->value = g_match_info_fetch (match_info, 2);
- } else if (g_regex_match (xorg_confd_line_xkb_variant_re, line, 0, &match_info)) {
+ } else if (_g_match_info_clear (&match_info) && g_regex_match (xorg_confd_line_xkb_variant_re, line, 0, &match_info)) {
g_debug ("Parsed line '%s' as XkbVariant option", line);
if (!in_section)
goto no_match;
entry->type = XORG_CONFD_LINE_TYPE_XKB_VARIANT;
entry->value = g_match_info_fetch (match_info, 2);
- } else if (g_regex_match (xorg_confd_line_xkb_options_re, line, 0, &match_info)) {
+ } else if (_g_match_info_clear (&match_info) && g_regex_match (xorg_confd_line_xkb_options_re, line, 0, &match_info)) {
g_debug ("Parsed line '%s' as XkbOptions option", line);
if (!in_section)
goto no_match;
@@ -515,7 +516,7 @@ xorg_confd_parser_new (GFile *xorg_confd_file,
if (entry->type == XORG_CONFD_LINE_TYPE_UNKNOWN)
g_debug ("Parsing line '%s' as unknown", line);
- g_match_info_free (match_info);
+ _g_match_info_clear (&match_info);
parser->line_list = g_list_prepend (parser->line_list, entry);
if (in_section) {
if (entry->type == XORG_CONFD_LINE_TYPE_SECTION_INPUT_CLASS)
@@ -534,7 +535,7 @@ xorg_confd_parser_new (GFile *xorg_confd_file,
no_match:
/* Nothing matched... */
g_free (entry);
- g_match_info_free (match_info);
+ _g_match_info_clear (&match_info);
goto parse_fail;
}
@@ -787,7 +788,7 @@ on_handle_set_locale_authorized_cb (GObject *source_object,
GError *err = NULL;
struct invoked_locale *data;
gchar **loc, **var, **val, **locale_values = NULL;
- ShellUtilsTrivial *locale_file_parsed = NULL;
+ ShellParser *locale_file_parsed = NULL;
data = (struct invoked_locale *) user_data;
if (!check_polkit_finish (res, &err)) {
@@ -825,16 +826,16 @@ on_handle_set_locale_authorized_cb (GObject *source_object,
}
}
- if ((locale_file_parsed = shell_utils_trivial_new (locale_file, &err)) == NULL) {
+ if ((locale_file_parsed = shell_parser_new (locale_file, &err)) == NULL) {
g_dbus_method_invocation_return_gerror (data->invocation, err);
G_UNLOCK (locale);
goto out;
}
- if (shell_utils_trivial_is_empty (locale_file_parsed)) {
+ if (shell_parser_is_empty (locale_file_parsed)) {
/* Simply write the new env file */
- shell_utils_trivial_free (locale_file_parsed);
- if ((locale_file_parsed = shell_utils_trivial_new_from_string (locale_file, "# Configuration file for eselect\n# This file has been automatically generated\n", &err)) == NULL) {
+ shell_parser_free (locale_file_parsed);
+ if ((locale_file_parsed = shell_parser_new_from_string (locale_file, "# Configuration file for eselect\n# This file has been automatically generated\n", &err)) == NULL) {
g_dbus_method_invocation_return_gerror (data->invocation, err);
G_UNLOCK (locale);
goto out;
@@ -843,12 +844,12 @@ on_handle_set_locale_authorized_cb (GObject *source_object,
for (val = locale_values, var = locale_variables; *var != NULL; val++, var++) {
if (*val == NULL)
- shell_utils_trivial_clear_variable (locale_file_parsed, *var);
+ shell_parser_clear_variable (locale_file_parsed, *var);
else
- shell_utils_trivial_set_variable (locale_file_parsed, *var, *val, TRUE);
+ shell_parser_set_variable (locale_file_parsed, *var, *val, TRUE);
}
- if (!shell_utils_trivial_save (locale_file_parsed, &err)) {
+ if (!shell_parser_save (locale_file_parsed, &err)) {
g_dbus_method_invocation_return_gerror (data->invocation, err);
G_UNLOCK (locale);
goto out;
@@ -869,7 +870,7 @@ on_handle_set_locale_authorized_cb (GObject *source_object,
G_UNLOCK (locale);
out:
- shell_utils_trivial_free (locale_file_parsed);
+ shell_parser_free (locale_file_parsed);
g_strfreev (locale_values);
invoked_locale_free (data);
if (err != NULL)
@@ -954,7 +955,7 @@ on_handle_set_vconsole_keyboard_authorized_cb (GObject *source_object,
}
/* We do not set vconsole_keymap_toggle because there is no good equivalent for it in OpenRC */
- if (!shell_utils_trivial_set_and_save (keymaps_file, &err, "keymap", NULL, data->vconsole_keymap, NULL)) {
+ if (!shell_parser_set_and_save (keymaps_file, &err, "keymap", NULL, data->vconsole_keymap, NULL)) {
g_dbus_method_invocation_return_gerror (data->invocation, err);
goto unlock;
}
@@ -1145,7 +1146,7 @@ on_handle_set_x11_keyboard_authorized_cb (GObject *source_object,
g_printerr ("Failed to find conversion entry for x11 layout '%s' in '%s'\n", data->x11_layout, filename);
g_free (filename);
} else {
- if (!shell_utils_trivial_set_and_save (keymaps_file, &err, "keymap", NULL, best_entry->vconsole_keymap, NULL)) {
+ if (!shell_parser_set_and_save (keymaps_file, &err, "keymap", NULL, best_entry->vconsole_keymap, NULL)) {
g_dbus_method_invocation_return_gerror (data->invocation, err);
goto unlock;
}
@@ -1273,7 +1274,7 @@ localed_init (gboolean _read_only)
x11_systemd_file = g_file_new_for_path (SYSCONFDIR "/X11/xorg.conf.d/00-keyboard.conf");
locale = g_new0 (gchar *, g_strv_length (locale_variables) + 1);
- locale_values = shell_utils_trivial_source_var_list (locale_file, (const gchar * const *)locale_variables, &err);
+ locale_values = shell_parser_source_var_list (locale_file, (const gchar * const *)locale_variables, &err);
if (locale_values != NULL) {
gchar **variable, **value, **loc;
loc = locale;
@@ -1291,7 +1292,7 @@ localed_init (gboolean _read_only)
g_clear_error (&err);
}
- vconsole_keymap = shell_utils_source_var (keymaps_file, "${keymap}", &err);
+ vconsole_keymap = shell_source_var (keymaps_file, "${keymap}", &err);
if (vconsole_keymap == NULL)
vconsole_keymap = g_strdup ("");
if (err != NULL) {
diff --git a/src/main.c b/src/main.c
index b7d6324..54eb407 100644
--- a/src/main.c
+++ b/src/main.c
@@ -25,7 +25,7 @@
#include "hostnamed.h"
#include "localed.h"
#include "timedated.h"
-#include "shell-utils.h"
+#include "utils.h"
#include "config.h"
@@ -76,7 +76,7 @@ main (gint argc, gchar *argv[])
} else
g_log_set_default_handler (log_handler, NULL);
- shell_utils_init ();
+ utils_init ();
hostnamed_init (read_only);
localed_init (read_only);
timedated_init (read_only, ntp_preferred_service);
@@ -87,7 +87,7 @@ main (gint argc, gchar *argv[])
timedated_destroy ();
localed_destroy ();
hostnamed_destroy ();
- shell_utils_destroy ();
+ utils_destroy ();
g_free (ntp_preferred_service);
return 0;
}
diff --git a/src/shell-utils.h b/src/shell-utils.h
deleted file mode 100644
index 629d017..0000000
--- a/src/shell-utils.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- Copyright 2012 Alexandre Rostovtsev
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#ifndef _SHELL_UTILS_H_
-#define _SHELL_UTILS_H_
-
-#include <glib.h>
-#include <gio/gio.h>
-
-typedef struct _ShellUtilsTrivial ShellUtilsTrivial;
-
-struct _ShellUtilsTrivial
-{
- GFile *file;
- gchar *filename;
- GList *entry_list;
-};
-
-gchar *
-shell_utils_source_var (GFile *file,
- const gchar *variable,
- GError **error);
-
-void
-shell_utils_init (void);
-
-void
-shell_utils_destroy (void);
-
-ShellUtilsTrivial *
-shell_utils_trivial_new (GFile *file,
- GError **error);
-
-ShellUtilsTrivial *
-shell_utils_trivial_new_from_string (GFile *file,
- gchar *filebuf,
- GError **error);
-
-void
-shell_utils_trivial_free (ShellUtilsTrivial *trivial);
-
-gboolean
-shell_utils_trivial_is_empty (ShellUtilsTrivial *trivial);
-
-gboolean
-shell_utils_trivial_set_variable (ShellUtilsTrivial *trivial,
- const gchar *variable,
- const gchar *value,
- gboolean add_if_unset);
-
-void
-shell_utils_trivial_clear_variable (ShellUtilsTrivial *trivial,
- const gchar *variable);
-
-gboolean
-shell_utils_trivial_save (ShellUtilsTrivial *trivial,
- GError **error);
-
-gboolean
-shell_utils_trivial_set_and_save (GFile *file,
- GError **error,
- const gchar *first_var_name,
- const gchar *first_alt_var_name,
- const gchar *first_value,
- ...);
-
-gchar **
-shell_utils_trivial_source_var_list (GFile *file,
- const gchar * const *var_names,
- GError **error);
-#endif
diff --git a/src/timedated.c b/src/timedated.c
index b8a41fc..d6588f4 100644
--- a/src/timedated.c
+++ b/src/timedated.c
@@ -30,8 +30,7 @@
#include "copypaste/hwclock.h"
#include "timedated.h"
#include "timedate1-generated.h"
-#include "bus-utils.h"
-#include "shell-utils.h"
+#include "utils.h"
#include "config.h"
@@ -61,7 +60,7 @@ get_local_rtc (GError **error)
gchar *clock = NULL;
gboolean ret = FALSE;
- clock = shell_utils_source_var (hwclock_file, "${clock}", error);
+ clock = shell_source_var (hwclock_file, "${clock}", error);
if (!g_strcmp0 (clock, "local"))
ret = TRUE;
return ret;
@@ -468,9 +467,9 @@ on_handle_set_local_rtc_authorized_cb (GObject *source_object,
}
G_LOCK (clock);
- clock = shell_utils_source_var (hwclock_file, "${clock}", NULL);
+ clock = shell_source_var (hwclock_file, "${clock}", NULL);
if (clock != NULL || data->local_rtc)
- if (!shell_utils_trivial_set_and_save (hwclock_file, &err, "clock", NULL, clock_types[data->local_rtc], NULL)) {
+ if (!shell_parser_set_and_save (hwclock_file, &err, "clock", NULL, clock_types[data->local_rtc], NULL)) {
g_dbus_method_invocation_return_gerror (data->invocation, err);
goto unlock;
}
diff --git a/src/shell-utils.c b/src/utils.c
index f5c9b20..d21f9f4 100644
--- a/src/shell-utils.c
+++ b/src/utils.c
@@ -21,8 +21,9 @@
#include <glib.h>
#include <gio/gio.h>
+#include <polkit/polkit.h>
-#include "shell-utils.h"
+#include "utils.h"
#include "config.h"
@@ -34,6 +35,128 @@ GRegex *single_quoted_regex = NULL;
GRegex *double_quoted_regex = NULL;
GRegex *unquoted_regex = NULL;
+/* Always returns TRUE */
+gboolean
+_g_match_info_clear (GMatchInfo **match_info)
+{
+ if (match_info == NULL || *match_info == NULL)
+ return TRUE;
+ g_match_info_free (*match_info);
+ *match_info = NULL;
+ return TRUE;
+}
+
+struct check_polkit_data {
+ const gchar *unique_name;
+ const gchar *action_id;
+ gboolean user_interaction;
+ GAsyncReadyCallback callback;
+ gpointer user_data;
+
+ PolkitAuthority *authority;
+ PolkitSubject *subject;
+};
+
+void
+check_polkit_data_free (struct check_polkit_data *data)
+{
+ if (data == NULL)
+ return;
+
+ if (data->subject != NULL)
+ g_object_unref (data->subject);
+ if (data->authority != NULL)
+ g_object_unref (data->authority);
+
+ g_free (data);
+}
+
+gboolean
+check_polkit_finish (GAsyncResult *res,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+
+ simple = G_SIMPLE_ASYNC_RESULT (res);
+ if (g_simple_async_result_propagate_error (simple, error))
+ return FALSE;
+
+ return g_simple_async_result_get_op_res_gboolean (simple);
+}
+
+static void
+check_polkit_authorization_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer _data)
+{
+ struct check_polkit_data *data;
+ PolkitAuthorizationResult *result;
+ GSimpleAsyncResult *simple;
+ GError *err = NULL;
+
+ data = (struct check_polkit_data *) _data;
+ if ((result = polkit_authority_check_authorization_finish (data->authority, res, &err)) == NULL) {
+ g_simple_async_report_take_gerror_in_idle (NULL, data->callback, data->user_data, err);
+ goto out;
+ }
+
+ if (!polkit_authorization_result_get_is_authorized (result)) {
+ g_simple_async_report_error_in_idle (NULL, data->callback, data->user_data, POLKIT_ERROR, POLKIT_ERROR_NOT_AUTHORIZED, "Authorizing for '%s': not authorized", data->action_id);
+ goto out;
+ }
+ simple = g_simple_async_result_new (NULL, data->callback, data->user_data, check_polkit_async);
+ g_simple_async_result_set_op_res_gboolean (simple, TRUE);
+ g_simple_async_result_complete_in_idle (simple);
+ g_object_unref (simple);
+
+ out:
+ check_polkit_data_free (data);
+ if (result != NULL)
+ g_object_unref (result);
+}
+
+static void
+check_polkit_authority_cb (GObject *source_object,
+ GAsyncResult *res,
+ gpointer _data)
+{
+ struct check_polkit_data *data;
+ GError *err = NULL;
+
+ data = (struct check_polkit_data *) _data;
+ if ((data->authority = polkit_authority_get_finish (res, &err)) == NULL) {
+ g_simple_async_report_take_gerror_in_idle (NULL, data->callback, data->user_data, err);
+ check_polkit_data_free (data);
+ return;
+ }
+ if (data->unique_name == NULL || data->action_id == NULL ||
+ (data->subject = polkit_system_bus_name_new (data->unique_name)) == NULL) {
+ g_simple_async_report_error_in_idle (NULL, data->callback, data->user_data, POLKIT_ERROR, POLKIT_ERROR_FAILED, "Authorizing for '%s': failed sanity check", data->action_id);
+ check_polkit_data_free (data);
+ return;
+ }
+ polkit_authority_check_authorization (data->authority, data->subject, data->action_id, NULL, (PolkitCheckAuthorizationFlags) data->user_interaction, NULL, check_polkit_authorization_cb, data);
+}
+
+void
+check_polkit_async (const gchar *unique_name,
+ const gchar *action_id,
+ const gboolean user_interaction,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ struct check_polkit_data *data;
+
+ data = g_new0 (struct check_polkit_data, 1);
+ data->unique_name = unique_name;
+ data->action_id = action_id;
+ data->user_interaction = user_interaction;
+ data->callback = callback;
+ data->user_data = user_data;
+
+ polkit_authority_get_async (NULL, check_polkit_authority_cb, data);
+}
+
enum ShellEntryType {
SHELL_ENTRY_TYPE_INDENT,
SHELL_ENTRY_TYPE_COMMENT,
@@ -49,9 +172,9 @@ struct ShellEntry {
};
gchar *
-shell_utils_source_var (GFile *file,
- const gchar *variable,
- GError **error)
+shell_source_var (GFile *file,
+ const gchar *variable,
+ GError **error)
{
gchar *argv[4] = { "sh", "-c", NULL, NULL };
gchar *filename = NULL, *quoted_filename = NULL;
@@ -110,26 +233,27 @@ shell_entry_free (struct ShellEntry *entry)
}
void
-shell_utils_trivial_free (ShellUtilsTrivial *trivial)
+shell_parser_free (ShellParser *parser)
{
- if (trivial == NULL)
+ if (parser == NULL)
return;
- if (trivial->file != NULL)
- g_object_unref (trivial->file);
- if (trivial->filename != NULL)
- g_free (trivial->filename);
- if (trivial->entry_list != NULL)
- g_list_free_full (trivial->entry_list, (GDestroyNotify)shell_entry_free);
- g_free (trivial);
+ if (parser->file != NULL)
+ g_object_unref (parser->file);
+ if (parser->filename != NULL)
+ g_free (parser->filename);
+ if (parser->entry_list != NULL)
+ g_list_free_full (parser->entry_list, (GDestroyNotify)shell_entry_free);
+ g_free (parser);
}
-ShellUtilsTrivial *
-shell_utils_trivial_new (GFile *file,
- GError **error)
+ShellParser *
+shell_parser_new (GFile *file,
+ GError **error)
{
gchar *filebuf = NULL;
GError *local_err = NULL;
+ ShellParser *ret = NULL;
if (file == NULL)
return NULL;
@@ -138,10 +262,8 @@ shell_utils_trivial_new (GFile *file,
if (local_err != NULL) {
/* Inability to parse or open is a failure; file not existing at all is *not* a failure */
if (local_err->code == G_IO_ERROR_NOT_FOUND) {
- ShellUtilsTrivial *ret = NULL;
-
g_error_free (local_err);
- ret = g_new0 (ShellUtilsTrivial, 1);
+ ret = g_new0 (ShellParser, 1);
g_object_ref (file);
ret->file = file;
ret->filename = g_file_get_path (file);
@@ -155,22 +277,24 @@ shell_utils_trivial_new (GFile *file,
}
return NULL;
}
- return shell_utils_trivial_new_from_string (file, filebuf, error);
+ ret = shell_parser_new_from_string (file, filebuf, error);
+ g_free (filebuf);
+ return ret;
}
-ShellUtilsTrivial *
-shell_utils_trivial_new_from_string (GFile *file,
+ShellParser *
+shell_parser_new_from_string (GFile *file,
gchar *filebuf,
GError **error)
{
- ShellUtilsTrivial *ret = NULL;
+ ShellParser *ret = NULL;
GError *local_err = NULL;
gchar *s;
if (file == NULL || filebuf == NULL)
return NULL;
- ret = g_new0 (ShellUtilsTrivial, 1);
+ ret = g_new0 (ShellParser, 1);
g_object_ref (file);
ret->file = file;
ret->filename = g_file_get_path (file);
@@ -191,13 +315,11 @@ shell_utils_trivial_new_from_string (GFile *file,
ret->entry_list = g_list_prepend (ret->entry_list, entry);
s += strlen (entry->string);
g_debug ("Scanned comment: ``%s''", entry->string);
- g_match_info_free (match_info);
- match_info = NULL;
+ _g_match_info_clear (&match_info);
want_separator = FALSE;
continue;
}
- g_match_info_free (match_info);
- match_info = NULL;
+ _g_match_info_clear (&match_info);
matched = g_regex_match (separator_regex, s, 0, &match_info);
if (matched) {
@@ -207,13 +329,11 @@ shell_utils_trivial_new_from_string (GFile *file,
ret->entry_list = g_list_prepend (ret->entry_list, entry);
s += strlen (entry->string);
g_debug ("Scanned separator: ``%s''", entry->string);
- g_match_info_free (match_info);
- match_info = NULL;
+ _g_match_info_clear (&match_info);
want_separator = FALSE;
continue;
}
- g_match_info_free (match_info);
- match_info = NULL;
+ _g_match_info_clear (&match_info);
matched = g_regex_match (indent_regex, s, 0, &match_info);
if (matched) {
@@ -223,12 +343,10 @@ shell_utils_trivial_new_from_string (GFile *file,
ret->entry_list = g_list_prepend (ret->entry_list, entry);
s += strlen (entry->string);
g_debug ("Scanned indent: ``%s''", entry->string);
- g_match_info_free (match_info);
- match_info = NULL;
+ _g_match_info_clear (&match_info);
continue;
}
- g_match_info_free (match_info);
- match_info = NULL;
+ _g_match_info_clear (&match_info);
matched = g_regex_match (var_equals_regex, s, 0, &match_info);
if (matched) {
@@ -243,8 +361,7 @@ shell_utils_trivial_new_from_string (GFile *file,
entry->variable = g_match_info_fetch (match_info, 1);
s += strlen (entry->string);
g_debug ("Scanned variable: ``%s''", entry->string);
- g_match_info_free (match_info);
- match_info = NULL;
+ _g_match_info_clear (&match_info);
want_separator = TRUE;
while (*s != 0) {
@@ -255,26 +372,23 @@ shell_utils_trivial_new_from_string (GFile *file,
if (matched2)
goto append_value;
- g_match_info_free (match_info);
- match_info = NULL;
+ _g_match_info_clear (&match_info);
matched2 = g_regex_match (double_quoted_regex, s, 0, &match_info);
if (matched2)
goto append_value;
- g_match_info_free (match_info);
- match_info = NULL;
+ _g_match_info_clear (&match_info);
matched2 = g_regex_match (unquoted_regex, s, 0, &match_info);
if (matched2)
goto append_value;
- g_match_info_free (match_info);
- match_info = NULL;
+ _g_match_info_clear (&match_info);
break;
-append_value:
+ append_value:
if (raw_value == NULL) {
raw_value = g_match_info_fetch (match_info, 0);
s += strlen (raw_value);
@@ -288,8 +402,7 @@ append_value:
g_free (temp1);
g_free (temp2);
}
- g_match_info_free (match_info);
- match_info = NULL;
+ _g_match_info_clear (&match_info);
}
if (raw_value != NULL) {
@@ -307,17 +420,16 @@ append_value:
continue;
}
-no_match:
+ no_match:
/* Nothing matches, parsing has failed! */
- g_match_info_free (match_info);
- match_info = NULL;
+ _g_match_info_clear (&match_info);
if (local_err != NULL)
g_propagate_prefixed_error (error, local_err, "Unable to parse '%s':", ret->filename);
else
g_propagate_error (error,
g_error_new (G_FILE_ERROR, G_FILE_ERROR_FAILED,
"Unable to parse '%s'", ret->filename));
- shell_utils_trivial_free (ret);
+ shell_parser_free (ret);
return NULL;
}
@@ -326,28 +438,28 @@ no_match:
}
gboolean
-shell_utils_trivial_is_empty (ShellUtilsTrivial *trivial)
+shell_parser_is_empty (ShellParser *parser)
{
- if (trivial == NULL || trivial->entry_list == NULL)
+ if (parser == NULL || parser->entry_list == NULL)
return TRUE;
return FALSE;
}
gboolean
-shell_utils_trivial_set_variable (ShellUtilsTrivial *trivial,
- const gchar *variable,
- const gchar *value,
- gboolean add_if_unset)
+shell_parser_set_variable (ShellParser *parser,
+ const gchar *variable,
+ const gchar *value,
+ gboolean add_if_unset)
{
GList *curr = NULL;
struct ShellEntry *found_entry = NULL;
gchar *quoted_value = NULL;
gboolean ret = FALSE;
- g_assert (trivial != NULL);
+ g_assert (parser != NULL);
g_assert (variable != NULL);
- for (curr = trivial->entry_list; curr != NULL; curr = curr->next) {
+ for (curr = parser->entry_list; curr != NULL; curr = curr->next) {
struct ShellEntry *entry;
entry = (struct ShellEntry *)(curr->data);
@@ -367,7 +479,7 @@ shell_utils_trivial_set_variable (ShellUtilsTrivial *trivial,
found_entry->type = SHELL_ENTRY_TYPE_ASSIGNMENT;
found_entry->variable = g_strdup (variable);
found_entry->string = g_strdup_printf ("%s=%s", variable, quoted_value);
- trivial->entry_list = g_list_append (trivial->entry_list, found_entry);
+ parser->entry_list = g_list_append (parser->entry_list, found_entry);
ret = TRUE;
}
}
@@ -377,16 +489,16 @@ shell_utils_trivial_set_variable (ShellUtilsTrivial *trivial,
}
void
-shell_utils_trivial_clear_variable (ShellUtilsTrivial *trivial,
- const gchar *variable)
+shell_parser_clear_variable (ShellParser *parser,
+ const gchar *variable)
{
GList *curr = NULL;
gboolean ret = FALSE;
- g_assert (trivial != NULL);
+ g_assert (parser != NULL);
g_assert (variable != NULL);
- for (curr = trivial->entry_list; curr != NULL; ) {
+ for (curr = parser->entry_list; curr != NULL; ) {
struct ShellEntry *entry;
entry = (struct ShellEntry *)(curr->data);
@@ -409,32 +521,32 @@ shell_utils_trivial_clear_variable (ShellUtilsTrivial *trivial,
}
gboolean
-shell_utils_trivial_save (ShellUtilsTrivial *trivial,
- GError **error)
+shell_parser_save (ShellParser *parser,
+ GError **error)
{
gboolean ret = FALSE;
GList *curr = NULL;
GFileOutputStream *os;
- g_assert (trivial != NULL && trivial->file != NULL && trivial->filename != NULL);
- if ((os = g_file_replace (trivial->file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, error)) == NULL) {
- g_prefix_error (error, "Unable to save '%s': ", trivial->filename);
+ g_assert (parser != NULL && parser->file != NULL && parser->filename != NULL);
+ if ((os = g_file_replace (parser->file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, error)) == NULL) {
+ g_prefix_error (error, "Unable to save '%s': ", parser->filename);
goto out;
}
- for (curr = trivial->entry_list; curr != NULL; curr = curr->next) {
+ for (curr = parser->entry_list; curr != NULL; curr = curr->next) {
struct ShellEntry *entry;
gsize written;
entry = (struct ShellEntry *)(curr->data);
if (!g_output_stream_write_all (G_OUTPUT_STREAM (os), entry->string, strlen (entry->string), &written, NULL, error)) {
- g_prefix_error (error, "Unable to save '%s': ", trivial->filename);
+ g_prefix_error (error, "Unable to save '%s': ", parser->filename);
goto out;
}
}
if (!g_output_stream_close (G_OUTPUT_STREAM (os), NULL, error)) {
- g_prefix_error (error, "Unable to save '%s': ", trivial->filename);
+ g_prefix_error (error, "Unable to save '%s': ", parser->filename);
g_output_stream_close (G_OUTPUT_STREAM (os), NULL, NULL);
goto out;
}
@@ -447,20 +559,20 @@ shell_utils_trivial_save (ShellUtilsTrivial *trivial,
}
gboolean
-shell_utils_trivial_set_and_save (GFile *file,
- GError **error,
- const gchar *first_var_name,
- const gchar *first_alt_var_name,
- const gchar *first_value,
- ...)
+shell_parser_set_and_save (GFile *file,
+ GError **error,
+ const gchar *first_var_name,
+ const gchar *first_alt_var_name,
+ const gchar *first_value,
+ ...)
{
va_list ap;
- ShellUtilsTrivial *trivial;
+ ShellParser *parser;
gboolean ret = FALSE;
const gchar *var_name, *alt_var_name, *value;
va_start (ap, first_value);
- if ((trivial = shell_utils_trivial_new (file, error)) == NULL)
+ if ((parser = shell_parser_new (file, error)) == NULL)
goto out;
var_name = first_var_name;
@@ -468,56 +580,56 @@ shell_utils_trivial_set_and_save (GFile *file,
value = first_value;
do {
if (alt_var_name == NULL) {
- if (!shell_utils_trivial_set_variable (trivial, var_name, value, TRUE)) {
+ if (!shell_parser_set_variable (parser, var_name, value, TRUE)) {
g_propagate_error (error,
g_error_new (G_FILE_ERROR, G_FILE_ERROR_FAILED,
- "Unable to set %s in '%s'", var_name, trivial->filename));
+ "Unable to set %s in '%s'", var_name, parser->filename));
goto out;
}
} else {
- if (!shell_utils_trivial_set_variable (trivial, var_name, value, FALSE) &&
- !shell_utils_trivial_set_variable (trivial, alt_var_name, value, FALSE) &&
- !shell_utils_trivial_set_variable (trivial, var_name, value, TRUE)) {
+ if (!shell_parser_set_variable (parser, var_name, value, FALSE) &&
+ !shell_parser_set_variable (parser, alt_var_name, value, FALSE) &&
+ !shell_parser_set_variable (parser, var_name, value, TRUE)) {
g_propagate_error (error,
g_error_new (G_FILE_ERROR, G_FILE_ERROR_FAILED,
- "Unable to set %s or %s in '%s'", var_name, alt_var_name, trivial->filename));
+ "Unable to set %s or %s in '%s'", var_name, alt_var_name, parser->filename));
goto out;
}
}
} while ((var_name = va_arg (ap, const gchar*)) != NULL ?
alt_var_name = va_arg (ap, const gchar*), value = va_arg (ap, const gchar*), 1 : 0);
- if (!shell_utils_trivial_save (trivial, error))
+ if (!shell_parser_save (parser, error))
goto out;
ret = TRUE;
out:
va_end (ap);
- if (trivial != NULL)
- shell_utils_trivial_free (trivial);
+ if (parser != NULL)
+ shell_parser_free (parser);
return ret;
}
gchar **
-shell_utils_trivial_source_var_list (GFile *file,
- const gchar * const *var_names,
- GError **error)
+shell_parser_source_var_list (GFile *file,
+ const gchar * const *var_names,
+ GError **error)
{
- ShellUtilsTrivial *trivial;
+ ShellParser *parser;
gchar **ret = NULL, **value;
const gchar* const* var_name;
if (var_names == NULL)
return NULL;
- if ((trivial = shell_utils_trivial_new (file, error)) == NULL)
+ if ((parser = shell_parser_new (file, error)) == NULL)
return NULL;
ret = g_new0 (gchar *, g_strv_length ((gchar **)var_names) + 1);
for (var_name = var_names, value = ret; *var_name != NULL; var_name++, value++) {
GList *curr;
- for (curr = trivial->entry_list; curr != NULL; curr = curr->next) {
+ for (curr = parser->entry_list; curr != NULL; curr = curr->next) {
struct ShellEntry *entry;
entry = (struct ShellEntry *)(curr->data);
@@ -525,12 +637,12 @@ shell_utils_trivial_source_var_list (GFile *file,
*value = g_strdup (entry->unquoted_value);
}
}
- shell_utils_trivial_free (trivial);
+ shell_parser_free (parser);
return ret;
}
void
-shell_utils_destroy (void)
+utils_destroy (void)
{
if (indent_regex != NULL) {
g_regex_unref (indent_regex);
@@ -563,7 +675,7 @@ shell_utils_destroy (void)
}
void
-shell_utils_init (void)
+utils_init (void)
{
if (indent_regex == NULL) {
indent_regex = g_regex_new ("^[ \\t]+", G_REGEX_ANCHORED, 0, NULL);
diff --git a/src/utils.h b/src/utils.h
new file mode 100644
index 0000000..bf03d3e
--- /dev/null
+++ b/src/utils.h
@@ -0,0 +1,102 @@
+/*
+ Copyright 2012 Alexandre Rostovtsev
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef _SHELL_UTILS_H_
+#define _SHELL_UTILS_H_
+
+#include <glib.h>
+#include <gio/gio.h>
+
+typedef struct _ShellParser ShellParser;
+
+struct _ShellParser
+{
+ GFile *file;
+ gchar *filename;
+ GList *entry_list;
+};
+
+/* Always return TRUE */
+gboolean
+_g_match_info_clear (GMatchInfo **match_info);
+
+void
+check_polkit_async (const gchar *unique_name,
+ const gchar *action_id,
+ const gboolean user_interaction,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+gboolean
+check_polkit_finish (GAsyncResult *res,
+ GError **error);
+
+gchar *
+shell_source_var (GFile *file,
+ const gchar *variable,
+ GError **error);
+
+ShellParser *
+shell_parser_new (GFile *file,
+ GError **error);
+
+ShellParser *
+shell_parser_new_from_string (GFile *file,
+ gchar *filebuf,
+ GError **error);
+
+void
+shell_parser_free (ShellParser *parser);
+
+gboolean
+shell_parser_is_empty (ShellParser *parser);
+
+gboolean
+shell_parser_set_variable (ShellParser *parser,
+ const gchar *variable,
+ const gchar *value,
+ gboolean add_if_unset);
+
+void
+shell_parser_clear_variable (ShellParser *parser,
+ const gchar *variable);
+
+gboolean
+shell_parser_save (ShellParser *parser,
+ GError **error);
+
+gboolean
+shell_parser_set_and_save (GFile *file,
+ GError **error,
+ const gchar *first_var_name,
+ const gchar *first_alt_var_name,
+ const gchar *first_value,
+ ...);
+
+gchar **
+shell_parser_source_var_list (GFile *file,
+ const gchar * const *var_names,
+ GError **error);
+
+void
+utils_init (void);
+
+void
+utils_destroy (void);
+
+#endif