Introduce command-line config utility
authorSteven Luo <steven+maemo@steven676.net>
Wed, 26 May 2010 14:52:17 +0000 (07:52 -0700)
committerSteven Luo <steven+maemo@steven676.net>
Wed, 26 May 2010 14:52:17 +0000 (07:52 -0700)
Add a simple command-line configuration utility,
browser-switchboard-config, which can be used to query or set
browser-switchboard config settings.

The primary purpose of this tool is to allow browser vendors to provide
an option in their browsers to set themselves as the default browser,
via something like this (shell-like pseudocode):
if [ -x /usr/bin/browser-switchboard-config ]; then
if [ `browser-switchboard-config -b` = "mybrowser" ]; then
display "MyBrowser is the default browser."
else
button "Make MyBrowser the default browser" action "browser-switchboard-config -s -b mybrowser"
fi
else
display "Install Browser Switchboard to make MyBrowser the default browser"
fi
Browser vendors: setting yourself as the default browser without
prompting the user first (via package maintainer scripts, for example)
is strongly discouraged.

config-ui/Makefile
config-ui/browser-switchboard-config.c [new file with mode: 0644]

index b6a7d17..090fc67 100644 (file)
@@ -14,7 +14,9 @@ PREFIX = /usr
 other_obj = ../configfile.o ../config.o save-config.o
 
 APP = browser-switchboard-cp
 other_obj = ../configfile.o ../config.o save-config.o
 
 APP = browser-switchboard-cp
+UTIL = browser-switchboard-config
 app_obj = $(APP).app.o $(other_obj)
 app_obj = $(APP).app.o $(other_obj)
+util_obj = $(UTIL).o $(other_obj)
 HILDON_APP = $(APP)-hildon
 happ_obj = $(APP).happ.o $(other_obj)
 PLUGIN = lib$(APP).so
 HILDON_APP = $(APP)-hildon
 happ_obj = $(APP).happ.o $(other_obj)
 PLUGIN = lib$(APP).so
@@ -23,11 +25,13 @@ plugin_obj = $(APP).plugin.o ../configfile.plugin.o ../config.plugin.o save-conf
 all:
        @echo 'Usage:'
        @echo '    make app -- build standalone GTK+ application'
 all:
        @echo 'Usage:'
        @echo '    make app -- build standalone GTK+ application'
+       @echo '    make util -- build command-line configuration utility'
        @echo '    make diablo-hildon-app -- build standalone Diablo Hildon application'
        @echo '    make diablo-plugin -- build Diablo hildon-control-panel plugin'
        @echo '    make fremantle-hildon-app -- build standalone Fremantle Hildon application'
        @echo '    make fremantle-plugin -- build Fremantle hildon-control-panel plugin'
 app: $(APP)
        @echo '    make diablo-hildon-app -- build standalone Diablo Hildon application'
        @echo '    make diablo-plugin -- build Diablo hildon-control-panel plugin'
        @echo '    make fremantle-hildon-app -- build standalone Fremantle Hildon application'
        @echo '    make fremantle-plugin -- build Fremantle hildon-control-panel plugin'
 app: $(APP)
+util: $(UTIL)
 diablo-hildon-app: $(HILDON_APP)
 diablo-plugin: $(PLUGIN)
 fremantle-hildon-app:
 diablo-hildon-app: $(HILDON_APP)
 diablo-plugin: $(PLUGIN)
 fremantle-hildon-app:
@@ -41,6 +45,9 @@ $(APP): $(app_obj)
 %.app.o: %.c
        $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
 
 %.app.o: %.c
        $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
 
+$(UTIL): $(util_obj)
+       $(CC) $(CFLAGS) -o $(UTIL) $(util_obj) $(LDFLAGS)
+
 $(HILDON_APP): $(happ_obj)
        $(CC) $(CFLAGS) -o $(HILDON_APP) $(happ_obj) \
                $(LDFLAGS) $(LDFLAGS_HILDON)
 $(HILDON_APP): $(happ_obj)
        $(CC) $(CFLAGS) -o $(HILDON_APP) $(happ_obj) \
                $(LDFLAGS) $(LDFLAGS_HILDON)
@@ -69,6 +76,6 @@ install-plugin: $(PLUGIN)
        install -c -m 0644 $(APP).desktop $(DESTDIR)$(PREFIX)/share/applications/hildon-control-panel
 
 clean:
        install -c -m 0644 $(APP).desktop $(DESTDIR)$(PREFIX)/share/applications/hildon-control-panel
 
 clean:
-       rm -f $(APP) $(HILDON_APP) $(PLUGIN) $(app_obj) $(happ_obj) $(plugin_obj)
+       rm -f $(APP) $(UTIL) $(HILDON_APP) $(PLUGIN) $(app_obj) $(util_obj) $(happ_obj) $(plugin_obj)
 
 
-.PHONY: strip strip-plugin install install-plugin app diablo-hildon-app diablo-plugin fremantle-hildon-app fremantle-plugin
+.PHONY: strip strip-plugin install install-plugin app util diablo-hildon-app diablo-plugin fremantle-hildon-app fremantle-plugin
diff --git a/config-ui/browser-switchboard-config.c b/config-ui/browser-switchboard-config.c
new file mode 100644 (file)
index 0000000..c14b80f
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * browser-switchboard-config.c -- command-line configuration utility for 
+ * Browser Switchboard
+ * 
+ * Copyright (C) 2009-2010 Steven Luo
+ * 
+ * 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, 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 Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <getopt.h>
+
+#include "config.h"
+
+extern struct swb_config_option swb_config_options[];
+
+static int get_config_value(char *name) {
+       struct swb_config cfg;
+       int i;
+       struct swb_config_option optinfo;
+       int retval = 1;
+
+       swb_config_init(&cfg);
+
+       if (!swb_config_load(&cfg))
+               return 1;
+
+       for (i = 0; swb_config_options[i].name; ++i) {
+               optinfo = swb_config_options[i];
+               if (strcmp(name, optinfo.name))
+                       continue;
+
+               switch (optinfo.type) {
+                 case SWB_CONFIG_OPT_STRING:
+                       printf("%s\n", *(char **)cfg.entries[i]);
+                       break;
+                 case SWB_CONFIG_OPT_INT:
+                       printf("%d\n", *(int *)cfg.entries[i]);
+                       break;
+                 default:
+                       break;
+               }
+               retval = 0;
+               break;
+       }
+
+       swb_config_free(&cfg);
+
+       return retval;
+}
+
+static int set_config_value(char *name, char *value) {
+       struct swb_config cfg;
+       int i;
+       struct swb_config_option optinfo;
+       int retval = 1;
+
+       swb_config_init(&cfg);
+
+       if (!swb_config_load(&cfg))
+               return 1;
+
+       for (i = 0; swb_config_options[i].name; ++i) {
+               optinfo = swb_config_options[i];
+               if (strcmp(name, optinfo.name))
+                       continue;
+
+               switch (optinfo.type) {
+                 case SWB_CONFIG_OPT_STRING:
+                       /* Free any existing string */
+                       if (cfg.flags & optinfo.set_mask)
+                               free(*(char **)cfg.entries[i]);
+
+                       if (strlen(value) == 0) {
+                               /* If the new value is empty, clear the config
+                                  setting */
+                               *(char **)cfg.entries[i] = NULL;
+                               cfg.flags &= ~optinfo.set_mask;
+                       } else {
+                               /* Make a copy of the string -- it's not safe
+                                  to free value, which comes from argv */
+                               if (!(*(char **)cfg.entries[i] =
+                                     strdup(value)))
+                                       exit(1);
+                               cfg.flags |= optinfo.set_mask;
+                       }
+                       break;
+                 case SWB_CONFIG_OPT_INT:
+                       if (strlen(value) == 0) {
+                               /* If the new value is empty, clear the config
+                                  setting */
+                               cfg.flags &= ~optinfo.set_mask;
+                       } else {
+                               *(int *)cfg.entries[i] = atoi(value);
+                               cfg.flags |= optinfo.set_mask;
+                       }
+                       break;
+               }
+               retval = 0;
+               break;
+       }
+
+       if (!retval)
+               if (!swb_config_save(&cfg))
+                       retval = 1;
+
+       swb_config_free(&cfg);
+
+       /* Try to send SIGHUP to any running browser-switchboard process
+          This causes it to reread config files if in continuous_mode, or
+          die so that the config will be reloaded on next start otherwise */
+       system("kill -HUP `pidof browser-switchboard` > /dev/null 2>&1");
+
+       return retval;
+}
+
+void usage(void) {
+       printf("Usage:\n");
+       printf("  browser-switchboard-config -b -- Display default browser\n");
+       printf("  browser-switchboard-config -c -- Display command used when default browser is \"other\"\n");
+       printf("  browser-switchboard-config -m -- Display continuous mode setting\n");
+       printf("  browser-switchboard-config -o option -- Display value of option\n");
+       printf("\n");
+       printf("  browser-switchboard-config -s [-b|-c|-m|-o option] value -- Set the selected option to value\n");
+       printf("\n");
+       printf("  browser-switchboard-config -h -- Show this message\n");
+}
+
+int main(int argc, char **argv) {
+       int opt, done = 0;
+       int set = 0;
+       char *selected_opt = NULL;
+       
+       while (!done && (opt = getopt(argc, argv, "hsbcmo:")) != -1) {
+               switch (opt) {
+                 case 'h':
+                       usage();
+                       exit(0);
+                       break;
+                 case 's':
+                       set = 1;
+                       break;
+                 case 'b':
+                       selected_opt = "default_browser";
+                       done = 1;
+                       break;
+                 case 'c':
+                       selected_opt = "other_browser_cmd";
+                       done = 1;
+                       break;
+                 case 'm':
+                       selected_opt = "continuous_mode";
+                       done = 1;
+                       break;
+                 case 'o':
+                       selected_opt = optarg;
+                       done = 1;
+                       break;
+                 default:
+                       usage();
+                       exit(1);
+                       break;
+               }
+       }
+
+       if (!selected_opt) {
+               printf("Must specify one of -b, -c, -m, -o\n");
+               usage();
+               exit(1);
+       }
+
+       if (set) {
+               if (optind >= argc) {
+                       printf("Value to set config option to not provided\n");
+                       usage();
+                       exit(1);
+               }
+               return set_config_value(selected_opt, argv[optind]);
+       } else
+               return get_config_value(selected_opt);
+}