diff options
author | Brendan Taylor <whateley@gmail.com> | 2009-06-26 19:42:03 -0600 |
---|---|---|
committer | Brendan Taylor <whateley@gmail.com> | 2009-06-26 19:42:03 -0600 |
commit | 91dc10ff7f2801ea6a5013ded9d55838fa8af77c (patch) | |
tree | db9446d7dae9ee84040630de9186cf695df88f7f /uzbl.c | |
parent | 8f6067a1b7706079fc9711f2cd23dc1125977b78 (diff) | |
parent | 8284be1a0682492a3d65b6fa12534e247460e94d (diff) |
Merge branch 'experimental' of git://github.com/Dieterbe/uzbl into clean
Diffstat (limited to 'uzbl.c')
-rw-r--r-- | uzbl.c | 478 |
1 files changed, 346 insertions, 132 deletions
@@ -45,6 +45,7 @@ #include <sys/time.h> #include <webkit/webkit.h> #include <libsoup/soup.h> +#include <JavaScriptCore/JavaScript.h> #include <stdio.h> #include <string.h> @@ -57,7 +58,6 @@ #include "config.h" static Uzbl uzbl; -typedef void (*Command)(WebKitWebView*, GArray *argv); @@ -191,12 +191,41 @@ make_var_to_name_hash() { } /* --- UTILITY FUNCTIONS --- */ + +enum {EXP_ERR, EXP_SIMPLE_VAR, EXP_BRACED_VAR, EXP_EXPR, EXP_JS}; +static guint +get_exp_type(gchar *s) { + /* variables */ + if(*(s+1) == '(') + return EXP_EXPR; + else if(*(s+1) == '{') + return EXP_BRACED_VAR; + else if(*(s+1) == '<') + return EXP_JS; + else + return EXP_SIMPLE_VAR; + +return EXP_ERR; +} + +/* + * recurse == 1: don't expand '@(command)@' + * recurse == 2: don't expand '@<java script>@' + */ static gchar * -expand_vars(char *s) { +expand(char *s, guint recurse) { uzbl_cmdprop *c; + guint etype; char upto = ' '; - char ret[256], *vend; + char *end_simple_var = "^°!\"§$%&/()=?'`'+~*'#-.:,;@<>| \\{}[]¹²³¼½"; + char str_end[2]; + char ret[4096]; + char *vend; + GError *err = NULL; + gchar *cmd_stdout = NULL; + gchar *mycmd = NULL; GString *buf = g_string_new(""); + GString *js_ret = g_string_new(""); while(*s) { switch(*s) { @@ -204,15 +233,51 @@ expand_vars(char *s) { g_string_append_c(buf, *++s); s++; break; + case '@': - if(*(s+1) == '{') { - upto = '}'; s++; - } + etype = get_exp_type(s); s++; - if( (vend = strchr(s, upto)) || - (vend = strchr(s, '\0')) ) { - strncpy(ret, s, vend-s); - ret[vend-s] = '\0'; + + switch(etype) { + case EXP_SIMPLE_VAR: + if( (vend = strpbrk(s, end_simple_var)) || + (vend = strchr(s, '\0')) ) { + strncpy(ret, s, vend-s); + ret[vend-s] = '\0'; + } + break; + case EXP_BRACED_VAR: + s++; upto = '}'; + if( (vend = strchr(s, upto)) || + (vend = strchr(s, '\0')) ) { + strncpy(ret, s, vend-s); + ret[vend-s] = '\0'; + } + break; + case EXP_EXPR: + s++; + strcpy(str_end, ")@"); + str_end[2] = '\0'; + if( (vend = strstr(s, str_end)) || + (vend = strchr(s, '\0')) ) { + strncpy(ret, s, vend-s); + ret[vend-s] = '\0'; + } + break; + case EXP_JS: + s++; + strcpy(str_end, ">@"); + str_end[2] = '\0'; + if( (vend = strstr(s, str_end)) || + (vend = strchr(s, '\0')) ) { + strncpy(ret, s, vend-s); + ret[vend-s] = '\0'; + } + break; + } + + if(etype == EXP_SIMPLE_VAR || + etype == EXP_BRACED_VAR) { if( (c = g_hash_table_lookup(uzbl.comm.proto_var, ret)) ) { if(c->type == TYPE_STR) g_string_append(buf, (gchar *)*c->ptr); @@ -222,17 +287,49 @@ expand_vars(char *s) { g_free(b); } } - if(upto == ' ') s = vend; - else s = vend+1; - upto = ' '; + if(etype == EXP_SIMPLE_VAR) + s = vend; + else + s = vend+1; + } + else if(recurse != 1 && + etype == EXP_EXPR) { + mycmd = expand(ret, 1); + g_spawn_command_line_sync(mycmd, &cmd_stdout, NULL, NULL, &err); + g_free(mycmd); + + if (err) { + g_printerr("error on running command: %s\n", err->message); + g_error_free (err); + } + else if (*cmd_stdout) { + g_string_append(buf, cmd_stdout); + g_free(cmd_stdout); + } + s = vend+2; + } + else if(recurse != 2 && + etype == EXP_JS) { + mycmd = expand(ret, 2); + eval_js(uzbl.gui.web_view, mycmd, js_ret); + g_free(mycmd); + + if(js_ret->str) { + g_string_append(buf, js_ret->str); + g_string_free(js_ret, TRUE); + js_ret = g_string_new(""); + } + s = vend+2; } break; + default: g_string_append_c(buf, *s); s++; break; } } + g_string_free(js_ret, TRUE); return g_string_free(buf, FALSE); } @@ -466,27 +563,27 @@ scroll (GtkAdjustment* bar, GArray *argv) { } static void -scroll_begin(WebKitWebView* page, GArray *argv) { - (void) page; (void) argv; +scroll_begin(WebKitWebView* page, GArray *argv, GString *result) { + (void) page; (void) argv; (void) result; gtk_adjustment_set_value (uzbl.gui.bar_v, gtk_adjustment_get_lower(uzbl.gui.bar_v)); } static void -scroll_end(WebKitWebView* page, GArray *argv) { - (void) page; (void) argv; +scroll_end(WebKitWebView* page, GArray *argv, GString *result) { + (void) page; (void) argv; (void) result; gtk_adjustment_set_value (uzbl.gui.bar_v, gtk_adjustment_get_upper(uzbl.gui.bar_v) - gtk_adjustment_get_page_size(uzbl.gui.bar_v)); } static void -scroll_vert(WebKitWebView* page, GArray *argv) { - (void) page; +scroll_vert(WebKitWebView* page, GArray *argv, GString *result) { + (void) page; (void) result; scroll(uzbl.gui.bar_v, argv); } static void -scroll_horz(WebKitWebView* page, GArray *argv) { - (void) page; +scroll_horz(WebKitWebView* page, GArray *argv, GString *result) { + (void) page; (void) result; scroll(uzbl.gui.bar_h, argv); } @@ -501,17 +598,19 @@ cmd_set_status() { } static void -toggle_zoom_type (WebKitWebView* page, GArray *argv) { +toggle_zoom_type (WebKitWebView* page, GArray *argv, GString *result) { (void)page; (void)argv; + (void)result; webkit_web_view_set_full_content_zoom (page, !webkit_web_view_get_full_content_zoom (page)); } static void -toggle_status_cb (WebKitWebView* page, GArray *argv) { +toggle_status_cb (WebKitWebView* page, GArray *argv, GString *result) { (void)page; (void)argv; + (void)result; if (uzbl.behave.show_status) { gtk_widget_hide(uzbl.gui.mainbar); @@ -612,7 +711,7 @@ log_history_cb () { /* VIEW funcs (little webkit wrappers) */ -#define VIEWFUNC(name) static void view_##name(WebKitWebView *page, GArray *argv){(void)argv; webkit_web_view_##name(page);} +#define VIEWFUNC(name) static void view_##name(WebKitWebView *page, GArray *argv, GString *result){(void)argv; (void)result; webkit_web_view_##name(page);} VIEWFUNC(reload) VIEWFUNC(reload_bypass_cache) VIEWFUNC(stop_loading) @@ -623,7 +722,7 @@ VIEWFUNC(go_forward) #undef VIEWFUNC /* -- command to callback/function map for things we cannot attach to any signals */ -static struct {char *name; Command command[2];} cmdlist[] = +static struct {char *key; CommandInfo value;} cmdlist[] = { /* key function no_split */ { "back", {view_go_back, 0} }, { "forward", {view_go_forward, 0} }, @@ -637,8 +736,8 @@ static struct {char *name; Command command[2];} cmdlist[] = { "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, NOSPLIT} }, - { "js", {run_js, NOSPLIT} }, + { "uri", {load_uri, TRUE} }, + { "js", {run_js, TRUE} }, { "script", {run_external_js, 0} }, { "toggle_status", {toggle_status_cb, 0} }, { "spawn", {spawn, 0} }, @@ -646,19 +745,19 @@ static struct {char *name; Command command[2];} cmdlist[] = { "sh", {spawn_sh, 0} }, { "sync_sh", {spawn_sh_sync, 0} }, // needed for cookie handler { "exit", {close_uzbl, 0} }, - { "search", {search_forward_text, NOSPLIT} }, - { "search_reverse", {search_reverse_text, NOSPLIT} }, + { "search", {search_forward_text, TRUE} }, + { "search_reverse", {search_reverse_text, TRUE} }, { "dehilight", {dehilight, 0} }, { "toggle_insert_mode", {toggle_insert_mode, 0} }, - { "set", {set_var, NOSPLIT} }, - //{ "get", {get_var, NOSPLIT} }, - { "bind", {act_bind, NOSPLIT} }, + { "set", {set_var, TRUE} }, + //{ "get", {get_var, TRUE} }, + { "bind", {act_bind, TRUE} }, { "dump_config", {act_dump_config, 0} }, - { "keycmd", {keycmd, NOSPLIT} }, - { "keycmd_nl", {keycmd_nl, NOSPLIT} }, + { "keycmd", {keycmd, TRUE} }, + { "keycmd_nl", {keycmd_nl, TRUE} }, { "keycmd_bs", {keycmd_bs, 0} }, { "chain", {chain, 0} }, - { "print", {print, NOSPLIT} } + { "print", {print, TRUE} } }; static void @@ -668,7 +767,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, cmdlist[i].name, cmdlist[i].command); + g_hash_table_insert(uzbl.behave.commands, cmdlist[i].key, &cmdlist[i].value); } /* -- CORE FUNCTIONS -- */ @@ -701,8 +800,8 @@ file_exists (const char * filename) { } static void -set_var(WebKitWebView *page, GArray *argv) { - (void) page; +set_var(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; (void) result; gchar **split = g_strsplit(argv_idx(argv, 0), "=", 2); if (split[0] != NULL) { gchar *value = parseenv(g_strdup(split[1] ? g_strchug(split[1]) : " ")); @@ -713,18 +812,18 @@ set_var(WebKitWebView *page, GArray *argv) { } static void -print(WebKitWebView *page, GArray *argv) { - (void) page; +print(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; (void) result; gchar* buf; - buf = expand_vars(argv_idx(argv, 0)); - puts(buf); + buf = expand(argv_idx(argv, 0), 0); + g_string_assign(result, buf); g_free(buf); } static void -act_bind(WebKitWebView *page, GArray *argv) { - (void) page; +act_bind(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; (void) result; gchar **split = g_strsplit(argv_idx(argv, 0), " = ", 2); gchar *value = parseenv(g_strdup(split[1] ? g_strchug(split[1]) : " ")); add_binding(g_strstrip(split[0]), value); @@ -739,8 +838,8 @@ act_dump_config() { } static void -toggle_insert_mode(WebKitWebView *page, GArray *argv) { - (void)page; +toggle_insert_mode(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; (void) result; if (argv_idx(argv, 0)) { if (strcmp (argv_idx(argv, 0), "0") == 0) { @@ -756,11 +855,13 @@ toggle_insert_mode(WebKitWebView *page, GArray *argv) { } static void -load_uri (WebKitWebView *web_view, GArray *argv) { +load_uri (WebKitWebView *web_view, GArray *argv, GString *result) { + (void) result; + if (argv_idx(argv, 0)) { GString* newuri = g_string_new (argv_idx(argv, 0)); if (g_strstr_len (argv_idx(argv, 0), 11, "javascript:") != NULL) { - run_js(web_view, argv); + run_js(web_view, argv, NULL); return; } if (g_strrstr (argv_idx(argv, 0), "://") == NULL && g_strstr_len (argv_idx(argv, 0), 5, "data:") == NULL) @@ -771,14 +872,111 @@ load_uri (WebKitWebView *web_view, GArray *argv) { } } + +/* Javascript*/ + +static JSValueRef +js_run_command (JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, + size_t argumentCount, const JSValueRef arguments[], + JSValueRef* exception) { + (void) function; + (void) thisObject; + (void) exception; + + JSStringRef js_result_string; + GString *result = g_string_new(""); + + if (argumentCount >= 1) { + JSStringRef arg = JSValueToStringCopy(ctx, arguments[0], NULL); + size_t arg_size = JSStringGetMaximumUTF8CStringSize(arg); + char ctl_line[arg_size]; + JSStringGetUTF8CString(arg, ctl_line, arg_size); + + parse_cmd_line(ctl_line, result); + + JSStringRelease(arg); + } + js_result_string = JSStringCreateWithUTF8CString(result->str); + + g_string_free(result, TRUE); + + return JSValueMakeString(ctx, js_result_string); +} + +static JSStaticFunction js_static_functions[] = { + {"run", js_run_command, kJSPropertyAttributeNone}, +}; + static void -run_js (WebKitWebView * web_view, GArray *argv) { +js_init() { + /* This function creates the class and its definition, only once */ + if (!uzbl.js.initialized) { + /* it would be pretty cool to make this dynamic */ + uzbl.js.classdef = kJSClassDefinitionEmpty; + uzbl.js.classdef.staticFunctions = js_static_functions; + + uzbl.js.classref = JSClassCreate(&uzbl.js.classdef); + } +} + + +static void +eval_js(WebKitWebView * web_view, gchar *script, GString *result) { + WebKitWebFrame *frame; + JSGlobalContextRef context; + JSObjectRef globalobject; + JSStringRef var_name; + + JSStringRef js_script; + JSValueRef js_result; + JSStringRef js_result_string; + size_t js_result_size; + + js_init(); + + frame = webkit_web_view_get_main_frame(WEBKIT_WEB_VIEW(web_view)); + context = webkit_web_frame_get_global_context(frame); + globalobject = JSContextGetGlobalObject(context); + + /* uzbl javascript namespace */ + var_name = JSStringCreateWithUTF8CString("Uzbl"); + JSObjectSetProperty(context, globalobject, var_name, + JSObjectMake(context, uzbl.js.classref, NULL), + kJSClassAttributeNone, NULL); + + /* evaluate the script and get return value*/ + js_script = JSStringCreateWithUTF8CString(script); + js_result = JSEvaluateScript(context, js_script, globalobject, NULL, 0, NULL); + if (js_result && !JSValueIsUndefined(context, js_result)) { + js_result_string = JSValueToStringCopy(context, js_result, NULL); + js_result_size = JSStringGetMaximumUTF8CStringSize(js_result_string); + + if (js_result_size) { + char js_result_utf8[js_result_size]; + JSStringGetUTF8CString(js_result_string, js_result_utf8, js_result_size); + g_string_assign(result, js_result_utf8); + } + + JSStringRelease(js_result_string); + } + + /* cleanup */ + JSObjectDeleteProperty(context, globalobject, var_name, NULL); + + JSStringRelease(var_name); + JSStringRelease(js_script); +} + +static void +run_js (WebKitWebView * web_view, GArray *argv, GString *result) { + if (argv_idx(argv, 0)) - webkit_web_view_execute_script (web_view, argv_idx(argv, 0)); + eval_js(web_view, argv_idx(argv, 0), result); } static void -run_external_js (WebKitWebView * web_view, GArray *argv) { +run_external_js (WebKitWebView * web_view, GArray *argv, GString *result) { + (void) result; if (argv_idx(argv, 0)) { GArray* lines = read_file_by_line (argv_idx (argv, 0)); gchar* js = NULL; @@ -804,7 +1002,7 @@ run_external_js (WebKitWebView * web_view, GArray *argv) { g_free (js); js = newjs; } - webkit_web_view_execute_script (web_view, js); + eval_js (web_view, js, result); g_free (js); g_array_free (lines, TRUE); } @@ -829,18 +1027,20 @@ search_text (WebKitWebView *page, GArray *argv, const gboolean forward) { } static void -search_forward_text (WebKitWebView *page, GArray *argv) { +search_forward_text (WebKitWebView *page, GArray *argv, GString *result) { + (void) result; search_text(page, argv, TRUE); } static void -search_reverse_text (WebKitWebView *page, GArray *argv) { +search_reverse_text (WebKitWebView *page, GArray *argv, GString *result) { + (void) result; search_text(page, argv, FALSE); } static void -dehilight (WebKitWebView *page, GArray *argv) { - (void) argv; +dehilight (WebKitWebView *page, GArray *argv, GString *result) { + (void) argv; (void) result; webkit_web_view_set_highlight_text_matches (page, FALSE); } @@ -865,41 +1065,44 @@ new_window_load_uri (const gchar * uri) { } static void -chain (WebKitWebView *page, GArray *argv) { - (void)page; +chain (WebKitWebView *page, GArray *argv, GString *result) { + (void) page; (void) result; gchar *a = NULL; gchar **parts = NULL; guint i = 0; while ((a = argv_idx(argv, i++))) { parts = g_strsplit (a, " ", 2); - parse_command(parts[0], parts[1]); + parse_command(parts[0], parts[1], result); g_strfreev (parts); } } static void -keycmd (WebKitWebView *page, GArray *argv) { +keycmd (WebKitWebView *page, GArray *argv, GString *result) { (void)page; (void)argv; + (void)result; g_string_assign(uzbl.state.keycmd, argv_idx(argv, 0)); run_keycmd(FALSE); update_title(); } static void -keycmd_nl (WebKitWebView *page, GArray *argv) { +keycmd_nl (WebKitWebView *page, GArray *argv, GString *result) { (void)page; (void)argv; + (void)result; g_string_assign(uzbl.state.keycmd, argv_idx(argv, 0)); run_keycmd(TRUE); update_title(); } static void -keycmd_bs (WebKitWebView *page, GArray *argv) { +keycmd_bs (WebKitWebView *page, GArray *argv, GString *result) { gchar *prev; (void)page; (void)argv; + (void)result; prev = g_utf8_find_prev_char(uzbl.state.keycmd->str, uzbl.state.keycmd->str + uzbl.state.keycmd->len); if (prev) g_string_truncate(uzbl.state.keycmd, prev - uzbl.state.keycmd->str); @@ -907,9 +1110,10 @@ keycmd_bs (WebKitWebView *page, GArray *argv) { } static void -close_uzbl (WebKitWebView *page, GArray *argv) { +close_uzbl (WebKitWebView *page, GArray *argv, GString *result) { (void)page; (void)argv; + (void)result; gtk_main_quit (); } @@ -1238,16 +1442,16 @@ split_quoted(const gchar* src, const gboolean unquote) { } static void -spawn(WebKitWebView *web_view, GArray *argv) { - (void)web_view; +spawn(WebKitWebView *web_view, GArray *argv, GString *result) { + (void)web_view; (void)result; //TODO: allow more control over argument order so that users can have some arguments before the default ones from run_command, and some after if (argv_idx(argv, 0)) run_command(argv_idx(argv, 0), 0, ((const gchar **) (argv->data + sizeof(gchar*))), FALSE, NULL); } static void -spawn_sync(WebKitWebView *web_view, GArray *argv) { - (void)web_view; +spawn_sync(WebKitWebView *web_view, GArray *argv, GString *result) { + (void)web_view; (void)result; if (argv_idx(argv, 0)) run_command(argv_idx(argv, 0), 0, ((const gchar **) (argv->data + sizeof(gchar*))), @@ -1255,8 +1459,8 @@ spawn_sync(WebKitWebView *web_view, GArray *argv) { } static void -spawn_sh(WebKitWebView *web_view, GArray *argv) { - (void)web_view; +spawn_sh(WebKitWebView *web_view, GArray *argv, GString *result) { + (void)web_view; (void)result; if (!uzbl.behave.shell_cmd) { g_printerr ("spawn_sh: shell_cmd is not set!\n"); return; @@ -1276,8 +1480,8 @@ spawn_sh(WebKitWebView *web_view, GArray *argv) { } static void -spawn_sh_sync(WebKitWebView *web_view, GArray *argv) { - (void)web_view; +spawn_sh_sync(WebKitWebView *web_view, GArray *argv, GString *result) { + (void)web_view; (void)result; if (!uzbl.behave.shell_cmd) { g_printerr ("spawn_sh_sync: shell_cmd is not set!\n"); return; @@ -1298,22 +1502,32 @@ spawn_sh_sync(WebKitWebView *web_view, GArray *argv) { } static void -parse_command(const char *cmd, const char *param) { - Command *c; +parse_command(const char *cmd, const char *param, GString *result) { + CommandInfo *c; if ((c = g_hash_table_lookup(uzbl.behave.commands, cmd))) { - guint i; gchar **par = split_quoted(param, TRUE); GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); - if (c[1] == NOSPLIT) { /* don't split */ + 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]); } - c[0](uzbl.gui.web_view, a); + + if (result == NULL) { + GString *result_print = g_string_new(""); + + c->function(uzbl.gui.web_view, a, result_print); + if (result_print->len) + printf("%*s\n", result_print->len, result_print->str); + + g_string_free(result_print, TRUE); + } else { + c->function(uzbl.gui.web_view, a, result); + } g_strfreev (par); g_array_free (a, TRUE); @@ -1355,7 +1569,7 @@ static void cmd_load_uri() { GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); g_array_append_val (a, uzbl.state.uri); - load_uri(uzbl.gui.web_view, a); + load_uri(uzbl.gui.web_view, a, NULL); g_array_free (a, TRUE); } @@ -1588,17 +1802,17 @@ set_var_value(gchar *name, gchar *val) { if( (c = g_hash_table_lookup(uzbl.comm.proto_var, name)) ) { /* check for the variable type */ if (c->type == TYPE_STR) { - buf = expand_vars(val); + buf = expand(val, 0); g_free(*c->ptr); *c->ptr = buf; } else if(c->type == TYPE_INT) { int *ip = (int *)c->ptr; - buf = expand_vars(val); + buf = expand(val, 0); *ip = (int)strtoul(buf, &endp, 10); g_free(buf); } else if (c->type == TYPE_FLOAT) { float *fp = (float *)c->ptr; - buf = expand_vars(val); + buf = expand(val, 0); *fp = strtod(buf, &endp); g_free(buf); } @@ -1623,7 +1837,7 @@ render_html() { enum {M_CMD, M_HTML}; static void -parse_cmd_line(const char *ctl_line) { +parse_cmd_line(const char *ctl_line, GString *result) { Behaviour *b = &uzbl.behave; size_t len=0; @@ -1656,7 +1870,7 @@ parse_cmd_line(const char *ctl_line) { else ctlstrip = g_strdup(ctl_line); tokens = g_strsplit(ctlstrip, " ", 2); - parse_command(tokens[0], tokens[1]); + parse_command(tokens[0], tokens[1], result); g_free(ctlstrip); g_strfreev(tokens); } @@ -1702,7 +1916,7 @@ control_fifo(GIOChannel *gio, GIOCondition condition) { g_error_free (err); } - parse_cmd_line(ctl_line); + parse_cmd_line(ctl_line, NULL); g_free(ctl_line); return TRUE; @@ -1758,7 +1972,7 @@ control_stdin(GIOChannel *gio, GIOCondition condition) { if ( (ret == G_IO_STATUS_ERROR) || (ret == G_IO_STATUS_EOF) ) return FALSE; - parse_cmd_line(ctl_line); + parse_cmd_line(ctl_line, NULL); g_free(ctl_line); return TRUE; @@ -1786,53 +2000,53 @@ create_stdin () { static gboolean control_socket(GIOChannel *chan) { struct sockaddr_un remote; - char buffer[512], *ctl_line; - char temp[128]; - int sock, clientsock, n, done; - unsigned int t; - - sock = g_io_channel_unix_get_fd(chan); + unsigned int t = sizeof(remote); + int clientsock; + GIOChannel *clientchan; - memset (buffer, 0, sizeof (buffer)); - - t = sizeof (remote); - clientsock = accept (sock, (struct sockaddr *) &remote, &t); - - done = 0; - do { - memset (temp, 0, sizeof (temp)); - n = recv (clientsock, temp, 128, 0); - if (n == 0) { - buffer[strlen (buffer)] = '\0'; - done = 1; - } - if (!done) - strcat (buffer, temp); - } while (!done); - - if (strcmp (buffer, "\n") < 0) { - buffer[strlen (buffer) - 1] = '\0'; - } else { - buffer[strlen (buffer)] = '\0'; + clientsock = accept (g_io_channel_unix_get_fd(chan), + (struct sockaddr *) &remote, &t); + + if ((clientchan = g_io_channel_unix_new(clientsock))) { + g_io_add_watch(clientchan, G_IO_IN|G_IO_HUP, + (GIOFunc) control_client_socket, clientchan); } - close (clientsock); - ctl_line = g_strdup(buffer); - parse_cmd_line (ctl_line); -/* - TODO: we should be able to do it with this. but glib errors out with "Invalid argument" + return TRUE; +} + +static gboolean +control_client_socket(GIOChannel *clientchan) { + char *ctl_line; + GString *result = g_string_new(""); GError *error = NULL; - gsize len; GIOStatus ret; - ret = g_io_channel_read_line(chan, &ctl_line, &len, NULL, &error); - if (ret == G_IO_STATUS_ERROR) - g_error ("Error reading: %s\n", error->message); + gsize len; - printf("Got line %s (%u bytes) \n",ctl_line, len); - if(ctl_line) { - parse_line(ctl_line); -*/ + ret = g_io_channel_read_line(clientchan, &ctl_line, &len, NULL, &error); + if (ret == G_IO_STATUS_ERROR) { + g_warning ("Error reading: %s\n", error->message); + g_io_channel_shutdown(clientchan, TRUE, &error); + return FALSE; + } else if (ret == G_IO_STATUS_EOF) { + /* shutdown and remove channel watch from main loop */ + g_io_channel_shutdown(clientchan, TRUE, &error); + return FALSE; + } + if (ctl_line) { + parse_cmd_line (ctl_line, result); + g_string_append_c(result, '\n'); + ret = g_io_channel_write_chars (clientchan, result->str, result->len, + &len, &error); + if (ret == G_IO_STATUS_ERROR) { + g_warning ("Error writing: %s", error->message); + } + g_io_channel_flush(clientchan, &error); + } + + if (error) g_error_free (error); + g_string_free(result, TRUE); g_free(ctl_line); return TRUE; } @@ -1944,7 +2158,7 @@ key_press_cb (GtkWidget* window, GdkEventKey* event) if (event->keyval == GDK_Escape) { g_string_truncate(uzbl.state.keycmd, 0); update_title(); - dehilight(uzbl.gui.web_view, NULL); + dehilight(uzbl.gui.web_view, NULL, NULL); return TRUE; } @@ -1965,7 +2179,7 @@ key_press_cb (GtkWidget* window, GdkEventKey* event) } if (event->keyval == GDK_BackSpace) - keycmd_bs(NULL, NULL); + keycmd_bs(NULL, NULL, NULL); gboolean key_ret = FALSE; if ((event->keyval == GDK_Return) || (event->keyval == GDK_KP_Enter)) @@ -1984,7 +2198,7 @@ run_keycmd(const gboolean key_ret) { Action *act; if ((act = g_hash_table_lookup(uzbl.bindings, uzbl.state.keycmd->str))) { g_string_truncate(uzbl.state.keycmd, 0); - parse_command(act->name, act->param); + parse_command(act->name, act->param, NULL); return; } @@ -2026,7 +2240,7 @@ exec_paramcmd(const Action *act, const guint i) { g_string_printf (actionname, act->name, parampart->str); if (act->param) g_string_printf (actionparam, act->param, parampart->str); - parse_command(actionname->str, actionparam->str); + parse_command(actionname->str, actionparam->str, NULL); g_string_free(actionname, TRUE); g_string_free(actionparam, TRUE); g_string_free(parampart, TRUE); @@ -2187,13 +2401,13 @@ run_handler (const gchar *act, const gchar *args) { cp++; } - parse_command(parts[0], &(newargs->str[1])); + parse_command(parts[0], &(newargs->str[1]), NULL); g_string_free(newargs, TRUE); g_strfreev(chainparts); } else { gchar **inparts = inject_handler_args(parts[0], parts[1], args); - parse_command(inparts[0], inparts[1]); + parse_command(inparts[0], inparts[1], NULL); g_free(inparts[0]); g_free(inparts[1]); } @@ -2277,7 +2491,7 @@ settings_init () { Network *n = &uzbl.net; int i; for (i = 0; default_config[i].command != NULL; i++) { - parse_cmd_line(default_config[i].command); + parse_cmd_line(default_config[i].command, NULL); } if (!s->config_file) { @@ -2290,7 +2504,7 @@ settings_init () { gchar* line; while ((line = g_array_index(lines, gchar*, i))) { - parse_cmd_line (line); + parse_cmd_line (line, NULL); i ++; g_free (line); } |