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
|
#include "common.h"
#include "server.h"
#include "proc.h"
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/select.h>
#include <sys/time.h>
#include <unistd.h>
volatile sig_atomic_t proc_message_request;
volatile sig_atomic_t proc_quit_request;
static void proc_message_request_setter (int signo) {
proc_message_request = 1;
}
static void proc_quit_request_setter (int signo) {
proc_quit_request = 1;
}
static void message_cb (server* svr, request* req, int maxfd) {
putchar ('\n');
printf (
"Dump server information ...\n"
" Server hostname: %s\n"
" Server port: %hu\n"
" Server is listening on fd %d\n",
svr->hostname, svr->port, svr->listen_fd);
puts ("Dump request table ...");
for (int i = 0; i < maxfd; i++) {
if (req[i].active) {
printf (
" Client %d hostname: %s\n"
" Client %d filename: %s\n"
" Client %d filename done: %s\n"
" Client %d transfer started: %s\n",
i, req[i].host,
i, req[i].filename,
i, req[i].header_done ? "true" : "false",
i, req[i].header_accept ? "true" : "false");
}
}
puts ("Dump file table ...");
for (int i = 0; i < maxfd; i++) {
if (svr->file_table->flist[i].active) {
printf (
" Entry %d reference count: %d\n"
" Entry %d device: %llu\n"
" Entry %d inode: %llu\n"
" Entry %d file descriptors:",
i, svr->file_table->flist[i].ref_count,
i, (unsigned long long)svr->file_table->flist[i].fdev,
i, (unsigned long long)svr->file_table->flist[i].fino, i);
for (int j = 0; j < maxfd; j++) {
if (FD_ISSET (j, &svr->file_table->flist[i].fset))
printf (" %d", j);
}
putchar ('\n');
}
}
puts ("Type Ctrl-\\ to terminate the server\n");
proc_message_request = 0;
}
int main(int argc, char** argv) {
if (argc != 2) {
fprintf(stderr, "usage: %s [port]\n", argv[0]);
exit(1);
}
// Setup signal handlers
struct sigaction signal_action = {
.sa_handler = SIG_IGN,
.sa_flags = 0
};
sigemptyset (&signal_action.sa_mask);
sigaction (SIGPIPE, &signal_action, NULL);
signal_action.sa_handler = proc_message_request_setter;
sigaction (SIGINT, &signal_action, NULL);
signal_action.sa_handler = proc_quit_request_setter;
sigaction (SIGQUIT, &signal_action, NULL);
// Get file descripter table size
int maxfd = getdtablesize();
// Initialize server
server svr; // server
server_init(&svr, (unsigned short) atoi(argv[1]), maxfd);
// Initialize request table
request* requestP = NULL; // point to a list of requests
requestP = (request*) e_malloc(sizeof(request) * maxfd);
for (int i = 0; i < maxfd; i++)
request_init(&requestP[i]);
requestP[svr.listen_fd].conn_fd = svr.listen_fd;
strcpy(requestP[svr.listen_fd].host, svr.hostname);
// Loop for handling connections
printf("\nstarting on %.80s, port %d, fd %d, maxfd %d ...\n",
svr.hostname, svr.port, svr.listen_fd, maxfd);
while (procconn(&svr, requestP, maxfd,
(struct timeval) { 1, 0 }, message_cb));
printf("\nquitting...\n");
for (int i = 0; i < maxfd; i++) {
if (requestP[i].filename != NULL) {
free (requestP[i].filename);
requestP[i].filename = NULL;
}
}
free(requestP);
server_free(&svr);
return 0;
}
|