Created
April 18, 2019 10:58
-
-
Save ebenezergraham/5f6ce109a213dbdeb3cf06d0640b3f67 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <sys/socket.h> | |
#include <sys/types.h> | |
#include <netinet/in.h> | |
#include <netdb.h> | |
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <errno.h> | |
#include <arpa/inet.h> | |
#include <sys/utsname.h> | |
#include "rdwrn.h" | |
#define INPUTSIZE 10 | |
void send_option(int, char); | |
void optionone(int); | |
void optiontwo(int); | |
void optionthree(int); | |
void optionfour(int); | |
void optionfive(int); | |
void displaymenu(); | |
int main(void) | |
{ | |
int sockfd = 0; | |
struct sockaddr_in serv_addr; | |
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { | |
perror("Error - could not create socket"); | |
exit(EXIT_FAILURE); | |
} | |
serv_addr.sin_family = AF_INET; | |
serv_addr.sin_port = htons(50031); | |
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); | |
if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) | |
== -1) { | |
perror("Error - connect failed"); | |
exit(1); | |
} else | |
printf("Connected to server...\n"); | |
char input; | |
char name[INPUTSIZE]; | |
displaymenu(); | |
do { | |
printf("Select an option: "); | |
fgets(name, INPUTSIZE, stdin); | |
name[strcspn(name, "\n")] = 0; | |
input = name[0]; | |
send_option(sockfd, input); | |
if (strlen(name) > 1) | |
input = 'x'; | |
switch (input) { | |
case '0': | |
displaymenu(); | |
break; | |
case '1': | |
optionone(sockfd); | |
break; | |
case '2': | |
optiontwo(sockfd); | |
break; | |
case '3': | |
optionthree(sockfd); | |
break; | |
case '4': | |
optionfour(sockfd); | |
break; | |
case '5': | |
optionfive(sockfd); | |
break; | |
case '6': | |
printf("Goodbye!\n"); | |
break; | |
default: | |
printf | |
("You have selected an invalid option, press 0 to display options again!\n"); | |
break; | |
} | |
} while (input != '6'); | |
close(sockfd); | |
exit(EXIT_SUCCESS); | |
} | |
void optionone(int socket) | |
{ | |
printf("Displaying Student Details\n"); | |
printf("==========================\n"); | |
size_t size; | |
readn(socket, (unsigned char *) &size, sizeof(size_t)); | |
char response[size]; | |
readn(socket, (unsigned char *) response, size); | |
printf("Server Response: %s\n", response); | |
} | |
void optiontwo(int socket) | |
{ | |
printf("Getting 5 Random Numbers\n"); | |
printf("========================\n"); | |
size_t size; | |
readn(socket, (unsigned char *) &size, sizeof(size_t)); | |
int response[size]; | |
readn(socket, (unsigned char *) response, size); | |
printf("Server Response: %s\n", response); | |
} | |
void optionthree(int socket) | |
{ | |
printf("Getting Server Information\n"); | |
printf("==========================\n"); | |
struct utsname uts; | |
size_t payload_length; | |
readn(socket, (unsigned char *) &payload_length, sizeof(size_t)); | |
readn(socket, (unsigned char *) &uts, payload_length); | |
printf("System name: %s\n", uts.sysname); | |
printf("Hostname: %s\n", uts.nodename); | |
printf("Release: %s\n", uts.release); | |
} | |
void optionfour(int socket) | |
{ | |
printf("Listing files on server's File Archive\n"); | |
printf("======================================\n"); | |
const char delimiter[] = "*"; | |
size_t size; | |
readn(socket, (unsigned char *) &size, sizeof(size_t)); | |
char data[size]; | |
readn(socket, (unsigned char *) &data, size); | |
if (strcmp(data, "-1") == 0) { | |
printf("Cannot serve files"); | |
} else { | |
char *response = strtok(data, delimiter); | |
while (response != NULL) { | |
printf("Filename: %s\n", response); | |
response = strtok(NULL, delimiter); | |
} | |
} | |
} | |
void optionfive(int socket) | |
{ | |
printf("Getting File to Download\n"); | |
printf("=======================\n"); | |
char name[INPUTSIZE]; | |
char path[] = "./download/"; | |
printf("Filename: "); | |
fgets(name, INPUTSIZE, stdin); | |
name[strcspn(name, "\n")] = 0; | |
size_t size = strlen(name) + 1; | |
writen(socket, (unsigned char *) &size, sizeof(size_t)); | |
writen(socket, (unsigned char *) name, size); | |
size_t datasize; | |
readn(socket, (unsigned char *) &datasize, sizeof(size_t)); | |
char response[datasize]; | |
readn(socket, (unsigned char *) response, datasize); | |
if (strcmp(response, "-1") != 0) { | |
FILE *fp; | |
char *full_path; | |
full_path = malloc(strlen(name) + strlen(path) + 1); | |
strcat(full_path, path); | |
strcat(full_path, name); | |
fp = fopen(full_path, "w"); | |
if (fp == NULL) { | |
printf("Error creating file!\n"); | |
} else { | |
printf("\nDownloading File into your download folder...\n"); | |
printf("=======================\n"); | |
printf("Filename: %s\nContent: %s", name, response); | |
fprintf(fp, "%s", response); | |
fclose(fp); | |
} | |
} else { | |
printf("Filename: %s\nError retrieving file!\n", name); | |
} | |
} | |
void displaymenu() | |
{ | |
printf("0. Display menu\n"); | |
printf("1. Student ID\n"); | |
printf("2. Five random numbers\n"); | |
printf("3. Server Information\n"); | |
printf("4. List of all Files\n"); | |
printf("5. Download File\n"); | |
printf("6. Exit Program\n"); | |
} | |
void send_option(int socket, char option) | |
{ | |
size_t size = sizeof(option); | |
writen(socket, (unsigned char *) &size, sizeof(size_t)); | |
writen(socket, (unsigned char *) &option, size); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <arpa/inet.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <errno.h> | |
#include <string.h> | |
#include <sys/types.h> | |
#include <pthread.h> | |
#include <sys/utsname.h> | |
#include <dirent.h> | |
#include <sys/stat.h> | |
#include <unistd.h> | |
#include <signal.h> | |
#include <sys/time.h> | |
#include "rdwrn.h" | |
#define INPUTSIZE 10 | |
struct timeval START_TIME; | |
struct timeval END_TIME; | |
#define CHOICESIZE 10; | |
void optionone(int); | |
void optiontwo(int); | |
void optionthree(int); | |
void optionfour(int); | |
void optionfive(int); | |
void *client_handler(void *); | |
char read_option(int); | |
void sigaction_handler(); | |
int main(void) | |
{ | |
sigaction_handler(); | |
int listenfd = 0, connfd = 0; | |
struct sockaddr_in serv_addr; | |
struct sockaddr_in client_addr; | |
socklen_t socksize = sizeof(struct sockaddr_in); | |
listenfd = socket(AF_INET, SOCK_STREAM, 0); | |
memset(&serv_addr, '0', sizeof(serv_addr)); | |
serv_addr.sin_family = AF_INET; | |
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); | |
serv_addr.sin_port = htons(50031); | |
bind(listenfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); | |
if (listen(listenfd, 10) == -1) { | |
perror("Failed to listen"); | |
exit(EXIT_FAILURE); | |
} | |
puts("Waiting for incoming connections..."); | |
while (1) { | |
printf("Waiting for a client to connect...\n"); | |
connfd = | |
accept(listenfd, (struct sockaddr *) &client_addr, &socksize); | |
printf("Connection accepted...\n"); | |
pthread_t sniffer_thread; | |
if (pthread_create | |
(&sniffer_thread, NULL, client_handler, | |
(void *) &connfd) < 0) { | |
perror("could not create thread"); | |
exit(EXIT_FAILURE); | |
} | |
pthread_join(sniffer_thread, NULL); | |
printf("Handler assigned\n"); | |
} | |
exit(EXIT_SUCCESS); | |
} | |
void *client_handler(void *socket_desc) | |
{ | |
//Get the socket descriptor | |
int connfd = *(int *) socket_desc; | |
char input; | |
do { | |
input = read_option(connfd); | |
printf("LOG INFO: Client option received :: %c\n", input); | |
switch (input) { | |
case '1': | |
optionone(connfd); | |
break; | |
case '2': | |
optiontwo(connfd); | |
break; | |
case '3': | |
optionthree(connfd); | |
break; | |
case '4': | |
optionfour(connfd); | |
break; | |
case '5': | |
optionfive(connfd); | |
break; | |
case '6': | |
printf("Server shutting down\n"); | |
exit(EXIT_SUCCESS); | |
break; | |
default: | |
printf("Server is unable to respond to this request\n"); | |
break; | |
} | |
} while (input != '6'); | |
shutdown(connfd, SHUT_RDWR); | |
close(connfd); | |
printf("Thread %lu exiting\n", (unsigned long) pthread_self()); | |
// always clean up sockets gracefully | |
shutdown(connfd, SHUT_RDWR); | |
close(connfd); | |
return 0; | |
} // end client_handler() | |
void optionone(int socket) | |
{ | |
printf("LOG INFO: Sending Student Details ..."); | |
char student_details_string[] = "Ebenezer Graham - S1725987"; | |
struct sockaddr_in address; | |
socklen_t len = sizeof(struct sockaddr_in); | |
getsockname(socket, (struct sockaddr *) &address, &len); | |
char *hostip = inet_ntoa(address.sin_addr); | |
char payload[200]; | |
strcat(payload, hostip); | |
strcat(payload, " - "); | |
strcat(payload, student_details_string); | |
strcat(payload, "\0"); | |
size_t n = strlen(payload) + 1; | |
writen(socket, (unsigned char *) &n, sizeof(size_t)); | |
writen(socket, (unsigned char *) payload, n); | |
} | |
void optiontwo(int socket) | |
{ | |
printf("LOG INFO: Sending 5 Random numbers"); | |
char result[50]; | |
time_t t; | |
int index; | |
int len = 5; | |
strcpy(result, " "); | |
srand((unsigned) time(&t)); | |
for (index = 0; index < len; index++) { | |
char x[10]; | |
int value = rand() % 1000; | |
sprintf(x, "%d", value); | |
strcat(result, x); | |
strcat(result, " "); | |
} | |
strcat(result, "\0"); | |
size_t size = strlen(result) + 1; | |
writen(socket, (unsigned char *) &size, sizeof(size_t)); | |
writen(socket, (unsigned char *) result, size); | |
} | |
void optionthree(int socket) | |
{ | |
printf("LOG INFO: Sending uname data\n"); | |
struct utsname uts; | |
uname(&uts); | |
if (uname(&uts) == -1) { | |
perror("uname error"); | |
exit(EXIT_FAILURE); | |
} | |
size_t payload_length = sizeof(uts); | |
writen(socket, (unsigned char *) &payload_length, sizeof(size_t)); | |
writen(socket, (unsigned char *) &uts, payload_length); | |
} | |
void optionfour(int socket) | |
{ | |
printf("LOG INFO: Sending concatenated filenames\n"); | |
struct dirent **files; | |
struct stat file_stat; | |
char *pathname; | |
pathname = "./upload"; | |
int n; | |
if (stat(pathname, &file_stat) == 0) { | |
if ((n = scandir(pathname, &files, NULL, alphasort)) == -1) { | |
perror("scandir"); | |
} else { | |
char files_string[sizeof(files)]; | |
strcpy(files_string, " "); | |
while (n--) { | |
if (files[n]->d_type == DT_REG) { | |
strcat(files_string, files[n]->d_name); | |
strcat(files_string, "*"); | |
} | |
strcat(files_string, "\0"); | |
free(files[n]); | |
} | |
free(files); | |
size_t x = strlen(files_string) + 1; | |
writen(socket, (unsigned char *) &x, sizeof(size_t)); | |
writen(socket, (unsigned char *) files_string, x); | |
} | |
} else { | |
char error[] = "No file available for display"; | |
size_t esize = sizeof(error); | |
writen(socket, (unsigned char *) &esize, sizeof(size_t)); | |
writen(socket, (unsigned char *) error, esize); | |
} | |
} | |
void optionfive(int socket) | |
{ | |
size_t size; | |
char path[] = "./upload/"; | |
long offset; | |
FILE *fp; | |
char *buffer; | |
char *full_path; | |
readn(socket, (unsigned char *) &size, sizeof(size_t)); | |
char filename[size]; | |
readn(socket, (unsigned char *) &filename, size); | |
full_path = malloc(strlen(filename) + strlen(path) + 1); | |
strcat(full_path, path); | |
strcat(full_path, filename); | |
fp = fopen(full_path, "r"); | |
if (fp == NULL) { | |
buffer = "-1"; | |
size_t n = strlen(buffer) + 1; | |
writen(socket, (unsigned char *) &n, sizeof(size_t)); | |
writen(socket, (unsigned char *) buffer, n); | |
} else { | |
fseek(fp, 0L, SEEK_END); | |
offset = ftell(fp); | |
fseek(fp, 0L, SEEK_SET); | |
buffer = (char *) calloc(offset, sizeof(char)); | |
fread(buffer, sizeof(char), offset, fp); | |
fclose(fp); | |
size_t n = strlen(buffer) + 1; | |
writen(socket, (unsigned char *) &n, sizeof(size_t)); | |
writen(socket, (unsigned char *) buffer, n); | |
free(buffer); | |
} | |
} | |
char read_option(int socket) | |
{ | |
size_t size; | |
char payload; | |
readn(socket, (unsigned char *) &size, sizeof(size_t)); | |
readn(socket, (unsigned char *) &payload, size); | |
printf("Choice: %c\n", payload); | |
printf("Received: %zu bytes\n\n", size); | |
return payload; | |
} | |
static void errorhandler(int sig, siginfo_t * siginfo, void *context) | |
{ | |
gettimeofday(&END_TIME, NULL); | |
long seconds = (END_TIME.tv_sec - START_TIME.tv_sec); | |
printf("Goodbye\n"); | |
printf("Total Execution time: %ld seconds\n", seconds); | |
exit(EXIT_SUCCESS); | |
} | |
void sigaction_handler() | |
{ | |
gettimeofday(&START_TIME, NULL); | |
struct sigaction act; | |
memset(&act, '\0', sizeof(act)); | |
act.sa_sigaction = &errorhandler; | |
act.sa_flags = SA_SIGINFO; | |
if (sigaction(SIGINT, &act, NULL) == -1) { | |
perror("sigaction"); | |
exit(EXIT_FAILURE); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment