aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Brendan Taylor <whateley@gmail.com>2011-02-14 22:51:46 -0700
committerGravatar Brendan Taylor <whateley@gmail.com>2011-02-14 22:54:54 -0700
commitdb3984b609153ff213233f1a78c8895fdb525350 (patch)
tree24e6b2959d08b8cadb93853cb3620681f6f05e64 /src
parent59af2a8499160a369aceed1bd5cb32109fb5e77c (diff)
parent700332fac498169927ced24731ce1278369b1425 (diff)
Merge branch 'experimental' into cleaning-commenting
Conflicts: src/callbacks.c src/uzbl-core.c src/uzbl-core.h
Diffstat (limited to 'src')
-rw-r--r--src/callbacks.c79
-rw-r--r--src/callbacks.h3
-rw-r--r--src/cookie-jar.c286
-rw-r--r--src/cookie-jar.h12
-rw-r--r--src/io.c20
-rw-r--r--src/util.c8
-rw-r--r--src/util.h1
-rwxr-xr-xsrc/uzbl-browser7
-rw-r--r--src/uzbl-core.c511
-rw-r--r--src/uzbl-core.h26
10 files changed, 292 insertions, 661 deletions
diff --git a/src/callbacks.c b/src/callbacks.c
index 2ba4e6c..c261234 100644
--- a/src/callbacks.c
+++ b/src/callbacks.c
@@ -52,16 +52,20 @@ set_authentication_handler() {
void
set_status_background() {
- GdkColor color;
- gdk_color_parse (uzbl.behave.status_background, &color);
-
/* labels and hboxes do not draw their own background. applying this
* on the vbox/main_window is ok as the statusbar is the only affected
* widget. (if not, we could also use GtkEventBox) */
- if (uzbl.gui.main_window)
- gtk_widget_modify_bg (uzbl.gui.main_window, GTK_STATE_NORMAL, &color);
- else if (uzbl.gui.plug)
- gtk_widget_modify_bg (GTK_WIDGET(uzbl.gui.plug), GTK_STATE_NORMAL, &color);
+ GtkWidget* widget = uzbl.gui.main_window ? uzbl.gui.main_window : GTK_WIDGET (uzbl.gui.plug);
+
+#if GTK_CHECK_VERSION(2,91,0)
+ GdkRGBA color;
+ gdk_rgba_parse (&color, uzbl.behave.status_background);
+ gtk_widget_override_background_color (widget, GTK_STATE_NORMAL, &color);
+#else
+ GdkColor color;
+ gdk_color_parse (uzbl.behave.status_background, &color);
+ gtk_widget_modify_bg (widget, GTK_STATE_NORMAL, &color);
+#endif
}
@@ -648,23 +652,26 @@ navigation_decision_cb (WebKitWebView *web_view, WebKitWebFrame *frame, WebKitNe
printf("Navigation requested -> %s\n", uri);
if (uzbl.behave.scheme_handler) {
- GString *s = g_string_new ("");
- g_string_printf(s, "'%s'", uri);
+ GString *result = g_string_new ("");
+ GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*));
+ const CommandInfo *c = parse_command_parts(uzbl.behave.scheme_handler, a);
- run_handler(uzbl.behave.scheme_handler, s->str);
+ if(c) {
+ g_array_append_val(a, uri);
+ run_parsed_command(c, a, result);
+ }
+ g_array_free(a, TRUE);
- if(uzbl.comm.sync_stdout && strcmp (uzbl.comm.sync_stdout, "") != 0) {
- char *p = strchr(uzbl.comm.sync_stdout, '\n' );
+ if(result->len > 0) {
+ char *p = strchr(result->str, '\n' );
if ( p != NULL ) *p = '\0';
- if (!strcmp(uzbl.comm.sync_stdout, "USED")) {
+ if (!strcmp(result->str, "USED")) {
webkit_web_policy_decision_ignore(policy_decision);
decision_made = TRUE;
}
}
- if (uzbl.comm.sync_stdout)
- uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout);
- g_string_free(s, TRUE);
+ g_string_free(result, TRUE);
}
if (!decision_made)
webkit_web_policy_decision_use(policy_decision);
@@ -851,27 +858,35 @@ download_cb(WebKitWebView *web_view, WebKitDownload *download, gpointer user_dat
(this may be inaccurate, there's nothing we can do about that.) */
unsigned int total_size = webkit_download_get_total_size(download);
- gchar *ev = g_strdup_printf("'%s' '%s' '%s' %d", uri, suggested_filename,
- content_type, total_size);
- run_handler(uzbl.behave.download_handler, ev);
- g_free(ev);
-
- /* no response, cancel the download */
- if(!uzbl.comm.sync_stdout) {
+ GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*));
+ const CommandInfo *c = parse_command_parts(uzbl.behave.download_handler, a);
+ if(!c) {
webkit_download_cancel(download);
+ g_array_free(a, TRUE);
return FALSE;
}
+ g_array_append_val(a, uri);
+ g_array_append_val(a, suggested_filename);
+ g_array_append_val(a, content_type);
+ gchar *total_size_s = g_strdup_printf("%d", total_size);
+ g_array_append_val(a, total_size_s);
+
+ GString *result = g_string_new ("");
+ run_parsed_command(c, a, result);
+
+ g_free(total_size_s);
+ g_array_free(a, TRUE);
+
/* no response, cancel the download */
- if(uzbl.comm.sync_stdout[0] == 0) {
+ if(result->len == 0) {
webkit_download_cancel(download);
- uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout);
return FALSE;
}
/* we got a response, it's the path we should download the file to */
- gchar *destination_path = uzbl.comm.sync_stdout;
- uzbl.comm.sync_stdout = NULL;
+ gchar *destination_path = result->str;
+ g_string_free(result, FALSE);
/* presumably people don't need newlines in their filenames. */
char *p = strchr(destination_path, '\n');
@@ -1005,13 +1020,3 @@ populate_popup_cb(WebKitWebView *v, GtkMenu *m, void *c) {
}
}
}
-
-void
-cmd_set_cookie_handler() {
- if(uzbl.behave.cookie_handler[0] == 0) {
- g_free(uzbl.behave.cookie_handler);
- uzbl.behave.cookie_handler = NULL;
- }
-
- uzbl_cookie_jar_set_handler(uzbl.net.soup_cookie_jar, uzbl.behave.cookie_handler);
-}
diff --git a/src/callbacks.h b/src/callbacks.h
index 899e959..13cb83d 100644
--- a/src/callbacks.h
+++ b/src/callbacks.h
@@ -216,6 +216,3 @@ scroll_vert_cb(GtkAdjustment *adjust, void *w);
gboolean
scroll_horiz_cb(GtkAdjustment *adjust, void *w);
-
-void
-cmd_set_cookie_handler();
diff --git a/src/cookie-jar.c b/src/cookie-jar.c
index 626e454..82a5269 100644
--- a/src/cookie-jar.c
+++ b/src/cookie-jar.c
@@ -1,51 +1,20 @@
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <poll.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <string.h>
-#include <errno.h>
-
-#include <libsoup/soup-uri.h>
#include <libsoup/soup-cookie.h>
#include "cookie-jar.h"
#include "uzbl-core.h"
#include "events.h"
-static void
-uzbl_cookie_jar_session_feature_init(SoupSessionFeatureInterface *iface, gpointer user_data);
-
-G_DEFINE_TYPE_WITH_CODE (UzblCookieJar, soup_cookie_jar_socket, SOUP_TYPE_COOKIE_JAR,
- G_IMPLEMENT_INTERFACE (SOUP_TYPE_SESSION_FEATURE, uzbl_cookie_jar_session_feature_init))
+G_DEFINE_TYPE (UzblCookieJar, soup_cookie_jar_socket, SOUP_TYPE_COOKIE_JAR)
-static void request_started (SoupSessionFeature *feature, SoupSession *session, SoupMessage *msg, SoupSocket *socket);
static void changed(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie);
-static void setup_handler(UzblCookieJar *jar);
-
-static void connect_cookie_socket(UzblCookieJar *jar);
-static void disconnect_cookie_socket(UzblCookieJar *jar);
-
-static gchar *do_socket_request(UzblCookieJar *jar, gchar *request, int request_len);
-
-static bool has_socket_handler(UzblCookieJar *jar) {
- return jar->socket_path != NULL;
-}
-
static void
soup_cookie_jar_socket_init(UzblCookieJar *jar) {
- jar->handler = NULL;
- jar->socket_path = NULL;
- jar->connection_fd = -1;
- jar->in_get_callback = 0;
jar->in_manual_add = 0;
}
static void
finalize(GObject *object) {
- disconnect_cookie_socket(UZBL_COOKIE_JAR(object));
G_OBJECT_CLASS(soup_cookie_jar_socket_parent_class)->finalize(object);
}
@@ -55,120 +24,30 @@ soup_cookie_jar_socket_class_init(UzblCookieJarClass *socket_class) {
SOUP_COOKIE_JAR_CLASS(socket_class)->changed = changed;
}
-/* override SoupCookieJar's request_started handler */
-static void
-uzbl_cookie_jar_session_feature_init(SoupSessionFeatureInterface *iface, gpointer user_data) {
- (void) user_data;
- iface->request_started = request_started;
-}
-
UzblCookieJar *uzbl_cookie_jar_new() {
return g_object_new(UZBL_TYPE_COOKIE_JAR, NULL);
}
-void
-uzbl_cookie_jar_set_handler(UzblCookieJar *jar, const gchar* handler) {
- jar->handler = handler;
- setup_handler(jar);
-}
-
-char *get_cookies(UzblCookieJar *jar, SoupURI *uri) {
- gchar *result, *path;
- GString *s = g_string_new ("GET");
-
- path = uri->path[0] ? uri->path : "/";
-
- if(has_socket_handler(jar)) {
- g_string_append_c(s, 0); /* null-terminate the GET */
- g_string_append_len(s, uri->scheme, strlen(uri->scheme)+1);
- g_string_append_len(s, uri->host, strlen(uri->host)+1 );
- g_string_append_len(s, path, strlen(path)+1 );
-
- result = do_socket_request(jar, s->str, s->len);
- /* try it again; older cookie daemons closed the connection after each request */
- if(result == NULL)
- result = do_socket_request(jar, s->str, s->len);
- } else {
- g_string_append_printf(s, " '%s' '%s' '%s'", uri->scheme, uri->host, uri->path);
-
- run_handler(jar->handler, s->str);
- result = g_strdup(uzbl.comm.sync_stdout);
- }
- g_string_free(s, TRUE);
- return result;
-}
-
-/* this is a duplicate of SoupCookieJar's request_started that uses our get_cookies instead */
-static void
-request_started(SoupSessionFeature *feature, SoupSession *session,
- SoupMessage *msg, SoupSocket *socket) {
- (void) session; (void) socket;
- gchar *cookies;
-
- UzblCookieJar *jar = UZBL_COOKIE_JAR (feature);
- SoupURI *uri = soup_message_get_uri(msg);
- gboolean add_to_internal_jar = false;
-
- if(jar->handler) {
- cookies = get_cookies(jar, uri);
- } else {
- /* no handler is set, fall back to the internal soup cookie jar */
- cookies = soup_cookie_jar_get_cookies(SOUP_COOKIE_JAR(jar), soup_message_get_uri (msg), TRUE);
- }
-
- if (cookies && cookies[0] != 0) {
- const gchar *next_cookie_start = cookies;
-
- if (add_to_internal_jar) {
- /* add the cookie data that we just obtained from the cookie handler
- to the cookie jar so that javascript has access to them.
- we set this flag so that we don't trigger the PUT handler. */
- jar->in_get_callback = true;
- do {
- SoupCookie *soup_cookie = soup_cookie_parse(next_cookie_start, uri);
- if(soup_cookie)
- soup_cookie_jar_add_cookie(SOUP_COOKIE_JAR(uzbl.net.soup_cookie_jar), soup_cookie);
- next_cookie_start = strchr(next_cookie_start, ';');
- } while(next_cookie_start++ != NULL);
- jar->in_get_callback = false;
- }
-
- soup_message_headers_replace (msg->request_headers, "Cookie", cookies);
- } else {
- soup_message_headers_remove (msg->request_headers, "Cookie");
- }
-
- if(cookies)
- g_free (cookies);
-}
-
static void
changed(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie) {
- SoupCookie * cookie = new_cookie ? new_cookie : old_cookie;
+ SoupCookie *cookie = new_cookie ? new_cookie : old_cookie;
UzblCookieJar *uzbl_jar = UZBL_COOKIE_JAR(jar);
- /* when Uzbl begins an HTTP request, it GETs cookies from the handler
- and then adds them to the cookie jar so that javascript can access
- these cookies. this causes a 'changed' callback, which we don't want
- to do anything, so we just return.
-
- (if SoupCookieJar let us override soup_cookie_jar_get_cookies we
- wouldn't have to do this.) */
- if(uzbl_jar->in_get_callback)
- return;
-
- gchar *scheme = cookie->secure ? "https" : "http";
-
- /* send a ADD or DELETE -_COOKIE event depending on what have changed */
+ /* send a ADD or DELETE -_COOKIE event depending on what has changed. these
+ * events aren't sent when a cookie changes due to an add/delete_cookie
+ * command because otherwise a loop would occur when a cookie change is
+ * propagated to other uzbl instances using add/delete_cookie. */
if(!uzbl_jar->in_manual_add) {
+ gchar *scheme = cookie->secure ? "https" : "http";
+
gchar *expires = NULL;
if(cookie->expires)
expires = g_strdup_printf ("%d", soup_date_to_time_t (cookie->expires));
gchar * eventstr = g_strdup_printf ("'%s' '%s' '%s' '%s' '%s' '%s'",
cookie->domain, cookie->path, cookie->name, cookie->value, scheme, expires?expires:"");
- if(new_cookie)
+ if(new_cookie)
send_event(ADD_COOKIE, eventstr, NULL);
else
send_event(DELETE_COOKIE, eventstr, NULL);
@@ -176,151 +55,4 @@ changed(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie) {
if(expires)
g_free(expires);
}
-
- /* the cookie daemon is only interested in new cookies and changed
- ones, it can take care of deleting expired cookies on its own. */
- if(!new_cookie)
- return;
-
- GString *s = g_string_new ("PUT");
-
- if(has_socket_handler(uzbl_jar)) {
- g_string_append_c(s, 0); /* null-terminate the PUT */
- g_string_append_len(s, scheme, strlen(scheme)+1);
- g_string_append_len(s, new_cookie->domain, strlen(new_cookie->domain)+1 );
- g_string_append_len(s, new_cookie->path, strlen(new_cookie->path)+1 );
- g_string_append_printf(s, "%s=%s", new_cookie->name, new_cookie->value);
-
- gchar *result = do_socket_request(uzbl_jar, s->str, s->len+1);
- /* try it again; older cookie daemons closed the connection after each request */
- if(!result)
- result = do_socket_request(uzbl_jar, s->str, s->len+1);
-
- g_free(result);
- } else {
- g_string_append_printf(s, " '%s' '%s' '%s' '%s=%s'", scheme, new_cookie->domain, new_cookie->path, new_cookie->name, new_cookie->value);
-
- run_handler(uzbl_jar->handler, s->str);
- }
-
- g_string_free(s, TRUE);
-}
-
-static void
-setup_handler(UzblCookieJar *jar) {
- if(jar->handler && strncmp(jar->handler, "talk_to_socket", strlen("talk_to_socket")) == 0) {
- /* extract the socket path from the handler. */
- jar->socket_path = jar->handler + strlen("talk_to_socket");
- while(isspace(*jar->socket_path))
- jar->socket_path++;
- if(*jar->socket_path == 0)
- return; /* there was no path specified. */
- disconnect_cookie_socket(jar);
- connect_cookie_socket(jar);
- } else {
- jar->socket_path = NULL;
- }
-}
-
-static void
-connect_cookie_socket(UzblCookieJar *jar) {
- struct sockaddr_un sa;
- int fd;
-
- g_strlcpy(sa.sun_path, jar->socket_path, sizeof(sa.sun_path));
- sa.sun_family = AF_UNIX;
-
- /* create socket file descriptor and connect it to path */
- fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
- if(fd == -1) {
- g_printerr("connect_cookie_socket: creating socket failed (%s)\n", strerror(errno));
- return;
- }
-
- if(connect(fd, (struct sockaddr*)&sa, sizeof(sa))) {
- g_printerr("connect_cookie_socket: connect failed (%s)\n", strerror(errno));
- close(fd);
- return;
- }
-
- /* successful connection! */
- jar->connection_fd = fd;
-}
-
-static void
-disconnect_cookie_socket(UzblCookieJar *jar) {
- if(jar->connection_fd > 0) {
- close(jar->connection_fd);
- jar->connection_fd = -1;
- }
-}
-
-static gchar *do_socket_request(UzblCookieJar *jar, gchar *request, int request_length) {
- int len;
- ssize_t ret;
- struct pollfd pfd;
- gchar *result = NULL;
-
- if(jar->connection_fd < 0)
- connect_cookie_socket(jar); /* connection was lost, reconnect */
-
- /* write request */
- ret = write(jar->connection_fd, request, request_length);
- if(ret == -1) {
- g_printerr("talk_to_socket: write failed (%s)\n", strerror(errno));
- disconnect_cookie_socket(jar);
- return NULL;
- }
-
- /* wait for a response, with a 500ms timeout */
- pfd.fd = jar->connection_fd;
- pfd.events = POLLIN;
- while(1) {
- ret = poll(&pfd, 1, 500);
- if(ret == 1) break;
- if(ret == 0) errno = ETIMEDOUT;
- if(errno == EINTR) continue;
- g_printerr("talk_to_socket: poll failed while waiting for input (%s)\n",
- strerror(errno));
- if(errno != ETIMEDOUT)
- disconnect_cookie_socket(jar);
- return NULL;
- }
-
- /* get length of response */
- if(ioctl(jar->connection_fd, FIONREAD, &len) == -1) {
- g_printerr("talk_to_socket: cannot find daemon response length, "
- "ioctl failed (%s)\n", strerror(errno));
- disconnect_cookie_socket(jar);
- return NULL;
- }
-
- /* there was an empty response. */
- if(len == 0)
- return g_strdup("");
-
- /* there is a response, read it */
- result = g_malloc(len + 1);
- if(!result) {
- g_printerr("talk_to_socket: failed to allocate %d bytes\n", len);
- return NULL;
- }
- result[len] = 0; /* ensure result is null terminated */
-
- gchar *p = result;
- while(len > 0) {
- ret = read(jar->connection_fd, p, len);
- if(ret == -1) {
- g_printerr("talk_to_socket: failed to read from socket (%s)\n",
- strerror(errno));
- disconnect_cookie_socket(jar);
- g_free(result);
- return NULL;
- } else {
- len -= ret;
- p += ret;
- }
- }
-
- return result;
}
diff --git a/src/cookie-jar.h b/src/cookie-jar.h
index f3e3733..05f4a6f 100644
--- a/src/cookie-jar.h
+++ b/src/cookie-jar.h
@@ -10,12 +10,6 @@
typedef struct {
SoupCookieJar parent;
- const gchar *handler;
-
- const gchar *socket_path;
- int connection_fd;
-
- gboolean in_get_callback;
gboolean in_manual_add;
} UzblCookieJar;
@@ -25,10 +19,4 @@ typedef struct {
UzblCookieJar *uzbl_cookie_jar_new();
-void
-uzbl_cookie_jar_set_handler(UzblCookieJar *jar, const gchar *handler);
-
-char
-*get_cookies(UzblCookieJar *jar, SoupURI *uri);
-
#endif
diff --git a/src/io.c b/src/io.c
index 1c463db..1e85237 100644
--- a/src/io.c
+++ b/src/io.c
@@ -129,27 +129,20 @@ control_stdin(GIOChannel *gio, GIOCondition condition) {
return TRUE;
}
-
void
-create_stdin () {
- GIOChannel *chan = NULL;
- GError *error = NULL;
-
- chan = g_io_channel_unix_new(fileno(stdin));
+create_stdin() {
+ GIOChannel *chan = g_io_channel_unix_new(fileno(stdin));
if (chan) {
if (!g_io_add_watch(chan, G_IO_IN|G_IO_HUP, (GIOFunc) control_stdin, NULL)) {
- g_error ("Stdin: could not add watch\n");
- } else {
- if (uzbl.state.verbose)
- printf ("Stdin: watch added successfully\n");
+ g_error ("create_stdin: could not add watch\n");
+ } else if (uzbl.state.verbose) {
+ printf ("create_stdin: watch added successfully\n");
}
} else {
- g_error ("Stdin: Error while opening: %s\n", error->message);
+ g_error ("create_stdin: error while opening stdin\n");
}
- if (error) g_error_free (error);
}
-
gboolean
remove_socket_from_array(GIOChannel *chan) {
gboolean ret = 0;
@@ -163,7 +156,6 @@ remove_socket_from_array(GIOChannel *chan) {
return ret;
}
-
gboolean
control_socket(GIOChannel *chan) {
struct sockaddr_un remote;
diff --git a/src/util.c b/src/util.c
index 3cf6416..f56eb57 100644
--- a/src/util.c
+++ b/src/util.c
@@ -172,7 +172,7 @@ find_existing_file(gchar* path_list) {
i++;
}
-g_free(executable);
+ g_free(executable);
g_strfreev(split);
return NULL;
}
@@ -187,12 +187,6 @@ itos(int val) {
}
gchar*
-strfree(gchar *str) {
- g_free(str);
- return NULL;
-}
-
-gchar*
argv_idx(const GArray *a, const guint idx) {
return g_array_index(a, gchar*, idx);
}
diff --git a/src/util.h b/src/util.h
index a0efe85..388c202 100644
--- a/src/util.h
+++ b/src/util.h
@@ -17,5 +17,4 @@ gboolean for_each_line_in_file(const gchar *path, void (*callback)(const gcha
enum exp_type get_exp_type(const gchar*);
gchar* find_existing_file(gchar*);
char* itos(int val);
-gchar* strfree(gchar *str);
gchar* argv_idx(const GArray*, const guint);
diff --git a/src/uzbl-browser b/src/uzbl-browser
index faa2829..81645ca 100755
--- a/src/uzbl-browser
+++ b/src/uzbl-browser
@@ -64,13 +64,6 @@ then
export UZBL_UTIL_DIR
fi
-# uzbl-cookie-manager will exit if another instance is already running.
-# we could also check if its pid file exists to avoid having to spawn it.
-#if [ ! -f "$XDG_CACHE_HOME"/uzbl/cookie_daemon_socket.pid ]
-#then
-# ${UZBL_COOKIE_DAEMON:-uzbl-cookie-manager}
-#fi
-
# uzbl-event-manager will exit if one is already running.
# we could also check if its pid file exists to avoid having to spawn it.
DAEMON_SOCKET="$XDG_CACHE_HOME"/uzbl/event_daemon
diff --git a/src/uzbl-core.c b/src/uzbl-core.c
index 4ee0129..a3a03b0 100644
--- a/src/uzbl-core.c
+++ b/src/uzbl-core.c
@@ -92,7 +92,6 @@ const struct var_name_to_ptr_t {
{ "title_format_short", PTR_V_STR(uzbl.behave.title_format_short, 1, NULL)},
{ "icon", PTR_V_STR(uzbl.gui.icon, 1, set_icon)},
{ "forward_keys", PTR_V_INT(uzbl.behave.forward_keys, 1, NULL)},
- { "cookie_handler", PTR_V_STR(uzbl.behave.cookie_handler, 1, cmd_set_cookie_handler)},
{ "authentication_handler", PTR_V_STR(uzbl.behave.authentication_handler, 1, set_authentication_handler)},
{ "scheme_handler", PTR_V_STR(uzbl.behave.scheme_handler, 1, NULL)},
{ "download_handler", PTR_V_STR(uzbl.behave.download_handler, 1, NULL)},
@@ -146,6 +145,7 @@ const struct var_name_to_ptr_t {
{ "SELECTED_URI", PTR_C_STR(uzbl.state.selected_url, NULL)},
{ "NAME", PTR_C_STR(uzbl.state.instance_name, NULL)},
{ "PID", PTR_C_STR(uzbl.info.pid_str, NULL)},
+ { "_", PTR_C_STR(uzbl.state.last_result, NULL)},
{ NULL, {.ptr.s = NULL, .type = TYPE_INT, .dump = 0, .writeable = 0, .func = NULL}}
};
@@ -334,7 +334,6 @@ expand(const char* s, guint recurse) {
return g_string_free(buf, FALSE);
}
-
void
clean_up(void) {
if (uzbl.info.pid_str) {
@@ -489,55 +488,55 @@ VIEWFUNC(go_forward)
#undef VIEWFUNC
/* -- command to callback/function map for things we cannot attach to any signals */
-struct {const char *key; CommandInfo value;} cmdlist[] =
+CommandInfo cmdlist[] =
{ /* key function no_split */
- { "back", {view_go_back, 0} },
- { "forward", {view_go_forward, 0} },
- { "scroll", {scroll_cmd, 0} },
- { "reload", {view_reload, 0}, },
- { "reload_ign_cache", {view_reload_bypass_cache, 0} },
- { "stop", {view_stop_loading, 0}, },
- { "zoom_in", {view_zoom_in, 0}, }, //Can crash (when max zoom reached?).
- { "zoom_out", {view_zoom_out, 0}, },
- { "toggle_zoom_type", {toggle_zoom_type, 0}, },
- { "uri", {load_uri, TRUE} },
- { "js", {run_js, TRUE} },
- { "script", {run_external_js, 0} },
- { "toggle_status", {toggle_status_cb, 0} },
- { "spawn", {spawn_async, 0} },
- { "sync_spawn", {spawn_sync, 0} }, // needed for cookie handler
- { "sync_spawn_exec", {spawn_sync_exec, 0} }, // needed for load_cookies.sh :(
- { "sh", {spawn_sh_async, 0} },
- { "sync_sh", {spawn_sh_sync, 0} }, // needed for cookie handler
- { "exit", {close_uzbl, 0} },
- { "search", {search_forward_text, TRUE} },
- { "search_reverse", {search_reverse_text, TRUE} },
- { "search_clear", {search_clear, TRUE} },
- { "dehilight", {dehilight, 0} },
- { "set", {set_var, TRUE} },
- { "dump_config", {act_dump_config, 0} },
- { "dump_config_as_events", {act_dump_config_as_events, 0} },
- { "chain", {chain, 0} },
- { "print", {print, TRUE} },
- { "event", {event, TRUE} },
- { "request", {event, TRUE} },
- { "menu_add", {menu_add, TRUE} },
- { "menu_link_add", {menu_add_link, TRUE} },
- { "menu_image_add", {menu_add_image, TRUE} },
- { "menu_editable_add", {menu_add_edit, TRUE} },
- { "menu_separator", {menu_add_separator, TRUE} },
- { "menu_link_separator", {menu_add_separator_link, TRUE} },
- { "menu_image_separator", {menu_add_separator_image, TRUE}},
- { "menu_editable_separator", {menu_add_separator_edit, TRUE} },
- { "menu_remove", {menu_remove, TRUE} },
- { "menu_link_remove", {menu_remove_link, TRUE} },
- { "menu_image_remove", {menu_remove_image, TRUE} },
- { "menu_editable_remove", {menu_remove_edit, TRUE} },
- { "hardcopy", {hardcopy, TRUE} },
- { "include", {include, TRUE} },
- { "show_inspector", {show_inspector, 0} },
- { "add_cookie", {add_cookie, 0} },
- { "delete_cookie", {delete_cookie, 0} }
+ { "back", view_go_back, 0 },
+ { "forward", view_go_forward, 0 },
+ { "scroll", scroll_cmd, 0 },
+ { "reload", view_reload, 0 },
+ { "reload_ign_cache", view_reload_bypass_cache, 0 },
+ { "stop", view_stop_loading, 0 },
+ { "zoom_in", view_zoom_in, 0 }, //Can crash (when max zoom reached?).
+ { "zoom_out", view_zoom_out, 0 },
+ { "toggle_zoom_type", toggle_zoom_type, 0 },
+ { "uri", load_uri, TRUE },
+ { "js", run_js, TRUE },
+ { "script", run_external_js, 0 },
+ { "toggle_status", toggle_status_cb, 0 },
+ { "spawn", spawn_async, 0 },
+ { "sync_spawn", spawn_sync, 0 },
+ { "sync_spawn_exec", spawn_sync_exec, 0 }, // needed for load_cookies.sh :(
+ { "sh", spawn_sh_async, 0 },
+ { "sync_sh", spawn_sh_sync, 0 },
+ { "exit", close_uzbl, 0 },
+ { "search", search_forward_text, TRUE },
+ { "search_reverse", search_reverse_text, TRUE },
+ { "search_clear", search_clear, TRUE },
+ { "dehilight", dehilight, 0 },
+ { "set", set_var, TRUE },
+ { "dump_config", act_dump_config, 0 },
+ { "dump_config_as_events", act_dump_config_as_events, 0 },
+ { "chain", chain, 0 },
+ { "print", print, TRUE },
+ { "event", event, TRUE },
+ { "request", event, TRUE },
+ { "menu_add", menu_add, TRUE },
+ { "menu_link_add", menu_add_link, TRUE },
+ { "menu_image_add", menu_add_image, TRUE },
+ { "menu_editable_add", menu_add_edit, TRUE },
+ { "menu_separator", menu_add_separator, TRUE },
+ { "menu_link_separator", menu_add_separator_link, TRUE },
+ { "menu_image_separator", menu_add_separator_image, TRUE },
+ { "menu_editable_separator", menu_add_separator_edit, TRUE },
+ { "menu_remove", menu_remove, TRUE },
+ { "menu_link_remove", menu_remove_link, TRUE },
+ { "menu_image_remove", menu_remove_image, TRUE },
+ { "menu_editable_remove", menu_remove_edit, TRUE },
+ { "hardcopy", hardcopy, TRUE },
+ { "include", include, TRUE },
+ { "show_inspector", show_inspector, 0 },
+ { "add_cookie", add_cookie, 0 },
+ { "delete_cookie", delete_cookie, 0 }
};
void
@@ -546,7 +545,7 @@ commands_hash(void) {
uzbl.behave.commands = g_hash_table_new(g_str_hash, g_str_equal);
for (i = 0; i < LENGTH(cmdlist); i++)
- g_hash_table_insert(uzbl.behave.commands, (gpointer) cmdlist[i].key, &cmdlist[i].value);
+ g_hash_table_insert(uzbl.behave.commands, (gpointer) cmdlist[i].key, &cmdlist[i]);
}
@@ -864,7 +863,8 @@ search_clear(WebKitWebView *page, GArray *argv, GString *result) {
(void) result;
webkit_web_view_unmark_text_matches (page);
- uzbl.state.searchtx = strfree (uzbl.state.searchtx);
+ g_free(uzbl.state.searchtx);
+ uzbl.state.searchtx = NULL;
}
void
@@ -887,16 +887,21 @@ dehilight(WebKitWebView *page, GArray *argv, GString *result) {
void
chain(WebKitWebView *page, GArray *argv, GString *result) {
- (void) page; (void) result;
- gchar *a = NULL;
- gchar **parts = NULL;
+ (void) page;
guint i = 0;
- while ((a = argv_idx(argv, i++))) {
- parts = g_strsplit (a, " ", 2);
- if (parts[0])
- parse_command(parts[0], parts[1], result);
- g_strfreev (parts);
+ const gchar *cmd;
+ GString *r = g_string_new ("");
+ while ((cmd = argv_idx(argv, i++))) {
+ GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*));
+ const CommandInfo *c = parse_command_parts(cmd, a);
+ if (c)
+ run_parsed_command(c, a, r);
+ g_array_free (a, TRUE);
}
+ if(result)
+ g_string_assign (result, r->str);
+
+ g_string_free(r, TRUE);
}
void
@@ -930,7 +935,8 @@ run_command (const gchar *command, const gchar **args, const gboolean sync,
gboolean result;
if (sync) {
- if (*output_stdout) *output_stdout = strfree(*output_stdout);
+ if (*output_stdout)
+ g_free(*output_stdout);
result = g_spawn_sync(NULL, (gchar **)a->data, NULL, G_SPAWN_SEARCH_PATH,
NULL, NULL, output_stdout, NULL, NULL, &err);
@@ -998,25 +1004,28 @@ split_quoted(const gchar* src, const gboolean unquote) {
}
void
-spawn(GArray *argv, gboolean sync, gboolean exec) {
+spawn(GArray *argv, GString *result, gboolean exec) {
gchar *path = NULL;
gchar *arg_car = argv_idx(argv, 0);
const gchar **arg_cdr = &g_array_index(argv, const gchar *, 1);
if (arg_car && (path = find_existing_file(arg_car))) {
- if (uzbl.comm.sync_stdout)
- uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout);
- run_command(path, arg_cdr, sync, sync?&uzbl.comm.sync_stdout:NULL);
- // run each line of output from the program as a command
- if (sync && exec && uzbl.comm.sync_stdout) {
- gchar *head = uzbl.comm.sync_stdout;
- gchar *tail;
- while ((tail = strchr (head, '\n'))) {
- *tail = '\0';
- parse_cmd_line(head, NULL);
- head = tail + 1;
+ gchar *r = NULL;
+ run_command(path, arg_cdr, result != NULL, result ? &r : NULL);
+ if(result) {
+ g_string_assign(result, r);
+ // run each line of output from the program as a command
+ if (exec && r) {
+ gchar *head = r;
+ gchar *tail;
+ while ((tail = strchr (head, '\n'))) {
+ *tail = '\0';
+ parse_cmd_line(head, NULL);
+ head = tail + 1;
+ }
}
}
+ g_free(r);
g_free(path);
}
}
@@ -1024,23 +1033,28 @@ spawn(GArray *argv, gboolean sync, gboolean exec) {
void
spawn_async(WebKitWebView *web_view, GArray *argv, GString *result) {
(void)web_view; (void)result;
- spawn(argv, FALSE, FALSE);
+ spawn(argv, NULL, FALSE);
}
void
spawn_sync(WebKitWebView *web_view, GArray *argv, GString *result) {
- (void)web_view; (void)result;
- spawn(argv, TRUE, FALSE);
+ (void)web_view;
+ spawn(argv, result, FALSE);
}
void
spawn_sync_exec(WebKitWebView *web_view, GArray *argv, GString *result) {
- (void)web_view; (void)result;
- spawn(argv, TRUE, TRUE);
+ (void)web_view;
+ if(!result) {
+ GString *force_result = g_string_new("");
+ spawn(argv, force_result, TRUE);
+ g_string_free (force_result, TRUE);
+ } else
+ spawn(argv, result, TRUE);
}
void
-spawn_sh(GArray *argv, gboolean sync) {
+spawn_sh(GArray *argv, GString *result) {
if (!uzbl.behave.shell_cmd) {
g_printerr ("spawn_sh: shell_cmd is not set!\n");
return;
@@ -1048,19 +1062,23 @@ spawn_sh(GArray *argv, gboolean sync) {
guint i;
gchar **cmd = split_quoted(uzbl.behave.shell_cmd, TRUE);
+ if(!cmd)
+ return;
+
gchar *cmdname = g_strdup(cmd[0]);
g_array_insert_val(argv, 1, cmdname);
for (i = 1; i < g_strv_length(cmd); i++)
g_array_prepend_val(argv, cmd[i]);
- if (cmd) {
- if (uzbl.comm.sync_stdout)
- uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout);
+ if (result) {
+ gchar *r = NULL;
+ run_command(cmd[0], (const gchar **) argv->data, TRUE, &r);
+ g_string_assign(result, r);
+ g_free(r);
+ } else
+ run_command(cmd[0], (const gchar **) argv->data, FALSE, NULL);
- run_command(cmd[0], (const gchar **) argv->data,
- sync, sync?&uzbl.comm.sync_stdout:NULL);
- }
g_free (cmdname);
g_strfreev (cmd);
}
@@ -1068,58 +1086,101 @@ spawn_sh(GArray *argv, gboolean sync) {
void
spawn_sh_async(WebKitWebView *web_view, GArray *argv, GString *result) {
(void)web_view; (void)result;
- spawn_sh(argv, FALSE);
+ spawn_sh(argv, NULL);
}
void
spawn_sh_sync(WebKitWebView *web_view, GArray *argv, GString *result) {
(void)web_view; (void)result;
- spawn_sh(argv, TRUE);
+ spawn_sh(argv, result);
}
void
-parse_command(const char *cmd, const char *param, GString *result) {
- CommandInfo *c;
- GString *tmp = g_string_new("");
+run_parsed_command(const CommandInfo *c, GArray *a, GString *result) {
+ c->function(uzbl.gui.web_view, a, result);
+
+ /* send the COMMAND_EXECUTED event, except for set and event/request commands */
+ if(strcmp("set", c->key) &&
+ strcmp("event", c->key) &&
+ strcmp("request", c->key)) {
+ GString *tmp = g_string_new(c->key);
+ const gchar *p;
+ guint i = 0;
+ while ((p = argv_idx(a, i++)))
+ g_string_append_printf(tmp, " '%s'", p);
+ send_event(COMMAND_EXECUTED, tmp->str, NULL);
+ g_string_free(tmp, TRUE);
+ }
+
+ if(result) {
+ g_free(uzbl.state.last_result);
+ uzbl.state.last_result = g_strdup(result->str);
+ }
+}
- if ((c = g_hash_table_lookup(uzbl.behave.commands, cmd))) {
+void
+parse_command_arguments(const gchar *p, GArray *a, gboolean no_split) {
+ if (no_split && p) { /* pass the parameters through in one chunk */
+ sharg_append(a, g_strdup(p));
+ return;
+ }
+
+ gchar **par = split_quoted(p, TRUE);
+ if (par) {
guint i;
- gchar **par = split_quoted(param, TRUE);
- GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*));
+ for (i = 0; i < g_strv_length(par); i++)
+ sharg_append(a, g_strdup(par[i]));
+ g_strfreev (par);
+ }
+}
- if (c->no_split) { /* don't split */
- sharg_append(a, param);
- } else if (par) {
- for (i = 0; i < g_strv_length(par); i++)
- sharg_append(a, par[i]);
- }
+const CommandInfo *
+parse_command_parts(const gchar *line, GArray *a) {
+ CommandInfo *c = NULL;
- if (result == NULL) {
- GString *result_print = g_string_new("");
+ gchar *exp_line = expand(line, 0);
+ if(exp_line[0] == '\0')
+ return NULL;
- c->function(uzbl.gui.web_view, a, result_print);
- if (result_print->len)
- printf("%*s\n", (int)result_print->len, result_print->str);
+ /* separate the line into the command and its parameters */
+ gchar **tokens = g_strsplit(exp_line, " ", 2);
- g_string_free(result_print, TRUE);
- } else {
- c->function(uzbl.gui.web_view, a, result);
- }
- g_strfreev (par);
- g_array_free (a, TRUE);
+ /* look up the command */
+ c = g_hash_table_lookup(uzbl.behave.commands, tokens[0]);
- if(strcmp("set", cmd) &&
- strcmp("event", cmd) &&
- strcmp("request", cmd)) {
- g_string_printf(tmp, "%s %s", cmd, param?param:"");
- send_event(COMMAND_EXECUTED, tmp->str, NULL);
- }
+ if(!c) {
+ send_event(COMMAND_ERROR, exp_line, NULL);
+ g_free(exp_line);
+ g_strfreev(tokens);
+ return NULL;
}
- else {
- g_string_printf (tmp, "%s %s", cmd, param?param:"");
- send_event(COMMAND_ERROR, tmp->str, NULL);
+
+ gchar *p = g_strdup(tokens[1]);
+ g_free(exp_line);
+ g_strfreev(tokens);
+
+ /* parse the arguments */
+ parse_command_arguments(p, a, c->no_split);
+ g_free(p);
+
+ return c;
+}
+
+void
+parse_command(const char *cmd, const char *params, GString *result) {
+ CommandInfo *c = g_hash_table_lookup(uzbl.behave.commands, cmd);
+ if(c) {
+ GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*));
+
+ parse_command_arguments(params, a, c->no_split);
+ run_parsed_command(c, a, result);
+
+ g_array_free (a, TRUE);
+ } else {
+ gchar *tmp = g_strconcat(cmd, " ", params, NULL);
+ send_event(COMMAND_ERROR, tmp, NULL);
+ g_free(tmp);
}
- g_string_free(tmp, TRUE);
}
@@ -1212,44 +1273,24 @@ set_var_value(const gchar *name, gchar *val) {
}
void
-parse_cmd_line(const char* ctl_line, GString* result) {
- size_t len = 0;
- gchar* ctlstrip = NULL;
- gchar* exp_line = NULL;
- gchar* work_string = NULL;
-
- work_string = g_strdup(ctl_line);
-
- /* Strip trailing newline */
- len = strlen(ctl_line);
- if (work_string[len - 1] == '\n')
- ctlstrip = g_strndup(work_string, len - 1);
- else
- ctlstrip = g_strdup(work_string);
- g_free(work_string);
-
- if( strcmp(g_strchug(ctlstrip), "") &&
- strcmp(exp_line = expand(ctlstrip, 0), "")
- ) {
- /* ignore comments */
- if((exp_line[0] == '#'))
- ;
-
- /* parse a command */
- else {
- gchar **tokens = NULL;
-
- tokens = g_strsplit(exp_line, " ", 2);
- parse_command(tokens[0], tokens[1], result);
- g_strfreev(tokens);
- }
- g_free(exp_line);
+parse_cmd_line(const char *ctl_line, GString *result) {
+ gchar *work_string = g_strdup(ctl_line);
+
+ /* strip trailing newline, and any other whitespace in front */
+ g_strstrip(work_string);
+
+ if( strcmp(work_string, "") ) {
+ if((work_string[0] != '#')) { /* ignore comments */
+ GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*));
+ const CommandInfo *c = parse_command_parts(work_string, a);
+ run_parsed_command(c, a, result);
+ g_array_free (a, TRUE);
+ }
}
- g_free(ctlstrip);
+ g_free(work_string);
}
-
void
update_title(void) {
Behaviour *b = &uzbl.behave;
@@ -1397,126 +1438,6 @@ create_plug() {
return plug;
}
-
-gchar**
-inject_handler_args(const gchar *actname, const gchar *origargs, const gchar *newargs) {
- /*
- If actname is one that calls an external command, this function will inject
- newargs in front of the user-provided args in that command line. They will
- come become after the body of the script (in sh) or after the name of
- the command to execute (in spawn).
- i.e. sh <body> <userargs> becomes sh <body> <ARGS> <userargs> and
- spawn <command> <userargs> becomes spawn <command> <ARGS> <userargs>.
-
- The return value consist of two strings: the action (sh, ...) and its args.
-
- If act is not one that calls an external command, then the given action merely
- gets duplicated.
- */
- GArray *rets = g_array_new(TRUE, FALSE, sizeof(gchar*));
- /* Arrr! Here be memory leaks */
- gchar *actdup = g_strdup(actname);
- g_array_append_val(rets, actdup);
-
- if ((g_strcmp0(actname, "spawn") == 0) ||
- (g_strcmp0(actname, "sh") == 0) ||
- (g_strcmp0(actname, "sync_spawn") == 0) ||
- (g_strcmp0(actname, "sync_sh") == 0)) {
- guint i;
- GString *a = g_string_new("");
- gchar **spawnparts = split_quoted(origargs, FALSE);
- g_string_append_printf(a, "%s", spawnparts[0]); /* sh body or script name */
- if (newargs) g_string_append_printf(a, " %s", newargs); /* handler args */
-
- for (i = 1; i < g_strv_length(spawnparts); i++) /* user args */
- if (spawnparts[i]) g_string_append_printf(a, " %s", spawnparts[i]);
-
- g_array_append_val(rets, a->str);
- g_string_free(a, FALSE);
- g_strfreev(spawnparts);
- } else {
- gchar *origdup = g_strdup(origargs);
- g_array_append_val(rets, origdup);
- }
- return (gchar**)g_array_free(rets, FALSE);
-}
-
-void
-run_handler (const gchar *act, const gchar *args) {
- /* Consider this code a temporary hack to make the handlers usable.
- In practice, all this splicing, injection, and reconstruction is
- inefficient, annoying and hard to manage. Potential pitfalls arise
- when the handler specific args 1) are not quoted (the handler
- callbacks should take care of this) 2) are quoted but interfere
- with the users' own quotation. A more ideal solution is
- to refactor parse_command so that it doesn't just take a string
- and execute it; rather than that, we should have a function which
- returns the argument vector parsed from the string. This vector
- could be modified (e.g. insert additional args into it) before
- passing it to the next function that actually executes it. Though
- it still isn't perfect for chain actions.. will reconsider & re-
- factor when I have the time. -duc */
-
- if (!act) return;
- char **parts = g_strsplit(act, " ", 2);
- if (!parts || !parts[0]) return;
- if (g_strcmp0(parts[0], "chain") == 0) {
- GString *newargs = g_string_new("");
- gchar **chainparts = split_quoted(parts[1], FALSE);
-
- /* for every argument in the chain, inject the handler args
- and make sure the new parts are wrapped in quotes */
- gchar **cp = chainparts;
- gchar quot = '\'';
- gchar *quotless = NULL;
- gchar **spliced_quotless = NULL; // sigh -_-;
- gchar **inpart = NULL;
-
- while (*cp) {
- if ((**cp == '\'') || (**cp == '\"')) { /* strip old quotes */
- quot = **cp;
- quotless = g_strndup(&(*cp)[1], strlen(*cp) - 2);
- } else quotless = g_strdup(*cp);
-
- spliced_quotless = g_strsplit(quotless, " ", 2);
- inpart = inject_handler_args(spliced_quotless[0], spliced_quotless[1], args);
- g_strfreev(spliced_quotless);
-
- g_string_append_printf(newargs, " %c%s %s%c", quot, inpart[0], inpart[1], quot);
- g_free(quotless);
- g_strfreev(inpart);
- cp++;
- }
-
- parse_command(parts[0], &(newargs->str[1]), NULL);
- g_string_free(newargs, TRUE);
- g_strfreev(chainparts);
-
- } else {
- gchar **inparts;
- gchar *inparts_[2];
- if (parts[1]) {
- /* expand the user-specified arguments */
- gchar* expanded = expand(parts[1], 0);
- inparts = inject_handler_args(parts[0], expanded, args);
- g_free(expanded);
- } else {
- inparts_[0] = parts[0];
- inparts_[1] = g_strdup(args);
- inparts = inparts_;
- }
-
- parse_command(inparts[0], inparts[1], NULL);
-
- if (inparts != inparts_) {
- g_free(inparts[0]);
- g_free(inparts[1]);
- } else
- g_free(inparts[1]);
- }
- g_strfreev(parts);
-}
-
void
settings_init () {
State* s = &uzbl.state;
@@ -1559,32 +1480,34 @@ void handle_authentication (SoupSession *session, SoupMessage *msg, SoupAuth *au
(void) user_data;
if (uzbl.behave.authentication_handler && *uzbl.behave.authentication_handler != 0) {
- gchar *info, *host, *realm;
- gchar *p;
-
soup_session_pause_message(session, msg);
- /* Sanitize strings */
- info = g_strdup(soup_auth_get_info(auth));
- host = g_strdup(soup_auth_get_host(auth));
- realm = g_strdup(soup_auth_get_realm(auth));
- for (p = info; *p; p++) if (*p == '\'') *p = '\"';
- for (p = host; *p; p++) if (*p == '\'') *p = '\"';
- for (p = realm; *p; p++) if (*p == '\'') *p = '\"';
+ GString *result = g_string_new ("");
- GString *s = g_string_new ("");
- g_string_printf(s, "'%s' '%s' '%s' '%s'",
- info, host, realm, retrying?"TRUE":"FALSE");
+ gchar *info = g_strdup(soup_auth_get_info(auth));
+ gchar *host = g_strdup(soup_auth_get_host(auth));
+ gchar *realm = g_strdup(soup_auth_get_realm(auth));
- run_handler(uzbl.behave.authentication_handler, s->str);
+ GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*));
+ const CommandInfo *c = parse_command_parts(uzbl.behave.authentication_handler, a);
+ if(c) {
+ sharg_append(a, info);
+ sharg_append(a, host);
+ sharg_append(a, realm);
+ sharg_append(a, retrying ? "TRUE" : "FALSE");
+
+ run_parsed_command(c, a, result);
+ }
+ g_array_free(a, TRUE);
- if (uzbl.comm.sync_stdout && strcmp (uzbl.comm.sync_stdout, "") != 0) {
+ if (result->len > 0) {
char *username, *password;
int number_of_endls=0;
- username = uzbl.comm.sync_stdout;
+ username = result->str;
- for (p = uzbl.comm.sync_stdout; *p; p++) {
+ gchar *p;
+ for (p = result->str; *p; p++) {
if (*p == '\n') {
*p = '\0';
if (++number_of_endls == 1)
@@ -1598,12 +1521,9 @@ void handle_authentication (SoupSession *session, SoupMessage *msg, SoupAuth *au
soup_auth_authenticate(auth, username, password);
}
- if (uzbl.comm.sync_stdout)
- uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout);
-
soup_session_unpause_message(session, msg);
- g_string_free(s, TRUE);
+ g_string_free(result, TRUE);
g_free(info);
g_free(host);
g_free(realm);
@@ -1714,6 +1634,7 @@ initialize(int argc, char** argv) {
uzbl.info.arch = ARCH;
uzbl.info.commit = COMMIT;
+ uzbl.state.last_result = NULL;
/* Parse commandline arguments */
GOptionContext* context = g_option_context_new ("[ uri ] - load a uri by default");
diff --git a/src/uzbl-core.h b/src/uzbl-core.h
index 76421d2..a10c0ce 100644
--- a/src/uzbl-core.h
+++ b/src/uzbl-core.h
@@ -43,6 +43,10 @@
#include <sys/ioctl.h>
#include <assert.h>
+#if GTK_CHECK_VERSION(2,91,0)
+ #include <gtk/gtkx.h>
+#endif
+
#include "cookie-jar.h"
#define LENGTH(x) (sizeof x / sizeof x[0])
@@ -90,7 +94,6 @@ typedef struct {
gchar *socket_path;
GHashTable *proto_var; /* stores (key)"variable name" -> (value)"pointer to var */
- gchar *sync_stdout;
GPtrArray *connect_chan;
GPtrArray *client_chan;
} Communication;
@@ -107,6 +110,7 @@ typedef struct {
gchar* searchtx;
gboolean verbose;
GdkEventButton* last_button;
+ gchar* last_result;
gboolean plug_mode;
/* Events */
@@ -148,7 +152,6 @@ typedef struct {
gchar* socket_dir;
/* Handlers */
- gchar* cookie_handler;
gchar* authentication_handler;
gchar* scheme_handler;
gchar* download_handler;
@@ -251,9 +254,9 @@ typedef struct {
/*@null@*/ void (*func)(void);
} uzbl_cmdprop;
-
/* Functions */
void clean_up(void);
+void update_title(void);
/* Signal management functions */
void catch_sigterm(int s);
@@ -278,9 +281,6 @@ void spawn_sync_exec(WebKitWebView *web_view, GArray *argv, GString *resu
void parse_command(const char *cmd, const char *param, GString *result);
void parse_cmd_line(const char *ctl_line, GString *result);
-
-void update_title(void);
-
/* Keyboard events functions */
gboolean key_press_cb(GtkWidget* window, GdkEventKey* event);
gboolean key_release_cb(GtkWidget* window, GdkEventKey* event);
@@ -340,10 +340,20 @@ void builtins();
typedef void (*Command)(WebKitWebView*, GArray *argv, GString *result);
typedef struct {
- Command function;
- gboolean no_split;
+ const gchar *key;
+ Command function;
+ gboolean no_split;
} CommandInfo;
+const CommandInfo *
+parse_command_parts(const gchar *line, GArray *a);
+
+void
+parse_command_arguments(const gchar *p, GArray *a, gboolean no_split);
+
+void
+run_parsed_command(const CommandInfo *c, GArray *a, GString *result);
+
typedef struct {
gchar* name;
gchar* cmd;