aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Brendan Taylor <whateley@gmail.com>2010-11-13 10:29:01 -0700
committerGravatar Brendan Taylor <whateley@gmail.com>2010-11-13 10:29:01 -0700
commit351428bd782a625f4534fac417b75d582c1d206b (patch)
tree696bcfe1aa1b677ec149038c25ee082fc7c63675
parentf6beec78c65c51938e1d01627564a6d1f8021673 (diff)
parent94a7ef21e4036407fa800567766e20957e8d55ae (diff)
Merge branch 'dev/soup-cookied'
Conflicts: Makefile
-rw-r--r--Makefile22
-rw-r--r--examples/uzbl-cookie-manager.c384
-rw-r--r--src/callbacks.c2
-rw-r--r--src/util.c110
-rw-r--r--src/util.h18
-rw-r--r--src/uzbl-core.c179
-rw-r--r--src/uzbl-core.h21
7 files changed, 555 insertions, 181 deletions
diff --git a/Makefile b/Makefile
index 06cc7a9..7a3f5a7 100644
--- a/Makefile
+++ b/Makefile
@@ -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 ();