// Server code for COMP-8567 Project Winter 2024
// Course: COMP-8567
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#define PORT 8080
#define BUFSIZE 1024
void dirlist_a(int sockfd) {
char buffer[BUFSIZE];
memset(buffer, 0, BUFSIZE);
struct dirent *dir;
DIR *d = opendir(".");
if (d) {
while ((dir = readdir(d)) != NULL) {
if (dir->d_type == DT_DIR) {
strcat(buffer, dir->d_name);
}
}
closedir(d);
send(sockfd, buffer, strlen(buffer), 0);
}
}
3
void dirlist_t(int sockfd) {
char buffer[BUFSIZE];
memset(buffer, 0, BUFSIZE);
struct dirent **namelist;
int n;
n = scandir(".", &namelist, NULL, alphasort);
if (n < 0) {
perror("scandir");
}
else {
while (n--) {
if (namelist[n]->d_type == DT_DIR) {
strcat(buffer, namelist[n]->d_name);
strcat(buffer, "\n");
}
else {
strcat(buffer, namelist[n]->d_name);
strcat(buffer, "\n");
}
}
free(namelist);
}
}
4
}
send(sockfd, buffer, strlen(buffer), 0);
}
void w24fn(int sockfd, char *filename) {
char buffer[BUFSIZE];
memset(buffer, 0, BUFSIZE);
struct stat file_stat;
if (stat(filename, &file_stat) == 0) {
printf(buffer, "Filename: %s\nSize: %ld bytes\nDate created: %s\nPermissions: %o\n",
filename, file_stat.st_size, ctime(&file_stat.st_ctime), file_stat.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));
} else {
strcpy(buffer, "File not found\n");
}
send(sockfd, buffer, strlen(buffer), 0);
}
}
void w24fz(int sockfd, int size1, int size2) {
char buffer[BUFSIZE];
memset(buffer, 0, BUFSIZE);
DIR *dir = opendir(".");
struct dirent *entry;
struct stat file_stat;
if (dir != NULL) {
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_REG) {
stat(entry->d_name, &file_stat);
strcat(buffer, entry->d_name);
strcat(buffer, "\n");
}
}
}
}
}
closedir(dir);
if (strlen(buffer) == 0) {
strcpy(buffer, "No file found\n");
}
} else {
strcpy(buffer, "Unable to open directory\n");
}
}
send(sockfd, buffer, strlen(buffer), 0);
}
void w24ft(int sockfd, char *extensions) {
char buffer[BUFSIZE];
memset(buffer, 0, BUFSIZE);
char *ext = strtok(extensions, " ");
DIR *dir = opendir(".");
struct dirent *entry;
struct stat file_stat;
if (dir != NULL) {
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_REG) {
char *file_ext = strrchr(entry->d_name, '.');
if (file_ext != NULL && strcmp(file_ext, ext) == 0) {
strcat(buffer, entry->d_name);
strcat(buffer, "\n");
}
}
}
}
closedir(dir);
if (strlen(buffer) == 0) {
strcpy(buffer, "No file found\n");
}
} else {
strcpy(buffer, "Unable to open directory\n");
}
send(sockfd, buffer, strlen(buffer), 0);
}
void w24fdb(int sockfd, char *date) {
char buffer[BUFSIZE];
memset(buffer, 0, BUFSIZE);
struct tm tm;
time_t t t = mktime(&tm);
DIR *dir = opendir(".");
struct dirent *entry;
struct stat file_stat;
9
if (dir != NULL) {
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_REG) {
stat(entry->d_name, &file_stat);
if (file_stat.st_ctime <= t) {
strcat(buffer, entry->d_name);
strcat(buffer, "\n");
}
}
}
closedir(dir);
if (strlen(buffer) == 0) {
strcpy(buffer, "No file found\n");
}
}
else {
strcpy(buffer, "Unable to open directory\n");
}
10
send(sockfd, buffer, strlen(buffer), 0);
}
void w24fda(int sockfd, char *date) {
char buffer[BUFSIZE];
memset(buffer, 0, BUFSIZE);
struct tm tm;
strptime(date, "%Y-%m-%d", &tm);
time_t t_t = mktime(&tm);
}
DIR *dir = opendir(".");
struct dirent *entry;
struct stat file_stat;
if (dir != NULL) {
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_REG) {
stat(entry->d_name, &file_stat);
if (file_stat.st_ctime >= t) {
strcat(buffer, entry->d_name);
strcat(buffer, "\n");
}
}
closedir(dir);
if (strlen(buffer) == 0) {
strcpy(buffer, "No file found\n");
}
else {
strcpy(buffer, "Unable to open directory\n");
}
send(sockfd, buffer, strlen(buffer), 0);
}
void crequest(int sockfd) {
12
char buffer[BUFSIZE];
while (1) {
memset(buffer, 0, BUFSIZE);
recv(sockfd, buffer, BUFSIZE, 0);
if (strcmp(buffer, "dirlist -a") == 0) {
dirlist_a(sockfd);
} else if ( strcmp(buffer, "dirlist -t") == 0) {
dirlist_t(sockfd);
} else if ( strcmp(buffer, "w24fn", 5) == 0) {
// Extract filename from buffer and call w24fn function
char *filename = strtok(buffer, " ");
filename = strtok(NULL, " ");
w24fn(sockfd, filename);
} else if ( strcmp(buffer, "w24fz", 5) == 0) {
// Extract sizel and size2 from buffer and call w24fz function
int size1, size2;
sscanf(buffer, "w24fz %d %d", &size1, &size2);
13
w24fz(sockfd, size1, size2);
} else if ( strncmp(buffer, "w24ft", 5) == 0) {
// Extract extensions from buffer and call w24ft function
char *extensions = strtok(buffer, " ");
extensions = strtok(NULL, " ");
w24ft(sockfd, extensions);
} else if ( strncmp(buffer, "w24fdb", 6) == 0) {
// Extract date from buffer and call w24db function
char *date = strtok(buffer, " ");
date = strtok(NULL, " ");
w24fdb(sockfd, date);
} else if ( strncmp(buffer, "w24fda", 6) == 0) {
// Extract date from buffer and call w24da function
char *date = strtok(buffer, " ");
date = strtok(NULL, " ");
w24fda(sockfd, date);
} else if ( strncmp(buffer, "quitc", 5) == 0) {
printf("Client requested to quit\n");
break;
} else {
printf("Received invalid command from client: %s\n", buffer);
send(sockfd, "Invalid command", strlen("Invalid command"), 0);
}
}
}
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int addrlen = sizeof(address);
int opt = 1;
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
15
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt,
sizeof(opt))) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
while (1) {
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) {
perror("accept");
exit(EXIT_FAILURE);
}
printf("New client connected. Forking child process...\n");
if (fork() == 0) {
close(server_fd);
crequest(new_socket);
close(new_socket);
exit(0);
} else {
close(new_socket);
}
}
return 0;
17
}