#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#define PORT_NO 9001
#define CLIENTS 5
#define AC
#define SL
char* handle_input ( char *data);
void update_seat_availability(const char* seat_type, int remaining_seats);
pthread_mutex_t lock_file; // mutex lock for file access
typedef struct {
struct sockaddr_in adres;
int address_length;
int bind_result;
} connect__data;
struct args {
int arg1;
int arg2;
};
void *handle_client(void *arg) {
struct args *my_args = (struct args *) arg;
int i = my_args ->arg1;
int new_socket = my_args -> arg2;
/* --------------------------------------------------------------------------------*/
// Receive the client request using recv() system call
char buffer[1024];
int bytes_received = recv(new_socket, buffer, 1024, 0);
if (bytes_received < 0) {
printf("Error receiving client request\n");
return NULL;
}
buffer[bytes_received] = '\0';
// Close the socket
char* message = malloc(2048*sizeof(char));
message = handle_input(buffer);
if ( message != NULL) {
// Send the message to the client
int bytes_sent = send(new_socket, message, strlen(message), 0);
if (bytes_sent < 0) {
printf("Error sending message to client\n");
}
close(new_socket);
// Mutex lock to protect the critical section
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&lock);
// Access the shared resources
FILE* file = fopen("server_records.txt", "a");
if (file != NULL) {
fprintf(file, "[Client-%d] Request: %s\nServer Response: %s\n\n", i, buffer, message);
fclose(file);
}
pthread_mutex_unlock(&lock);
}
return NULL;
}
char* handle_input(char* data) {
int i = 1;
int k = 0;
char seat_type[50];
char number_of_seats[50];
sscanf(data, "%s", seat_type);
char* ptr = data + strlen(seat_type);
while ( *ptr == ' ' ) ptr++;
strcpy (number_of_seats, ptr);
char* msg = malloc(1024*sizeof(char));
char* file_msg = malloc(1024 * sizeof(char));
pthread_mutex_lock(&lock_file); // lock file access
FILE* file = fopen("Seat_Availability.txt", "r+");
if (file != NULL) {
int found = 0;
char line[500], avl_seats[50];
while (fgets(line, sizeof(line), file) != NULL) {
char* token = strtok(line, " ");
if (strcmp(token, seat_type) == 0) {
token = strtok(NULL, " ");
strcpy(avl_seats, token);
found = 1;
break;
}
}
if (found) {
int required_seats = atoi(number_of_seats);
int available_seats = atoi(avl_seats);
int remaining_seats = 0;
char new_data[500];
if (required_seats > available_seats) {
strcpy(msg,"Required Number of Seats Not Available");
} else {
remaining_seats = available_seats - required_seats;
sprintf(new_data, "%s %d", seat_type, remaining_seats);
update_seat_availability(seat_type, remaining_seats);
sprintf(msg, "%d Seats have been booked for type %s", required_seats, seat_type);
}
} else {
strcpy(msg,"Seat type not found!");
}
}
fclose(file);
pthread_mutex_unlock(&lock_file); // unlock file access
return msg;
}
void update_seat_availability(const char* seat_type, int remaining_seats) {
pthread_mutex_lock(&lock_file);
FILE* file = fopen("Seat_Availability.txt", "r+");
if (file == NULL) {
perror("Failed to open Seat_Availability.txt");
pthread_mutex_unlock(&lock_file);
return;
}
// Find the line for the specified seat type
char line[500];
while (fgets(line, sizeof(line), file) != NULL) {
char* token = strtok(line, " ");
if (strcmp(token, seat_type) == 0) {
break;
}
}
// Write the updated seat availability data to the file
if (fprintf(file, "%s %d\n", seat_type, remaining_seats) < 0) {
perror("Failed to write updated seat availability");
}
fclose(file);
pthread_mutex_unlock(&lock_file);
return;
}
void handle_agent_login () {
char* user_id = "Agent123";
char* password = "123456";
char input_id[100];
char input_pass[100];
do {
puts("Agent Login:");
printf("Enter User ID: ");
fgets(input_id,100,stdin);
input_id[strcspn(input_id, "\n")] = '\0';
printf("Enter Password: ");
fgets(input_pass, 100, stdin);
input_pass[strcspn(input_pass, "\n")] = '\0';
if ( strcmp(input_id,user_id) != 0 || strcmp(input_pass,password) != 0) {
puts("Invalid Login Credentials, Please Try Again!\n");
}
} while ( strcmp(input_id,user_id) != 0 || strcmp(input_pass,password) != 0);
return;
}
int create_socket () {
int my_socket = socket(AF_INET, SOCK_STREAM, 0);
if ( my_socket == -1 ) {
printf("Socket Error!\n");
return -1;
} else {
puts("Socket creation successful!");
}
return my_socket;
}
connect__data bind_port ( int sock ) {
connect__data temp;
struct sockaddr_in address;
int adlength = sizeof(address);
memset(&address, 0, sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT_NO);
int opt = 1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) {
printf("Error setting socket options!\n");
exit(0);
}
int bind_res = bind(sock, (struct sockaddr*)&address, sizeof(address));
if (bind_res == -1) {
printf("Bind Error!\n");
exit(0);
} else {
puts("Bind Successful!");
}
temp.adres = address;
temp.address_length = adlength;
temp.bind_result = bind_res;
return temp;
}
int main() {
//handle_agent_login();
int i = 1;
struct sockaddr_in address;
int adlength;
//Create a socket using socket( ) system call.
int sock = create_socket();
if ( sock == -1 ) {
printf("\n*************Socket Error!*******************\n");
}
/* --------------------------------------------------------------------------------*/
//Bind server’s address and port using bind( ) system call.
connect__data result = bind_port(sock);
address = result.adres;
adlength = result.address_length;
int bind_res = result.bind_result;
/* --------------------------------------------------------------------------------*/
//Convert the socket into a listening socket using listen( ) system call.
if ( listen(sock, CLIENTS) < 0 ) {
printf("Listen Error!\n");
return 1;
}
/* --------------------------------------------------------------------------------*/
//Accept client connections using accept( ) system call.
printf("\nServer is listening on port %d....\n\n", PORT_NO);
while (1) {
int new_socket = accept(sock, (struct sockaddr*)&address, (socklen_t*)&adlength);
if (new_socket < 0) {
printf("Accept Error!\n");
return 1;
}
printf("Client-%d connected\n",i);
// Create a new thread to handle the client request
pthread_t client_thread;
struct args my_args = {i,new_socket};
if (pthread_create(&client_thread, NULL, handle_client, (void*) &my_args) < 0) {
printf("Error creating thread for client\n");
return 1;
}
i++;
}
/* --------------------------------------------------------------------------------*/
//Close the socket
close(sock);
return 0;
}