aboutsummaryrefslogtreecommitdiff
path: root/snowcast_server_concurrent.c
diff options
context:
space:
mode:
authorsotech117 <michael_foiani@brown.edu>2023-09-20 01:19:39 -0400
committersotech117 <michael_foiani@brown.edu>2023-09-20 01:19:39 -0400
commitea7aff51be44884e22c8bdabef917c77c291951e (patch)
tree7ecb12326287eb9c3799b047c36e555b5ccfbbaf /snowcast_server_concurrent.c
parent1263cbdbb6cf3ebbb157286b2bb2e488e4b931c8 (diff)
add better command line interface to server repl. also, add the print function that can go to file.
Diffstat (limited to 'snowcast_server_concurrent.c')
-rw-r--r--snowcast_server_concurrent.c117
1 files changed, 108 insertions, 9 deletions
diff --git a/snowcast_server_concurrent.c b/snowcast_server_concurrent.c
index d855bab..2c74cab 100644
--- a/snowcast_server_concurrent.c
+++ b/snowcast_server_concurrent.c
@@ -8,6 +8,9 @@
#include <netdb.h>
#include <string.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
#include "protocol.h"
#define LINE_MAX 1024
@@ -53,6 +56,9 @@ void *send_udp_packet_routine(void* arg);
void *select_thread(void* arg);
void *synchronization_thread(void* arg);
+int parse(char buffer[LINE_MAX], char *tokens[LINE_MAX / 2]);
+void *print_info_routine(void *arg);
+
void *get_in_addr(struct sockaddr *sa);
void *init_user(int sockfd);
@@ -118,27 +124,105 @@ int main(int argc, char *argv[])
// command line interface
char input[LINE_MAX];
- while (1) {
- char *line = fgets(input, LINE_MAX, stdin);
+ memset(input, 0, LINE_MAX);
- if (line == NULL) {
+ char *tokens[LINE_MAX / 2];
+ while (read(STDIN_FILENO, input, LINE_MAX) > 0) {
+ // init tokens
+ memset(tokens, 0, (LINE_MAX / 2) * sizeof(char *));
+
+ // if 0, all whitespace
+ if (!parse(input, tokens))
continue;
- } else if (strncmp("q\n", input, LINE_MAX) == 0) {
- // end code if type in q
+
+ char *command = tokens[0];
+ // if q, shutdown!
+ if (!strcmp(command, "q")) {
printf("Exiting.\n");
+ // TODO: exit better than break
break;
- } else if (strncmp("p\n", input, LINE_MAX) == 0) {
+ }
+
+ // if p, print info
+ else if (!strcmp(command, "p")) {
+ // get the file descriptor
+ int print_fd = 0;
+ // see if there is a file path
+ char *output_file_path = tokens[1];
+ if (output_file_path != NULL)
+ {
+ if ((print_fd = open(output_file_path, O_CREAT | O_WRONLY | O_TRUNC, S_IRWXU)) == -1)
+ {
+ perror("open");
+ continue;
+ }
+ } else {
+ print_fd = STDOUT_FILENO;
+ }
+ printf("print_fd: %d\n", print_fd);
+ pthread_t print_info_thread;
+ pthread_create(&print_info_thread, NULL, print_info_routine, print_fd);
+ // note - this file descriptor is closed in the thread
+ }
+ else if (strncmp("u\n", input, LINE_MAX) == 0)
+ {
// print all user data
- for (int i = 0; i < max_active_users; i++) {
+ for (int i = 0; i < max_active_users; i++)
+ {
print_user_data(i);
}
- } else if (strncmp("s\n", input, LINE_MAX) == 0) {
}
}
return 0;
}
+void write_int_to_fd(int fd, int n) {
+ int l = snprintf(NULL, 0, "%d", n);
+ char *num = malloc(l + 1);
+ if (!num) { perror("malloc"); return; }
+
+ snprintf(num, l + 1, "%d", n);
+ if (write(fd, num, strlen(num)) == -1) {
+ perror("write");
+ }
+
+
+ free(num);
+}
+
+void *print_info_routine(void *arg) {
+ int print_fd = (int) arg;
+ // printf("thread print_fd: %d\n", print_fd);
+ // printf("num_stations: %d\n", num_stations);
+ for (int i = 0; i < num_stations; i++) {
+ write_int_to_fd(print_fd, i);
+ char *comma = ",";
+ write(print_fd, comma, strlen(comma));
+
+ // write file path
+ char* file_path = station_data[i].filePath;
+ write(print_fd, file_path, strlen(file_path));
+
+ for (int j = 0; j < max_active_users; j++) {
+ if (user_data[j].sockfd == -1)
+ continue;
+ if (user_data[j].stationNum == i) {
+ char *localhost_ip = ",127.0.0.1:";
+ write(print_fd, localhost_ip, strlen(localhost_ip));
+ // write udpPort
+ write_int_to_fd(print_fd, user_data[j].udpPort);
+ }
+ }
+ // wrtie new line
+ char *newline = "\n";
+ write(print_fd, newline, strlen(newline));
+ }
+
+ if (print_fd != STDOUT_FILENO) close(print_fd);
+ return (NULL);
+}
+
int sendall(int udp_sockfd, char *buf, int *len, struct addrinfo *thread_res)
{
int MAX_PACKET_SIZE = 512;
@@ -606,4 +690,19 @@ void send_announce_message(int fd, int station_num) {
printf("sent %d bytes\n", bytessent);
free(send_buffer);
-} \ No newline at end of file
+}
+
+
+// Parses a buffer into tokens, from cs33 :)
+int parse(char buffer[LINE_MAX], char *tokens[LINE_MAX / 2]) {
+ const char *regex = " \n\t\f\r";
+ char *current_token = strtok(buffer, regex);
+ if (current_token == NULL) return 0;
+
+ for (int i = 0; current_token != NULL; i++) {
+ tokens[i] = current_token;
+ current_token = strtok(NULL, regex);
+ }
+
+ return 1;
+}