aboutsummaryrefslogtreecommitdiff
path: root/src/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/server.c')
-rw-r--r--src/server.c279
1 files changed, 0 insertions, 279 deletions
diff --git a/src/server.c b/src/server.c
deleted file mode 100644
index d028330b..00000000
--- a/src/server.c
+++ /dev/null
@@ -1,279 +0,0 @@
1/* Copyrights 2002 Luis Figueiredo (stdio@netc.pt) All rights reserved.
2 *
3 * See the LICENSE file
4 *
5 * The origin of this software must not be misrepresented, either by
6 * explicit claim or by omission. Since few users ever read sources,
7 * credits must appear in the documentation.
8 *
9 * date: Sat Mar 30 14:44:42 GMT 2002
10 *
11 * -- core server functions
12 *
13 */
14
15#include "webserver_gnunet.h"
16#include <stdio.h>
17#include <signal.h>
18#include <time.h>
19
20#include "memory.h"
21#include "client.h"
22#include "socket.h"
23
24#ifdef WIN32
25#define SHUT_RDWR SD_BOTH
26#endif
27
28struct web_server {
29 int socket;
30 unsigned int port;
31 struct gethandler * gethandler;
32 struct web_client *client;
33};
34
35
36/*
37 * initializate (allocate) handler list
38 */
39struct gethandler *__ILWS_init_handler_list() {
40 struct gethandler *ret;
41
42 ret = __ILWS_malloc(sizeof(struct gethandler));
43 if (ret==NULL)
44 return NULL;
45 ret->next = NULL;
46 ret->func = NULL;
47 ret->ctx = NULL;
48 ret->str = NULL;
49 return ret;
50}
51
52/*
53 * add an handler to list
54 */
55static int __ILWS_add_handler(struct gethandler * head,
56 const char * mstr,
57 void (*func)(),
58 void * ctx) {
59 struct gethandler * temp = head;
60 while (temp->next != NULL)
61 temp = temp->next;
62
63 temp->next = __ILWS_malloc(sizeof(struct gethandler));
64 if (temp->next==NULL)
65 return 0;
66 temp = temp->next;
67 temp->str=__ILWS_malloc(strlen(mstr)+1);
68 if (temp->str==NULL) {
69 __ILWS_free(temp);
70 return 0;
71 };
72 memcpy(temp->str,
73 mstr,
74 strlen(mstr) + 1);
75 temp->func = func;
76 temp->ctx = ctx;
77 temp->next = NULL;
78 return 1;
79}
80
81/*
82 * Deletes the entire handler list including the head
83 */
84static void __ILWS_delete_handler_list(struct gethandler * handler) {
85 struct gethandler * next;
86
87 while (handler) {
88 next = handler->next;
89 if (handler->str != NULL)
90 __ILWS_free(handler->str);
91 __ILWS_free(handler);
92 handler = next;
93 }
94}
95
96/*
97 * to add a listen socket
98 */
99static int __ILWS_listensocket(short port,
100 int saddr) {
101 struct sockaddr_in sa;
102 int ret;
103 int sockopt=1;
104
105 sa.sin_addr.s_addr=saddr;
106 sa.sin_port=htons((short)port);
107 sa.sin_family=AF_INET;
108 ret=socket(AF_INET,SOCK_STREAM,6); // tcp
109 if(ret==-1)
110 return -1;
111
112 setsockopt(ret,
113 SOL_SOCKET,
114 SO_REUSEADDR,
115 (char *)&sockopt,
116 sizeof(sockopt));
117
118 if (bind(ret,
119 (struct sockaddr *)&sa,
120 sizeof(sa))==-1) {
121 close(ret);
122 return -1;
123 }
124
125 if (listen(ret,512)==-1) { // 512 backlog
126 close(ret);
127 return -1;
128 }
129 return ret;
130}
131
132
133/*
134 * Add an handler to request data
135 */
136int web_server_addhandler(struct web_server *server,
137 const char *mstr,
138 void (*func)(),
139 void * hctx) {
140 return __ILWS_add_handler(server->gethandler,
141 mstr,
142 func,
143 hctx);
144}
145
146/*
147 * This function initialize one web_server handler
148 */
149int web_server_init(struct web_server *server,
150 int port,
151 int flags) {
152#ifdef WIN32
153 unsigned long t=IOC_INOUT;
154 WSADATA WSAinfo;
155 WSAStartup(2,&WSAinfo); // Damn w32 sockets
156#endif
157 server->port=port;
158 // Create a listen socket port 'port' and listen addr (0) (all interfaces)
159 server->socket=__ILWS_listensocket((short)server->port,0);
160 if (server->socket==-1) {
161#ifdef WIN32
162 WSACleanup();
163#endif
164 return 0;
165 };
166#ifdef WIN32
167 ioctlsocket(server->socket,
168 FIONBIO,
169 &t); //non blocking sockets for win32
170#else
171 fcntl(server->socket,
172 F_SETFL,
173 O_NONBLOCK);
174#endif
175
176 // Setup Flags
177 server->client = __ILWS_init_client_list();
178 server->gethandler = __ILWS_init_handler_list();
179
180#ifndef WIN32
181 signal(SIGPIPE, SIG_IGN);
182#endif
183 return 1;
184}
185
186/*
187 * This function shuts down a running web server, frees its allocated memory,
188 * and closes its socket. If called on a struct web_server that has already
189 * been shut down, this is a noop.
190 */
191void web_server_shutdown(struct web_server * server) {
192 // free and close things in opposite order of web_server_init
193 __ILWS_delete_handler_list(server->gethandler);
194 server->gethandler = NULL;
195 __ILWS_delete_client_list(server->client);
196 server->client = NULL;
197 if(server->socket > 0) {
198#ifdef WIN32
199 closesocket(server->socket);
200#else
201 close(server->socket);
202#endif
203 server->socket = -1;
204 }
205#ifdef WIN32
206 WSACleanup();
207#endif
208}
209
210/*
211 * Core function, return 2 if no client to process, 1 if some client processed, 0 if error
212 */
213int web_server_run(struct web_server *server) {
214 struct web_client * client;
215 struct web_client * pos;
216 int rt;
217 size_t tsalen=0;
218 int tsocket=0;
219 int cond;
220 struct sockaddr_in tsa;
221
222 tsalen = sizeof(client->sa);
223 tsocket = accept(server->socket,
224 (struct sockaddr *)&tsa,
225 &tsalen);
226 if (tsocket == -1) {
227#ifdef WIN32
228 cond = WSAGetLastError() != WSAEWOULDBLOCK;
229#else
230 cond = errno!=EAGAIN;
231#endif
232 if (cond) {
233 // client fucked up? warn somebody? (error or log or something?)
234 return 0;
235 }
236 } else {
237 client = __ILWS_malloc(sizeof(struct web_client));
238 if (client == NULL) {
239 rt = shutdown(tsocket,
240 SHUT_RDWR);
241#ifdef WIN32
242 rt=closesocket(tsocket);
243#else
244 rt=close(tsocket);
245#endif
246 return 0;
247 };
248 client->salen=tsalen;
249 client->socket=tsocket;
250 client->sa=tsa;
251 if(!__ILWS_add_client(server->client,client))
252 return 0;
253 };
254 // end search for client
255 client = server->client; // init list
256 if(!client->next) { // think of Rocco Carbone (rocco@tecsiel.it)
257 return 2; // i don't need to process the list (nothing next) returns 2 if there is no client to process
258 }
259 while (client->next != NULL) { // Process the client and swap to next;
260 pos = client->next;
261 switch (pos->stat) {
262 case 1:
263 __ILWS_read_client(pos);
264 break;
265 case 2:
266 __ILWS_process_client(pos, server->gethandler);
267 break;
268 case 4:
269 __ILWS_output_client(pos);
270 break;
271 case 5:
272 __ILWS_delete_next_client(client);
273 continue;
274 }
275 client=client->next;
276 }
277 return 1; // return 1 if something processed
278}
279