summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCody Hiar <cody@hiar.ca>2021-03-27 13:59:05 -0600
committerCody Hiar <cody@hiar.ca>2021-03-27 13:59:05 -0600
commit74e5e824defa0a2bb111625e325c93bbf2e3f4bd (patch)
tree0a9f0cac4f5ab99c8fe1efb585095d0c936079d9
parent9142f56b4c3773e9d1779b0bbffdc26549c9734d (diff)
add port to file codeHEADmaster
-rw-r--r--port2file/Makefile6
-rw-r--r--port2file/README.md3
-rw-r--r--port2file/port2file.c139
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;
+}
+