summaryrefslogtreecommitdiff
path: root/piper_webext.c
blob: 72996c8d936a3f571100d577ebd43bc348192053 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//
// !!! THIS IS STILL A CONCEPT/PROTOTYPE. USE AT YOUR OWN RISK !!!
//
// Author:      Michal Idziorek <m.i@gmx.at>
//
// Last Update: 16th March 2018
//
// Last Tested: with surf commit 81f0452bc6c2a110239fa303ad1e72f11c33dc94
//              from htps://git.suckless.org/surf
//
// The following simple Webkit2GTK+ extension was hacked together
// in the sleepless night between 09th and 10th March 2018 (and later 
// refined).
//
// The DOM is manipulated,i.e: a <span> with a number added to every 
// link encountered.
// 
// Named FIFO pipes are used for communication with the ui process.
//
#include <sys/types.h>
#include <sys/stat.h>
#include <glib.h>
#include <stdbool.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>

#include "piper_webext.h"

static int pipe_out_fd;
static void (*pipe_in_callback)(char *msg);

// returns full path to pipe in users runtime dir.
// dont forge't to g_free after use
static gchar* getpath(char *path)
{
    return g_strdup_printf("%s/piper-%s",g_get_user_runtime_dir(),path);
}

// callback function wrapper for received messages
static gboolean mycallback(GIOChannel *ch, GIOCondition c, gpointer p)
{
    gchar *line;
    g_io_channel_read_line(ch, &line, NULL, NULL, NULL);
    g_strchomp(line);
    pipe_in_callback(line);
    g_free(line);
    return true;
}

static void register_callback(char *path)
{
	gchar *fullpath=getpath(path);
	mkfifo(fullpath,0600);
	GMainContext *ctx = g_main_context_default();
	GIOChannel *io = g_io_channel_new_file(fullpath, "r+", NULL);
	GSource *watch = g_io_create_watch(io, G_IO_IN);
	g_source_attach(watch,ctx);
	g_source_set_callback(watch,(GSourceFunc)mycallback,NULL,NULL);
	g_free(fullpath);
}

// open for writing, lock and return pipe fd
static int piper_lock(char *path)
{
	gchar *fullpath=getpath(path);
	mkfifo(fullpath,0600);
	int pipe=open(fullpath, O_RDWR | O_CREAT | O_TRUNC);
	g_free(fullpath);
	if(pipe == -1) return -1;
	int lock=lockf(pipe,F_TLOCK,0);
	if(lock == -1) return -1;
	return pipe;
}

void piper_init(char *path_in,char *path_out,void (*callback_func)(char *msg),char *url)
{
	pipe_in_callback=callback_func;
        pipe_out_fd=piper_lock(path_out);
	if(pipe_out_fd==-1)
	{
	    g_print("can not get exclusive lock! Sending messsage and Bailing out.\n");
	    if(url!=NULL)
	    {
		gchar *fullpath=getpath(path_in);
		int pipe=open(fullpath, O_RDWR | O_CREAT | O_TRUNC);
		g_print("pipe fd: %i",pipe);
		write(pipe,url,strlen(url));
		write(pipe,"\n",1);
		close(pipe);
	    }
	    exit(0);
	}
	register_callback(path_in);
}

void piper_send(char *msg)
{
        int ret=write(pipe_out_fd,msg,strlen(msg));
	if(ret==-1)g_print("Can not write to pipe :(\n");
}