# signal watcher ## Proof of concept [Here's the snippet](http://gitlab.corp.kbact.org/-/snippets/29) ## Makefile ```shell= #name of this module ACT_EXE = ws-ports-status-alerter # act libs needed by this module DEP_ACT_LIBS = network # dbus interfaces needed by this module DEP_ACT_DBUS = network ACT_SRCS := $(wildcard src/*.c) ACT_HEADS := $(wildcard src/*.h) ACT_OBJ = $(ACT_SRCS:.c=.o) ACT_TOPDIR = .. ACT_INCDIR = $(ACT_TOPDIR)/include ACT_BINDIR = $(ACT_TOPDIR)/.bin CFLAGS = LDLIBS = -Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed all: $(ACT_EXE) $(ACT_OBJ): $(ACT_HEADS) $(ACT_EXE): $(ACT_OBJ) $(CC) $(ACT_OBJ) -g $(LDFLAGS) -o $@ install: $(ACT_EXE) mkdir -p $(ACT_BINDIR) install -m 0755 $(ACT_EXE) $(ACT_BINDIR) .PHONY: all clean install clean: rm -f $(ACT_OBJ) $(ACT_EXE) $(MAKE) -C test clean ``` ## ws-ports-status-alerter.c ```c= #include <errno.h> #include <stdio.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <unistd.h> #include <glib-2.0/glib.h> #include <dbus_network.h> OrgActNetwork *proxyNetwork; GIOChannel *server_channel int watchID; GSList* client_sockets = NULL; int writeall(int fd, char const* buf, size_t len) { while (len > 0) { int r = write(fd, buf, len); if (r < 0) { switch (errno) { case EINTR: continue; default: fprintf(stderr, "Failed writing data: %s\n", strerror(errno)); return -1; } } len -= r; buf += r; } return 0; } void cb_signal_iface_change(gpointer dummy, char* content) { char **args = g_strsplit(content, ";", -1); if (g_strv_length(args) >= 2) { gboolean state = strcmp(args[1], "up") == 0; char *portName = args[0]; char *stringa_da_mandare = g_strdup_print("%s;%s", portName, state?"UP":"DOWN"); for (GSList* iter = client_sockets; iter; iter = iter->next) { int sock = GPOINTER_TO_INT(iter->data); writeall(sock, stringa_da_mandare, strlen(stringa_da_mandare)); } g_free(stringa_da_mandare); } g_strfreev(args); } static void initClientCB(GObject *source_object, GAsyncResult *result, gpointer user_data) { GError *error = NULL; proxyNetwork = org_act_network_proxy_new_finish(result, &error); if (error != NULL) { act_messFatal("ERROR opening network proxy: %s", error->message); g_error_free(error); // quit application exit(-1); } else g_signal_connect(proxyNetwork, ACT_NETWORK_SIGNAL_INTERFACE_STATE_CHANGE, G_CALLBACK(cb_signal_iface_change), NULL); } static gboolean acceptFromSocket(GIOChannel *source, GIOCondition condition, gpointer data) { int server_sock = g_io_channel_unix_get_fd(source); int client_sock = accept(server_sock, NULL, NULL); char buf[256] = {0}; strcpy(buf, "éç°§§§§§ùùùùAAAAAFINE"); if (writeall(sock, buf, strlen(buf)) < 0) { g_print("OMMIODIO ERRORE...\n"); } client_sockets = g_slist_prepend(client_sockets, GINT_TO_POINTER(client_sock)); // close(client_sock); return TRUE; } static GIOChannel * initialize_channel(int sock) { GIOChannel *iochan = g_io_channel_unix_new(sock); GError *error = NULL; g_io_channel_set_encoding(iochan, NULL, &error); if (error != NULL) { act_messTraceLog("Error setting encoding for %s: %s", _U(if_name), error->message); g_error_free(error); } watchID = g_io_add_watch(info->channel, G_IO_IN, (GIOFunc) acceptFromSocket, NULL); return iochan; } int main() { // init GMainLoop *mainloop = g_main_loop_new(NULL, FALSE); //#define DBUS_MODE G_BUS_TYPE_SYSTEM //#define ACT_INTROSPECT_PATH_NETWORK "/org/act/network" //#define ACT_INTROSPECT_NAME_NETWORK "org.act.network" org_act_network_proxy_new_for_bus(DBUS_MODE, G_DBUS_PROXY_FLAGS_NONE, ACT_INTROSPECT_NAME_NETWORK, ACT_INTROSPECT_PATH_NETWORK, NULL, (GAsyncReadyCallback) initClientCB, NULL); server_channel = initialize_channel(0); // enter main loop g_main_loop_run(mainloop); // clean up and exit g_main_loop_unref(mainloop); return 0; } ``` ## lighttpd.ws-ports-status-alerter.conf See [here](https://redmine.lighttpd.net/boards/2/topics/8801) ```javascript= server.port = 9191 server.document-root = "/www/pages/" server.modules = ( "mod_wstunnel" ) wstunnel.ping-interval = 30 wstunnel.server = ( "" => ( "websocket" => ( "socket" => "/tmp/ws-ports-status-alerter.socket", "bin-path" => "/var/usr/bin/ws-ports-status-alerter", # lighttpd itself daemonizes the c program "max-procs" => 1, ) ) ) ```