--- /dev/null
+CC = gcc
+CFLAGS = -Wall -Os -mcpu=arm1136jf-s -mthumb
+CPPFLAGS = -Wall `pkg-config --cflags dbus-glib-1`
+LDFLAGS = `pkg-config --libs dbus-glib-1`
+PREFIX = /usr/local
+
+APP = browser-switchboard
+obj = main.o launcher.o dbus-server-bindings.o
+
+all: $(APP)
+
+$(APP): dbus-server-glue.h $(obj)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $(APP) $(obj)
+
+dbus-server-glue.h:
+ dbus-binding-tool --mode=glib-server --prefix="osso_browser" \
+ dbus-server-glue.xml > dbus-server-glue.h
+
+strip: $(APP)
+ strip $(APP)
+
+install: all
+ mkdir -p $(DESTDIR)$(PREFIX)/bin
+ install -c -m 0755 browser-switchboard $(DESTDIR)$(PREFIX)/bin
+
+clean:
+ rm -f $(APP) *.o dbus-server-glue.h
+
+.PHONY: strip install
+++ /dev/null
-#!/usr/bin/python
-# browser-switchboard
-# version 2.2 by steven676 and xiojason
-
-# simple python-dbus service that proxies osso_browser events to Tear
-# based on code from http://paste.lisp.org/display/45824
-
-# Copyright (C) 2009 Jason Simpson
-# Copyright (C) 2009 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
-# 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-# On Maemo systems, a copy of the GPL can be found in
-# /usr/share/common-licenses/GPL .
-
-
-import os
-import gobject
-import dbus
-import dbus.service
-import dbus.glib
-
-# Set default configuration values
-# These can be overriden by the config file $HOME/.config/browser-switchboard
-def setconfigdefaults():
- global continuous_mode, default_browser, other_browser_cmd
-
- # continuous_mode: 0 -- close after handling a request; 1 -- run
- # continuously in the background
- continuous_mode = 0
- # default_browser: "tear", "microb", "fennec", "midori", or "other"
- # empty string is handled specially -- see below
- default_browser = ""
- # If default browser is "other", what program to run (%s will be replaced
- # by URI)
- other_browser_cmd = ""
-
-class BrowserLauncher:
- def LaunchTear(self, uri):
- # We should be able to just call the D-Bus service to open Tear ...
- # but if Tear's not open, that causes D-Bus to start Tear and then
- # pass it the OpenAddress call, which results in two browser windows.
- # Properly fixing this probably requires Tear to provide a D-Bus method
- # that opens an address in an existing window, but for now work around
- # by just opening Tear via the command line if it's not running.
- if os.system("pidof tear > /dev/null") == 0:
- dbus.SessionBus().get_object('com.nokia.tear', '/com/nokia/tear').OpenAddress(uri, dbus_interface='com.nokia.Tear')
- if continuous_mode == 0:
- quit()
- else:
- if continuous_mode:
- if os.fork() != 0:
- # parent process doesn't need to do anything
- return
- # child process
- os.setsid()
- os.execl('/usr/bin/tear', '/usr/bin/tear', uri)
-
- def LaunchMicroB(self, uri):
- if os.system("pidof /usr/sbin/browserd > /dev/null") != 0:
- kill_browserd = 1
- os.system("/usr/sbin/browserd -d")
- else:
- kill_browserd = 0
- dbus.SessionBus().release_name("com.nokia.osso_browser")
- if uri == "new_window":
- # exec maemo-invoker directly instead of relying on the
- # /usr/bin/browser symlink, since /usr/bin/browser may have been
- # replaced with a shell script calling us via D-Bus
- os.spawnl(os.P_WAIT, '/usr/bin/maemo-invoker', '/usr/bin/browser')
- else:
- os.spawnl(os.P_WAIT, '/usr/bin/maemo-invoker', '/usr/bin/browser', '--url', uri)
- if kill_browserd:
- os.system("kill `pidof /usr/sbin/browserd`")
- if continuous_mode:
- dbus.SessionBus().request_name("com.nokia.osso_browser")
- else:
- quit()
-
- def LaunchOtherBrowser(self, uri):
- if uri == "new_window":
- uri = ""
- try:
- # URI must be quoted and quotes in the URI must be URL-escaped
- # to prevent the shell from interpreting any part of the URI
- command = other_browser_cmd % "'%s'" % uri.replace("'", "%27")
- except TypeError:
- # Couldn't substitute URI in, just launch the browser
- print "other_browser_cmd should have a %s placeholder for the URI"
- command = other_browser_cmd
- import subprocess
- subprocess.Popen(command, shell=True)
- if continuous_mode == 0:
- quit()
-
- def UpdateDefaultBrowser(self):
- global other_browser_cmd
- if default_browser == "tear":
- self.LaunchBrowser = self.LaunchTear
- elif default_browser == "microb":
- self.LaunchBrowser = self.LaunchMicroB
- elif default_browser == "fennec":
- # Cheat and reuse LaunchOtherBrowser, since we don't appear to
- # need to do anything special
- # TODO: does Fennec have a D-Bus API or signaling mechanism?
- # Invoking the fennec binary appears to be somewhat expensive
- other_browser_cmd = "fennec '%s'"
- self.LaunchBrowser = self.LaunchOtherBrowser
- elif default_browser == "midori":
- other_browser_cmd = "midori '%s'"
- self.LaunchBrowser = self.LaunchOtherBrowser
- elif default_browser == "other":
- if other_browser_cmd != "":
- self.LaunchBrowser = self.LaunchOtherBrowser
- else:
- print "default_browser is 'other', but no other_browser_cmd set -- using default"
- self.LaunchBrowser = self.LaunchTear
- elif default_browser == "":
- # If default_browser is empty, use Tear as the default if
- # installed, otherwise use MicroB
- if os.access("/usr/bin/tear", X_OK):
- self.LaunchBrowser = self.LaunchTear
- else
- self.LaunchBrowser = self.LaunchMicroB
- else:
- print "Unknown default_browser %s, using default" % default_browser
- self.LaunchBrowser = self.LaunchTear
-
- def __init__(self):
- self.UpdateDefaultBrowser()
-
-class ProxyBrowserService(dbus.service.Object):
- def __init__(self):
- bus_name = dbus.service.BusName('com.nokia.osso_browser', bus=dbus.SessionBus())
- dbus.service.Object.__init__(self, bus_name, '/com/nokia/osso_browser')
- dbus.service.Object.__init__(self, bus_name, '/com/nokia/osso_browser/request')
-
- def OpenAddress(self, uri):
- print uri
-
- if uri[0] == '/':
- print "prefixing apparent local path with file://"
- uri = "file://" + uri
-
- launcher.LaunchBrowser(uri)
-
- @dbus.service.method(dbus_interface='com.nokia.osso_browser', in_signature='s')
- def load_url(self, uri):
- print "load_url"
- self.OpenAddress(uri)
-
- @dbus.service.method(dbus_interface='com.nokia.osso_browser', in_signature='s')
- def mime_open(self, uri):
- print "mime_open"
- self.OpenAddress(uri)
-
- @dbus.service.method(dbus_interface='com.nokia.osso_browser', in_signature='s')
- def open_new_window(self, uri):
- print "open_new_window"
- self.OpenAddress(uri)
-
- @dbus.service.method(dbus_interface='com.nokia.osso_browser')
- def top_application(self):
- print "top_application"
- launcher.LaunchMicroB("new_window")
-
- # This method is an "undocumented", non-standard extension to the
- # osso_browser D-Bus API, intended solely to allow a wrapper script
- # replacing /usr/bin/browser to implement --url
- @dbus.service.method(dbus_interface='com.nokia.osso_browser')
- def switchboard_launch_microb(self, uri="new_window"):
- print "switchboard_launch_microb"
- launcher.LaunchMicroB(uri)
-
-def readconfigfile(signalnum=None, frame=None):
- # reset configuration to defaults
- setconfigdefaults()
-
- # read configuration from the config file, if available
- try:
- execfile(os.getenv("HOME", "/home/user") + "/.config/browser-switchboard", globals())
- launcher.UpdateDefaultBrowser()
- except:
- # No valid config file available
- pass
-
-setconfigdefaults()
-
-launcher = BrowserLauncher()
-pbrowser = ProxyBrowserService()
-
-readconfigfile()
-
-if continuous_mode:
- import signal
- def waitforzombies(signalnum, frame):
- try:
- while os.waitpid(-1, os.WNOHANG) != (0, 0):
- continue
- except OSError:
- pass
- signal.signal(signal.SIGCHLD, waitforzombies)
- signal.signal(signal.SIGHUP, readconfigfile)
-
-loop = gobject.MainLoop()
-loop.run()
--- /dev/null
+/*
+ * browser-switchboard.h -- definitions common to all of browser-switchboard
+ *
+ * Copyright (C) 2009 Steven Luo
+ * Derived from a Python implementation by Jason Simpson and 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
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+#ifndef _BROWSER_SWITCHBOARD_H
+#define _BROWSER_SWITCHBOARD_H 1
+
+struct swb_context {
+ int continuous_mode;
+ void (*default_browser_launcher)(struct swb_context *, char *);
+ char * other_browser_cmd;
+ DBusGConnection * session_bus;
+ DBusGProxy * dbus_proxy;
+};
+
+#endif /* _BROWSER_SWITCHBOARD_H */
--- /dev/null
+/*
+ * dbus-server-bindings.c -- osso_browser D-Bus interface implementation
+ *
+ * Copyright (C) 2009 Steven Luo
+ * Derived from a Python implementation by Jason Simpson and 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
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <dbus/dbus-glib.h>
+
+#include "browser-switchboard.h"
+#include "launcher.h"
+#include "dbus-server-bindings.h"
+
+extern struct swb_context ctx;
+
+G_DEFINE_TYPE(OssoBrowser, osso_browser, G_TYPE_OBJECT);
+static void osso_browser_init(OssoBrowser *obj)
+{
+}
+
+static void osso_browser_class_init(OssoBrowserClass *klass)
+{
+}
+
+#include "dbus-server-glue.h"
+
+
+static void open_address(const char * uri) {
+ char * new_uri;
+ size_t new_uri_len;
+
+ if (!uri && uri[0] == '/') {
+ new_uri_len = strlen("file://") + strlen(uri) + 1;
+ if (!(new_uri = calloc(new_uri_len, sizeof(char))))
+ exit(1);
+ strncpy(new_uri, "file://", strlen("file://"));
+ strncat(new_uri, uri, strlen(uri));
+
+ launch_browser(&ctx, new_uri);
+ /* If launch_browser didn't exec something in this process,
+ we need to clean up after ourselves */
+ free(new_uri);
+ } else {
+ printf("open_address '%s'\n", uri);
+ launch_browser(&ctx, (char *)uri);
+ }
+}
+
+
+/*
+ * The com.nokia.osso_browser D-Bus interface
+ */
+gboolean osso_browser_load_url(OssoBrowser *obj,
+ const char * uri, GError **error) {
+ open_address(uri);
+ return TRUE;
+}
+
+gboolean osso_browser_mime_open(OssoBrowser *obj,
+ const char * uri, GError **error) {
+ open_address(uri);
+ return TRUE;
+}
+
+gboolean osso_browser_open_new_window(OssoBrowser *obj,
+ const char * uri, GError **error) {
+ open_address(uri);
+ return TRUE;
+}
+
+gboolean osso_browser_top_application(OssoBrowser *obj,
+ GError **error) {
+ launch_microb(&ctx, "new_window");
+ return TRUE;
+}
+
+/* This is a "undocumented", non-standard extension to the API, ONLY
+ for use by /usr/bin/browser wrapper to implement --url */
+gboolean osso_browser_switchboard_launch_microb(OssoBrowser *obj,
+ const char * uri, GError **error) {
+ launch_microb(&ctx, (char *)uri);
+ return TRUE;
+}
+
+
+/* Register the name com.nokia.osso_browser on the D-Bus session bus */
+void dbus_request_osso_browser_name(struct swb_context * ctx) {
+ GError * error = NULL;
+ guint result;
+
+ if (!ctx || !ctx->dbus_proxy)
+ return;
+
+ if (!dbus_g_proxy_call(ctx->dbus_proxy, "RequestName", &error,
+ G_TYPE_STRING, "com.nokia.osso_browser",
+ G_TYPE_UINT, DBUS_NAME_FLAG_REPLACE_EXISTING|DBUS_NAME_FLAG_DO_NOT_QUEUE,
+ G_TYPE_INVALID,
+ G_TYPE_UINT, &result,
+ G_TYPE_INVALID)) {
+ printf("Couldn't acquire name com.nokia.osso_browser\n");
+ exit(1);
+ }
+ if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+ printf("Couldn't acquire name com.nokia.osso_browser\n");
+ exit(1);
+ }
+}
+
+/* Release the name com.nokia.osso_browser on the D-Bus session bus */
+void dbus_release_osso_browser_name(struct swb_context * ctx) {
+ GError * error = NULL;
+ guint result;
+
+ if (!ctx || !ctx->dbus_proxy)
+ return;
+
+ dbus_g_proxy_call(ctx->dbus_proxy, "ReleaseName", &error,
+ G_TYPE_STRING, "com.nokia.osso_browser",
+ G_TYPE_INVALID,
+ G_TYPE_UINT, &result,
+ G_TYPE_INVALID);
+}
--- /dev/null
+/*
+ * dbus-server-bindings.h -- definitions for the osso_browser interface
+ *
+ * Copyright (C) 2009 Steven Luo
+ * Derived from a Python implementation by Jason Simpson and 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
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+#ifndef _DBUS_SERVER_BINDINGS_H
+#define _DBUS_SERVER_BINDINGS_H 1
+
+#include "browser-switchboard.h"
+
+GType osso_browser_get_type(void);
+#define OSSO_BROWSER_TYPE (osso_browser_get_type())
+typedef struct _OssoBrowser {
+ GObject parent;
+} OssoBrowser;
+typedef struct _OssoBrowserClass {
+ GObjectClass parent;
+} OssoBrowserClass;
+
+/* The com.nokia.osso_browser D-Bus interface */
+gboolean osso_browser_load_url(OssoBrowser *obj,
+ const char * uri, GError **error);
+gboolean osso_browser_mime_open(OssoBrowser *obj,
+ const char * uri, GError **error);
+gboolean osso_browser_open_new_window(OssoBrowser *obj,
+ const char * uri, GError **error);
+gboolean osso_browser_top_application(OssoBrowser *obj, GError **error);
+/* This is an "undocumented", non-standard extension; DO NOT USE */
+gboolean osso_browser_switchboard_launch_microb(OssoBrowser *obj,
+ const char * uri, GError **error);
+
+void dbus_request_osso_browser_name(struct swb_context * ctx);
+void dbus_release_osso_browser_name(struct swb_context * ctx);
+
+const DBusGObjectInfo dbus_glib_osso_browser_object_info;
+
+#endif /* _DBUS_SERVER_BINDINGS_H */
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/com/nokia/osso_browser">
+ <interface name="com.nokia.osso_browser">
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="osso_browser" />
+ <method name="load_url">
+ <arg type="s" name="uri" direction="in" />
+ </method>
+ <method name="mime_open">
+ <arg type="s" name="uri" direction="in" />
+ </method>
+ <method name="open_new_window">
+ <arg type="s" name="uri" direction="in" />
+ </method>
+ <method name="top_application" />
+ <method name="switchboard_launch_microb">
+ <arg type="s" name="uri" direction="in" />
+ </method>
+ </interface>
+</node>
--- /dev/null
+/*
+ * launcher.c -- functions for launching web browsers for browser-switchboard
+ *
+ * Copyright (C) 2009 Steven Luo
+ * Derived from a Python implementation by Jason Simpson and 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
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <dbus/dbus-glib.h>
+
+#include "browser-switchboard.h"
+#include "launcher.h"
+#include "dbus-server-bindings.h"
+
+#define LAUNCH_DEFAULT_BROWSER launch_tear
+
+static void launch_tear(struct swb_context * ctx, char * uri) {
+ int status;
+ static DBusGProxy * tear_proxy = NULL;
+ GError * error = NULL;
+ pid_t pid;
+
+ if (!uri)
+ uri = "new_window";
+
+ printf("launch_tear with uri '%s'\n", uri);
+
+ status = system("pidof tear > /dev/null");
+ if (!WIFEXITED(status))
+ exit(1);
+ if (!WEXITSTATUS(status)) {
+ if (!tear_proxy)
+ tear_proxy = dbus_g_proxy_new_for_name(ctx->session_bus,
+ "com.nokia.tear", "/com/nokia/tear",
+ "com.nokia.Tear");
+ dbus_g_proxy_call(tear_proxy, "OpenAddress",
+ &error,
+ G_TYPE_STRING, uri,
+ G_TYPE_INVALID);
+ if (!ctx->continuous_mode)
+ exit(0);
+ } else {
+ if (ctx->continuous_mode) {
+ if ((pid = fork()) != 0) {
+ /* Parent process or error in fork() */
+ printf("child: %d\n", (int)pid);
+ return;
+ }
+ /* Child process */
+ setsid();
+ }
+ execl("/usr/bin/tear", "/usr/bin/tear", uri, (char *)NULL);
+ }
+}
+
+void launch_microb(struct swb_context * ctx, char * uri) {
+ int kill_browserd = 0;
+ int status;
+ pid_t pid;
+
+ if (!uri)
+ uri = "new_window";
+
+ status = system("pidof /usr/sbin/browserd > /dev/null");
+ if (!WIFEXITED(status))
+ exit(1);
+ if (WEXITSTATUS(status)) {
+ kill_browserd = 1;
+ system("/usr/sbin/browserd -d");
+ }
+
+ dbus_release_osso_browser_name(ctx);
+
+ if ((pid = fork()) == -1) {
+ perror("fork");
+ exit(1);
+ }
+ if (pid > 0) {
+ /* Parent process */
+ waitpid(pid, &status, 0);
+ } else {
+ /* Child process */
+ if (!strcmp(uri, "new_window")) {
+ execl("/usr/bin/maemo-invoker",
+ "browser", (char *)NULL);
+ } else {
+ execl("/usr/bin/maemo-invoker",
+ "browser", "--url", uri, (char *)NULL);
+ }
+ }
+
+ if (kill_browserd)
+ system("kill `pidof /usr/sbin/browserd`");
+
+ if (!ctx || !ctx->continuous_mode)
+ exit(0);
+
+ dbus_request_osso_browser_name(ctx);
+}
+
+static void launch_other_browser(struct swb_context * ctx, char * uri) {
+ char * command;
+ char * quoted_uri;
+ size_t cmdlen, urilen;
+
+ if (!uri || !strcmp(uri, "new_window"))
+ uri = "";
+ urilen = strlen(uri);
+ if (urilen > 0) {
+ char * quote;
+
+ /* Quote the URI */
+ /* urilen+3 = length of URI + 2x \' + \0 */
+ if (!(quoted_uri = calloc(urilen+3, sizeof(char))))
+ exit(1);
+ strncpy(quoted_uri+1, uri, urilen);
+ quoted_uri[0] = quoted_uri[urilen+1] = '\'';
+ /* calloc zeroes the memory, so string is automatically
+ null terminated */
+
+ /* If there are any 's in the original URI, URL-escape them
+ (replace them with %27) */
+ quote = quoted_uri + 1;
+ while ((quote = strchr(quote, '\'')) &&
+ (quote-quoted_uri) < strlen(quoted_uri)-1) {
+ /* 3 = strlen("%27")-strlen("'") + \0 */
+ if (!(quoted_uri = realloc(quoted_uri,
+ strlen(quoted_uri)+3)))
+ exit(1);
+ /* Move the string after the ', including the \0,
+ over two chars */
+ memmove(quote+3, quote+1, strlen(quote)+1);
+ memcpy(quote, "%27", 3);
+ quote = quote + 3;
+ }
+ urilen = strlen(quoted_uri);
+ } else
+ quoted_uri = uri;
+
+ cmdlen = strlen(ctx->other_browser_cmd);
+
+ /* cmdlen+urilen+1 is normally two bytes longer than we need (uri will
+ replace "%s"), but is needed in the case other_browser_cmd has no %s
+ and urilen < 2 */
+ if (!(command = calloc(cmdlen+urilen+1, sizeof(char))))
+ exit(1);
+ snprintf(command, cmdlen+urilen+1, ctx->other_browser_cmd, quoted_uri);
+ printf("command: '%s'\n", command);
+
+ if (ctx->continuous_mode) {
+ if (fork() != 0) {
+ /* Parent process or error in fork() */
+ if (urilen > 0)
+ free(quoted_uri);
+ free(command);
+ return;
+ }
+ /* Child process */
+ setsid();
+ }
+ execl("/bin/sh", "/bin/sh", "-c", command, (char *)NULL);
+}
+
+static void use_other_browser_cmd(struct swb_context * ctx, char * cmd) {
+ size_t len = strlen(cmd);
+
+ free(ctx->other_browser_cmd);
+ ctx->other_browser_cmd = calloc(len+1, sizeof(char));
+ if (!ctx->other_browser_cmd) {
+ printf("malloc failed!\n");
+ ctx->default_browser_launcher = LAUNCH_DEFAULT_BROWSER;
+ } else {
+ ctx->other_browser_cmd = strncpy(ctx->other_browser_cmd,
+ cmd, len);
+ ctx->other_browser_cmd[len] = '\0';
+ ctx->default_browser_launcher = launch_other_browser;
+ }
+}
+
+void update_default_browser(struct swb_context * ctx, char * default_browser) {
+ if (!ctx)
+ return;
+
+ if (!default_browser) {
+ ctx->default_browser_launcher = LAUNCH_DEFAULT_BROWSER;
+ return;
+ }
+
+ if (!strcmp(default_browser, "tear"))
+ ctx->default_browser_launcher = launch_tear;
+ else if (!strcmp(default_browser, "microb"))
+ ctx->default_browser_launcher = launch_microb;
+ else if (!strcmp(default_browser, "fennec"))
+ use_other_browser_cmd(ctx, "fennec %s");
+ else if (!strcmp(default_browser, "midori"))
+ use_other_browser_cmd(ctx, "midori %s");
+ else if (!strcmp(default_browser, "other")) {
+ if (ctx->other_browser_cmd)
+ ctx->default_browser_launcher = launch_other_browser;
+ else {
+ printf("default_browser is 'other', but no other_browser_cmd set -- using default\n");
+ ctx->default_browser_launcher = LAUNCH_DEFAULT_BROWSER;
+ }
+ } else {
+ printf("Unknown default_browser %s, using default", default_browser);
+ ctx->default_browser_launcher = LAUNCH_DEFAULT_BROWSER;
+ }
+}
+
+void launch_browser(struct swb_context * ctx, char * uri) {
+ if (ctx && ctx->default_browser_launcher)
+ ctx->default_browser_launcher(ctx, uri);
+}
--- /dev/null
+/*
+ * launcher.h -- definitions for the browser launching functions
+ *
+ * Copyright (C) 2009 Steven Luo
+ * Derived from a Python implementation by Jason Simpson and 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
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+#ifndef _LAUNCHER_H
+#define _LAUNCHER_H 1
+
+#include "browser-switchboard.h"
+
+void launch_microb(struct swb_context * ctx, char * uri);
+void launch_browser(struct swb_context * ctx, char * uri);
+void update_default_browser(struct swb_context * ctx, char * default_browser);
+
+#endif /* _LAUNCHER_H */
--- /dev/null
+/*
+ * main.c -- config file parsing and main loop for browser-switchboard
+ *
+ * Copyright (C) 2009 Steven Luo
+ * Derived from a Python implementation by Jason Simpson and 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
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <dbus/dbus-glib.h>
+
+#include "browser-switchboard.h"
+#include "launcher.h"
+#include "dbus-server-bindings.h"
+
+#define DEFAULT_HOMEDIR "/home/user"
+#define CONFIGFILE_LOC "/.config/browser-switchboard"
+#define MAXLINE 1024
+
+struct swb_context ctx;
+
+static void set_config_defaults(struct swb_context * ctx) {
+ if (!ctx)
+ return;
+ free(ctx->other_browser_cmd);
+ ctx->continuous_mode = 0;
+ ctx->default_browser_launcher = NULL;
+ ctx->other_browser_cmd = NULL;
+}
+
+static void waitforzombies(int signalnum) {
+ while (waitpid(-1, NULL, WNOHANG) > 0)
+ printf("Waited for a zombie\n");
+}
+
+static void read_config(int signalnum) {
+ char * homedir;
+ char * configfile;
+ size_t len;
+ char buf[MAXLINE];
+ char * tmp;
+ char * value;
+ char * default_browser = NULL;
+ FILE * fp;
+
+ set_config_defaults(&ctx);
+
+ if (!(homedir = getenv("HOME")))
+ homedir = DEFAULT_HOMEDIR;
+ len = strlen(homedir) + strlen(CONFIGFILE_LOC) + 1;
+ if (!(configfile = calloc(len, sizeof(char))))
+ goto out_noopen;
+ strncpy(configfile, homedir, strlen(homedir));
+ strncat(configfile, CONFIGFILE_LOC, strlen(CONFIGFILE_LOC));
+
+ if (!(fp = fopen(configfile, "r")))
+ goto out_noopen;
+
+ /* Read in the config file one line at a time and parse it
+ XXX doesn't deal with lines longer than MAXLINE */
+ while (fgets(buf, MAXLINE, fp)) {
+ /* skip comments */
+ if (buf[0] == '#')
+ continue;
+ /* look for the = in the line */
+ if (!(tmp = strchr(buf, '=')))
+ continue;
+
+ /* split the line into parameter (before =, in buf) and
+ value (after =, in value) */
+ if (!(value = calloc(strlen(tmp+1)+1, sizeof(char))))
+ goto out;
+ strncpy(value, tmp+1, strlen(tmp+1));
+ value[strlen(tmp+1)] = '\0';
+ /* scribble over the = in buf with a \0 -- that makes buf
+ just the parameter name */
+ *tmp = '\0';
+ /* if we find a newline in value, replace that with a \0 too */
+ if ((tmp = strchr(value, '\n')))
+ *tmp = '\0';
+
+ if (!strcmp(buf, "continuous_mode")) {
+ ctx.continuous_mode = atoi(value);
+ free(value);
+ } else if (!strcmp(buf, "default_browser")) {
+ if (!default_browser)
+ default_browser = value;
+ } else if (!strcmp(buf, "other_browser_cmd")) {
+ if (!ctx.other_browser_cmd)
+ ctx.other_browser_cmd = value;
+ } else {
+ /* Don't need this line's contents */
+ free(value);
+ }
+ value = NULL;
+ }
+
+ printf("continuous_mode: %d\n", ctx.continuous_mode);
+ printf("default_browser: '%s'\n", default_browser?default_browser:"NULL");
+ printf("other_browser_cmd: '%s'\n", ctx.other_browser_cmd?ctx.other_browser_cmd:"NULL");
+
+out:
+ fclose(fp);
+out_noopen:
+ update_default_browser(&ctx, default_browser);
+ free(configfile);
+ free(default_browser);
+ return;
+}
+
+int main() {
+ OssoBrowser * obj;
+ GMainLoop * mainloop;
+ GError * error = NULL;
+
+ read_config(0);
+
+ if (ctx.continuous_mode) {
+ struct sigaction act;
+ act.sa_flags = SA_RESTART;
+
+ act.sa_handler = waitforzombies;
+ if (sigaction(SIGCHLD, &act, NULL) == -1) {
+ printf("Installing signal handler failed\n");
+ return 1;
+ }
+
+ act.sa_handler = read_config;
+ if (sigaction(SIGHUP, &act, NULL) == -1) {
+ printf("Installing signal handler failed\n");
+ return 1;
+ }
+ }
+
+ g_type_init();
+
+ dbus_g_object_type_install_info(OSSO_BROWSER_TYPE,
+ &dbus_glib_osso_browser_object_info);
+
+ ctx.session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
+ if (!ctx.session_bus) {
+ printf("Couldn't get a D-Bus bus connection\n");
+ return 1;
+ }
+ ctx.dbus_proxy = dbus_g_proxy_new_for_name(ctx.session_bus,
+ "org.freedesktop.DBus", "/org/freedesktop/DBus",
+ "org.freedesktop.DBus");
+ if (!ctx.dbus_proxy) {
+ printf("Couldn't get an org.freedesktop.DBus proxy\n");
+ return 1;
+ }
+
+ dbus_request_osso_browser_name(&ctx);
+
+ obj = g_object_new(OSSO_BROWSER_TYPE, NULL);
+ dbus_g_connection_register_g_object(ctx.session_bus,
+ "/com/nokia/osso_browser", G_OBJECT(obj));
+ dbus_g_connection_register_g_object(ctx.session_bus,
+ "/com/nokia/osso_browser/request", G_OBJECT(obj));
+
+ mainloop = g_main_loop_new(NULL, FALSE);
+ printf("Starting main loop\n");
+ g_main_loop_run(mainloop);
+ printf("Main loop completed\n");
+
+ return 0;
+}