diff options
author | Cody Hiar <cody@hiar.ca> | 2021-03-27 13:59:05 -0600 |
---|---|---|
committer | Cody Hiar <cody@hiar.ca> | 2021-03-27 13:59:05 -0600 |
commit | 74e5e824defa0a2bb111625e325c93bbf2e3f4bd (patch) | |
tree | 0a9f0cac4f5ab99c8fe1efb585095d0c936079d9 | |
parent | 9142f56b4c3773e9d1779b0bbffdc26549c9734d (diff) |
-rw-r--r-- | port2file/Makefile | 6 | ||||
-rw-r--r-- | port2file/README.md | 3 | ||||
-rw-r--r-- | port2file/port2file.c | 139 |
3 files changed, 148 insertions, 0 deletions
diff --git a/port2file/Makefile b/port2file/Makefile new file mode 100644 index 0000000..3c57cf7 --- /dev/null +++ b/port2file/Makefile @@ -0,0 +1,6 @@ + +build: + gcc -Wall -Wextra -Wpedantic --std=gnu99 port2file.c -o port2file + +lint: + splint port2file.c diff --git a/port2file/README.md b/port2file/README.md new file mode 100644 index 0000000..7266ab3 --- /dev/null +++ b/port2file/README.md @@ -0,0 +1,3 @@ +# port2file + +A program that listens on a a port and writes to a file when it receives data diff --git a/port2file/port2file.c b/port2file/port2file.c new file mode 100644 index 0000000..9d641d4 --- /dev/null +++ b/port2file/port2file.c @@ -0,0 +1,139 @@ +#include <arpa/inet.h> +#include <fcntl.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <time.h> +#include <unistd.h> +#include <errno.h> + +#define BUFF_SIZE 1024 +#define ONE_SECOND_IN_NANOSECONDS 1000000000 +#define ONE_SECOND_IN_MICROSECONDS 1000000 + +static long int calulate_difference(struct timespec a, struct timespec b); + +int +main() { + int server_fd, new_socket; + struct sockaddr_in address; + int opt = 1; + int port = 41401; + int addrlen = sizeof(address); + + // Create socket + if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) + { + perror("Could not create socket"); + exit(EXIT_FAILURE); + } + + // Set socket options + if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, + &opt, sizeof(opt))) + { + perror("Error during setsockopt"); + exit(EXIT_FAILURE); + } + address.sin_family = AF_INET; + address.sin_addr.s_addr = INADDR_ANY; + address.sin_port = htons( port ); + + //Bind + if(bind(server_fd,(struct sockaddr *)&address , sizeof(address)) < 0) + { + perror("Bind failure"); + exit(EXIT_FAILURE); + } + + if (listen(server_fd, 20) < 0) + { + perror("Listen failure"); + exit(EXIT_FAILURE); + } + + + while (true) { + new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen); + + printf("new connection\n"); + if (new_socket < 0) { + perror("accept"); + exit(EXIT_FAILURE); + } + + // Set the socket to non blocking + fcntl(new_socket, F_SETFL, O_NONBLOCK); + + char *buffer; + buffer = malloc(sizeof(char) * BUFF_SIZE); + + /* int res = 0; */ + int count = 0; + int idx = 0; + int size_recv = 0; + long int timeout = ONE_SECOND_IN_NANOSECONDS / 10; + struct timespec begin; + struct timespec now; + long int timediff; + char chunk[BUFF_SIZE]; + + clock_gettime(CLOCK_MONOTONIC, &begin); + + while (true) { + clock_gettime(CLOCK_MONOTONIC, &now); + + timediff = calulate_difference(now, begin); + + //if you got some data, then break after timeout + if( count > 0 && timediff > timeout ) + { + break; + } + + memset(chunk, 0, BUFF_SIZE); //clear the variable + size_recv = recv(new_socket, chunk, BUFF_SIZE, 0); + /* printf("chunk: %s\n", chunk); */ + + + if (size_recv > 0) + { + buffer = realloc(buffer, (idx + BUFF_SIZE) * sizeof(char)); + memcpy((char *)buffer + idx, chunk, BUFF_SIZE); + clock_gettime(CLOCK_MONOTONIC, &begin); + /* printf("buff: %s\n", buffer); */ + count++; + idx = count * BUFF_SIZE; + } + else if (errno != EWOULDBLOCK) + { + (void) usleep(ONE_SECOND_IN_MICROSECONDS / 100); + } else { + (void) usleep(ONE_SECOND_IN_MICROSECONDS / 100); + } + + } + + FILE *f = fopen("output.log", "w"); + if (f == NULL) + { + printf("Error opening file!\n"); + exit(1); + } + + fprintf(f, "%s", buffer); + + (void) fclose(f); + (void) close(new_socket); + (void) free(buffer); + } +} + +static long int +calulate_difference(struct timespec a, struct timespec b) { + int seconds_to_nanoseconds = (a.tv_sec - b.tv_sec) * 1000000000; + return seconds_to_nanoseconds + a.tv_nsec - b.tv_nsec; +} + |