diff options
author | Brendan Taylor <whateley@gmail.com> | 2010-11-13 10:29:01 -0700 |
---|---|---|
committer | Brendan Taylor <whateley@gmail.com> | 2010-11-13 10:29:01 -0700 |
commit | 351428bd782a625f4534fac417b75d582c1d206b (patch) | |
tree | 696bcfe1aa1b677ec149038c25ee082fc7c63675 | |
parent | f6beec78c65c51938e1d01627564a6d1f8021673 (diff) | |
parent | 94a7ef21e4036407fa800567766e20957e8d55ae (diff) |
Merge branch 'dev/soup-cookied'
Conflicts:
Makefile
-rw-r--r-- | Makefile | 22 | ||||
-rw-r--r-- | examples/uzbl-cookie-manager.c | 384 | ||||
-rw-r--r-- | src/callbacks.c | 2 | ||||
-rw-r--r-- | src/util.c | 110 | ||||
-rw-r--r-- | src/util.h | 18 | ||||
-rw-r--r-- | src/uzbl-core.c | 179 | ||||
-rw-r--r-- | src/uzbl-core.h | 21 |
7 files changed, 555 insertions, 181 deletions
@@ -3,14 +3,14 @@ CFLAGS:=-std=c99 $(shell pkg-config --cflags gtk+-2.0 webkit-1.0 libsoup-2.4 gthread-2.0 glib-2.0) -ggdb -Wall -W -DARCH="\"$(shell uname -m)\"" -lgthread-2.0 -DCOMMIT="\"$(shell ./misc/hash.sh)\"" $(CPPFLAGS) -fPIC -W -Wall -Wextra -pedantic CFLAGS!=echo -std=c99 `pkg-config --cflags gtk+-2.0 webkit-1.0 libsoup-2.4 gthread-2.0 glib-2.0` -ggdb -Wall -W -DARCH='"\""'`uname -m`'"\""' -lgthread-2.0 -DCOMMIT='"\""'`./misc/hash.sh`'"\""' $(CPPFLAGS) -fPIC -W -Wall -Wextra -pedantic -LDFLAGS:=$(shell pkg-config --libs gtk+-2.0 webkit-1.0 libsoup-2.4 gthread-2.0 x11) -pthread $(LDFLAGS) -LDFLAGS!=echo `pkg-config --libs gtk+-2.0 webkit-1.0 libsoup-2.4 gthread-2.0 x11` -pthread $(LDFLAGS) +UZBL_LDFLAGS:=$(shell pkg-config --libs gtk+-2.0 webkit-1.0 libsoup-2.4 gthread-2.0 x11) -pthread $(LDFLAGS) +UZBL_LDFLAGS!=echo `pkg-config --libs gtk+-2.0 webkit-1.0 libsoup-2.4 gthread-2.0 x11` -pthread $(LDFLAGS) SRC = $(wildcard src/*.c) HEAD = $(wildcard src/*.h) OBJ = $(foreach obj, $(SRC:.c=.o), $(notdir $(obj))) -all: uzbl-browser +all: uzbl-browser uzbl-cookie-manager VPATH:=src @@ -21,10 +21,14 @@ VPATH:=src ${OBJ}: ${HEAD} uzbl-core: ${OBJ} - @echo -e "\n${CC} -o $@ ${OBJ} ${LDFLAGS}" - @${CC} -o $@ ${OBJ} ${LDFLAGS} + @echo -e "\n${CC} -o $@ ${OBJ} ${UZBL_LDFLAGS}" + @${CC} -o $@ ${OBJ} ${UZBL_LDFLAGS} -uzbl-browser: uzbl-core +uzbl-cookie-manager: examples/uzbl-cookie-manager.o src/util.o + @echo -e "\n${CC} -o $@ uzbl-cookie-manager.o util.o ${LDFLAGS} ${shell pkg-config --libs glib-2.0 libsoup-2.4}" + @${CC} -o $@ uzbl-cookie-manager.o util.o ${LDFLAGS} $(shell pkg-config --libs glib-2.0 libsoup-2.4) + +uzbl-browser: uzbl-core uzbl-cookie-manager # packagers, set DESTDIR to your "package directory" and PREFIX to the prefix you want to have on the end-user system # end-users who build from source: don't care about DESTDIR, update PREFIX if you want to @@ -72,11 +76,13 @@ test-uzbl-browser-sandbox: uzbl-browser clean: rm -f uzbl-core + rm -f uzbl-cookie-manager rm -f uzbl-core.o rm -f events.o rm -f callbacks.o rm -f inspector.o rm -f cookie-jar.o + rm -f util.o find ./examples/ -name "*.pyc" -delete cd ./tests/; $(MAKE) clean rm -rf ./sandbox/ @@ -105,9 +111,9 @@ install-uzbl-core: all install-dirs rm $(INSTALLDIR)/share/uzbl/examples/config/config.bak install -m755 uzbl-core $(INSTALLDIR)/bin/uzbl-core -install-uzbl-browser: install-dirs +install-uzbl-browser: uzbl-cookie-manager install-dirs install -m755 src/uzbl-browser $(INSTALLDIR)/bin/uzbl-browser - install -m755 examples/data/scripts/uzbl-cookie-daemon $(INSTALLDIR)/bin/uzbl-cookie-daemon + install -m755 uzbl-cookie-manager $(INSTALLDIR)/bin/uzbl-cookie-manager install -m755 examples/data/scripts/uzbl-event-manager $(INSTALLDIR)/bin/uzbl-event-manager mv $(INSTALLDIR)/bin/uzbl-browser $(INSTALLDIR)/bin/uzbl-browser.bak sed 's#^PREFIX=.*#PREFIX=$(RUN_PREFIX)#' < $(INSTALLDIR)/bin/uzbl-browser.bak > $(INSTALLDIR)/bin/uzbl-browser diff --git a/examples/uzbl-cookie-manager.c b/examples/uzbl-cookie-manager.c new file mode 100644 index 0000000..133a857 --- /dev/null +++ b/examples/uzbl-cookie-manager.c @@ -0,0 +1,384 @@ +#define _POSIX_SOURCE + +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include <ctype.h> +#include <signal.h> + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <sys/select.h> +#include <sys/unistd.h> + +#include <sys/stat.h> +#include <sys/file.h> +#include <fcntl.h> +#include <stdlib.h> + +#include <libsoup/soup-cookie.h> +#include <libsoup/soup-cookie-jar-text.h> +#include <libsoup/soup-uri.h> + +#include "../src/util.h" + +extern const XDG_Var XDG[]; + +int verbose = 0; + +#define SOCK_BACKLOG 10 +#define MAX_COOKIE_LENGTH 4096 + +char cookie_buffer[MAX_COOKIE_LENGTH]; + +int setup_socket(const char *cookied_socket_path) { + /* delete the cookie socket if it was left behind on a previous run */ + unlink(cookied_socket_path); + + int socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0); + + if(socket_fd < 0) { + fprintf(stderr, "socket failed (%s)\n", strerror(errno)); + return -1; + } + + struct sockaddr_un sa; + sa.sun_family = AF_UNIX; + strcpy(sa.sun_path, cookied_socket_path); + + if(bind(socket_fd, (struct sockaddr*)&sa, sizeof(sa)) < 0) { + fprintf(stderr, "bind failed (%s)\n", strerror(errno)); + return -1; + } + + if(listen(socket_fd, SOCK_BACKLOG) < 0) { + fprintf(stderr, "listen failed (%s)\n", strerror(errno)); + return -1; + } + + return socket_fd; +} + +const char *whitelist_path = NULL; +GPtrArray *whitelisted_hosts = NULL; +time_t whitelist_update_time = 0; + +void whitelist_line_cb(const gchar* line, void *user_data) { + (void) user_data; + + gchar *norm_host; + + const gchar *p = line; + while(isspace(*p)) + p++; + + if(p[0] == '#' || !p[0]) /* ignore comments and blank lines */ + return; + + if(p[0] == '.') + norm_host = g_strdup(p); + else + norm_host = g_strconcat(".", p, NULL); + + g_ptr_array_add(whitelisted_hosts, g_strchomp(norm_host)); +} + +gboolean load_whitelist(const char *whitelist_path) { + if(!file_exists(whitelist_path)) + return FALSE; + + /* check if the whitelist file was updated */ + struct stat f; + if(stat(whitelist_path, &f) < 0) + return FALSE; + + if(whitelisted_hosts == NULL) + whitelisted_hosts = g_ptr_array_new(); + + if(f.st_mtime > whitelist_update_time) { + /* the file was updated, reload the whitelist */ + if(verbose) puts("reloading whitelist"); + while(whitelisted_hosts->len > 0) { + g_free(g_ptr_array_index(whitelisted_hosts, 0)); + g_ptr_array_remove_index_fast(whitelisted_hosts, 0); + } + for_each_line_in_file(whitelist_path, whitelist_line_cb, NULL); + whitelist_update_time = f.st_mtime; + } + + return TRUE; +} + +gboolean should_save_cookie(const char *host) { + if(!load_whitelist(whitelist_path)) + return TRUE; /* some error with the file, assume no whitelist */ + + /* we normalize the hostname so it has a . in front like the whitelist entries */ + gchar *test_host = (host[0] == '.') ? g_strdup(host) : g_strconcat(".", host, NULL); + int hl = strlen(test_host); + + /* test against each entry in the whitelist */ + gboolean result = FALSE; + guint i; + for(i = 0; i < whitelisted_hosts->len; i++) { + /* a match means the host ends with (or is equal to) the whitelist entry */ + const gchar *entry = g_ptr_array_index(whitelisted_hosts, i); + int el = strlen(entry); + result = (el <= hl) && !strcmp(test_host + (hl - el), entry); + + if(result) + break; + } + + g_free(test_host); + + return result; +} + +void handle_request(SoupCookieJar *j, const char *buff, int len, int fd) { + const char *command = buff; + + const char *scheme = command + strlen(command) + 1; + if((scheme - buff) > len) { + fprintf(stderr, "got malformed or partial request\n"); + return; + } + + const char *host = scheme + strlen(scheme) + 1; + if((host - buff) > len) { + fprintf(stderr, "got malformed or partial request\n"); + return; + } + + const char *path = host + strlen(host) + 1; + if((path - buff) > len) { + fprintf(stderr, "got malformed or partial request\n"); + return; + } + + /* glue the parts back together into a SoupURI */ + char *u = g_strconcat(scheme, "://", host, path, NULL); + if(verbose) printf("%s %s\n", command, u); + SoupURI *uri = soup_uri_new(u); + g_free(u); + + if(!strcmp(command, "GET")) { + char *result = soup_cookie_jar_get_cookies(j, uri, TRUE); + if(result) { + if(verbose) puts(result); + if(write(fd, result, strlen(result)+1) < 0) + fprintf(stderr, "write failed (%s)", strerror(errno)); + + g_free(result); + } else { + if(verbose) puts("-"); + if(write(fd, "", 1) < 0) + fprintf(stderr, "write failed (%s)", strerror(errno)); + } + } else if(!strcmp(command, "PUT")) { + const char *name_and_val = path + strlen(path) + 1; + if((name_and_val - buff) > len) { + fprintf(stderr, "got malformed or partial request\n"); + return; + } + + if(verbose) puts(name_and_val); + + if(should_save_cookie(host)) { + char *eql = strchr(name_and_val, '='); + eql[0] = 0; + + const char *name = name_and_val; + const char *value = eql + 1; + + SoupCookie *cookie = soup_cookie_new(name, value, host, path, SOUP_COOKIE_MAX_AGE_ONE_YEAR); + + soup_cookie_jar_add_cookie(j, cookie); + } else if(verbose) + puts("no, blacklisted."); + + if(write(fd, "", 1) < 0) + fprintf(stderr, "write failed (%s)", strerror(errno)); + } + + soup_uri_free(uri); +} + +void +wait_for_things_to_happen_and_then_do_things(SoupCookieJar* j, int cookie_socket) { + GArray *connections = g_array_new (FALSE, FALSE, sizeof (int)); + + while(1) { + unsigned int i; + int r; + fd_set fs; + + int maxfd = cookie_socket; + FD_ZERO(&fs); + FD_SET(maxfd, &fs); + + for(i = 0; i < connections->len; i++) { + int fd = g_array_index(connections, int, i); + if(fd > maxfd) maxfd = fd; + FD_SET(fd, &fs); + } + + r = select(maxfd+1, &fs, NULL, NULL, NULL); + if(r < 0) { + fprintf(stderr, "select failed (%s)\n", strerror(errno)); + continue; + } + + if(FD_ISSET(cookie_socket, &fs)) { + /* handle new connection */ + int fd = accept(cookie_socket, NULL, NULL); + g_array_append_val(connections, fd); + if(verbose) puts("got connection."); + } + + for(i = 0; i < connections->len; i++) { + /* handle activity on a connection */ + int fd = g_array_index(connections, int, i); + if(FD_ISSET(fd, &fs)) { + r = read(fd, cookie_buffer, MAX_COOKIE_LENGTH); + if(r < 0) { + fprintf(stderr, "read failed (%s)\n", strerror(errno)); + continue; + } else if(r == 0) { + if(verbose) puts("client hung up."); + g_array_remove_index(connections, i); + i--; /* other elements in the array are moved down to fill the gap */ + continue; + } + cookie_buffer[r] = 0; + + handle_request(j, cookie_buffer, r, fd); + } + } + } +} + +void usage(const char *progname) { + printf("%s [-s socket-path] [-f cookies.txt] [-w whitelist-file] [-n] [-v]\n", progname); + puts("\t-n\tdon't daemonise the process"); + puts("\t-v\tbe verbose"); +} + +void daemonise() { + int r = fork(); + + if(r < 0) { + fprintf(stderr, "fork failed (%s)", strerror(errno)); + exit(1); + } else if (r > 0) { + /* this is the parent, which has done its job */ + exit(0); + } + + if(setsid() < 0) { + fprintf(stderr, "setsid failed (%s)", strerror(errno)); + exit(1); + } +} + +const char *pid_file_path = NULL; +const char *cookied_socket_path = NULL; + +void cleanup_after_signal(int signal) { + (void) signal; + unlink(pid_file_path); + unlink(cookied_socket_path); + exit(0); +} + +int main(int argc, char *argv[]) { + int i; + + const char *cookies_txt_path = NULL; + gboolean foreground = FALSE; + + for(i = 1; i < argc && argv[i][0] == '-'; i++) { + switch(argv[i][1]) { + case 's': + cookied_socket_path = argv[++i]; + break; + case 'f': + cookies_txt_path = argv[++i]; + break; + case 'w': + whitelist_path = argv[++i]; + break; + case 'n': + foreground = TRUE; + break; + case 'v': + verbose = 1; + break; + default: + usage(argv[0]); + return 1; + } + } + + if(verbose) + foreground = TRUE; + + if(!foreground) + daemonise(); + + if(!cookies_txt_path) + cookies_txt_path = g_strconcat(get_xdg_var(XDG[1]), "/uzbl/cookies.txt", NULL); + + if(!cookied_socket_path) + cookied_socket_path = g_strconcat(get_xdg_var(XDG[2]), "/uzbl/cookie_daemon_socket", NULL); + + if(!whitelist_path) + whitelist_path = g_strconcat(get_xdg_var(XDG[0]), "/uzbl/cookie_whitelist", NULL); + + /* write out and lock the pid file. + * this ensures that only one uzbl-cookie-manager is running per-socket. + * (we should probably also lock the cookies.txt to prevent accidents...) */ + pid_file_path = g_strconcat(cookied_socket_path, ".pid", NULL); + int lockfd = open(pid_file_path, O_RDWR|O_CREAT, 0600); + if(lockfd < 0) { + fprintf(stderr, "couldn't open pid file %s (%s)\n", pid_file_path, strerror(errno)); + return 1; + } + + if(flock(lockfd, LOCK_EX|LOCK_NB) < 0) { + fprintf(stderr, "couldn't lock pid file %s (%s)\n", pid_file_path, strerror(errno)); + fprintf(stderr, "uzbl-cookie-manager is probably already running\n"); + return 1; + } + + gchar* pids = g_strdup_printf("%d\n", getpid()); + write(lockfd, pids, strlen(pids)); + g_free(pids); + + struct sigaction sa; + sa.sa_handler = cleanup_after_signal; + if(sigaction(SIGINT, &sa, NULL) || sigaction(SIGTERM, &sa, NULL)) { + fprintf(stderr, "sigaction failed (%s)\n", strerror(errno)); + return 1; + } + + if(!foreground) { + /* close STDIO */ + close(0); + close(1); + close(2); + } + + g_type_init(); + + SoupCookieJar *j = soup_cookie_jar_text_new(cookies_txt_path, FALSE); + + int cookie_socket = setup_socket(cookied_socket_path); + if(cookie_socket < 0) + return 1; + + wait_for_things_to_happen_and_then_do_things(j, cookie_socket); + + return 0; +} diff --git a/src/callbacks.c b/src/callbacks.c index 0cfa7f4..0cf713b 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -6,7 +6,7 @@ #include "uzbl-core.h" #include "callbacks.h" #include "events.h" - +#include "util.h" void set_proxy_url() { diff --git a/src/util.c b/src/util.c new file mode 100644 index 0000000..c9c728e --- /dev/null +++ b/src/util.c @@ -0,0 +1,110 @@ +#define _POSIX_SOURCE + +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +#include "util.h" + +const XDG_Var XDG[] = +{ + { "XDG_CONFIG_HOME", "~/.config" }, + { "XDG_DATA_HOME", "~/.local/share" }, + { "XDG_CACHE_HOME", "~/.cache" }, + { "XDG_CONFIG_DIRS", "/etc/xdg" }, + { "XDG_DATA_DIRS", "/usr/local/share/:/usr/share/" }, +}; + +/*@null@*/ gchar* +get_xdg_var (XDG_Var xdg) { + const gchar* actual_value = getenv (xdg.environmental); + const gchar* home = getenv ("HOME"); + gchar* return_value; + + if (! actual_value || strcmp (actual_value, "") == 0) { + if (xdg.default_value) { + return_value = str_replace ("~", home, xdg.default_value); + } else { + return_value = NULL; + } + } else { + return_value = str_replace("~", home, actual_value); + } + + return return_value; +} + +/*@null@*/ gchar* +find_xdg_file (int xdg_type, const char* filename) { + /* xdg_type = 0 => config + xdg_type = 1 => data + xdg_type = 2 => cache*/ + + gchar* xdgv = get_xdg_var (XDG[xdg_type]); + gchar* temporary_file = g_strconcat (xdgv, filename, NULL); + g_free (xdgv); + + gchar* temporary_string; + char* saveptr; + char* buf; + + if (! file_exists (temporary_file) && xdg_type != 2) { + buf = get_xdg_var (XDG[3 + xdg_type]); + temporary_string = (char *) strtok_r (buf, ":", &saveptr); + g_free(buf); + + while ((temporary_string = (char * ) strtok_r (NULL, ":", &saveptr)) && ! file_exists (temporary_file)) { + g_free (temporary_file); + temporary_file = g_strconcat (temporary_string, filename, NULL); + } + } + + //g_free (temporary_string); - segfaults. + + if (file_exists (temporary_file)) { + return temporary_file; + } else { + g_free(temporary_file); + return NULL; + } +} + +gboolean +file_exists (const char * filename) { + return (access(filename, F_OK) == 0); +} + +char * +str_replace (const char* search, const char* replace, const char* string) { + gchar **buf; + char *ret; + + if(!string) + return NULL; + + buf = g_strsplit (string, search, -1); + ret = g_strjoinv (replace, buf); + g_strfreev(buf); + + return ret; +} + +gboolean +for_each_line_in_file(const gchar *path, void (*callback)(const gchar *l, void *c), void *user_data) { + gchar *line = NULL; + gsize len; + + GIOChannel *chan = g_io_channel_new_file(path, "r", NULL); + + if (chan) { + while (g_io_channel_read_line(chan, &line, &len, NULL, NULL) == G_IO_STATUS_NORMAL) { + callback(line, user_data); + g_free(line); + } + g_io_channel_unref (chan); + + return TRUE; + } + + return FALSE; +} diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..f03f13e --- /dev/null +++ b/src/util.h @@ -0,0 +1,18 @@ +#include <glib.h> + +typedef struct { + gchar* environmental; + gchar* default_value; +} XDG_Var; + +gchar* get_xdg_var (XDG_Var xdg); + +gchar* find_xdg_file (int xdg_type, const char* filename); + +gboolean file_exists(const char* filename); + +char * +str_replace (const char* search, const char* replace, const char* string); + +gboolean +for_each_line_in_file(const gchar *path, void (*callback)(const gchar *l, void *c), void *user_data); diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 6b120d0..777c9b4 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -34,6 +34,7 @@ #include "events.h" #include "inspector.h" #include "config.h" +#include "util.h" UzblCore uzbl; @@ -62,15 +63,6 @@ GOptionEntry entries[] = { NULL, 0, 0, 0, NULL, NULL, NULL } }; -XDG_Var XDG[] = -{ - { "XDG_CONFIG_HOME", "~/.config" }, - { "XDG_DATA_HOME", "~/.local/share" }, - { "XDG_CACHE_HOME", "~/.cache" }, - { "XDG_CONFIG_DIRS", "/etc/xdg" }, - { "XDG_DATA_DIRS", "/usr/local/share/:/usr/share/" }, -}; - /* abbreviations to help keep the table's width humane */ #define PTR_V_STR(var, d, fun) { .ptr.s = &(var), .type = TYPE_STR, .dump = d, .writeable = 1, .func = fun } #define PTR_V_INT(var, d, fun) { .ptr.i = (int*)&(var), .type = TYPE_INT, .dump = d, .writeable = 1, .func = fun } @@ -372,48 +364,6 @@ strfree(gchar *str) { gchar* argv_idx(const GArray *a, const guint idx) { return g_array_index(a, gchar*, idx); } -char * -str_replace (const char* search, const char* replace, const char* string) { - gchar **buf; - char *ret; - - if(!string) - return NULL; - - buf = g_strsplit (string, search, -1); - ret = g_strjoinv (replace, buf); - g_strfreev(buf); - - return ret; -} - -GArray* -read_file_by_line (const gchar *path) { - GIOChannel *chan = NULL; - gchar *readbuf = NULL; - gsize len; - GArray *lines = g_array_new(TRUE, FALSE, sizeof(gchar*)); - int i = 0; - - chan = g_io_channel_new_file(path, "r", NULL); - if (chan) { - while (g_io_channel_read_line(chan, &readbuf, &len, NULL, NULL) == G_IO_STATUS_NORMAL) { - const gchar* val = g_strdup (readbuf); - g_array_append_val (lines, val); - g_free (readbuf); - i ++; - } - - g_io_channel_unref (chan); - } else { - gchar *tmp = g_strdup_printf("File %s can not be read.", path); - send_event(COMMAND_ERROR, tmp, NULL); - g_free(tmp); - } - - return lines; -} - /* search a PATH style string for an existing file+path combination */ gchar* find_existing_file(gchar* path_list) { @@ -735,11 +685,6 @@ builtins() { /* -- CORE FUNCTIONS -- */ -bool -file_exists (const char * filename) { - return (access(filename, F_OK) == 0); -} - void set_var(WebKitWebView *page, GArray *argv, GString *result) { (void) page; (void) result; @@ -970,28 +915,30 @@ hardcopy(WebKitWebView *page, GArray *argv, GString *result) { webkit_web_frame_print(webkit_web_view_get_main_frame(page)); } +/* just a wrapper so parse_cmd_line can be used with for_each_line_in_file */ +static void +parse_cmd_line_cb(const char *line, void *user_data) { + (void) user_data; + parse_cmd_line(line, NULL); +} + void include(WebKitWebView *page, GArray *argv, GString *result) { (void) page; (void) result; gchar *pe = NULL, - *path = NULL, - *line; - int i=0; + *path = NULL; if(!argv_idx(argv, 0)) return; pe = parseenv(argv_idx(argv, 0)); if((path = find_existing_file(pe))) { - GArray* lines = read_file_by_line(path); - - while ((line = g_array_index(lines, gchar*, i))) { - parse_cmd_line (line, NULL); - i++; - g_free (line); + if(!for_each_line_in_file(path, parse_cmd_line_cb, NULL)) { + gchar *tmp = g_strdup_printf("File %s can not be read.", path); + send_event(COMMAND_ERROR, tmp, NULL); + g_free(tmp); } - g_array_free (lines, TRUE); send_event(FILE_INCLUDED, path, NULL); g_free(path); @@ -1163,32 +1110,23 @@ run_external_js (WebKitWebView * web_view, GArray *argv, GString *result) { if (argv_idx(argv, 0) && ((path = find_existing_file(argv_idx(argv, 0)))) ) { - GArray* lines = read_file_by_line (path); - gchar* js = NULL; - int i = 0; - gchar* line; - - while ((line = g_array_index(lines, gchar*, i))) { - if (js == NULL) { - js = g_strdup (line); - } else { - gchar* newjs = g_strconcat (js, line, NULL); - js = newjs; - } - i ++; - g_free (line); + gchar *file_contents = NULL; + + GIOChannel *chan = g_io_channel_new_file(path, "r", NULL); + if (chan) { + gsize len; + g_io_channel_read_to_end(chan, &file_contents, &len, NULL); + g_io_channel_unref (chan); } if (uzbl.state.verbose) printf ("External JavaScript file %s loaded\n", argv_idx(argv, 0)); - gchar* newjs = str_replace("%s", argv_idx (argv, 1)?argv_idx (argv, 1):"", js); - g_free (js); - js = newjs; + gchar *js = str_replace("%s", argv_idx (argv, 1) ? argv_idx (argv, 1) : "", file_contents); + g_free (file_contents); eval_js (web_view, js, result, path); g_free (js); - g_array_free (lines, TRUE); g_free(path); } } @@ -1639,7 +1577,6 @@ parse_cmd_line(const char *ctl_line, GString *result) { g_free(ctlstrip); } - /*@null@*/ gchar* build_stream_name(int type, const gchar* dir) { State *s = &uzbl.state; @@ -2138,59 +2075,6 @@ run_handler (const gchar *act, const gchar *args) { g_strfreev(parts); } -/*@null@*/ gchar* -get_xdg_var (XDG_Var xdg) { - const gchar* actual_value = getenv (xdg.environmental); - const gchar* home = getenv ("HOME"); - gchar* return_value; - - if (! actual_value || strcmp (actual_value, "") == 0) { - if (xdg.default_value) { - return_value = str_replace ("~", home, xdg.default_value); - } else { - return_value = NULL; - } - } else { - return_value = str_replace("~", home, actual_value); - } - - return return_value; -} - -/*@null@*/ gchar* -find_xdg_file (int xdg_type, const char* filename) { - /* xdg_type = 0 => config - xdg_type = 1 => data - xdg_type = 2 => cache*/ - - gchar* xdgv = get_xdg_var (XDG[xdg_type]); - gchar* temporary_file = g_strconcat (xdgv, filename, NULL); - g_free (xdgv); - - gchar* temporary_string; - char* saveptr; - char* buf; - - if (! file_exists (temporary_file) && xdg_type != 2) { - buf = get_xdg_var (XDG[3 + xdg_type]); - temporary_string = (char *) strtok_r (buf, ":", &saveptr); - g_free(buf); - - while ((temporary_string = (char * ) strtok_r (NULL, ":", &saveptr)) && ! file_exists (temporary_file)) { - g_free (temporary_file); - temporary_file = g_strconcat (temporary_string, filename, NULL); - } - } - - //g_free (temporary_string); - segfaults. - - if (file_exists (temporary_file)) { - return temporary_file; - } else { - g_free(temporary_file); - return NULL; - } -} void settings_init () { State *s = &uzbl.state; @@ -2211,20 +2095,13 @@ settings_init () { } if (s->config_file) { - GArray* lines = read_file_by_line (s->config_file); - int i = 0; - gchar* line; - - while ((line = g_array_index(lines, gchar*, i))) { - parse_cmd_line (line, NULL); - i ++; - g_free (line); + if(!for_each_line_in_file(s->config_file, parse_cmd_line_cb, NULL)) { + gchar *tmp = g_strdup_printf("File %s can not be read.", s->config_file); + send_event(COMMAND_ERROR, tmp, NULL); + g_free(tmp); } - g_array_free (lines, TRUE); - } else { - if (uzbl.state.verbose) - printf ("No configuration file loaded.\n"); - } + } else if (uzbl.state.verbose) + printf ("No configuration file loaded.\n"); if(s->connect_socket_names) init_connect_socket(); diff --git a/src/uzbl-core.h b/src/uzbl-core.h index 19a5887..a572d72 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -206,12 +206,6 @@ extern UzblCore uzbl; typedef void sigfunc(int); -/* XDG Stuff */ -typedef struct { - gchar* environmental; - gchar* default_value; -} XDG_Var; - /* uzbl variables */ enum ptr_type {TYPE_INT, TYPE_STR, TYPE_FLOAT}; typedef struct { @@ -230,15 +224,9 @@ typedef struct { char * itos(int val); -char * -str_replace (const char* search, const char* replace, const char* string); - gchar* strfree(gchar *str); -GArray* -read_file_by_line (const gchar *path); - gchar* parseenv (gchar* string); @@ -263,9 +251,6 @@ print(WebKitWebView *page, GArray *argv, GString *result); void commands_hash(void); -bool -file_exists (const char * filename); - void load_uri (WebKitWebView * web_view, GArray *argv, GString *result); @@ -351,12 +336,6 @@ create_plug (); void run_handler (const gchar *act, const gchar *args); -/*@null@*/ gchar* -get_xdg_var (XDG_Var xdg); - -/*@null@*/ gchar* -find_xdg_file (int xdg_type, const char* filename); - void settings_init (); |