Repository navigation
Expand file tree
/
Copy pathserver_ftp.c
More file actions
135 lines (116 loc) · 3.75 KB
/
Copy pathserver_ftp.c
File metadata and controls
135 lines (116 loc) · 3.75 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
/*
* Function: ftp server
*
* Author : Daniel Lai
* Created On: 2014-02-21
*/
#include <server_ftp.h>
size_t size_sockaddr = sizeof(struct sockaddr),
size_packet = sizeof(struct packet);
void* serve_client(void*);
int main(void)
{
// initialization starts
struct sockaddr_in skin_server, skin_client;
int sfd_server, sfd_client, x;
short int connection_id = 0;
if(( x = sfd_server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) <0 )
er("socket()", x);
memset((char*) &skin_server, 0, sizeof(struct sockaddr_in));
skin_server.sin_family = AF_INET;
skin_server.sin_port = htons(PORTSERVER);
skin_server.sin_addr.s_addr = htonl(INADDR_ANY);
if(( x = bind(sfd_server, (struct sockaddr*) &skin_server, size_sockaddr)) < 0)
er("bind()", x);
if(( x = listen(sfd_server, 1)) < 0)
er("listen()", x);
printf(ID "FTP Server started up @ local: %d. Waiting for clients...\n\n", PORTSERVER);
// initialization ends
while(1)
{
// begin connetction with client
if((x = sfd_client = accept(sfd_server, (struct sockaddr*) &skin_client, &size_sockaddr)) < 0)
er("accept()", x);
printf(ID "Communication started with %s:%d\n", inet_ntoa(skin_client.sin_addr), ntohs(skin_client.sin_port));
fflush(stdout);
struct client_info* ci = client_info_alloc(sfd_client, connection_id++);
pid_t fpid = fork();
if( fpid == 0 )
{
// handle the request from client
serve_client(ci);
}
else if(fpid < 0)
{
printf("server fork error!");
return -1;
}
}
close(sfd_server);
print(ID "Done.\n");
return 0;
}
void* serve_client(void* info)
{
int sfd_client, connection_id, x;
struct packet* data = (struct packet*) malloc(size_packet);
struct packet* shp;
char lpwd[LENBUFFER];
struct client_info* ci = (struct client_info*) info;
sfd_client = ci->sfd;
connection_id = ci->cid;
while(1)
{
if((x = recv(sfd_client, data, size_packet, 0)) == 0)
{
fprintf(stderr, "client closed or terminated. Closing connection...\n");
break;
}
shp = ntohp(data);
printpacket(shp, HP);
if(shp->type == TERM)
break;
if(shp->conid == -1)
shp->conid = connection_id;
if(shp->type == REQU)
{
switch(shp->comid)
{
// choose the operation of commands according to the comid
case GET:
if(!getcwd(lpwd, sizeof lpwd))
er("getcwd()", 0);
command_get(shp, data, sfd_client, lpwd);
break;
case DIR_:
if(!getcwd(lpwd, sizeof lpwd))
er("getcwd()", 0);
command_dir(shp, data, sfd_client, lpwd);
break;
case PRT:
if(!getcwd(lpwd, sizeof lpwd))
er("getcwd()", 0);
command_prt(shp, data, sfd_client, lpwd);
break;
case BYE:
if(!getcwd(lpwd, sizeof lpwd))
er("getcwd()", 0);
command_bye(shp, data, sfd_client, lpwd);
goto bye_end;
default:
// print error
break;
}
}
else
{
//show error, send TERM and break
fprintf(stderr, "packet incomprihensible. closing connection.\n");
send_TERM(shp, data, sfd_client);
break;
}
}
close(sfd_client);
bye_end:
fflush(stdout);
}