diff --git a/.gitignore b/.gitignore index 80ff5a8..4833947 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ adblock.so -cssoutput +librun.o +wyebab +testrun user.css diff --git a/README.md b/README.md index b6b9285..e9fbfb2 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,9 @@ An adblock extension for [wyeb](https://github.com/jun7/wyeb), also webkit2gtk b most of code of this are from https://github.com/GNOME/epiphany/tree/master/embed/web-extension +wyebad is shared by clients, So even nowadays, browsers spawn procs for each windows, +wyebad keeps single server proc that makes less memory and less cpu times. +Don't worry, wyeb wills quit automatically when there is no client and 30 secs past. ### usage: @@ -14,9 +17,8 @@ copy **easylist.txt** to ~/.config/wyebadblock/ wyebadblock only checks 'easylist.txt' - +Testing element hiding is not supported though, You can check if it works on http://simple-adblock.com/faq/testing-your-adblocker/ -Testing element hiding is not supported though. ### Disabling @@ -64,10 +66,22 @@ and make link from the dir to the wyebadblock as above. ## Element Hiding -Per domain CSS hider rule is not supported and this may crash webkit2gtk. +Per domain CSS hider rule is not supported - make cssoutput - ./cssoutput > user.css + wyebab -css > user.css And add the user.css to your browser as user css. -On wyeb, just copy the user.css to the conf dir. +For wyeb, just copy the user.css to the conf dir. + + +## Shell + + wyebab + +Reads stdin outputs to stdout. +blank + enter quits. + + wyebab requst_uri + ' ' + page_uri + +Outputs result +Keeps server 30 sec diff --git a/ephy-uri-tester.c b/ephy-uri-tester.c index 6a9908f..48f0f91 100644 --- a/ephy-uri-tester.c +++ b/ephy-uri-tester.c @@ -868,6 +868,7 @@ ephy_uri_tester_new (const char *adblock_data_dir) return EPHY_URI_TESTER (g_object_new (EPHY_TYPE_URI_TESTER, "adblock-data-dir", adblock_data_dir, NULL)); } +/* static void ephy_uri_tester_adblock_filters_changed_cb (GSettings *settings, char *key, @@ -886,12 +887,13 @@ ephy_uri_tester_adblock_filters_changed_cb (GSettings *settings, tester->adblock_loaded = FALSE; ephy_uri_tester_load (tester); } +*/ void ephy_uri_tester_load (EphyUriTester *tester) { GTask *task; - char **trash; +// char **trash; g_return_if_fail (EPHY_IS_URI_TESTER (tester)); @@ -920,90 +922,58 @@ ephy_uri_tester_load (EphyUriTester *tester) //added -#include #include -static EphyUriTester *uri_tester; -static GThread *initt = NULL; -static bool tend = false; +#include -static gboolean reqcb (WebKitWebPage *web_page, - WebKitURIRequest *request, - WebKitURIResponse *redirected_response, - gpointer *p) +#include "wyebrun.h" + +#define EXE "wyebab" + +#if DEBUG +# define D(f, ...) g_print(#f"\n", __VA_ARGS__); +# define DD(a) g_print(#a"\n"); +#else +# define D(f, ...) ; +# define DD(a) ; +#endif + +#if ISEXT + +#include +static bool first = true; +static gboolean reqcb(WebKitWebPage *page, WebKitURIRequest *request, + WebKitURIResponse *r, gpointer p) { - const char *request_uri; - const char *redirected_response_uri; - const char *page_uri; - char *modified_uri = NULL; - EphyUriTestFlags flags = EPHY_URI_TEST_ADBLOCK; - request_uri = webkit_uri_request_get_uri (request); - page_uri = webkit_web_page_get_uri (web_page); + const char *request_uri = webkit_uri_request_get_uri(request); + const char *page_uri = webkit_web_page_get_uri(page); - redirected_response_uri = redirected_response ? - webkit_uri_response_get_uri (redirected_response) : NULL; - - if ((flags & EPHY_URI_TEST_ADBLOCK) || (flags & EPHY_URI_TEST_HTTPS_EVERYWHERE)) { - char *result; - if (initt) + if (first) { - SoupMessageHeaders *head = webkit_uri_request_get_http_headers(request); - if (head || tend) - { - g_thread_join(initt); - initt = NULL; - } + if (webkit_uri_request_get_http_headers(request)) + first = false; else //no head is local data. so haven't to block return false; } - result = ephy_uri_tester_rewrite_uri (uri_tester, - modified_uri ? modified_uri : request_uri, - page_uri, flags); - g_free (modified_uri); - if (!result) { - return TRUE; - } + char *req = g_strconcat(request_uri, " ", page_uri, NULL); + char *res = wyebreq(EXE, req); + g_free(req); - modified_uri = result; - } else if (!modified_uri) { - return FALSE; - } + if (!res) return true; - if (g_strcmp0 (request_uri, modified_uri) != 0) { - webkit_uri_request_set_uri (request, modified_uri); - } - g_free (modified_uri); + if (g_strcmp0(request_uri, res)) + webkit_uri_request_set_uri(request, res); - return FALSE; + return FALSE; } -static gpointer inittcb(gpointer data) + +static void pageinit(WebKitWebExtension *ex, WebKitWebPage *wp) { - ephy_uri_tester_load(uri_tester); - tend = true; - return NULL; + DD(pageinit) + g_signal_connect(wp, "send-request", G_CALLBACK(reqcb), NULL); } -static void initex(WebKitWebExtension *ex, WebKitWebPage *wp) -{ - gchar *filter_path = g_build_filename( - g_get_user_config_dir(), APPNAME, "easylist.txt", NULL); - - if (g_file_test(filter_path, G_FILE_TEST_EXISTS)) - { - if (!filter_file) - { - filter_file = g_file_new_for_path(filter_path); - uri_tester = ephy_uri_tester_new("/foo/bar"); - - initt = g_thread_new("init", inittcb, NULL); - } - if (wp) - g_signal_connect(wp, "send-request", G_CALLBACK(reqcb), NULL); - } - - g_free(filter_path); -} G_MODULE_EXPORT void webkit_web_extension_initialize_with_user_data( WebKitWebExtension *ex, const GVariant *v) { @@ -1028,18 +998,101 @@ G_MODULE_EXPORT void webkit_web_extension_initialize_with_user_data( enable = false; if (enable) - g_signal_connect(ex, "page-created", G_CALLBACK(initex), NULL); + { + wyebloop(EXE, 30, 24); + g_signal_connect(ex, "page-created", G_CALLBACK(pageinit), NULL); + } +} + +#endif + + +static EphyUriTester *tester = NULL; +static GThread *initt = NULL; + +static gpointer inittcb(gpointer data) +{ + ephy_uri_tester_load(tester); + return NULL; +} + +static void monitorcb( + GFileMonitor *m, GFile *f, GFile *o, GFileMonitorEvent e, gpointer p) +{ + if (e == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT || + e == G_FILE_MONITOR_EVENT_DELETED) + exit(0); +} +static void init() +{ + DD(wyebad init) + gchar *path = g_build_filename( + g_get_user_config_dir(), APPNAME, "easylist.txt", NULL); + + GFile *gf = g_file_new_for_path(path); + GFileMonitor *gm = g_file_monitor_file(gf, + G_FILE_MONITOR_NONE, NULL, NULL); + g_signal_connect(gm, "changed", G_CALLBACK(monitorcb), NULL); + g_object_unref(gf); + + if (g_file_test(path, G_FILE_TEST_EXISTS)) + { + filter_file = g_file_new_for_path(path); + tester = ephy_uri_tester_new("/foo/bar"); + + initt = g_thread_new("init", inittcb, NULL); + } + + g_free(path); +} + +static char *datafunc(char *req) +{ + if (initt) + { + g_thread_join(initt); + initt = NULL; + } + + //req uri + ' ' + page uri + gchar **args = g_strsplit(req, " ", 2); + + char *ret = !tester ? g_strdup(args[0]) : ephy_uri_tester_rewrite_uri(tester, + args[0], args[1] ?: args[0], EPHY_URI_TEST_ADBLOCK); + + g_strfreev(args); + + return ret; } int main(int argc, char **argv) { - initex(NULL, NULL); - g_thread_join(initt); + DD(This bin is compiled with DEBUG=1) - g_print(uri_tester->blockcss->str); - g_print("\n\n\n\n{display: none !important}\n\n\n\n"); -// g_print(uri_tester->blockcssprivate->str); + if (argc == 1) + { + wyebclient(argv[0]); + } + else if (g_str_has_prefix(argv[1], WYEBPREFIX)) + { + init(); + wyebsvr(argc, argv, datafunc); + } + else if (!strcmp(argv[1], "-css")) + { + init(); + g_thread_join(initt); + + g_print(tester->blockcss->str); + g_print("\n\n\n\n{display: none !important}\n\n\n\n"); + //g_print(tester->blockcssprivate->str); + } + else + { + wyebuntil(argv[0], 30); + g_print("%s", wyebreq(argv[0], argv[1])); + } exit(0); } diff --git a/makefile b/makefile index 1dc8cff..7a0adab 100644 --- a/makefile +++ b/makefile @@ -4,26 +4,51 @@ CFLAGS += -Wno-deprecated-declarations EXTENSION_DIR=$(DESTDIR)/usr/lib/wyebrowser DAPPNAME=-DAPPNAME='"wyebadblock"' -all: adblock.so +ifdef DEBUG + DDEBUG=-DDEBUG=${DEBUG} -adblock.so: ephy-uri-tester.c ephy-uri-tester.h - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -shared -fPIC \ +ifneq ($(DEBUG), 0) + CFLAGS += -Wall +endif +endif + +all: adblock.so wyebab librun.o testrun + +adblock.so: ephy-uri-tester.c ephy-uri-tester.h librun.o makefile + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< librun.o -shared -fPIC \ `pkg-config --cflags --libs gtk+-3.0 glib-2.0 webkit2gtk-4.0` \ -DEXTENSION_DIR=\"$(EXTENSION_DIR)\" \ + $(DDEBUG) $(DAPPNAME) -DISEXT + +wyebab: ephy-uri-tester.c ephy-uri-tester.h librun.o makefile + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< librun.o \ + `pkg-config --cflags --libs glib-2.0 libsoup-2.4` \ + -DEXTENSION_DIR=\"$(EXTENSION_DIR)\" \ $(DDEBUG) $(DAPPNAME) -cssoutput: ephy-uri-tester.c ephy-uri-tester.h +librun.o: wyebrun.c wyebrun.h makefile + $(CC) $(CFLAGS) $(LDFLAGS) -c -o $@ $< -fPIC\ + `pkg-config --cflags --libs glib-2.0` \ + -DDEBUG=0 + +testrun: wyebrun.c wyebrun.h makefile $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< \ - `pkg-config --cflags --libs gtk+-3.0 glib-2.0 webkit2gtk-4.0` \ - -DEXTENSION_DIR=\"$(EXTENSION_DIR)\" \ - $(DDEBUG) $(DAPPNAME) + `pkg-config --cflags --libs glib-2.0` \ + -DDEBUG=1 clean: rm -f adblock.so + rm -f wyebab + rm -f librun.o + rm -f testrun install: all + install -Dm755 wyebab $(DESTDIR)/usr/bin/wyebab install -Dm755 adblock.so $(EXTENSION_DIR)/adblock.so +re: clean all + uninstall: + rm -f $(DESTDIR)/usr/bin/wyebab rm -f $(EXTENSION_DIR)/adblock.so -rmdir $(EXTENSION_DIR) diff --git a/wyebrun.c b/wyebrun.c new file mode 100644 index 0000000..c7591e1 --- /dev/null +++ b/wyebrun.c @@ -0,0 +1,541 @@ +/* +Copyright 2018 jun7@hush.mail + +This file is part of wyebrun. + +wyebrun is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +wyebrun is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with wyebrun. If not, see . +*/ + + +#include +#include +#include + +//getpid +#include +#include + +//flock +#include + +#include "wyebrun.h" + +#define ROOTNAME "wyebrun" +#define PREFIX WYEBPREFIX +#define INPUT "wyebinput" +#define PING "wyebping" + +#define DUNTIL WYEBDUNTIL +#define DPINGTIME 1000 + +#define P(f, ...) g_print(#f"\n", __VA_ARGS__); + +#if DEBUG +static gint64 start; +# define D(f, ...) g_print(#f"\n", __VA_ARGS__); +# define DD(a) g_print(#a"\n"); +#else +# define D(...) ; +# define DD(a) ; +#endif + +typedef enum { + //to svr + CSuntil = 'u', + CSdata = 'd', + CSping = 'p', + + //to client + CCwoke = 'w', + CCret = 'r', //retrun data + CClost = 'l', //we lost the req +} Com; + + + + + +//shared +static void fatal(int i) +{ + P(\n!!! fatal %d !!!\n, i) + exit(1); +} +static void mkdirif(char *path) +{ + char *dir = g_path_get_dirname(path); + if (!g_file_test(dir, G_FILE_TEST_EXISTS)) + g_mkdir_with_parents(dir, 0700); + + g_free(dir); +} +static char *ipcpath(char *exe, char *name) +{ + return g_build_filename(g_get_user_runtime_dir(), + ROOTNAME,exe, name, NULL); +} +static char *preparepp(char *exe, char *name) +{ + char *path = ipcpath(exe, name); + if (!g_file_test(path, G_FILE_TEST_EXISTS)) + { + mkdirif(path); + mkfifo(path, 0600); + } + return path; +} + +static bool ipcsend(char *exe, char *name, + Com type, char *caller, char *data) +{ + //D(ipcsend exe:%s name:%s, exe, name) + char *path = preparepp(exe, name); + + char *esc = g_strescape(data ?: "", ""); + char *line = g_strdup_printf("%c%s:%s\n", type, caller ?: "", esc); + g_free(esc); + + int pp = open(path, O_WRONLY | O_NONBLOCK); + + bool ret = write(pp, line, strlen(line)) != -1; + g_free(line); + + close(pp); + + g_free(path); + return ret; +} + +static gboolean ipccb(GIOChannel *ch, GIOCondition c, gpointer p); + +static GSource *ipcwatch(char *exe, char *name, GMainContext *ctx) { + char *path = preparepp(exe, name); + + GIOChannel *io = g_io_channel_new_file(path, "r+", NULL); + GSource *watch = g_io_create_watch(io, G_IO_IN); + g_io_channel_unref(io); + g_source_set_callback(watch, (GSourceFunc)ipccb, NULL, NULL); + g_source_attach(watch, ctx); + + g_free(path); + return watch; +} + + + +//@server +static char *svrexe = NULL; +static GMainLoop *sloop = NULL; +static wyebdataf dataf = NULL; +static gboolean quit(gpointer p) +{ + DD(\nsvr quits\n) + g_main_loop_quit(sloop); + return false; +} +static void until(int sec) +{ + if (!sloop) return; + + static guint last = 0; + if (last) + g_source_remove(last); + last = g_timeout_add_full(G_PRIORITY_LOW * 2, sec * 1000, quit, NULL, NULL); +} +static gpointer pingt(gpointer p) +{ + GMainContext *ctx = g_main_context_new(); + ipcwatch(svrexe, PING, ctx); + g_main_loop_run(g_main_loop_new(ctx, true)); + return NULL; +} + +void wyebwatch(char *exe, char *caller, wyebdataf func) +{ + svrexe = exe; + dataf = func; + until(DUNTIL); + + g_thread_new("ping", pingt, NULL); + ipcwatch(exe, INPUT, g_main_context_default()); + + if (!ipcsend(exe, caller, CCwoke, "", NULL)) + fatal(1); +} + +static gboolean svrinit(char *caller) +{ + wyebwatch(svrexe, caller, dataf); + return false; +} + +bool wyebsvr(int argc, char **argv, wyebdataf func) +{ + if (argc < 2 || !g_str_has_prefix(argv[1], PREFIX)) return false; + + svrexe = argv[0]; + dataf = func; + sloop = g_main_loop_new(NULL, false); + g_idle_add((GSourceFunc)svrinit, argv[1]); + g_main_loop_run(sloop); + + return true; +} + +static void getdata(char *caller, char *req) +{ + char *data = dataf(req); + if (!ipcsend(svrexe, caller, CCret, "", data)) + fatal(2); + + g_free(data); +} + + + + +//@client +static GMutex retm; +static GMainLoop *cloop; +static GMainContext *wctx = NULL; +static char *retdata = NULL; +static char *pid() +{ + static char *pid = NULL; + if (!pid) pid = g_strdup_printf(PREFIX"%d", getpid()); + return pid; +} + +static void spawnsvr(char *exe) +{ + char **argv = g_new0(char*, 2); + argv[0] = exe; + argv[1] = pid(); + GError *err = NULL; + if (!g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, + NULL, NULL, NULL, &err)) + { + g_print("err %s", err->message); + g_error_free(err); + } + + g_free(argv); +} +static gboolean pingloop(gpointer p) +{ + if (!ipcsend((char *)p, PING, CSping, pid(), NULL)) + g_mutex_unlock(&retm); + + return true; +} +static char *pppath = NULL; +static void removepp() +{ + remove(pppath); +} +static gpointer watcht(char *exe) +{ + wctx = g_main_context_new(); + cloop = g_main_loop_new(wctx, true); + + GSource *watch = ipcwatch(exe, pid(), wctx); + + if (!pppath) + { + pppath = ipcpath(exe, pid()); + atexit(removepp); + } + + g_mutex_unlock(&retm); + g_main_loop_run(cloop); + + g_source_unref(watch); + g_main_context_unref(wctx); + g_main_loop_unref(cloop); + cloop = NULL; + + return NULL; +} +static void watchstart(char *exe) +{ + g_mutex_lock(&retm); + + g_thread_new("watch", (GThreadFunc)watcht, exe); + + g_mutex_lock(&retm); + g_mutex_unlock(&retm); +} +static gboolean timeout(gpointer p) +{ + g_mutex_unlock(&retm); + return false; +} + +static GHashTable *lastsec = NULL; +static void reuntil(char *exe) +{ + if (!lastsec) return; + int sec = GPOINTER_TO_INT( + g_hash_table_lookup(lastsec, exe)); + if (sec) + wyebuntil(exe, sec); +} + +//don't free +static char *request(char *exe, Com type, char *caller, char *req) +{ + g_free(retdata); + retdata = NULL; + + if (!cloop) watchstart(exe); + + if (caller) + g_mutex_lock(&retm); + + if (!ipcsend(exe, INPUT, type, caller, req)) + { //svr is not running + char *path = ipcpath(exe, "lock"); + if (!g_file_test(path, G_FILE_TEST_EXISTS)) + mkdirif(path); + + int lock = open(path, O_RDONLY | O_CREAT, S_IRUSR); + g_free(path); + + //retry in single proc + if (!ipcsend(exe, INPUT, type, caller, req)) + { + if (!caller) + g_mutex_lock(&retm); + + GSource *tout = g_timeout_source_new(DUNTIL * 1000); + g_source_set_callback(tout, timeout, NULL, NULL); + g_source_attach(tout, wctx); + + spawnsvr(exe); + g_mutex_lock(&retm); + g_mutex_unlock(&retm); + + g_source_destroy(tout); + g_source_unref(tout); + + //wyebloop doesn't know svr quits + reuntil(exe); + + if (caller) + g_mutex_lock(&retm); + if (!ipcsend(exe, INPUT, type, caller, req)) + fatal(3); //spawning svr failse is fatal + } + close(lock); + } + + if (caller) + { + GSource *ping = g_timeout_source_new(DPINGTIME); + g_source_set_callback(ping, (GSourceFunc)pingloop, exe, NULL); + g_source_attach(ping, wctx); //attach to ping thread + + g_mutex_lock(&retm); + g_mutex_unlock(&retm); + + g_source_destroy(ping); + g_source_unref(ping); + } + + return retdata; +} + +char *wyebreq(char *exe, char *req) +{ + return request(exe, CSdata, pid(), req); +} +void wyebuntil(char *exe, int sec) +{ + if (!lastsec) + lastsec = g_hash_table_new(g_str_hash, g_str_equal); + + g_hash_table_replace(lastsec, exe, GINT_TO_POINTER(sec)); + + char *str = g_strdup_printf("%d", sec); + request(exe, CSuntil, NULL, str); + g_free(str); +} + +typedef struct { + char *exe; + int sec; +} wyebloopt; +static void wlfree(wyebloopt *wl) +{ + g_free(wl->exe); + g_free(wl); +} +static gboolean loopcb(wyebloopt *wl) +{ + wyebuntil(wl->exe, wl->sec); + return true; +} +guint wyebloop(char *exe, int sec, int loopsec) +{ + wyebloopt *wl = g_new(wyebloopt, 1); + wl->exe = g_strdup(exe); + wl->sec = sec; + + loopcb(wl); + return g_timeout_add_full(G_PRIORITY_DEFAULT, + loopsec * 1000, + (GSourceFunc)loopcb, + wl, + (GDestroyNotify)wlfree); +} + +static gboolean tcinputcb(GIOChannel *ch, GIOCondition c, char *exe) +{ + char *line; + g_io_channel_read_line(ch, &line, NULL, NULL, NULL); + if (!line) return true; + + g_strstrip(line); + if (!strlen(line)) + exit(0); + +#if DEBUG + if (!strcmp(line, "l")) + { + start = g_get_monotonic_time(); + for (int i = 0; i < 10000; i++) + { + char *is = g_strdup_printf("l%d", i); + //g_print("loop %d ret %s\n", i, wyebreq(exe, is)); + wyebreq(exe, is); + g_free(is); + } + gint64 now = g_get_monotonic_time(); + D(time %f, (now - start) / 1000000.0) + } + else + g_print("RET is %s\n", wyebreq(exe, line)); +#else + g_print("%s\n", wyebreq(exe, line)); //don't free +#endif + + g_free(line); + return true; +} +static gboolean tcinit(char *exe) +{ + //wyebuntil(exe, 1); + wyebloop(exe, 2, 1); + + GIOChannel *io = g_io_channel_unix_new(fileno(stdin)); + g_io_add_watch(io, G_IO_IN, (GIOFunc)tcinputcb, exe); + + return false; +} +void wyebclient(char *exe) +{ + //pid_t getpid(void); + sloop = g_main_loop_new(NULL, false); + g_idle_add((GSourceFunc)tcinit, exe); + g_main_loop_run(sloop); +} + + + +//@ipccb +static GHashTable *orders = NULL; +gboolean ipccb(GIOChannel *ch, GIOCondition c, gpointer p) +{ + if (!orders) + orders = g_hash_table_new(g_str_hash, g_str_equal); + + char *line; + g_io_channel_read_line(ch, &line, NULL, NULL, NULL); + if (!line) return true; + g_strchomp(line); + + char *unesc = g_strcompress(line); + g_free(line); + + Com type = *unesc; + char *id = unesc + 1; + char *arg = strstr(unesc, ":"); + *arg++ = '\0'; + +#if DEBUG + static int i = 0; + D(ipccb%d %c/%s/%s;, i++, type ,id ,arg) +#endif + + static int lastuntil = DUNTIL; + switch (type) { + //server + case CSuntil: + until(lastuntil = atoi(arg)); + break; + case CSdata: + g_hash_table_add(orders, id); + getdata(id, arg); + g_hash_table_remove(orders, id); + until(lastuntil); + break; + case CSping: + if (!g_hash_table_lookup(orders, id)) + ipcsend(svrexe, id, CClost, NULL, NULL); + break; + + //client + case CCret: + retdata = g_strdup(arg); + case CClost: + case CCwoke: + //g_main_loop_quit(cloop); + g_mutex_unlock(&retm); + break; + } + + g_free(unesc); + return true; +} + + + +//test +#if DEBUG +static char *testdata(char *req) +{ + //sleep(9); + //g_free(req); //makes crash + + static int i = 0; + return g_strdup_printf("%d th dummy data. req is %s", ++i, req); +} + + +int main(int argc, char **argv) +{ + start = g_get_monotonic_time(); +// gint64 now = g_get_monotonic_time(); +// D(time %ld %ld, now - start, now) + + //char path[PATH_MAX] = {0}; + //readlink("/proc/self/exe", path, PATH_MAX); + //D(progrname %s, path) + + if (!wyebsvr(argc, argv, testdata)) + wyebclient(argv[0]); + + exit(0); +} +#endif diff --git a/wyebrun.h b/wyebrun.h new file mode 100644 index 0000000..4fa56e9 --- /dev/null +++ b/wyebrun.h @@ -0,0 +1,47 @@ +/* +Copyright 2018 jun7@hush.mail + +This file is part of wyebrun. + +wyebrun is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +wyebrun is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with wyebrun. If not, see . +*/ + + +#ifndef _WYEBRUN_H +#define _WYEBRUN_H + +#define WYEBPREFIX "-wyeb" +#define WYEBDUNTIL 3 + +//client +//wyebrun spawns the exe if wyebsend failes +char *wyebreq( char *exe, char *req); +void wyebuntil( char *exe, int sec); //keep alive. default is 10s +//loop the wyebuntil. to stop, use g_source_remove +guint wyebloop( char *exe, int sec, int loopsec); +//send stdin to svr and ret data to stdout +//blank and enter exit it +void wyebclient(char *exe); + + +//server +typedef char *(*wyebdataf)(char *req); +//server is spawned with an arg the caller +bool wyebsvr(int argc, char **argv, wyebdataf func); +//or if there is own GMainLoop +void wyebwatch(char *exe, char *caller, wyebdataf func); +//the caller is used to send the res meaning we are ready. +//3 sec left or client will die + +#endif //_WYEBRUN_H