aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile18
-rw-r--r--examples/uzbl-cookie-manager.c211
-rw-r--r--src/util.c2
3 files changed, 222 insertions, 9 deletions
diff --git a/Makefile b/Makefile
index 5287d5c..2a08b5c 100644
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,7 @@ 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
@@ -24,7 +24,11 @@ uzbl-core: ${OBJ}
@echo -e "\n${CC} -o $@ ${OBJ} ${LDFLAGS}"
@${CC} -o $@ ${OBJ} ${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}"
+ @${CC} -o $@ uzbl-cookie-manager.o util.o ${LDFLAGS}
+
+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,10 +76,8 @@ test-uzbl-browser-sandbox: uzbl-browser
clean:
rm -f uzbl-core
- rm -f uzbl-core.o
- rm -f events.o
- rm -f callbacks.o
- rm -f inspector.o
+ rm -f uzbl-cookie-manager
+ rm -f *.o
find ./examples/ -name "*.pyc" -delete
cd ./tests/; $(MAKE) clean
rm -rf ./sandbox/
@@ -104,9 +106,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{,.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..b873aeb
--- /dev/null
+++ b/examples/uzbl-cookie-manager.c
@@ -0,0 +1,211 @@
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/select.h>
+#include <sys/unistd.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) {
+ 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;
+}
+
+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);
+
+ 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);
+
+ if(write(fd, "", 1) < 0)
+ fprintf(stderr, "write failed (%s)", strerror(errno));
+ }
+
+ soup_uri_free(uri);
+}
+
+void usage(const char *progname) {
+ printf("%s [-s socket-path] [-f cookies.txt] [-w whitelist-file] [-v]\n", progname);
+}
+
+int main(int argc, char *argv[]) {
+ int i;
+
+ const char *cookies_txt_path = NULL;
+ const char *cookied_socket_path = NULL;
+
+ 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 'v':
+ verbose = 1;
+ break;
+ default:
+ usage(argv[0]);
+ return 1;
+ }
+ }
+
+ if(!cookies_txt_path)
+ cookies_txt_path = find_xdg_file(1, "/uzbl/cookies.txt");
+
+ if(!cookied_socket_path)
+ cookied_socket_path = g_strconcat(get_xdg_var(XDG[2]), "/uzbl/cookie_daemon_socket", NULL);
+
+ 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;
+ }
+
+ 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);
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/src/util.c b/src/util.c
index f6c2e0a..54d1d02 100644
--- a/src/util.c
+++ b/src/util.c
@@ -6,7 +6,7 @@
#include "util.h"
-XDG_Var XDG[] =
+const XDG_Var XDG[] =
{
{ "XDG_CONFIG_HOME", "~/.config" },
{ "XDG_DATA_HOME", "~/.local/share" },