# 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,
)
)
)
```