#include "launcher.h"
#include "dbus-server-bindings.h"
-#define LAUNCH_DEFAULT_BROWSER launch_tear
+#define LAUNCH_DEFAULT_BROWSER launch_microb
static void launch_tear(struct swb_context *ctx, char *uri) {
int status;
printf("launch_tear with uri '%s'\n", uri);
+ /* We should be able to just call the D-Bus service to open Tear ...
+ but if Tear's not open, that cuases 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 invoking Tear with exec() if it's not running. */
status = system("pidof tear > /dev/null");
- if (!WIFEXITED(status))
- exit(1);
- if (!WEXITSTATUS(status)) {
+ if (WIFEXITED(status) && !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);
+ dbus_g_proxy_call(tear_proxy, "OpenAddress", &error,
+ G_TYPE_STRING, uri, G_TYPE_INVALID);
if (!ctx->continuous_mode)
exit(0);
} else {
if (!uri)
uri = "new_window";
+ printf("launch_microb with uri '%s'\n", uri);
+
+ /* Launch browserd if it's not running */
status = system("pidof /usr/sbin/browserd > /dev/null");
- if (!WIFEXITED(status))
- exit(1);
- if (WEXITSTATUS(status)) {
+ if (WIFEXITED(status) && WEXITSTATUS(status)) {
kill_browserd = 1;
system("/usr/sbin/browserd -d");
}
+ /* Release the osso_browser D-Bus name so that MicroB can take it */
dbus_release_osso_browser_name(ctx);
if ((pid = fork()) == -1) {
waitpid(pid, &status, 0);
} else {
/* Child process */
+ /* 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 */
if (!strcmp(uri, "new_window")) {
execl("/usr/bin/maemo-invoker",
- "browser", (char *)NULL);
+ "browser", (char *)NULL);
} else {
execl("/usr/bin/maemo-invoker",
- "browser", "--url", uri, (char *)NULL);
+ "browser", "--url", uri, (char *)NULL);
}
}
+ /* Kill off browserd if we started it */
if (kill_browserd)
system("kill `pidof /usr/sbin/browserd`");
char *quoted_uri, *quote;
size_t cmdlen, urilen;
+ size_t quoted_uri_size;
+ size_t offset;
if (!uri || !strcmp(uri, "new_window"))
uri = "";
- urilen = strlen(uri);
- if (urilen > 0) {
- /* Quote the URI */
+
+ printf("launch_other_browser with uri '%s'\n", uri);
+
+ if ((urilen = strlen(uri)) > 0) {
+ /* Quote the URI to prevent the shell from interpreting it */
/* 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 */
+ snprintf(quoted_uri, urilen+3, "'%s'", uri);
/* If there are any 's in the original URI, URL-escape them
(replace them with %27) */
+ quoted_uri_size = urilen + 3;
quote = quoted_uri + 1;
while ((quote = strchr(quote, '\'')) &&
- (quote-quoted_uri) < strlen(quoted_uri)-1) {
- /* 3 = strlen("%27")-strlen("'") + \0 */
+ (offset = quote-quoted_uri) < strlen(quoted_uri)-1) {
+ /* Check to make sure we don't shrink the memory area
+ as a result of integer overflow */
+ if (quoted_uri_size+2 <= quoted_uri_size)
+ exit(1);
+
+ /* Grow the memory area;
+ 2 = strlen("%27")-strlen("'") */
if (!(quoted_uri = realloc(quoted_uri,
- strlen(quoted_uri)+3)))
+ quoted_uri_size+2)))
exit(1);
+ quoted_uri_size = quoted_uri_size + 2;
+
+ /* Recalculate the location of the ' character --
+ realloc() may have moved the string in memory */
+ quote = quoted_uri + offset;
+
/* Move the string after the ', including the \0,
over two chars */
- memmove(quote+3, quote+1, strlen(quote)+1);
+ memmove(quote+3, quote+1, strlen(quote));
memcpy(quote, "%27", 3);
quote = quote + 3;
}
execl("/bin/sh", "/bin/sh", "-c", command, (char *)NULL);
}
+/* Use launch_other_browser as the default browser launcher, with the string
+ passed in as the other_browser_cmd
+ Resulting other_browser_cmd is always safe to free(), even if a pointer
+ to a string constant is passed in */
static void use_other_browser_cmd(struct swb_context *ctx, char *cmd) {
size_t len = strlen(cmd);
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';
+ cmd, len+1);
ctx->default_browser_launcher = launch_other_browser;
}
}
return;
if (!default_browser) {
+ /* No default_browser configured -- use built-in default */
ctx->default_browser_launcher = LAUNCH_DEFAULT_BROWSER;
return;
}
else if (!strcmp(default_browser, "microb"))
ctx->default_browser_launcher = launch_microb;
else if (!strcmp(default_browser, "fennec"))
+ /* Cheat and reuse launch_other_browser, since we don't appear
+ to need to do anything special */
use_other_browser_cmd(ctx, "fennec %s");
else if (!strcmp(default_browser, "midori"))
use_other_browser_cmd(ctx, "midori %s");