diff options
Diffstat (limited to 'mate-panel/libpanel-util/panel-keyfile.c')
-rw-r--r-- | mate-panel/libpanel-util/panel-keyfile.c | 363 |
1 files changed, 363 insertions, 0 deletions
diff --git a/mate-panel/libpanel-util/panel-keyfile.c b/mate-panel/libpanel-util/panel-keyfile.c new file mode 100644 index 00000000..28ec5853 --- /dev/null +++ b/mate-panel/libpanel-util/panel-keyfile.c @@ -0,0 +1,363 @@ +/* + * panel-keyfile.c: GKeyFile extensions + * + * Copyright (C) 2008 Novell, Inc. + * + * Based on code from panel-util.c (there was no copyright header at the time) + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Authors: + * Vincent Untz <[email protected]> + */ + +#include <string.h> +#include <sys/stat.h> + +#include <glib.h> +#include <gio/gio.h> + +#include "panel-keyfile.h" + +#define KEYFILE_TRUSTED_SHEBANG "#!/usr/bin/env xdg-open\n" + +GKeyFile * +panel_key_file_new_desktop (void) +{ + GKeyFile *retval; + + retval = g_key_file_new (); + + //FIXME? g_key_file_set_string (retval, G_KEY_FILE_DESKTOP_GROUP, "Name", _("No Name")); + g_key_file_set_string (retval, G_KEY_FILE_DESKTOP_GROUP, "Version", "1.0"); + + return retval; +} + +static void +_panel_key_file_make_executable (const gchar *path) +{ + GFile *file; + GFileInfo *info; + guint32 current_perms; + guint32 new_perms; + + file = g_file_new_for_path (path); + + info = g_file_query_info (file, + G_FILE_ATTRIBUTE_STANDARD_TYPE"," + G_FILE_ATTRIBUTE_UNIX_MODE, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL, + NULL); + + if (info == NULL) { + g_warning ("Cannot mark %s executable", path); + g_object_unref (file); + return; + } + + if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_UNIX_MODE)) { + current_perms = g_file_info_get_attribute_uint32 (info, + G_FILE_ATTRIBUTE_UNIX_MODE); + new_perms = current_perms | S_IXGRP | S_IXUSR | S_IXOTH; + if ((current_perms != new_perms) && + !g_file_set_attribute_uint32 (file, + G_FILE_ATTRIBUTE_UNIX_MODE, + new_perms, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL, NULL)) + g_warning ("Cannot mark %s executable", path); + } + + g_object_unref (info); + g_object_unref (file); +} + +//FIXME: kill this when bug #309224 is fixed +gboolean +panel_key_file_to_file (GKeyFile *keyfile, + const gchar *file, + GError **error) +{ + gchar *filename; + GError *write_error; + gchar *data; + gsize length; + gboolean res; + + g_return_val_if_fail (keyfile != NULL, FALSE); + g_return_val_if_fail (file != NULL, FALSE); + + write_error = NULL; + data = g_key_file_to_data (keyfile, &length, &write_error); + if (write_error) { + g_propagate_error (error, write_error); + return FALSE; + } + + if (!g_path_is_absolute (file)) + filename = g_filename_from_uri (file, NULL, &write_error); + else + filename = g_filename_from_utf8 (file, -1, NULL, NULL, + &write_error); + + if (write_error) { + g_propagate_error (error, write_error); + g_free (data); + return FALSE; + } + + if (!g_str_has_prefix (data, "#!")) { + gchar *new_data; + gsize new_length; + + new_length = length + strlen (KEYFILE_TRUSTED_SHEBANG); + new_data = g_malloc (new_length); + + strcpy (new_data, KEYFILE_TRUSTED_SHEBANG); + memcpy (new_data + strlen (KEYFILE_TRUSTED_SHEBANG), + data, length); + + g_free (data); + data = new_data; + length = new_length; + } + + res = g_file_set_contents (filename, data, length, &write_error); + + if (write_error) { + g_propagate_error (error, write_error); + g_free (data); + g_free (filename); + return FALSE; + } + + g_free (data); + + _panel_key_file_make_executable (filename); + g_free (filename); + + return res; +} + +gboolean +panel_key_file_load_from_uri (GKeyFile *keyfile, + const gchar *uri, + GKeyFileFlags flags, + GError **error) +{ + char *scheme; + gboolean is_local; + gboolean result; + + g_return_val_if_fail (keyfile != NULL, FALSE); + g_return_val_if_fail (uri != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + scheme = g_uri_parse_scheme (uri); + is_local = (scheme == NULL) || !g_ascii_strcasecmp (scheme, "file"); + g_free (scheme); + + if (is_local) { + char *path; + + if (g_path_is_absolute (uri)) + path = g_filename_from_utf8 (uri, -1, NULL, NULL, NULL); + else + path = g_filename_from_uri (uri, NULL, NULL); + result = g_key_file_load_from_file (keyfile, path, + flags, error); + g_free (path); + } else { + GFile *file; + char *contents; + gsize size; + gboolean ret; + + file = g_file_new_for_uri (uri); + ret = g_file_load_contents (file, NULL, &contents, &size, + NULL, NULL); + g_object_unref (file); + + if (!ret) + return FALSE; + + result = g_key_file_load_from_data (keyfile, contents, size, + flags, error); + + g_free (contents); + } + + return result; +} + +gboolean +panel_key_file_copy_and_mark_trusted (const char *source_path, + const char *target_path, + GError **error) +{ + GKeyFile *key_file; + gboolean res = FALSE; + + key_file = g_key_file_new (); + res = g_key_file_load_from_file (key_file, source_path, + G_KEY_FILE_KEEP_COMMENTS|G_KEY_FILE_KEEP_TRANSLATIONS, + error); + if (!res) { + g_key_file_free (key_file); + return FALSE; + } + + res = panel_key_file_to_file (key_file, target_path, error); + + g_key_file_free (key_file); + + return res; +} + +gboolean +panel_key_file_get_boolean (GKeyFile *keyfile, + const gchar *key, + gboolean default_value) +{ + GError *error; + gboolean retval; + + error = NULL; + retval = g_key_file_get_boolean (keyfile, G_KEY_FILE_DESKTOP_GROUP, key, &error); + if (error != NULL) { + retval = default_value; + g_error_free (error); + } + + return retval; +} + +void +panel_key_file_set_locale_string (GKeyFile *keyfile, + const gchar *key, + const gchar *value) +{ + const char *locale; + const char * const *langs_pointer; + int i; + + locale = NULL; + langs_pointer = g_get_language_names (); + for (i = 0; langs_pointer[i] != NULL; i++) { + /* find first without encoding */ + if (strchr (langs_pointer[i], '.') == NULL) { + locale = langs_pointer[i]; + break; + } + } + + if (locale) + g_key_file_set_locale_string (keyfile, G_KEY_FILE_DESKTOP_GROUP, + key, locale, value); + else + g_key_file_set_string (keyfile, G_KEY_FILE_DESKTOP_GROUP, + key, value); +} + +void +panel_key_file_remove_locale_key (GKeyFile *keyfile, + const gchar *key) +{ + const char * const *langs_pointer; + int i; + char *locale_key; + + locale_key = NULL; + langs_pointer = g_get_language_names (); + for (i = 0; langs_pointer[i] != NULL; i++) { + /* find first without encoding */ + if (strchr (langs_pointer[i], '.') == NULL) { + locale_key = g_strdup_printf ("%s[%s]", + key, langs_pointer[i]); + if (g_key_file_has_key (keyfile, G_KEY_FILE_DESKTOP_GROUP, + locale_key, NULL)) + break; + + g_free (locale_key); + locale_key = NULL; + } + } + + if (locale_key) { + g_key_file_remove_key (keyfile, G_KEY_FILE_DESKTOP_GROUP, + locale_key, NULL); + g_free (locale_key); + } else + g_key_file_remove_key (keyfile, G_KEY_FILE_DESKTOP_GROUP, + key, NULL); +} + +void +panel_key_file_remove_all_locale_key (GKeyFile *keyfile, + const gchar *key) +{ + char **keys; + int key_len; + int i; + + if (!key) + return; + + keys = g_key_file_get_keys (keyfile, G_KEY_FILE_DESKTOP_GROUP, NULL, NULL); + if (!keys) + return; + + key_len = strlen (key); + + for (i = 0; keys[i] != NULL; i++) { + int len; + + if (strncmp (keys[i], key, key_len)) + continue; + + len = strlen (keys[i]); + if (len == key_len || + (len > key_len && keys[i][key_len] == '[')) + g_key_file_remove_key (keyfile, G_KEY_FILE_DESKTOP_GROUP, + keys[i], NULL); + } + + g_strfreev (keys); +} + +void +panel_key_file_ensure_C_key (GKeyFile *keyfile, + const char *key) +{ + char *C_value; + char *buffer; + + /* Make sure we set the "C" locale strings to the terms we set here. + * This is so that if the user logs into another locale they get their + * own description there rather then empty. It is not the C locale + * however, but the user created this entry herself so it's OK */ + C_value = panel_key_file_get_string (keyfile, key); + if (C_value == NULL || C_value [0] == '\0') { + buffer = panel_key_file_get_locale_string (keyfile, key); + if (buffer) { + panel_key_file_set_string (keyfile, key, buffer); + g_free (buffer); + } + } + g_free (C_value); +} |