Compare commits

...

6 Commits

4 changed files with 86 additions and 44 deletions

14
README.md Normal file
View File

@@ -0,0 +1,14 @@
## Chat server
This is a simple, barely-working chat server (which uses a custom protocol). It is written in C, and relies on BSD sockets.
##Usage
To use it, compile the program with `make`.
TODO:
- Finish README
- Implement password authentication
- Fix bugs with message string manipulation (the actual message isn't being stored correctly, and contains extra characters).
- Do additional testing to ensure that everything works correctly (it probably doesn't).

72
main.c
View File

@@ -16,6 +16,7 @@
#define BUFFER_SIZE 10000 #define BUFFER_SIZE 10000
#define MAX_CONNECTIONS 100 #define MAX_CONNECTIONS 100
#define DATA_SIZE 50000 #define DATA_SIZE 50000
#define MESSAGE_SIZE 50000
User** create_user_list(char* filename); User** create_user_list(char* filename);
void sigint_handler(int dummy); void sigint_handler(int dummy);
@@ -80,6 +81,9 @@ int main() {
} }
for (int i=1; i < MAX_CONNECTIONS; i++) { for (int i=1; i < MAX_CONNECTIONS; i++) {
memset(data,0x00,DATA_SIZE);
if (FD_ISSET(conn_sockets[i],&read_fd_set)) { if (FD_ISSET(conn_sockets[i],&read_fd_set)) {
while ( strstr(buffer,"END_OF_DATA") == NULL ) { while ( strstr(buffer,"END_OF_DATA") == NULL ) {
@@ -94,7 +98,16 @@ int main() {
} }
strcat(data,"\0"); strcat(data,"\0");
if (strcmp(strtok(data," \r\n"), "SENDING") == 0) { buffer[0] = '\0'; /* Clear the buffer */
char* send_or_receive = malloc(10);
int k=0;
while (*(data + k) != '\n') {
k++;
}
memcpy(send_or_receive,data,k);
if (strstr(send_or_receive, "SENDING") != NULL) {
if (from_user[i] == NULL) { if (from_user[i] == NULL) {
from_user[i] = fetch_user(fetch_from_string(data,"IAM")); from_user[i] = fetch_user(fetch_from_string(data,"IAM"));
if (from_user[i] == NULL) { if (from_user[i] == NULL) {
@@ -116,14 +129,16 @@ int main() {
printf("Message intended for %s\n",to_user[i]->username); printf("Message intended for %s\n",to_user[i]->username);
} }
} }
char* message_string = fetch_message_string(data); char* message_string = malloc(sizeof(char) * MESSAGE_SIZE);
memset(message_string, 0x00, MESSAGE_SIZE);
message_string = fetch_message_string(data);
if (message_string == NULL) { if (message_string == NULL) {
printf("Invalid message.\n"); printf("Invalid message.\n");
return -10; return -10;
} }
printf("Your message is: %s\n",message_string); printf("Your message is: \n------------------\n%s\n------------------\n",message_string);
if (user_to_index(to_user[i]) < 0) { if (user_to_index(to_user[i]) < 0) {
printf("Recipient user does not exist!\n"); printf("Recipient user does not exist!\n");
@@ -135,7 +150,7 @@ int main() {
printf("Message has been pushed onto stack for %s\n",to_user[i]->username); printf("Message has been pushed onto stack for %s\n",to_user[i]->username);
} else if (strcmp(strtok(buffer," \r\n"), "SENDING") == 0) { } else if (strstr(send_or_receive, "RECEIVING") != NULL) {
if (from_user[i] == NULL) { if (from_user[i] == NULL) {
from_user[i] = fetch_user(fetch_from_string(data,"IAM")); from_user[i] = fetch_user(fetch_from_string(data,"IAM"));
@@ -155,7 +170,7 @@ int main() {
printf("Invalid GET request.\n"); printf("Invalid GET request.\n");
return -30; return -30;
} else { } else {
if (strstr(num_of_messages_string,"ALL") == 0) { if (strstr(num_of_messages_string,"ALL") != NULL) {
num_of_messages = stack_size(message_stack[user_to_index(from_user[i])]); num_of_messages = stack_size(message_stack[user_to_index(from_user[i])]);
} else { } else {
num_of_messages = atoi(num_of_messages_string); num_of_messages = atoi(num_of_messages_string);
@@ -166,7 +181,7 @@ int main() {
num_of_messages = stack_size(message_stack[user_to_index(from_user[i])]); num_of_messages = stack_size(message_stack[user_to_index(from_user[i])]);
} }
for (int i=0;i<num_of_messages;i++) { for (int k=0;k<num_of_messages;k++) {
Message* message = stack_pop(message_stack[user_to_index(from_user[i])]); Message* message = stack_pop(message_stack[user_to_index(from_user[i])]);
printf("You have a message from %s" printf("You have a message from %s"
", sent at %s" ", sent at %s"
@@ -176,41 +191,34 @@ int main() {
message->text); message->text);
} }
} else { } else {
printf("You are not sending or receiving.\n"); printf("You are not sending or receiving.\n");
} }
close(conn_sockets[i]);
conn_sockets[i] = -1;
close(conn_sockets[i]); continue_for_loop:
memset(data,0,DATA_SIZE);
memset(buffer,0,BUFFER_SIZE);
to_user[i] = NULL;
from_user[i] = NULL;
} }
continue_for_loop:
data[0] = '\0'; /* This effectively clears the string, since the first element is null. */
to_user[i] = NULL;
} }
}
if (stop_running == true) { if (stop_running == true) {
printf("Stopping...\n"); printf("Stopping...\n");
for (int i=MAX_CONNECTIONS-1; i>= 0; i--) { for (int i=MAX_CONNECTIONS-1; i>= 0; i--) {
close(i); close(i);
close(conn_sockets[i]); close(conn_sockets[i]);
}
return 130;
}
} }
return 130;
}
} }
// Message message = new_message("Hello, this is a text message",users[0],users[1]);
// printf("Message was: %s\nSentfrom: %s\nSent to: %s\nWith password: %s\nSent at: %s\n",message.text, message.sender.username, message.recipient.username, message.recipient.password, asctime(&message.timeinfo));
} }
@@ -242,7 +250,9 @@ User** create_user_list(char* filename) {
} }
void sigint_handler(int dummy) { void sigint_handler(int dummy) {
stop_running = true; stop_running = true;
printf("sigint_handler is stopping...\n");
exit(130);
} }
User* fetch_user(char* username) { User* fetch_user(char* username) {

View File

@@ -25,39 +25,57 @@ char* fetch_from_string(char* message, char* indicator) {
} }
char* fetch_message_string(char* message) { char* fetch_message_string(char* message) {
int num_of_terminators;
char* start = strstr(message,"START_OF_MESSAGE"); char* message_copy = malloc(strlen(message));
strcpy(message_copy,message);
int num_of_terminators = 0;
int start_index = 0;
int end_index = 0;
int message_length = 0;
char* start = strstr(message_copy,"START_OF_MESSAGE");
if (start == NULL) { if (start == NULL) {
return NULL; return NULL;
} }
int start_index = start - message; start_index = start - message_copy;
start_index += strlen("START_OF_MESSAGE"); start_index += strlen("START_OF_MESSAGE");
while (*(message + start_index) == '\n' || *(message + start_index) == '\r') { while (*(message_copy + start_index) == '\n' || *(message_copy + start_index) == '\r') {
start_index++; start_index++;
} }
char* end = strstr(message,"END_OF_MESSAGE"); char* end = strstr(message_copy,"END_OF_MESSAGE");
if (end == NULL) { if (end == NULL) {
return NULL; return NULL;
} }
int end_index = end - message; end_index = end - message_copy;
if (*(message+ end_index-2) = '\r') { if (*(message_copy + end_index-2) == '\r') {
num_of_terminators = 2; num_of_terminators = 2;
} else { } else {
num_of_terminators = 1; num_of_terminators = 1;
} }
int message_length = end_index - start_index; end_index -= num_of_terminators;
char* message_string = malloc(message_length + 1);
for (int i=0;i < message_length-num_of_terminators; i++) { /* The reason the upper-bound is message_length-1 is because the last message_length = end_index - start_index;
char* message_string = malloc(message_length + 2);
printf("Message goes from %d to %d\n",start_index,end_index);
for (int i=0; i<message_length; i++) { /* The reason the upper-bound is message_length-1 is because the last
character is a new-line, which the user would not have typed. */ character is a new-line, which the user would not have typed. */
*(message_string + i) = *(message + start_index + i);
*(message_string + i) = *(message_copy + start_index + i);
printf("%c",*(message_string + i));
} }
*(message_string + (message_length - num_of_terminators)) = '\0'; strcat(message_string,"\0");
// printf("%s\n",message_string);
// *(message_string + (message_length - num_of_terminators)) = '\0';
return message_string; return message_string;
} }

View File

@@ -35,7 +35,7 @@ void stack_push(Stack* stack,void* element) {
void* stack_pop(Stack* stack) { void* stack_pop(Stack* stack) {
assert( !(stack_isEmpty(stack)) ); assert( !(stack_isEmpty(stack)) );
free(stack->data + stack->top_index); // free(stack->data + stack->top_index);
stack->top_index--; stack->top_index--;
void* to_return = *(stack->data + stack->top_index); void* to_return = *(stack->data + stack->top_index);
*(stack->data + stack->top_index) = NULL; *(stack->data + stack->top_index) = NULL;