From e9576b5574d8d9abf0b22b98337f6bff58955cdd Mon Sep 17 00:00:00 2001
From: Philippe PITTOLI
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
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+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
+#include
+#include
+
+#include
+
+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
+#include
+#include
+#include
+#include
+
+#include
+
+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
+#include
+#include
+
+#include
+#include
+
+
+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
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/* 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
+#include
+#include
+
+#include
+
+#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
+#include
+#include
+
+#include
+
+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
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+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
+#include
+#include
+
+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;
+}