From e9576b5574d8d9abf0b22b98337f6bff58955cdd Mon Sep 17 00:00:00 2001
From: Philippe PITTOLI <p.pittoli@unistra.fr>
Date: Tue, 28 Jan 2020 12:41:11 +0100
Subject: [PATCH] adding C tests

---
 c/libipc/.gitignore             |   3 +
 c/libipc/build.sh               |  24 ++++
 c/libipc/client-tcp.c           | 125 +++++++++++++++++++++
 c/libipc/example-syslog.c       |  22 ++++
 c/libipc/print-bytes.c          |  27 +++++
 c/libipc/print-hexa.c           |  27 +++++
 c/libipc/select.c               | 161 ++++++++++++++++++++++++++
 c/libipc/struct-ipc-switching.c |  55 +++++++++
 c/libipc/test-connection.c      |  37 ++++++
 c/libipc/test-select.c          | 193 ++++++++++++++++++++++++++++++++
 c/libipc/tests-envvars.c        |  54 +++++++++
 c/libipc/to-pascal.pl           |   9 ++
 12 files changed, 737 insertions(+)
 create mode 100644 c/libipc/.gitignore
 create mode 100755 c/libipc/build.sh
 create mode 100644 c/libipc/client-tcp.c
 create mode 100644 c/libipc/example-syslog.c
 create mode 100644 c/libipc/print-bytes.c
 create mode 100644 c/libipc/print-hexa.c
 create mode 100644 c/libipc/select.c
 create mode 100644 c/libipc/struct-ipc-switching.c
 create mode 100644 c/libipc/test-connection.c
 create mode 100644 c/libipc/test-select.c
 create mode 100644 c/libipc/tests-envvars.c
 create mode 100644 c/libipc/to-pascal.pl

diff --git a/c/libipc/.gitignore b/c/libipc/.gitignore
new file mode 100644
index 0000000..a9c0ef0
--- /dev/null
+++ b/c/libipc/.gitignore
@@ -0,0 +1,3 @@
+*.bin
+*.swp
+*~
diff --git a/c/libipc/build.sh b/c/libipc/build.sh
new file mode 100755
index 0000000..249e987
--- /dev/null
+++ b/c/libipc/build.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+nontapmsg() {
+	echo $*
+}
+
+if [ $# -eq 0 ] ; then
+	SRC="*.c"
+else
+	SRC="$*"
+fi
+
+for i in $SRC
+do
+    BIN=$(echo ${i} | sed "s/.c$/.bin/")
+    if [ ! -f ${BIN} ] || [ $(stat -c "%X" ${BIN}) -lt  $(stat -c "%X" ${i}) ]
+    then
+		nontapmsg "compiling ${BIN}"
+		# gcc $BIN.c ./lib/*.o -o $BIN -I../src -I ./lib/ -L../ -L./lib/ -lipc -Wall -g -Wextra
+		# gcc -Wall -g -Wextra "${i}" -o "${BIN}" -I../src -L../ ../src/ipc.h -lipc
+		gcc -Wall -g -Wextra "${i}" -o "${BIN}" -lipc
+		touch "${BIN}"
+	fi
+done
diff --git a/c/libipc/client-tcp.c b/c/libipc/client-tcp.c
new file mode 100644
index 0000000..2de8391
--- /dev/null
+++ b/c/libipc/client-tcp.c
@@ -0,0 +1,125 @@
+/**
+ * @section LICENSE
+ *
+ * This program 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 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program 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 at
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @section DESCRIPTION
+ *
+ * Simple program that creates an IPv4 TCP socket and tries to connect
+ * to a remote host before sending a string to this host. The string,
+ * IPv4 addr and port number of the remote host are passed as command
+ * line parameters as follow:
+ * ./pg_name IPv4_addr port_number string
+ */
+
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+
+int setup_connection (char *str_serveraddr, char *str_port)
+{
+	int sockfd;
+	struct sockaddr_in server;
+	socklen_t addrlen;
+
+	// socket factory
+	if ((sockfd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
+		perror ("socket");
+		exit (EXIT_FAILURE);
+	}
+	// init remote addr structure and other params
+	server.sin_family = AF_INET;
+	server.sin_port = htons (atoi (str_port));
+	addrlen = sizeof (struct sockaddr_in);
+
+	// get addr from command line and convert it
+	if (inet_pton (AF_INET, str_serveraddr, &server.sin_addr) != 1) {
+		perror ("inet_pton");
+		close (sockfd);
+		exit (EXIT_FAILURE);
+	}
+
+	printf ("Trying to connect to the remote host\n");
+	if (connect (sockfd, (struct sockaddr *)&server, addrlen) == -1) {
+		perror ("connect");
+		exit (EXIT_FAILURE);
+	}
+
+	return sockfd;
+}
+
+int send_msg(int sockfd, char *message)
+{
+	int ret;
+
+	// send string
+	if ((ret = send (sockfd, message, strlen (message), 0)) == -1) {
+		perror ("send");
+		close (sockfd);
+		exit (EXIT_FAILURE);
+	}
+
+	return ret;
+}
+
+int recv_msg(int sockfd)
+{
+	char buf[1024] = { 0 };
+	int ret;
+
+	// send string
+	if ((ret = recv (sockfd, buf, sizeof(buf), 0)) == -1) {
+		perror ("recv");
+		close (sockfd);
+		exit (EXIT_FAILURE);
+	}
+
+	printf ("message received: %s\n", buf);
+
+	return ret;
+}
+
+int main (int argc, char **argv)
+{
+	int sockfd;
+
+	// check the number of args on command line
+	if (argc != 4) {
+		printf ("USAGE: %s @server port_num string\n", argv[0]);
+		exit (-1);
+	}
+
+	sockfd = setup_connection(argv[1], argv[2]);
+	printf ("Connection OK\n");
+
+	send_msg (sockfd, argv[3]);
+	send_msg (sockfd, argv[3]);
+	send_msg (sockfd, argv[3]);
+	send_msg (sockfd, argv[3]);
+	send_msg (sockfd, argv[3]);
+
+	recv_msg (sockfd);
+
+	printf ("Disconnection\n");
+
+	// close the socket
+	close (sockfd);
+
+	return 0;
+}
diff --git a/c/libipc/example-syslog.c b/c/libipc/example-syslog.c
new file mode 100644
index 0000000..2ea3241
--- /dev/null
+++ b/c/libipc/example-syslog.c
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <syslog.h>
+
+int main(int argc, char * argv[])
+{
+	argc = argc; // warnings
+	argv = argv; // warnings
+
+	setlogmask (LOG_UPTO (LOG_NOTICE));
+
+	openlog ("exampleprog", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
+
+	syslog (LOG_NOTICE, "Program started by User %d",  1000);
+	syslog (LOG_INFO, "A tree falls in a forest");
+
+	closelog ();
+
+	return EXIT_SUCCESS;
+}
diff --git a/c/libipc/print-bytes.c b/c/libipc/print-bytes.c
new file mode 100644
index 0000000..585ba7a
--- /dev/null
+++ b/c/libipc/print-bytes.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+
+#include <ipc.h>
+
+int main(int argc, char * argv[])
+{
+	SECURE_BUFFER_DECLARATION (char, buffer, 4096);
+	uint32_t msize = 0;
+	char *message = "coucou";
+
+	if (argc == 2) {
+		message = argv[1];
+	}
+
+	msize = ipc_message_raw_serialize (buffer, 2, 42, message, strlen(message));
+	write (1, buffer, msize);
+	fflush (stdout);
+
+	// to wait for a response
+	sleep (1);
+
+    return EXIT_SUCCESS;
+}
diff --git a/c/libipc/print-hexa.c b/c/libipc/print-hexa.c
new file mode 100644
index 0000000..d65ae1f
--- /dev/null
+++ b/c/libipc/print-hexa.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <ipc.h>
+#include <utils.h>
+
+
+int main(int argc, char * argv[])
+{
+	argc = argc; // warnings
+	argv = argv; // warnings
+
+
+	SECURE_BUFFER_DECLARATION (uint8_t, buffer, 100);
+
+	buffer[0] = 1;
+	buffer[1] = 16;
+	buffer[2] = 17;
+	buffer[3] = 18;
+	buffer[4] = 1;
+	buffer[5] = 2;
+
+	print_hexa ("coucou", buffer, 50);
+
+    return EXIT_SUCCESS;
+}
diff --git a/c/libipc/select.c b/c/libipc/select.c
new file mode 100644
index 0000000..79635dc
--- /dev/null
+++ b/c/libipc/select.c
@@ -0,0 +1,161 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+/* port we're listening on */
+
+#define PORT 2020
+
+int main(int argc, char *argv[])
+{
+
+	argc = argc;
+
+	/* master file descriptor list */
+	fd_set master;
+	/* temp file descriptor list for select() */
+	fd_set read_fds;
+	/* server address */
+	struct sockaddr_in serveraddr;
+	/* client address */
+	struct sockaddr_in clientaddr;
+
+	/* maximum file descriptor number */
+	int fdmax;
+	/* listening socket descriptor */
+	int listener;
+	/* newly accept()ed socket descriptor */
+	int newfd;
+	/* buffer for client data */
+	char buf[1024];
+	int nbytes;
+
+	/* for setsockopt() SO_REUSEADDR, below */
+	int yes = 1;
+	socklen_t addrlen = 0;
+	int i, j;
+
+	/* clear the master and temp sets */
+	FD_ZERO(&master);
+	FD_ZERO(&read_fds);
+
+	/* get the listener */
+	if((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1)
+	{
+		perror("Server-socket()");
+		exit(1);
+	}
+
+	printf("Server-socket() is OK...\n");
+	/*"address already in use" error message */
+	if(setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
+	{
+		perror("Server-setsockopt()");
+		exit(1);
+	}
+	printf("Server-setsockopt() is OK...\n");
+
+	/* bind */
+	serveraddr.sin_family = AF_INET;
+	serveraddr.sin_addr.s_addr = INADDR_ANY;
+	serveraddr.sin_port = htons(PORT);
+	memset(&(serveraddr.sin_zero), '\0', 8);
+
+	if(bind(listener, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) == -1)
+	{
+
+		perror("Server-bind()");
+		exit(1);
+	}
+	printf("Server-bind() is OK...\n");
+
+	/* listen */
+	if(listen(listener, 10) == -1)
+	{
+		perror("Server-listen()");
+		exit(1);
+	}
+	printf("Server-listen() is OK...\n");
+
+	/* add the listener to the master set */
+	FD_SET(listener, &master);
+
+	/* keep track of the biggest file descriptor */
+	fdmax = listener; /* so far, it's this one*/
+
+	/* loop */
+	for(;;) {
+		/* copy it */
+		read_fds = master;
+		if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1)
+		{
+			perror("Server-select()");
+			exit(1);
+		}
+		printf("Server-select() is OK...\n");
+
+		/*run through the existing connections looking for data to be read*/
+		for(i = 0; i <= fdmax; i++) {
+			if(FD_ISSET(i, &read_fds)) {
+				/* we got one... */
+				if(i == listener) {
+					/* handle new connections */
+					addrlen = sizeof(clientaddr);
+					if((newfd = accept(listener, (struct sockaddr *)&clientaddr, &addrlen)) == -1)
+					{
+						perror("Server-accept()");
+					}
+					else
+					{
+						printf("Server-accept() is OK...\n");
+						FD_SET(newfd, &master); /* add to master set */
+						if(newfd > fdmax)
+						{ /* keep track of the maximum */
+							fdmax = newfd;
+						}
+
+						printf("%s: New connection from %s on socket %d\n"
+								, argv[0], inet_ntoa(clientaddr.sin_addr), newfd);
+					}
+				}
+				else {
+					/* handle data from a client */
+					if((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0) {
+						/* got error or connection closed by client */
+						if(nbytes == 0)
+							/* connection closed */
+							printf("%s: socket %d hung up\n", argv[0], i);
+
+						else
+							perror("recv()");
+
+						/* close it... */
+						close(i);
+						/* remove from master set */
+						FD_CLR(i, &master);
+					}
+					else {
+						/* we got some data from a client*/
+						for(j = 0; j <= fdmax; j++) {
+							/* send to everyone! */
+							if(FD_ISSET(j, &master)) {
+								/* except the listener and ourselves */
+								if(j != listener && j != i) {
+									if(send(j, buf, nbytes, 0) == -1)
+										perror("send()");
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	return 0;
+}
diff --git a/c/libipc/struct-ipc-switching.c b/c/libipc/struct-ipc-switching.c
new file mode 100644
index 0000000..c242516
--- /dev/null
+++ b/c/libipc/struct-ipc-switching.c
@@ -0,0 +1,55 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <ipc.h>
+
+#define NTAB(t)     ((int) (sizeof (t) / sizeof (t)[0]))
+
+struct ipc_connection_info *srv = NULL;
+struct ipc_connection_infos *clients = NULL;
+
+struct ipc_switching * TCP_TO_IPC;
+struct ipc_switching * IPC_TO_TCP;
+
+// void ipc_switching_add (struct ipc_switchings *is, int orig, int dest);
+// int ipc_switching_del (struct ipc_switchings *is, int orig);
+// int ipc_switching_get (struct ipc_switchings *is, int orig);
+// void ipc_switching_print (struct ipc_switchings *is);
+
+int main(int argc, char * argv[])
+{
+	argc = argc;
+	argv = argv;
+	
+	struct ipc_switchings TCP_TO_IPC;
+	memset (&TCP_TO_IPC, 0, sizeof(struct ipc_switchings));
+	TCP_TO_IPC.collection = malloc(sizeof(struct ipc_switching));
+
+	ipc_switching_add (&TCP_TO_IPC, 1, 2);
+	ipc_switching_add (&TCP_TO_IPC, 5, 6);
+	ipc_switching_print(&TCP_TO_IPC);
+
+	int ret;
+
+	ret = ipc_switching_get (&TCP_TO_IPC, 1);
+	printf ("ret ipc_switching_get 1 : %d\n", ret);
+	ret = ipc_switching_get (&TCP_TO_IPC, 5);
+	printf ("ret ipc_switching_get 5 : %d\n", ret);
+	ret = ipc_switching_get (&TCP_TO_IPC, 2);
+	printf ("ret ipc_switching_get 2 : %d\n", ret);
+
+
+
+	ipc_switching_del (&TCP_TO_IPC, 5);
+	ipc_switching_print(&TCP_TO_IPC);
+	ipc_switching_del (&TCP_TO_IPC, 5);
+	ipc_switching_print(&TCP_TO_IPC);
+	ipc_switching_del (&TCP_TO_IPC, 1);
+	ipc_switching_print(&TCP_TO_IPC);
+
+	free (TCP_TO_IPC.collection);
+	// free (IPC_TO_TCP);
+
+    return EXIT_SUCCESS;
+}
diff --git a/c/libipc/test-connection.c b/c/libipc/test-connection.c
new file mode 100644
index 0000000..d65f884
--- /dev/null
+++ b/c/libipc/test-connection.c
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <ipc.h>
+
+int main(int argc, char * argv[], char * env[])
+{
+
+	(void) argc;
+	(void) argv;
+
+	SECURE_DECLARATION(struct ipc_error, ret);
+	SECURE_DECLARATION (struct ipc_connection_info, srv);
+
+	if (argc != 2) {
+		fprintf (stderr, "usage: %s service_name\n", argv[0]);
+		exit (1);
+	}
+
+	char *service_name = argv[1];
+
+	ret = ipc_connection (env, &srv, service_name);
+
+	printf ("ret = %d\n", ret.error_code);
+
+	if (ret.error_code == 0 && srv.fd != 0) {
+		printf ("Success\n");
+	}
+	else {
+		printf ("Ow. :(\n");
+	}
+
+	usock_close (srv.fd);
+
+    return EXIT_SUCCESS;
+}
diff --git a/c/libipc/test-select.c b/c/libipc/test-select.c
new file mode 100644
index 0000000..e87e30e
--- /dev/null
+++ b/c/libipc/test-select.c
@@ -0,0 +1,193 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+int setup_tcp_socket(short int port)
+{
+	/* server address */
+	struct sockaddr_in serveraddr;
+	memset(&serveraddr, 0, sizeof(struct sockaddr_in));
+	socklen_t addrlen = sizeof(struct sockaddr_in);
+
+    /* for setsockopt() SO_REUSEADDR, below */
+    int yes = 1;
+	int listener = -1;
+
+	if((listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
+		perror("Server-socket()");
+		exit(1);
+	}
+	printf("Server-socket() is OK... fd %d\n", listener);
+
+	/*"address already in use" error message */
+	if(setsockopt(listener
+		, SOL_SOCKET
+		, SO_REUSEADDR
+		, &yes
+		, sizeof(int)) == -1) {
+		perror("Server-setsockopt()");
+		exit(1);
+	}
+	printf("Server-setsockopt() is OK...\n");
+
+	/* bind */
+	serveraddr.sin_family      = AF_INET;
+	serveraddr.sin_port        = htons(port);
+	serveraddr.sin_addr.s_addr = INADDR_ANY;
+	// memset(&(serveraddr.sin_zero), '\0', 8);
+
+	if(bind(listener, (struct sockaddr *)&serveraddr, addrlen) == -1) {
+		perror("Server-bind()");
+		exit(1);
+	}
+	printf("Server-bind() is OK...\n");
+
+	/* listen */
+	if(listen(listener, 10) == -1)
+	{
+		perror("Server-listen()");
+		exit(1);
+	}
+	printf("Server-listen() is OK...\n");
+
+	return listener;
+}
+
+int main(int argc, char * argv[])
+{
+	if (argc < 2) {
+		fprintf (stderr, "usage: %s port\n", argv[0]);
+		exit(1);
+	}
+
+	short int port = atoi(argv[1]);
+
+	printf ("port : %d\n", port);
+
+	/* client address */
+	struct sockaddr_in clientaddr;
+    memset(&clientaddr, 0, sizeof(struct sockaddr_in));
+
+    /* master file descriptor list */
+    fd_set master;
+    /* temp file descriptor list for select() */
+    fd_set read_fds;
+
+    /* maximum file descriptor number */
+    int fdmax;
+    /* listening socket descriptor */
+    // int listener = open ("/tmp/bla", O_RDONLY);
+    int listener;
+    int newfd;
+    /* buffer for client data */
+    char buf[6];
+    int nbytes;
+
+    socklen_t addrlen;
+    int i, j;
+
+
+	/* Now we set variables */
+
+	listener = setup_tcp_socket (port);
+
+    /* clear the master and temp sets */
+    FD_ZERO(&master);
+    FD_ZERO(&read_fds);
+
+    /* add the listener to the master set */
+    FD_SET(listener, &master);
+
+    /* keep track of the biggest file descriptor */
+    fdmax = listener; /* so far, it's this one*/
+
+	int times_going_in_select = 0;
+
+    /* loop */
+    for(;;) {
+        /* copy it */
+        read_fds = master;
+        if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1)
+        {
+            perror("Server-select() error lol!");
+            exit(1);
+        }
+        times_going_in_select++;
+
+        // printf("Server-select() is OK... message received\n");
+
+        /*run through the existing connections looking for data to be read*/
+        for(i = 0; i <= fdmax; i++) {
+            if(FD_ISSET(i, &read_fds)) {
+                /* we got one... */
+                if(i == listener) {
+                    printf("new connection");
+
+					/* handle new connections */
+					addrlen = sizeof(clientaddr);
+					if((newfd = accept(listener, (struct sockaddr *)&clientaddr, &addrlen)) == -1) {
+						perror("Server-accept()");
+					}
+					else
+					{
+						printf("Server-accept() is OK...\n");
+						FD_SET(newfd, &master); /* add to master set */
+						if(newfd > fdmax)
+						{ /* keep track of the maximum */
+							fdmax = newfd;
+						}
+
+						printf("%s: New connection from %s on socket %d\n"
+								, argv[0], inet_ntoa(clientaddr.sin_addr), newfd);
+					}
+                }
+                else {
+                    /* handle data from a client */
+                    if((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0) {
+                        /* got error or connection closed by client */
+                        if(nbytes == 0)
+                            /* connection closed */
+                            printf("%s: socket %d hung up\n", argv[0], i);
+
+                        else
+                            perror("recv() error lol!");
+
+                        /* close it... */
+                        close(i);
+                        /* remove from master set */
+                        FD_CLR(i, &master);
+                    }
+                    else {
+                    	printf("received message: %s  (%d going in select function)\n", buf, times_going_in_select);
+
+                        /* we got some data from a client*/
+                        for(j = 0; j <= fdmax; j++) {
+                            /* send to everyone! */
+                            if(FD_ISSET(j, &master)) {
+#if 0
+                                /* except the listener and ourselves */
+                                if(j != listener && j != i)
+#endif
+                                /* except the listener */
+                                if(j != listener) {
+                                    if(send(j, buf, nbytes, 0) == -1)
+                                        perror("send() error lol!");
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    return EXIT_SUCCESS;
+}
diff --git a/c/libipc/tests-envvars.c b/c/libipc/tests-envvars.c
new file mode 100644
index 0000000..a63b01c
--- /dev/null
+++ b/c/libipc/tests-envvars.c
@@ -0,0 +1,54 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+void fun(char * env[])
+{
+	char buffer[4096];
+	memset (buffer, 0, 4096);
+
+	char *curp = buffer;
+	char *endp = buffer + 4096;
+
+	for (size_t i = 0 ; env[i] != NULL ; i++) {
+		// TODO: check for every IPC_NETWORK_* environment variable
+		if (strncmp(env[i], "IPC_NETWORK", 11) == 0) {
+			curp += snprintf (curp, endp - curp, "%s\n", env[i]);
+		}
+	}
+
+	printf ("%s", buffer);
+}
+
+int main(int argc, char * argv[], char *env[])
+{
+	// fun (env);
+
+	argc = argc;
+	argv = argv;
+	env = env;
+
+	char *network_envvar = getenv("IPC_NETWORK");
+	if (network_envvar == NULL)
+	{
+		fprintf (stderr, "no IPC_NETWORK env var\n");
+		exit (1);
+	}
+
+	printf ("IPC_NETWORK: %s\n", network_envvar);
+
+	// size_t nenvsize = strlen (network_envvar);
+	// size_t i = 0;
+
+	if (strncmp (network_envvar, "pong", 4) == 0) {
+		printf ("pong found\n");
+	}
+	else if (strstr (network_envvar, ";pong") != NULL) {
+		printf ("pong found\n");
+	}
+	else {
+		printf ("pong not found\n");
+	}
+
+    return EXIT_SUCCESS;
+}
diff --git a/c/libipc/to-pascal.pl b/c/libipc/to-pascal.pl
new file mode 100644
index 0000000..61a18da
--- /dev/null
+++ b/c/libipc/to-pascal.pl
@@ -0,0 +1,9 @@
+#!/usr/bin/perl -w
+use v5.14;
+
+while(<>) {
+	chomp;
+	my @wl = split "_\+";
+	my @wl2 = map { ucfirst lc } @wl;
+	say join "", @wl2;
+}