|
dvander@2444
|
1 |
#include <errno.h> |
|
pred@2129
|
2 |
#include "smud.h" |
|
pred@2129
|
3 |
#include "smud_threads.h" |
|
pred@2129
|
4 |
|
|
pred@2129
|
5 |
#define LISTEN_PORT 6500 |
|
pred@2129
|
6 |
#define LISTEN_QUEUE_LENGTH 6 |
|
pred@2129
|
7 |
|
|
pred@2129
|
8 |
char fileNames[NUM_FILES][30] = { |
|
pred@2129
|
9 |
"core.games.txt", |
|
pred@2129
|
10 |
"sdktools.games.txt", |
|
pred@2129
|
11 |
"sdktools.games.ep2.txt", |
|
pred@2462
|
12 |
"sdktools.games.l4d.txt", |
|
pred@2129
|
13 |
"sm-cstrike.games.txt", |
|
pred@2129
|
14 |
"sm-tf2.games.txt", |
|
pred@2129
|
15 |
}; |
|
pred@2129
|
16 |
|
|
pred@2129
|
17 |
void *fileLocations[NUM_FILES]; |
|
pred@2129
|
18 |
int fileLength[NUM_FILES]; |
|
pred@2129
|
19 |
|
|
pred@2129
|
20 |
int main(int argc, char **argv) |
|
pred@2129
|
21 |
{ |
|
pred@2129
|
22 |
ThreadPool *pool; |
|
pred@2129
|
23 |
struct protoent *pProtocol; |
|
pred@2129
|
24 |
struct sockaddr_in serverAddress; |
|
pred@2129
|
25 |
struct sockaddr_in clientAddress; |
|
pred@2129
|
26 |
int serverSocket; |
|
pred@2129
|
27 |
int clientSocket; |
|
pred@2129
|
28 |
int addressLen; |
|
pred@2129
|
29 |
int opts; |
|
pred@2129
|
30 |
int file; |
|
pred@2129
|
31 |
char filename[100]; |
|
pred@2129
|
32 |
struct stat sbuf; |
|
pred@2129
|
33 |
|
|
dvander@2444
|
34 |
#if defined DEBUG |
|
dvander@2444
|
35 |
fprintf(stdout, "Loading Gamedata files into memory\n"); |
|
dvander@2444
|
36 |
#endif |
|
pred@2129
|
37 |
|
|
pred@2129
|
38 |
for (int i=0; i<NUM_FILES; i++) |
|
pred@2129
|
39 |
{ |
|
pred@2129
|
40 |
snprintf(filename, sizeof(filename), "./md5/%s", fileNames[i]); |
|
pred@2129
|
41 |
file = open(filename, O_RDWR); |
|
pred@2129
|
42 |
|
|
pred@2129
|
43 |
if (!file) |
|
pred@2129
|
44 |
{ |
|
dvander@2444
|
45 |
fprintf(stderr, "Could not find file: %s", filename); |
|
pred@2129
|
46 |
return 1; |
|
pred@2129
|
47 |
} |
|
pred@2129
|
48 |
|
|
pred@2129
|
49 |
if (stat(filename, &sbuf) == -1) |
|
pred@2129
|
50 |
{ |
|
dvander@2444
|
51 |
fprintf(stderr, "Could not stat file: %s (error: %s)", filename, strerror(errno)); |
|
pred@2129
|
52 |
return 1; |
|
pred@2129
|
53 |
} |
|
pred@2129
|
54 |
|
|
dvander@2444
|
55 |
if ((fileLocations[i] = mmap(NULL, sbuf.st_size, PROT_READ, MAP_PRIVATE, file, 0)) == MAP_FAILED) |
|
pred@2129
|
56 |
{ |
|
dvander@2444
|
57 |
fprintf(stderr, "Could not mmap file: %s (error: %s)", filename, strerror(errno)); |
|
pred@2129
|
58 |
return 1; |
|
pred@2129
|
59 |
} |
|
pred@2129
|
60 |
|
|
pred@2129
|
61 |
fileLength[i] = sbuf.st_size; |
|
pred@2129
|
62 |
|
|
dvander@2444
|
63 |
#if defined DEBUG |
|
dvander@2444
|
64 |
fprintf(stdout, "Initialised file of %s of length %i\n", fileNames[i], fileLength[i]); |
|
dvander@2444
|
65 |
#endif |
|
pred@2129
|
66 |
} |
|
pred@2129
|
67 |
|
|
dvander@2444
|
68 |
#if defined DEBUG |
|
dvander@2444
|
69 |
fprintf(stdout, "Initializing Thread Pool\n"); |
|
dvander@2444
|
70 |
#endif |
|
pred@2129
|
71 |
|
|
pred@2129
|
72 |
pool = new ThreadPool(); |
|
pred@2129
|
73 |
|
|
pred@2129
|
74 |
if (!pool->Start()) |
|
pred@2129
|
75 |
{ |
|
dvander@2444
|
76 |
fprintf(stderr, "Could not initialize thread pool!\n"); |
|
pred@2129
|
77 |
return 1; |
|
pred@2129
|
78 |
} |
|
pred@2129
|
79 |
|
|
dvander@2444
|
80 |
#if defined DEBUG |
|
pred@2129
|
81 |
printf("Create Server Socket\n"); |
|
dvander@2444
|
82 |
#endif |
|
pred@2129
|
83 |
|
|
pred@2129
|
84 |
memset(&serverAddress, 0, sizeof(serverAddress)); |
|
pred@2129
|
85 |
serverAddress.sin_family = AF_INET; |
|
pred@2129
|
86 |
serverAddress.sin_addr.s_addr = INADDR_ANY; |
|
pred@2129
|
87 |
serverAddress.sin_port = htons(LISTEN_PORT); |
|
pred@2129
|
88 |
|
|
pred@2129
|
89 |
pProtocol = getprotobyname("tcp"); |
|
pred@2129
|
90 |
|
|
pred@2129
|
91 |
if (pProtocol == NULL) |
|
pred@2129
|
92 |
{ |
|
dvander@2444
|
93 |
fprintf(stderr, "Could not get tcp proto: %s", strerror(errno)); |
|
pred@2129
|
94 |
return 1; |
|
pred@2129
|
95 |
} |
|
pred@2129
|
96 |
|
|
pred@2129
|
97 |
serverSocket = socket(AF_INET, SOCK_STREAM, pProtocol->p_proto); |
|
pred@2129
|
98 |
|
|
pred@2129
|
99 |
if (serverSocket < 0) |
|
pred@2129
|
100 |
{ |
|
dvander@2444
|
101 |
fprintf(stderr, "Could not open socket: %s", strerror(errno)); |
|
pred@2129
|
102 |
return 1; |
|
pred@2129
|
103 |
} |
|
pred@2129
|
104 |
|
|
pred@2129
|
105 |
opts = 1; |
|
pred@2129
|
106 |
setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &opts, sizeof(opts)); |
|
pred@2129
|
107 |
|
|
pred@2129
|
108 |
if (bind(serverSocket, (struct sockaddr *)&serverAddress, sizeof(serverAddress)) < 0) |
|
pred@2129
|
109 |
{ |
|
dvander@2444
|
110 |
fprintf(stderr, "Could not bind socket: %s", strerror(errno)); |
|
pred@2129
|
111 |
return 1; |
|
pred@2129
|
112 |
} |
|
pred@2129
|
113 |
|
|
pred@2129
|
114 |
if (listen(serverSocket, LISTEN_QUEUE_LENGTH) < 0) |
|
pred@2129
|
115 |
{ |
|
dvander@2444
|
116 |
fprintf(stderr, "Could not listen on socket: %s", strerror(errno)); |
|
pred@2129
|
117 |
return 1; |
|
pred@2129
|
118 |
} |
|
pred@2129
|
119 |
|
|
dvander@2444
|
120 |
fprintf(stdout, "Server has started.\n"); |
|
pred@2129
|
121 |
|
|
pred@2129
|
122 |
while (1) |
|
pred@2129
|
123 |
{ |
|
pred@2129
|
124 |
addressLen = sizeof(clientAddress); |
|
pred@2129
|
125 |
|
|
dvander@2444
|
126 |
clientSocket = accept(serverSocket, |
|
dvander@2444
|
127 |
(struct sockaddr *)&clientAddress, |
|
dvander@2444
|
128 |
(socklen_t *)&addressLen); |
|
dvander@2444
|
129 |
if (clientSocket < 0) |
|
pred@2129
|
130 |
{ |
|
dvander@2444
|
131 |
fprintf(stderr, "Could not accept client: %s", strerror(errno)); |
|
pred@2129
|
132 |
continue; |
|
pred@2129
|
133 |
} |
|
pred@2129
|
134 |
|
|
pred@2129
|
135 |
opts = fcntl(clientSocket, F_GETFL, 0); |
|
pred@2129
|
136 |
if (fcntl(clientSocket, F_SETFL, opts|O_NONBLOCK) < 0) |
|
pred@2129
|
137 |
{ |
|
dvander@2444
|
138 |
fprintf(stderr, "Could not non-block client: %s", strerror(errno)); |
|
pred@2129
|
139 |
closesocket(clientSocket); |
|
pred@2129
|
140 |
continue; |
|
pred@2129
|
141 |
} |
|
pred@2129
|
142 |
|
|
dvander@2444
|
143 |
#if defined DEBUG |
|
dvander@2444
|
144 |
fprintf(stdout, |
|
dvander@2444
|
145 |
"Accepting connection from client (sock %d, ip %s)", |
|
dvander@2444
|
146 |
clientSocket, |
|
pred@2462
|
147 |
inet_ntoa(clientAddress.sin_addr)); |
|
dvander@2444
|
148 |
#endif |
|
pred@2129
|
149 |
|
|
pred@2129
|
150 |
pool->AddConnection(clientSocket); |
|
pred@2129
|
151 |
} |
|
pred@2129
|
152 |
|
|
pred@2129
|
153 |
delete pool; |
|
pred@2129
|
154 |
} |
|
pred@2129
|
155 |
|
|
pred@2129
|
156 |
|
|
pred@2129
|
157 |
|