-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.c
More file actions
141 lines (103 loc) · 3.64 KB
/
server.c
File metadata and controls
141 lines (103 loc) · 3.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
//socket stuff
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
//signal stuff
#include <signal.h>
//reap children
#include <sys/wait.h>
#include "utils.h"
#include "file_transfer.h"
#include "networking.h"
#define SERVER_DATA "./server_data"
void sighandler(int signo){
switch(signo){
case SIGCHLD:
{
//reap all available children but don't block
while(waitpid(-1,NULL,WNOHANG) > 0);
}
}
}
int server_action(int new_socket){
// what the server should do
//generic for forking server (thats why this is set up this way)
//read instruction struct
struct ft_init init;
read(new_socket, &init, sizeof(struct ft_init));
//get a path var ready if needed
char path[ (strlen(SERVER_DATA) + strlen(init.user.name) + strlen(init.repo_name)) * sizeof(char) ];
int success;
//based on the init connection mode
switch (init.mode){
case TR_AINIT:
//create a user
printf("RECIVED MAKE USER ORDER\n------------------------------------\n\n");
sprintf(path, "%s/%s", SERVER_DATA, init.user.name);
mkdir(path, 0744);
// user can be created on download or push so see if there is more
server_action(new_socket);
return 0;
case TR_TRSMT:
printf("RECIVED TRANSMIT ORDER\n------------------------------------\n\n");
// get_repo_path(SERVER_DATA, &init, path);
sprintf(path, "%s/%s/%s/", SERVER_DATA, init.user.name, init.repo_name);
int r = chdir(path);
v_err(r, __FILE__ " : " " chdir err", 1);
printf("serving download from %s\n", path);
success = send_full_directory_contents(new_socket, ".dit");
break;
case TR_RECV:
printf("RECIEVED RECIEVE REQUEST\n------------------------------------\n\n");
// assemble path to recieve to
sprintf(path, "%s/%s/%s/", SERVER_DATA, init.user.name, init.repo_name);
printf("recieving push to %s\n", path);
// recieve the push
success = recv_full_directory_contents(new_socket, path);
break;
case TR_RINIT:
printf("RECIEVED REPO INIT REQUEST\n------------------------------------\n\n");
sprintf(path, "%s/%s/%s/", SERVER_DATA, init.user.name, init.repo_name);
int r_mkdir = mkdir(path, 0744);
success = r_mkdir;
v_err(r_mkdir, __FILE__ " : " " error initing repo, mkdir", 0);
}
// send back success value
int send = TR_FAIL;
if(success != -1){
printf("setting send to TR_SUCCESS\n");
send = TR_SUCCESS;
}
write(new_socket, &send, sizeof(int));
printf("%s\n", send == TR_SUCCESS ? "CONNECTION WAS A SUCCESS" : "CONNECTION WAS A FAILURE");
}
int main(int argc, char const* argv[]){
signal(SIGCHLD, sighandler); //set SIGCHILD to reaper...
//if the server data dir is not already created, make it
mkdir(SERVER_DATA,0744);
//set up server listening ...
int server_fd = setup_server();
//server loop
while(1){
//main server loop
printf("establishing connection to client...\n");
int new_socket = accept(server_fd, NULL,NULL); //block until a client tries to connect
printf("client connected. forking...\n");
if(fork()==0){//if fork is child
// do what the server should do
server_action(new_socket);
//clean up
close(new_socket);
printf("closing connection to client...\n");
exit(0);
}
//if we are not the subserver, close the socket to the client
close(new_socket);
}
return 0;
}