/* * Copyright (c) 2008 Stephan Arts * Copyright (c) 2008 Brian Tarricone * * 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 Library 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. */ #include #include #include #include #ifdef HAVE_CONFIG_H #include #endif #include #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #ifdef HAVE_ERRNO_H #include #endif #ifdef HAVE_FCNTL_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_STRING_H #include #endif #include #include #ifdef ENABLE_NLS #ifdef HAVE_LOCALE_H #include #endif #endif #include "xfconf-gvaluefuncs.h" #include "xfconf-common-private.h" #include "xfconf/xfconf.h" typedef struct { int type; char * value; }array_pair; int atoi(const char *str); void free(void *__ptr); static gboolean version = FALSE; static gboolean list = FALSE; static gboolean verbose = FALSE; static gboolean create = FALSE; static gboolean reset = FALSE; static gboolean recursive = FALSE; static gboolean force_array = FALSE; static gboolean monitor = FALSE; static gchar *channel_name = NULL; static gchar *property_name = NULL; static gchar **set_value = NULL; static gchar **type = NULL; static void xfconf_query_list_sorted (gpointer key, gpointer value, gpointer user_data) { GSList **listp = user_data; *listp = g_slist_insert_sorted (*listp, key, (GCompareFunc) g_utf8_collate); } static GOptionEntry entries[] = { { "version", 'V', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &version, N_("Version information"), NULL }, { "channel", 'c', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING, &channel_name, N_("The channel to query/modify"), NULL }, { "property", 'p', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING, &property_name, N_("The property to query/modify"), NULL }, { "set", 's', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING_ARRAY, &set_value, N_("The new value to set for the property"), NULL }, { "list", 'l', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &list, N_("List properties (or channels if -c is not specified)"), NULL }, { "verbose", 'v', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &verbose, N_("Verbose output"), NULL }, { "create", 'n', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &create, N_("Create a new property if it does not already exist"), NULL }, { "type", 't', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING_ARRAY, &type, N_("Specify the property value type"), NULL }, { "reset", 'r', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &reset, N_("Reset property"), NULL }, { "recursive", 'R', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &recursive, N_("Recursive (use with -r)"), NULL }, { "force-array", 'a', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &force_array, N_("Force array even if only one element"), NULL }, /* { "export", 'x', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING, &export_file, N_("Export channel to file"), NULL, }, { "import", 'i', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING, &import_file, N_("Import channel from file"), NULL, }, */ { "monitor", 'm', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &monitor, N_("Monitor a channel for property changes"), NULL, }, { NULL } }; char* substring(const char* str, size_t begin, size_t len) { if (str == 0 || strlen(str) == 0 || strlen(str) < begin || strlen(str) < (begin+len)) return 0; return strndup(str + begin, len); } void reset_channel(XfconfChannel *channel){ GHashTable *channel_contents; gchar *property_name=NULL; /** used getting properties */ GSList *li; /** GET LIST OF PROPERTIES */ channel_contents = xfconf_channel_get_properties(channel, property_name); if (channel_contents) { GSList *sorted_contents = NULL; /** get properties sorted */ g_hash_table_foreach (channel_contents, (GHFunc)xfconf_query_list_sorted, &sorted_contents); for (li = sorted_contents; li != NULL; li = li->next){ property_name = (gchar *) li->data; /** reset all channel */ xfconf_channel_reset_property(channel, property_name, recursive); } g_slist_free (sorted_contents); g_hash_table_destroy (channel_contents); } } int assign_value(XfconfChannel *channel, gchar *property_name, char *new_value, int type){ GType gtype = (GType) type; GValue value = { 0, }; /*gboolean prop_exists; prop_exists = xfconf_channel_has_property(channel, property_name); if (!prop_exists) g_printerr(_("Property doesn't exist.\n"));*/ if(XFCONF_TYPE_G_VALUE_ARRAY == gtype) { g_printerr(_("A value type must be specified to change an array into a single value.\n")); return 1; } if(G_VALUE_TYPE(&value)) g_value_unset(&value); g_value_init(&value, gtype); if(!_xfconf_gvalue_from_string(&value, new_value)) { g_printerr(_("Unable to convert \"%s\" to type \"%s\"\n"), new_value, g_type_name(gtype)); return 1; } if(!xfconf_channel_set_property(channel, property_name, &value)) { g_printerr(_("Failed to set property.\n")); return 1; } return 0; } int assign_array(XfconfChannel *channel, char *property_name, array_pair * array_values, int len_array){ GValue value = { 0, }; int i; GPtrArray * arr_new=NULL; arr_new=g_ptr_array_new(); for(i = 0; inext){ fprintf(file,"*%s\n", (gchar *) li->data); GValue value = { 0, }; xfconf_channel_get_property(channel,(gchar *) li->data, &value); if(XFCONF_TYPE_G_VALUE_ARRAY != G_VALUE_TYPE(&value)) { gchar *str_val = _xfconf_string_from_gvalue(&value); fprintf(file,"@%s\n", str_val ? str_val : _("(unknown)")); fprintf(file,"t%i\n", G_VALUE_TYPE(&value)); g_free(str_val); g_value_unset(&value); } else { GPtrArray *arr = g_value_get_boxed(&value); guint i; fprintf(file,"+%d\n", arr->len); for(i = 0; i < arr->len; ++i) { GValue *item_value = g_ptr_array_index(arr, i); if(item_value) { gchar *str_val = _xfconf_string_from_gvalue(item_value); fprintf(file,"@%s\n", str_val ? str_val : _("(unknown)")); fprintf(file,"t%i\n", G_VALUE_TYPE(item_value)); g_free(str_val); } } } } g_slist_free (sorted_contents); g_hash_table_destroy (channel_contents); } else { g_print(_("Channel '%s' contains no properties\n"), channel_name); } } /** CLOSE CHANNEL LIST */ g_strfreev(channels); fclose(file); } static void restore_all(){ FILE * file; char * line = NULL; size_t len = 0; ssize_t read; char * line_t; //line type char * line_d; //line data char * property_name; int i, value_type, len_array=0; XfconfChannel *channel = NULL; file = fopen("/tmp/desktop.conf", "r"); if (file == NULL) printf ("Config file not exist"); while ((read = getline(&line, &len, file)) != -1) { line_t=substring(line,0,1); //line type line_d=(char *) substring(line,1,strlen(line)-2); //line data if (*line_t == '#'){//channel channel = xfconf_channel_get (line_d); //printf ("Channel: %s\n",line_d); reset_channel(channel); } else{ if (*line_t == '*'){//property property_name = line_d; xfconf_channel_reset_property(channel, property_name, recursive); //printf ("Property: %s\n",property_name); } else{ if (*line_t == '@'){//value getline(&line, &len, file); value_type=atoi(substring(line,1,strlen(line)-2)); assign_value(channel, property_name, line_d, value_type); //printf ("Value: %s\n",line_d); } else{ if (*line_t == '+'){//array len_array=atoi(line_d); array_pair * array_values; array_values = g_new0(array_pair,len_array); for (i=0;imessage); g_error_free(error); return 1; } context = g_option_context_new("- xfconf commandline utility"); g_option_context_add_main_entries(context, entries, "xconf"); if(!g_option_context_parse(context, &argc, &argv, &cli_error)) { g_printerr("option parsing failed: %s\n", cli_error->message); return 1; } //store_all(); restore_all(); return 0; }