-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.c
159 lines (144 loc) · 5.25 KB
/
server.c
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
* File: server.c
* Author: erico
*
* Created on March 27, 2013, 11:54 AM
*
* Purpose : tcp echo server
*/
#include"header.h"
#include<netdb.h> //gethostbyname
int sock_fd = -1, conn_fd = -1;
/**
* Find a file in server filesystem
* @param filename Filename/filepath to search for
* @param buf Buffer to put response
*/
void find(const char*filename, char*buf);
/**
* Get filetype from a stat struct
* @param s Stat struct
* @return filetype
*/
char*fileType(const struct stat*s);
/**
* Write data to file...overwrites same filenames
* @param data Data to write
* @param filename Filename
* @param buf Buffer to place response
*/
void saveFile(const char*data, const char*filename, char*buf);
int main(int argc, char** argv) {
struct sockaddr_in srv_socket, client_socket;
signal(SIGINT, cleanup);
if ((sock_fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
perror("socket creation error");
return EXIT_FAILURE;
}
srv_socket.sin_family = AF_INET;
srv_socket.sin_port = htons(PORT);
srv_socket.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sock_fd, (struct sockaddr *) &srv_socket, sizeof (srv_socket)) < 0) {
perror("binding error");
return EXIT_FAILURE;
}
while (TRUE) {
listen(sock_fd, CONN_MAX);
char msg[BUF_MAX];
socklen_t*size = malloc(sizeof (socklen_t));
*size = sizeof (client_socket);
if ((conn_fd = accept(sock_fd, (struct sockaddr*) &client_socket, size)) < 0) {
perror("accept error");
return EXIT_FAILURE;
}
free(size); //free mem
fprintf(stdout, "Accepted %s...\n", inet_ntoa(client_socket.sin_addr));
while (TRUE) {
if (recv(conn_fd, msg, BUF_MAX - 1, 0) > 0) {
fprintf(stdout, "\nReceiving transmission from %s...\n", inet_ntoa(client_socket.sin_addr));
char ans[BUF_MAX];
char*msg_ptr = msg;
if (msg[0] == CHECK_FIND) {
find(++msg_ptr, ans);
} else if (msg[0] == SAVE_FILE) {
char*last_sep = strchr(++msg_ptr, '\n');
if (last_sep != NULL) {
char filename[MAX_FILNAME_SIZE];
strncpy(filename, msg_ptr, last_sep - msg_ptr);
saveFile(++last_sep, filename, ans);
} else {
strcpy(ans, "filename not specified");
}
} else {
strcpy(ans, "action not specified");
printf(ans);
}
fprintf(stdout, "Sending transmission to %s...\n", inet_ntoa(client_socket.sin_addr));
send(conn_fd, ans, strlen(ans), 0);
memset(ans, '\0', sizeof (ans));
memset(msg, '\0', sizeof (msg));
sleep(1);
break;
}
}
fprintf(stdout, "Shutting down connection : %s\n", ((shutdown(conn_fd, SHUT_RDWR) != -1) ? "OK" : "FAIL"));
}
return EXIT_SUCCESS;
}
void cleanup(int sig) {
printf("\n^C caught. Cleaning up...\n");
if (conn_fd > 0)close(conn_fd);
if (sock_fd > 0)close(sock_fd);
exit(EXIT_SUCCESS);
}
void saveFile(const char*data, const char*filename, char*buf) {
printf("writing to file %s\n", filename);
chdir(ROOT_FOLDER);
FILE*fd = fopen(filename, "wb");
fputs(data, fd);
fclose(fd);
chdir(UP_FOLDER);
strcpy(buf, "written to ");
strcat(buf, filename);
}
void find(const char*filename, char*buf) {
printf("Finding file : %s\n", filename);
struct stat *result = malloc(sizeof (struct stat));
if (filename == NULL) {
strcpy(buf, "filename not given\0");
return;
}
chdir(ROOT_FOLDER);
int status = stat(filename, result);
if (status == -1) {
fprintf(stdout, "File %s not found\n", filename);
strcpy(buf, FILE_NOT_FOUND);
return;
}
fprintf(stdout, "File %s found\n", filename);
char created[20], last_modified[20];
snprintf(created, sizeof (created) - 1, "%i", (int) result->st_ctim.tv_sec);
snprintf(last_modified, sizeof (created) - 1, "%i", (int) result->st_mtim.tv_sec);
memset(buf, '\0', BUF_MAX);
snprintf(buf, BUF_MAX - 1, "filepath: /%s\nsize : %i bytes\ncreated : %s\nlast modified : %s\ntype : %s\n",
filename, (int) result->st_size, created, last_modified, fileType(result));
strcat(buf, "File Permissions: ");
strcat(buf, (S_ISDIR(result->st_mode)) ? "d" : "-");
strcat(buf, (result->st_mode & S_IRUSR) ? "r" : "-");
strcat(buf, (result->st_mode & S_IWUSR) ? "w" : "-");
strcat(buf, (result->st_mode & S_IXUSR) ? "x" : "-");
strcat(buf, (result->st_mode & S_IRGRP) ? "r" : "-");
strcat(buf, (result->st_mode & S_IWGRP) ? "w" : "-");
strcat(buf, (result->st_mode & S_IXGRP) ? "x" : "-");
strcat(buf, (result->st_mode & S_IROTH) ? "r" : "-");
strcat(buf, (result->st_mode & S_IWOTH) ? "w" : "-");
strcat(buf, (result->st_mode & S_IXOTH) ? "x" : "-");
strcat(buf, "\n");
printf(buf);
chdir(UP_FOLDER);
free(result);
}
char*fileType(const struct stat*s) {
return S_ISDIR(s->st_mode) ? "folder" :
S_ISREG(s->st_mode) ? "regular file" : "file";
}