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; +}