serverRun.c
4.31 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
#include <sys/select.h> /* for select system call and related */
#include <string.h> /* for memset and stuff */
#include <stdlib.h> /* for exit */
#include <errno.h> /* for errno */
#include "include/server.h"
#include "include/socket.h"
#include "include/monitor.h"
#include "include/signalHandling.h"
#undef MAX
#define MAX(x,y) ((x) > (y) ? (x) : (y))
void
serverRun(tVirtualItemServer * server)
{
syslogMonitor(LOG_INFO, MON_INFO, "startup", "service started");
while (!doShutdown) /* until error or signal */
{
fd_set rfds;
int i;
memcpy(&rfds, &(server->socks), sizeof(fd_set));
/*
* wait for handles to become ready
*/
if (-1 == select((server->maxFd)+1, &rfds, NULL, NULL, NULL))
{
switch (errno) {
default:
case EBADF:
case EINVAL:
case ENOMEM:
doShutdown = 1;
/* Fallthrough */
case EINTR:
syslogMonitor(LOG_ERR, MON_CRITICAL, "select",
"select systemcall failed: [%s]",
strerror(errno));
syslogMonitor(LOG_ERR, MON_FAILURE, "select",
"select systemcall failed: [%s] - service terminated",
strerror(errno));
continue; /* in while loop above */
}
}
/*
* update file to actual time
*/
logRotate(server);
if (NULL == server->wHandle) {
syslogMonitor(LOG_ERR, MON_CRITICAL, "logfile.rotate",
"no valid handle for logfile - service terminated");
exit(EXIT_FAILURE);
}
/*
* handle accept
*/
if (FD_ISSET(server->servSock, &rfds)) {
int fd;
char remoteAddr[16] = "";
if (-1 != (fd = acceptConnection(server->servSock, remoteAddr))) {
(server->clients)[fd].socket = fd; // save the socket handle
// within the client struct
//
strncpy(
(server->clients)[fd].remoteAddr,
remoteAddr,
sizeof((server->clients)[fd].remoteAddr)-1);
FD_SET(fd, &(server->socks));
server->maxFd = MAX(fd, server->maxFd);
}
FD_CLR(server->servSock, &rfds);
}
/* handle reads */
for (i=3; i<=server->maxFd; i++) {
if (FD_ISSET(i, &rfds)) {
switch (clientRead(&((server->clients)[i]))) {
case 0:
/*
* normal close: write remaining data
*/
writeRemaining(
&((server->clients)[i]),
server->wHandle);
/* FALLTHROUGH */
case -1:
/*
* read failure / close connection
* FALLTHROUGH
*/
case READ_ERR_LONGLINE:
/*
* detected very long line read from client
* message is already given now terminate connection
* FALLTHROUG
*/
clientClose(&((server->clients)[i]));
FD_CLR(i, &(server->socks));
break;
default:
if (0 > writeBuffer(
&((server->clients)[i]),
server->wHandle))
{
/*
* got IO Error or binary data
* the message is already monitored in client code
*/
clientClose(&((server->clients)[i]));
FD_CLR(i, &(server->socks));
}
break;
}
}
}
}
}