aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am26
-rw-r--r--src/client.c1190
-rw-r--r--src/client.h159
-rw-r--r--src/clientinfo.c1124
-rw-r--r--src/clientinfo.h118
-rw-r--r--src/config.h133
-rw-r--r--src/debug.h29
-rw-r--r--src/error.c34
-rw-r--r--src/error.h33
-rw-r--r--src/fnmatch.c195
-rw-r--r--src/fnmatch.h59
-rw-r--r--src/gethandler.c96
-rw-r--r--src/gethandler.h60
-rw-r--r--src/logo.h396
-rw-r--r--src/memory.c155
-rw-r--r--src/memory.h46
-rw-r--r--src/module.c22
-rw-r--r--src/module.h25
-rw-r--r--src/outgif.c587
-rw-r--r--src/outgif.h63
-rw-r--r--src/outstream.c122
-rw-r--r--src/outstream.h53
-rw-r--r--src/server.c448
-rw-r--r--src/server.h86
-rw-r--r--src/socket.c74
-rw-r--r--src/socket.h51
-rw-r--r--src/utils.c155
-rw-r--r--src/utils.h59
-rw-r--r--src/web_server.h129
-rw-r--r--src/weblog.c43
-rw-r--r--src/weblog.h40
31 files changed, 5810 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 00000000..5670792b
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,26 @@
1SUBDIRS = .
2
3INCLUDES = -I$(top_srcdir)/src/include
4
5lib_LTLIBRARIES = libwebserver_gnunet.la
6
7AM_CFLAGS = \
8 -D_SERVER_VERSION="\"0.6.3-GNUnet\""
9
10libwebserver_gnunet_la_SOURCES = \
11 clientinfo.c \
12 server.c \
13 client.c \
14 gethandler.c \
15 socket.c \
16 memory.c \
17 outstream.c \
18 weblog.c \
19 utils.c \
20 fnmatch.c \
21 outgif.c \
22 error.c
23
24libwebserver_gnunet_la_LDFLAGS = \
25 -version-info 0:0:0
26
diff --git a/src/client.c b/src/client.c
new file mode 100644
index 00000000..25ad55b8
--- /dev/null
+++ b/src/client.c
@@ -0,0 +1,1190 @@
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 * -- client handler functions
12 *
13 */
14
15
16#include "client.h"
17
18
19extern char *_libwebserver_version; // Defined in server.c
20
21
22struct web_client *current_web_client;
23int WEBTIMEOUT=10000;
24
25/*********************************************************************************************************/
26/*
27 * initializate (allocate) client list
28 */
29struct web_client *__ILWS_init_client_list() {
30 struct web_client *ret;
31 ret=__ILWS_malloc(sizeof(struct web_client));
32 if(ret==NULL) {
33 LWSERR(LE_MEMORY);
34 return NULL;
35 };
36#ifdef HAVE_OPENSSL
37 ret->ssl=NULL; // ssl handler for this client
38#endif
39 ret->next=NULL;
40 return ret;
41}
42
43
44/*********************************************************************************************************/
45/*
46 * Add a client node to client list
47 */
48int __ILWS_add_client(struct web_client *list, struct web_client *node) {
49 struct web_client *temp=list;
50
51#ifdef WIN32
52 unsigned long t=IOC_INOUT;
53#endif
54 while(temp->next!=NULL)temp=temp->next; // run to last client
55 temp->next=node;
56 temp->next->rbuf=NULL;
57 temp->next->rbufsize=0;
58
59 if(!(temp->next->outstream=__ILWS_init_outstream_list())) {
60 return 0;
61 };
62 if(!(temp->next->varlist=__ILWS_init_var_list())) {
63 return 0;
64 };
65
66 temp->next->contentlength=0;
67 temp->next->headersize=0;
68
69 temp->next->wheadersize=0;
70 temp->next->writelength=0;
71 temp->next->readsize=0;
72 temp->next->range=0;
73 temp->next->skipped=0;
74 temp->next->cookies=NULL;
75 //temp->next->oldcl=clock();
76
77
78 temp->next->newdata_try=0;
79#ifdef WIN32
80 // should be optional
81 ioctlsocket(temp->next->socket,FIONBIO,&t); //non blocking sockets for win32
82#else
83 fcntl(temp->next->socket,F_SETFL,O_NONBLOCK);
84#endif
85 temp->next->next=NULL;
86 temp->next->HTTPdirective=NULL;
87 temp->next->stat=1; // Add a connected client
88
89 return 1;
90}
91/*********************************************************************************************************/
92
93
94
95/*********************************************************************************************************/
96/*
97 * Delete client node
98 */
99void __ILWS_delete_client(struct web_client *node) {
100 int rt;
101 rt=shutdown(node->socket,SHUT_RDWR);
102#ifdef WIN32
103 rt=closesocket(node->socket);
104#else
105 rt=close(node->socket);
106#endif
107 __ILWS_free(node->cookies); // (0.5.1)
108 __ILWS_delete_outstream_list(node->outstream);
109 __ILWS_delete_var_list(node->varlist);
110#ifdef HAVE_OPENSSL
111 SSL_free (node->ssl);
112#endif
113 __ILWS_free(node->rbuf); // free's
114 __ILWS_free(node); // free's
115
116}
117
118
119/*********************************************************************************************************/
120/*
121 * Delete next client node
122 */
123void __ILWS_delete_next_client(struct web_client *node) {
124 struct web_client *temp=node->next;
125 node->next=node->next->next;
126 __ILWS_delete_client(temp);
127}
128
129/*********************************************************************************************************/
130/*
131 * Delete entire client list
132 */
133void __ILWS_delete_client_list(struct web_client *node) {
134 struct web_client *next;
135
136 while(node) {
137 next = node->next;
138 __ILWS_free(node);
139 node = next;
140 }
141}
142
143/*********************************************************************************************************/
144/*
145 * Read what client have to say
146 */
147void __ILWS_read_client(struct web_client *node) {
148 int tmp,tmp1;
149 char *tmp2,*tmp3=NULL;
150 char readtemp[READMAX+1];
151 unsigned long datasize=0;
152
153#ifdef HAVE_OPENSSL
154 if(node->ssl!=NULL) {
155 tmp=SSL_read(node->ssl,readtemp,READMAX);
156 } else {
157 tmp=__ILWS_read(node->socket,readtemp,READMAX);
158 };
159#else
160 tmp=__ILWS_read(node->socket,readtemp,READMAX);
161#endif
162 //fprintf(stderr,"readed %d bytes\n",tmp);
163 if(tmp<1) {
164
165#ifdef WIN32
166 if(WSAGetLastError()!=WSAEWOULDBLOCK) {
167#else
168 if(errno!=EAGAIN) {
169#endif
170 node->stat=5;return;
171
172 };
173 //fprintf(stderr,"try: %d (%s)\n",node->newdata_try,node->rbuf);
174 // check if it is over
175 node->newdata_try++;
176 //fprintf(stderr,"node->newdata_try:%d\n",node->newdata_try);
177 if(node->rbufsize >0) { //&& node->newdata_try>5) {
178 if(node->headersize==0) { // always reachs "\r\n\r\n"
179 if((tmp3=strstr(node->rbuf,"\r\n\r\n"))) {
180 node->headersize=(tmp3-node->rbuf);
181 };
182 } else {
183 datasize=node->rbufsize-node->headersize;
184 if(node->contentlength==0) { // well if it 0 read all at once
185 __ILWS_init_clientinfo(); // always call this?
186 node->contentlength=atol(ClientInfo->Header("Content-Length"));
187 // range for resuming
188 if((tmp3=strstr(ClientInfo->Header("Range"),"bytes="))) { // if it is in bytes (i hope, always)
189 tmp3+=6; // go to end of "bytes="
190 node->range=atol(tmp3);
191 //printf("Range is %d - %s - %s\n",node->range,ClientInfo->Header("Range"),tmp3);
192 };
193 // end range
194 __ILWS_free_clientinfo();
195 };
196 if(node->contentlength==datasize-4) {
197 //fprintf(stderr,"client (%d) all readed (%d) (try's)-%d\n",node->socket,node->curcl-node->oldcl,node->newdata_try);
198 node->newdata_try=WEBTIMEOUT; // assume done reading
199 //fprintf(stderr,"Ended naturaly\n");
200
201 }
202 };
203 if((node->newdata_try>=WEBTIMEOUT)) { // All readed
204 node->rbuf[node->rbufsize]='\0';
205 node->stat=2; // Next state
206 //fprintf(stderr,"%s\n",node->rbuf);
207 //fprintf(stderr,"%d\n",node->rbufsize);
208 }
209 };
210 }else {
211 tmp1=node->rbufsize;
212 node->rbufsize+=tmp;
213 tmp2=__ILWS_realloc(node->rbuf,node->rbufsize+1);
214 if(tmp2==NULL) {
215 LWSERR(LE_MEMORY);
216 node->stat=5;
217
218 return;
219 }else {
220 node->rbuf=tmp2;
221 };
222 memcpy(node->rbuf+tmp1,readtemp,tmp);
223 node->newdata_try=0;
224 };
225}
226
227
228/*********************************************************************************************************/
229/*
230 * Process headers w/ get handlers
231 */
232void __ILWS_process_client(struct web_client *node,struct gethandler *list) {
233 struct gethandler *gettemp=list;
234 long secs=time(NULL);
235// for determining content length
236#define RTMPMAX 400
237 struct outstream *tmpstream; // new on 0.5.1
238 char rtmp[RTMPMAX+1];
239 int rtmps=0;
240 char *thead=NULL;
241 char *tmpl;
242///
243 int tmp=0;
244 int oumask=0; // old usermask
245 char *tmp1=__ILWS_web_client_getreq();
246 char matchbuf[MATCHMAX];
247 FILE *nfile; // new file
248 char *fname; // new file name
249
250
251 while(gettemp->next!=NULL && tmp==0) {
252 gettemp=gettemp->next;
253 snprintf(matchbuf,MATCHMAX,"%s",gettemp->str);
254 if(!tmp1) {
255 __ILWS_web_client_writef(node,"HTTP/1.1 400 Invalid request\r\n");
256 __ILWS_web_client_writef(node,"Server: %s\r\n",_libwebserver_version);
257 __ILWS_web_client_writef(node,"Date: %s\r\n",__ILWS_date(mktime(gmtime(&secs)),"%a, %d %b %Y %H:%M:%S GMT")); // Date header
258 __ILWS_web_client_writef(node,"Content-type: text/html\r\n\r\n<HTML><title>Invalid request</title><body bgcolor=FFFFFF><font size=6>400 Invalid request</font><BR><BR><small>Yout request doesn't match the requesits to be processed</small><BR><HR><small><i>%s</i></small></body></html>\n\r",_libwebserver_version);
259 tmpl=__ILWS_web_client_getreqline();
260 web_log("%s - - [%s] \"%s\" 400 (invalid request)\n",inet_ntoa(node->sa.sin_addr),__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),tmpl);
261 __ILWS_free(tmpl);
262 node->stat=5;
263 return;
264 };
265 if(strlen(tmp1)>MAXURLSIZE) {
266 __ILWS_web_client_writef(node,"HTTP/1.1 414 URL to large\r\n");
267 __ILWS_web_client_writef(node,"Server: %s\r\n",_libwebserver_version);
268 __ILWS_web_client_writef(node,"Date: %s\r\n",__ILWS_date(mktime(gmtime(&secs)),"%a, %d %b %Y %H:%M:%S GMT")); // Date header
269 __ILWS_web_client_writef(node,"Content-type: text/html\r\n\r\n<HTML><title>URL to large</title><body bgcolor=FFFFFF><font size=6>414 Requested url to large</font><BR><BR><small>Wonder this... why is that so large?</small><BR><HR><small><i>%s</i></small></body></html>\n\r",_libwebserver_version);
270 tmpl=__ILWS_web_client_getreqline();
271 web_log("%s - - [%s] \"%s\" 414 (url to large)\n",inet_ntoa(node->sa.sin_addr),__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),tmpl);
272 __ILWS_free(tmpl);
273 node->stat=5;
274 __ILWS_free(tmp1);
275 return;
276 };
277 if(!fnmatch(matchbuf,tmp1,5)) {
278 if((gettemp->flag & WS_LOCAL) == WS_LOCAL) {
279 if(node->sa.sin_addr.s_addr!=0x0100007F) {
280 __ILWS_web_client_writef(node,"HTTP/1.1 403 Forbidden\r\n");
281 __ILWS_web_client_writef(node,"Server: %s\r\n",_libwebserver_version);
282 __ILWS_web_client_writef(node,"Date: %s\r\n",__ILWS_date(mktime(gmtime(&secs)),"%a, %d %b %Y %H:%M:%S GMT")); // Date header
283 __ILWS_web_client_writef(node,"Content-type: text/html\r\n\r\n<HTML><title>Forbidden</title><body bgcolor=FFFFFF><font size=6>403 Forbidden</font><BR><BR><small>only local host accepted</small><BR><HR><small><i>%s</i></small></body></html>\n\r",_libwebserver_version);
284 tmpl=__ILWS_web_client_getreqline();
285 web_log("%s - - [%s] \"%s\" 403 (Forbidden)\n",inet_ntoa(node->sa.sin_addr),__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),tmpl);
286 __ILWS_free(tmpl);
287 node->stat=5;
288 __ILWS_free(tmp1);
289 return;
290 };
291 };
292 tmp=1; // Was found
293 node->outstream->flags=(gettemp->flag & WS_DYNVAR); // pass to outstreams
294 };
295 };
296 __ILWS_free(tmp1);
297 if(!tmp) { // Nothing found
298 __ILWS_web_client_writef(node,"HTTP/1.1 404 Not Found\r\n");
299 __ILWS_web_client_writef(node,"Server: %s\r\n",_libwebserver_version);
300 __ILWS_web_client_writef(node,"Date: %s\r\n",__ILWS_date(mktime(gmtime(&secs)),"%a, %d %b %Y %H:%M:%S GMT")); // Date header
301 __ILWS_web_client_writef(node,"Content-type: text/html\r\n\r\n<HTML><title>not found</title><body bgcolor=FFFFFF><font size=6>404 NOT FOUND</font><BR><BR><small>The requested content wasn't found</small><BR><HR><small><i>%s</i></small></body></html>\n\r",_libwebserver_version);
302 tmpl=__ILWS_web_client_getreqline();
303 web_log("%s - - [%s] \"%s\" 404 (Not Found)\n",inet_ntoa(node->sa.sin_addr),__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),tmpl);
304 __ILWS_free(tmpl);
305 node->stat=5;
306 }else {
307
308 // if cgi do something else, present headers
309 oumask=umask(077);
310 if(!(fname=__ILWS_tmpfname())) {
311 libws_error(LE_FILESYS,": Error giving a temp filename\n");
312 node->stat=5;
313 return;
314 };
315 if((nfile=freopen(fname,"wb+",stdout))!=NULL) {
316 flock(fileno(stdout),LOCK_EX);
317 tmp=dup(fileno(stdout));
318 nfile=fdopen(tmp,"wb+");
319 if(!__ILWS_add_outstream(node->outstream,fname,nfile,1)) {
320 node->stat=5; // (delete client)
321 return; // ERROR reported by add_outstream
322
323 };
324// THE PROCESS
325
326 // Setup Clientinfo before running function
327 if(gettemp->type==GH_FUNCTION) {
328 __ILWS_init_clientinfo();
329 gettemp->hdl.func(); // changed (0.5.3) Access by named union (Hilobok Andrew (han@km.if.ua) said that wasn't compile on freeBSD)
330 __ILWS_free_clientinfo();
331 };
332 // new on 0.5.2
333 if(gettemp->type==GH_DIRECTORY) { // as builtin function for directory listing
334 __ILWS_init_clientinfo();
335 if(strcmp(gettemp->str,"* /*"))ClientInfo->request+=1; // skip '/' if not equal to "* /*" (used by default)
336 __ILWS_lws_list(gettemp->hdl.path); // changed (0.5.3) Access by named union (Hilobok Andrew (han@km.if.ua) said that wasn't compile on freeBSD)
337 __ILWS_free_clientinfo();
338 };
339
340 fflush(stdout);
341 fclose(stdout); // it is a tempfile freopened
342 __ILWS_free(fname); // doesn't need anymore
343#ifdef WIN32
344 freopen("con","w",stdout);
345#else
346 freopen("/dev/tty","w",stdout);
347#endif
348 if((gettemp->flag & WS_USELEN) == WS_USELEN) {
349// determine writelength (for content-length: header) (new on 0.5.1)
350 tmpstream=node->outstream;
351 tmp=0;
352 while(tmpstream->next!=NULL) { // end of header probably in the firsts outstream nodes check for that
353 if(tmpstream->next->fname!=NULL) {
354 if(tmpstream->next->fstream==NULL) {
355 nfile=fopen(tmpstream->next->fname,"rb");
356 tmpstream->next->fstream=nfile; // here (corrected on 0.5.3);
357 } else {
358 fflush(tmpstream->next->fstream); // <- flush tha thing
359 nfile=tmpstream->next->fstream;
360 fseek(nfile,0,SEEK_SET);
361 };
362 if(nfile!=NULL) {
363 rtmps=0;
364 while((!node->wheadersize) && (!feof(nfile))) { // wheadersize is 0, suposed to be fast, at least if is not malformed
365 if(rtmps>0) {tmp-=4;fseek(nfile,rtmps-4,SEEK_SET);}
366 if((rtmps=fread(rtmp,1,RTMPMAX,nfile))>0) {
367 rtmp[rtmps]=0;
368 if((tmp1=strstr(rtmp,"\r\n\r\n"))) {
369 node->wheadersize=(tmp+((tmp1+4)-rtmp));
370 rtmps=((tmp1+4)-rtmp);
371
372 };
373 if(node->range>0) {
374 tmp1=realloc(thead,tmp+rtmps+1);
375 thead=tmp1;
376 memcpy(thead+tmp,rtmp,rtmps);
377 thead[tmp+rtmps]=0;
378 };
379 tmp+=rtmps;
380 };
381 };
382 fseek(nfile,SEEK_END,SEEK_END);
383 node->writelength+=(ftell(nfile)-2);
384 //fclose(nfile); // <- don't worry they close the file later
385 };
386 };
387 tmpstream=tmpstream->next;
388
389 };
390// end writelength
391 } else {
392 node->range=0; // no content-range
393 };
394
395 if(node->range>node->writelength-node->wheadersize && node->range>0) {
396 __ILWS_web_client_writef(node,"HTTP/1.1 416 Requested Range Not Satisfiable\r\n");
397 __ILWS_web_client_writef(node,"Server: %s\r\n",_libwebserver_version);
398 __ILWS_web_client_writef(node,"Date: %s\r\n",__ILWS_date(mktime(gmtime(&secs)),"%a, %d %b %Y %H:%M:%S GMT")); // Date header
399 __ILWS_web_client_writef(node,"Content-range: bytes */%d\r\n",node->writelength-node->wheadersize);
400 __ILWS_web_client_writef(node,"Content-type: text/html\r\n\r\n<HTML><title>Requested Range Not Satisfiable</title><body bgcolor=FFFFFF><font size=6>416 Requested Range Not Satisfiable</font><BR><BR><small>You're trying to resume an content that is smaller than the requested range</small><BR><HR><small><i>%s</i></small></body></html>\n\r",_libwebserver_version);
401 tmpl=__ILWS_web_client_getreqline();
402 web_log("%s - - [%s] \"%s\" 416 (Requested Range Not Satisfiable)\n",inet_ntoa(node->sa.sin_addr),__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),tmpl);
403 __ILWS_free(tmpl);
404 node->stat=5;
405 __ILWS_free(thead);
406 umask(oumask);
407 return;
408 };
409 if(node->range>0 && ((node->outstream->flags & WS_DYNVAR)==WS_DYNVAR)) { // if request range interval and dynvar on than produces not implemented
410 __ILWS_web_client_writef(node,"HTTP/1.1 501 Not Implemented\r\n");
411 __ILWS_web_client_writef(node,"Server: %s\r\n",_libwebserver_version);
412 __ILWS_web_client_writef(node,"Date: %s\r\n",__ILWS_date(mktime(gmtime(&secs)),"%a, %d %b %Y %H:%M:%S GMT")); // Date header
413 __ILWS_web_client_writef(node,"Content-type: text/html\r\n\r\n<HTML><title>Not implemented</title><body bgcolor=FFFFFF><font size=6>501 Not implemented</font><BR><BR><small>Your trying to resume an content that is not possible to resume(WS_DYNVAR fault)</small><BR><HR><small><i>%s</i></small></body></html>\n\r",_libwebserver_version);
414 tmpl=__ILWS_web_client_getreqline();
415 web_log("%s - - [%s] \"%s\" 501 (Not Implemented)\n",inet_ntoa(node->sa.sin_addr),__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),tmpl);
416 __ILWS_free(tmpl);
417 node->stat=5;
418 __ILWS_free(thead);
419 umask(oumask);
420 return;
421 };
422
423 }else {
424 LWSERR(LE_FILESYS);
425
426 };
427 node->stat=4;
428 if(node->HTTPdirective==NULL) {
429 if(node->range>0) {
430 __ILWS_web_client_writef(node,"HTTP/1.1 206 Partial Content\r\n");
431 tmpl=__ILWS_web_client_getreqline();
432 web_log("%s - - [%s] \"%s\" 206 (Partial Content)\n",inet_ntoa(node->sa.sin_addr),__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),tmpl);
433 __ILWS_free(tmpl);
434 } else {
435 __ILWS_web_client_writef(node,"HTTP/1.1 200 OK\r\n");
436 tmpl=__ILWS_web_client_getreqline();
437 web_log("%s - - [%s] \"%s\" 200 (OK)\n",inet_ntoa(node->sa.sin_addr),__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),tmpl);
438 __ILWS_free(tmpl);
439 };
440
441 } else {
442 __ILWS_web_client_writef(node,"%s\r\n",node->HTTPdirective);
443 tmpl=__ILWS_web_client_getreqline();
444 web_log("%s - - [%s] \"%s\" XXX (User defined)\n",inet_ntoa(node->sa.sin_addr),__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),tmpl);
445 __ILWS_free(tmpl);
446 };
447 __ILWS_web_client_writef(node,"Server: %s\r\n",_libwebserver_version);
448 __ILWS_web_client_writef(node,"Date: %s\r\n",__ILWS_date(mktime(gmtime(&secs)),"%a, %d %b %Y %H:%M:%S GMT")); // Date header
449 __ILWS_web_client_writef(node,"Accept-Ranges: bytes\r\n");
450 if((((node->writelength-node->wheadersize)-node->range)>0) && !((node->outstream->flags & WS_DYNVAR)==WS_DYNVAR))__ILWS_web_client_writef(node,"Content-length: %d\r\n",(node->writelength-node->wheadersize)-node->range);
451 if(node->cookies!=NULL)__ILWS_web_client_writef(node,"%s",node->cookies); // new (0.5.1)
452 if(node->range>0) {
453 __ILWS_web_client_writef(node,"Content-range: bytes %d-%d/%d\r\n",node->range,(node->writelength-node->wheadersize)-1,node->writelength-node->wheadersize);
454 __ILWS_web_client_writef(node,"%s",thead); // the rest of header
455 __ILWS_free(thead);
456 };
457 umask(oumask);
458
459 };
460
461}
462/*********************************************************************************************************/
463/*
464 * Process stream output
465 */
466void __ILWS_output_client(struct web_client *node) {
467 struct outstream *tstream=node->outstream;
468 char *tmp1,*tmp2,*tmp3;
469 char writetemp[WRITEMAX+1];
470 int beginsize=0;
471 int endsize=0;
472 int varsize=0;
473 int namesize=0;
474 if(tstream->next!=NULL) {
475 if(tstream->next->fname!=NULL) {
476 if(tstream->next->fstream==NULL) {
477 if((tstream->next->fstream=fopen(tstream->next->fname,"rb"))==NULL) {
478 LWSERR(LE_FILESYS);
479 __ILWS_delete_next_outstream(tstream);
480 //node->outstream->next=tstream->next;
481 return;
482 }
483 };
484
485 // read part (must always read)
486 if(tstream->next->rsize==0) { // start from 0
487 fseek(tstream->next->fstream,0,SEEK_SET);
488 };
489 memset(writetemp,0,WRITEMAX);
490 tstream->next->rsize=fread(writetemp,1,WRITEMAX,tstream->next->fstream);
491 writetemp[tstream->next->rsize]=0;
492 // if read make var changes on writetemp;
493 // new on 0.5.1 -- UNDERDEV // FIX -
494 if((node->outstream->flags & WS_DYNVAR) == WS_DYNVAR) {
495
496 tmp1=writetemp;
497 while(((tmp1=strstr(tmp1,"$")+1)!=(char*)1) && beginsize==0) { // check var found
498 for(namesize=0;namesize<50;namesize++) {
499 if(tmp1[namesize]==';') {namesize++;break;}
500 if((tmp1[namesize]<'a' || tmp1[namesize]>'z') &&
501 (tmp1[namesize]<'A' || tmp1[namesize]>'Z') &&
502 (tmp1[namesize]<'1' || tmp1[namesize]>'0') &&
503 tmp1[namesize]!='_') {namesize=0;break;};
504
505 };
506 if(namesize>0) {
507 if(namesize==1) { // this is $; for sure
508 if(!(tmp3=__ILWS_malloc(2))) {
509 LWSERR(LE_MEMORY);
510 node->stat=5;
511 return;
512 };
513 memcpy(tmp3,"$",namesize);
514 tmp3[namesize]=0;
515 } else {
516 if(!(tmp3=__ILWS_malloc(namesize))) {
517 LWSERR(LE_MEMORY);
518 node->stat=5;
519 return;
520 };
521 memcpy(tmp3,tmp1,namesize-1);
522 tmp3[namesize-1]=0;
523 };
524
525 tmp1-=1;
526
527 beginsize=tmp1-writetemp;
528 tmp1+=namesize; // get var from whateverwhere (client node probably)
529
530 endsize=strlen(tmp1);
531
532 //varsize=2;
533
534 if((tmp2=__ILWS_malloc(beginsize+1))) {
535 memcpy(tmp2,writetemp,beginsize);
536 tmp2[beginsize]=0;
537 if(namesize==1) {
538 varsize=strlen(tmp3);
539 snprintf(writetemp,WRITEMAX,"%s%s",tmp2,tmp3);
540 } else {
541 varsize=strlen(__ILWS_get_var(node->varlist,tmp3));
542 snprintf(writetemp,WRITEMAX,"%s%s",tmp2,__ILWS_get_var(node->varlist,tmp3));
543 };
544 writetemp[strlen(tmp2)+varsize]=0;
545 __ILWS_free(tmp2);
546 __ILWS_free(tmp3);
547 tstream->next->rsize=(beginsize+varsize);
548 tstream->next->varsize+=(varsize-namesize)-1;
549 } else {
550 LWSERR(LE_MEMORY);
551 __ILWS_free(tmp3);
552 node->stat=5;
553 return;
554 };
555 };
556 };
557 }; // dynvar
558
559 /* there is nothing more to read here */
560 if(tstream->next->rsize<1){ // i guess rsize < 1 is eof (make sure that server writed last time)
561 //only change if everything written
562 if(feof(tstream->next->fstream) && (ftell(tstream->next->fstream)==tstream->next->wrotesize)) {
563 //fclose(tstream->next->fstream);
564
565 __ILWS_delete_next_outstream(tstream);
566 //node->outstream->next=tstream->next;
567 }
568 return;
569 }
570 node->readsize+=tstream->next->rsize;
571 if(!node->skipped && node->range>0) {
572 tstream->next->wsize=tstream->next->rsize;
573 tstream->next->wrotesize+=tstream->next->wsize;
574 if((node->readsize-node->wheadersize)<node->range) { // skip range bytes
575 return; // do nothing
576 }else {
577 node->skipped=1;
578 tstream->next->wrotesize-=(node->readsize-node->wheadersize)-node->range; // the right offset
579 fseek(tstream->next->fstream,tstream->next->wrotesize,SEEK_SET);
580 tstream->next->wsize=tstream->next->rsize;
581 return;
582 };
583 };
584 // write part
585
586#ifdef HAVE_OPENSSL
587 if(node->ssl!=NULL) {
588 tstream->next->wsize=SSL_write(node->ssl,writetemp,tstream->next->rsize);
589 } else {
590 tstream->next->wsize=send(node->socket,writetemp,tstream->next->rsize,0);
591 };
592#else
593 tstream->next->wsize=send(node->socket,writetemp,tstream->next->rsize,0);
594#endif
595 if(tstream->next->wsize>0) {
596 tstream->next->wrotesize+=tstream->next->wsize;
597 if(tstream->next->rsize!=tstream->next->wsize || beginsize>0) { // FIX
598 fseek(tstream->next->fstream,tstream->next->wrotesize-(tstream->next->varsize),SEEK_SET); // FIX
599 };
600 };
601#ifdef WIN32
602 if((tstream->next->wsize<=0) && (WSAGetLastError()!=WSAEWOULDBLOCK)) { // WIN32 only
603#else
604 if(tstream->next->wsize<=0 && errno!=EAGAIN) { // linux only // *nix i guess
605#endif
606 //fclose(tstream->next->fstream);
607
608 __ILWS_delete_next_outstream(tstream);
609 //node->outstream->next=tstream->next;
610 return;
611 }else { // broken pipe
612 if(tstream->next->wsize<0) {
613 fseek(tstream->next->fstream,tstream->next->wrotesize-(tstream->next->varsize),SEEK_SET); //didn't read must back to where it was
614 };
615 };
616
617 }else { // filename is null
618
619 __ILWS_delete_next_outstream(tstream);
620 return;
621 };
622 }else { // End of streams
623
624 current_web_client->stat=5; // done
625
626 };
627}
628
629/*********************************************************************************************************/
630/*
631 * Set http directive
632 */
633void web_client_HTTPdirective(char *str) {
634 current_web_client->HTTPdirective=str;
635}
636
637
638/*********************************************************************************************************/
639/*
640 * GET request name
641 */
642char *__ILWS_web_client_getreq() {
643 char *ret;
644 char *tmp1=strstr(current_web_client->rbuf,"?");
645 char *tmp2=strstr(current_web_client->rbuf," HTTP");
646 char *tmp3=strstr(current_web_client->rbuf,"\r\n");
647 int size;
648 if(tmp1==NULL || tmp1>tmp2) {
649 tmp1=tmp2;
650 };
651 if(tmp2>tmp3) {
652 return NULL;
653 };
654 size=tmp1-current_web_client->rbuf;
655 if(size<1) return NULL;
656
657 if(!(ret=__ILWS_malloc(size+1))) {
658 LWSERR(LE_MEMORY);
659 return NULL;
660 };
661 memcpy(ret,current_web_client->rbuf,size);
662 ret[size]=0;
663 return ret;
664
665};
666
667/*********************************************************************************************************/
668/*
669 * GET request line
670 */
671char *__ILWS_web_client_getreqline() {
672 char *ret;
673 char *tmp1=strstr(current_web_client->rbuf,"\r\n");
674 int size=0;
675 if(tmp1==NULL) return NULL;
676 size=tmp1-current_web_client->rbuf;
677 if(size<1) return NULL;
678
679 if(!(ret=__ILWS_malloc(size+1))) {
680 LWSERR(LE_MEMORY);
681 return NULL;
682 };
683 memcpy(ret,current_web_client->rbuf,size);
684 ret[size]=0;
685 return ret;
686}
687
688
689/*********************************************************************************************************/
690/*
691 * Add a FILE stream type to client output
692 */
693int web_client_addfile(char *in) {
694 int ret=__ILWS_add_outstream(current_web_client->outstream,in,NULL,0);
695 int nfd=0;
696 char *fname;
697 FILE *nfile=NULL;
698 fname=__ILWS_tmpfname();
699 fflush(stdout);
700 fclose(stdout); // oldstdout close it?
701
702 if((nfile=freopen(fname,"w+b",stdout))!=NULL){ // redirect
703 flock(fileno(stdout),LOCK_EX); // <- yah
704 nfd=dup(fileno(stdout));
705 nfile=fdopen(nfd,"wb+");
706 if(!__ILWS_add_outstream(current_web_client->outstream,fname,nfile,1)) {
707 LWSERR(LE_MEMORY);
708 return 0;
709 };
710 };
711 __ILWS_free(fname);
712 ClientInfo->outfd=fileno(nfile);
713 return ret;
714}
715
716
717/*********************************************************************************************************/
718/*
719 * Output data as gif (with width w and height h)
720 */
721unsigned char __ILWS_GLOBALGIFPAL[256][3];
722
723
724void web_client_gifsetpalette(const char *fname) {
725 int j;
726 FILE *palfile;
727 if(strcmp(fname,"EGA")==0) {
728 static int EGApalette[16][3] = {
729 {0,0,0}, {0,0,128}, {0,128,0}, {0,128,128},
730 {128,0,0}, {128,0,128}, {128,128,0}, {200,200,200},
731 {100,100,100}, {100,100,255}, {100,255,100}, {100,255,255},
732 {255,100,100}, {255,100,255}, {255,255,100}, {255,255,255} };
733 for (j=0; j<256; j++) {
734 __ILWS_GLOBALGIFPAL[j][0] = (unsigned char)EGApalette[j&15][0];
735 __ILWS_GLOBALGIFPAL[j][1] = (unsigned char)EGApalette[j&15][1];
736 __ILWS_GLOBALGIFPAL[j][2] = (unsigned char)EGApalette[j&15][2];
737 }
738 } else {
739 if(!(palfile=fopen(fname,"rb"))) {
740 return;
741 };
742 fread(__ILWS_GLOBALGIFPAL,sizeof(__ILWS_GLOBALGIFPAL),1,palfile);
743 fclose(palfile);
744 };
745};
746
747int web_client_gifoutput(char *data,int w,int h,int transparencyindex) {
748 int i;
749 unsigned char rm[256],gm[256],bm[256];
750 for(i=0;i<256;i++) {
751 rm[i]=__ILWS_GLOBALGIFPAL[i][0];
752 gm[i]=__ILWS_GLOBALGIFPAL[i][1];
753 bm[i]=__ILWS_GLOBALGIFPAL[i][2];
754 };
755
756 i=__ILWS_WriteGIF(stdout,data,w,h,rm,gm,bm,256,0,transparencyindex,"libwebserver export gif (xvgifwr.c)");
757
758 return i;
759};
760
761
762/*********************************************************************************************************/
763/*
764 * an util to write with format on client_nodes
765 */
766void __ILWS_web_client_writef(struct web_client *node,const char *fmt,...) {
767 va_list args;
768 char buf[WRITEMAX];
769 va_start(args,fmt);
770 vsnprintf(buf,512,fmt,args);
771 va_end(args);
772
773#ifdef HAVE_OPENSSL
774 if(node->ssl!=NULL) {
775 SSL_write(node->ssl,buf,strlen(buf));
776 } else {
777 send(node->socket,buf,strlen(buf),0);
778 };
779#else
780 send(node->socket,buf,strlen(buf),0);
781#endif
782}
783
784
785/*********************************************************************************************************/
786/*
787 * function "web_client_setcookie" (improved on 0.5.1) to be called what ever were over handler function
788 *
789 * name = Name of the cookie
790 * value = Value of the cookie
791 * timeout = Timeout in second from current time on
792 * (0 = Until end of session)
793 * (-1 = Delete cookie)
794 * path = Subset of URLs in a domain for which the cookie is valid
795 * (If the path is not specified (path == NULL), it as assumed to be
796 * the same path as the document being described by the header which
797 * contains the cookie.)
798 * domain = Domain the cookie is valid for
799 * (If the domain is not set (domain == NULL), the default value of
800 * domain is the host name of the server which generated the cookie
801 * response.)
802 * secure = If a cookie is marked secure (secure == 1), it will only be
803 * transmitted if the communications channel with the host is a
804 * secure one. Currently this means that secure cookies will only be
805 * sent to HTTPS (HTTP over SSL) servers.
806 * (If secure is not specified (secure == 0), a cookie is considered
807 * safe to be sent in the clear over unsecured channels. )
808 */
809void web_client_setcookie(char *name, char *value, char *timeoutf, char *path, char *domain, int secure) {
810 char *tmp1=timeoutf;
811 long toffset=0;
812 time_t secs; // to time offset
813 int timeout;
814 int offset=(current_web_client->cookies!=NULL)?strlen(current_web_client->cookies):0;
815 if(timeoutf==NULL) {
816 timeout=0;
817 } else if (!strcmp(timeoutf,"DEL")){
818 timeout=-1;
819 } else {
820 while(*tmp1) {
821 if(*tmp1=='S')toffset=1; // seconds
822 if(*tmp1=='M')toffset=60; // minutes
823 if(*tmp1=='H')toffset=60*60; // hours
824 if(*tmp1=='d')toffset=60*60*24; // days
825 if(*tmp1=='m')toffset=60*60*24*30; // Month
826 if(*tmp1=='y')toffset=60*60*24*365; // years
827 tmp1++;
828 };
829 timeout=atoi(timeoutf)*toffset;
830 };
831
832 if (timeout < 0){
833 current_web_client->cookies=__ILWS_realloc(current_web_client->cookies,offset+59+strlen(name));
834 snprintf(current_web_client->cookies+offset,59+strlen(name),"Set-Cookie: %s=deleted; expires=%s", name, __ILWS_date(time(NULL)-31536001,"%a, %d-%b-%Y %H:%M:%S GMT"));
835 offset+=59+strlen(name);
836 }else{
837 current_web_client->cookies=__ILWS_realloc(current_web_client->cookies,offset+14+strlen(name)+strlen(value));
838 snprintf(current_web_client->cookies+offset,14+strlen(name)+strlen(value),"Set-Cookie: %s=%s", name, value);
839 offset+=13+strlen(name)+strlen(value);
840
841 if (timeout != 0){
842 //timeout += timezone; Hilobok Andrew (han@km.if.ua) removed this and use gmtime (thanks)
843 // exchanged by mktime(gmtime(&secs))
844 current_web_client->cookies=__ILWS_realloc(current_web_client->cookies,offset+40);
845 secs=time(NULL);
846 snprintf(current_web_client->cookies+offset,40,"; expires=%s", __ILWS_date(mktime(gmtime(&secs))+timeout,"%a, %d-%b-%Y %H:%M:%S GMT"));
847 offset+=39;
848 }
849 if (path != NULL && *path!=0) {
850 current_web_client->cookies=__ILWS_realloc(current_web_client->cookies,offset+8+strlen(path));
851 snprintf(current_web_client->cookies+offset,8+strlen(path),"; path=%s", path);
852 offset+=7+strlen(path);
853 }
854 if (domain != NULL && *domain!=0){
855 current_web_client->cookies=__ILWS_realloc(current_web_client->cookies,offset+10+strlen(domain));
856 snprintf(current_web_client->cookies+offset,10+strlen(domain),"; domain=%s", domain);
857 offset+=9+strlen(domain);
858 };
859 if (secure == 1) {
860 current_web_client->cookies=__ILWS_realloc(current_web_client->cookies,offset+9);
861 snprintf(current_web_client->cookies+offset,9,"; secure");
862 offset+=8;
863 };
864 }
865
866 current_web_client->cookies=__ILWS_realloc(current_web_client->cookies,offset+3);
867 snprintf(current_web_client->cookies+offset,3,"\r\n"); // '\0' included
868 offset+=2;
869 // fprintf(stderr,"current_web_client->cookies=\"%s\"\n",current_web_client->cookies); // DEBUG TO REMOVE
870
871
872}
873
874
875
876
877/*
878 * function "web_client_deletecookie"
879 *
880 * name = Name of the cookie to delete
881 */
882
883void web_client_deletecookie(char *name){
884 web_client_setcookie(name, NULL, "DEL", NULL, NULL, 0);
885}
886
887
888
889
890
891
892
893
894int web_client_setvar(char *name,char *value) {
895 return __ILWS_add_var(current_web_client->varlist,name,value);
896};
897char *web_client_getvar(char *name) {
898 return __ILWS_get_var(current_web_client->varlist,name);
899
900};
901int web_client_delvar(char *name) {
902 return __ILWS_del_var(current_web_client->varlist,name);
903
904};
905
906
907/***************
908 * variables
909 ***************/
910
911
912// prepare this to work in another file var.c
913struct web_var *__ILWS_init_var_list() {
914 struct web_var *ret;
915 if(!(ret=__ILWS_malloc(sizeof(struct web_var)))) {
916 LWSERR(LE_MEMORY);
917 return NULL;
918 };
919 ret->name=NULL;
920 ret->value=NULL;
921 ret->next=NULL;
922 return ret;
923};
924
925int __ILWS_add_var(struct web_var *list, char *name, char *value) {
926 struct web_var *node=list;
927 int namesize=strlen(name);
928 int valuesize=strlen(value);
929 while(node->next!=NULL) {
930 if(!strcmp(node->next->name,name)) {
931 return 0;
932 };
933 node=node->next;
934 };
935
936 if(!(node->next=__ILWS_malloc(sizeof(struct web_var)))) {
937 LWSERR(LE_MEMORY);
938 return 0;
939 };
940
941 if(!(node->next->name=__ILWS_malloc(namesize+1))) {
942 LWSERR(LE_MEMORY);
943 return 0;
944 };
945 memcpy(node->next->name,name,namesize);
946 node->next->name[namesize]=0;
947
948 if(!(node->next->value=__ILWS_malloc(valuesize+1))) {
949 LWSERR(LE_MEMORY);
950 return 0;
951 };
952 memcpy(node->next->value,value,valuesize);
953 node->next->value[valuesize]=0;
954 node->next->next=NULL;
955 return 1;
956};
957
958int __ILWS_del_var(struct web_var *list, char *name) {
959 struct web_var *node=list;
960 struct web_var *tmp;
961 while(node->next!=NULL) {
962 if(!strcmp(node->next->name,name)) {
963 tmp=node->next;
964 node->next=node->next->next;
965 __ILWS_free(tmp->name);
966 __ILWS_free(tmp->value);
967 __ILWS_free(tmp);
968 return 1;
969 };
970 };
971 return 0;
972};
973void __ILWS_delete_var_list(struct web_var *list) {
974 struct web_var *node=list;
975 struct web_var *tmp;
976
977 while(node->next!=NULL) {
978 tmp=node->next;
979 node->next=node->next->next;
980 __ILWS_free(tmp->name);
981 __ILWS_free(tmp->value);
982
983 __ILWS_free(tmp);
984 };
985 __ILWS_free(node);
986};
987
988
989char *__ILWS_get_var(struct web_var *list , char *name) {
990 struct web_var *node=list;
991 while(node->next!=NULL) {
992 if(!strcmp(node->next->name,name)) {
993 return node->next->value;
994 };
995 node=node->next;
996 };
997 return "";
998};
999
1000
1001/****************************
1002 * give mime by ext (mime file declared on server)
1003 */
1004
1005void web_client_contenttype(char *ext) {
1006 FILE *mimefileh;
1007 char *mimedata;
1008 char *mimeline;
1009 size_t extsize;
1010 size_t mimesize;
1011 char *tmp;
1012 /* -- mime */
1013 int isok=0;
1014 size_t i;
1015
1016 if(ext==NULL || current_web_server->mimefile==NULL) {
1017 printf("Content-type: text/plain\r\n\r\n"); // <- mime type, change this calculating mime with extension
1018 } else {
1019 extsize=strlen(ext);
1020 if((mimefileh=fopen(current_web_server->mimefile,"r"))) {
1021 // retrieve file size
1022 fseek(mimefileh,SEEK_END,SEEK_END);
1023 mimesize=ftell(mimefileh);
1024 fseek(mimefileh,0,SEEK_SET);
1025 //
1026 // malloc and read data
1027 mimedata=__ILWS_malloc(mimesize+1);
1028 fread(mimedata,1,mimesize,mimefileh);
1029 fclose(mimefileh); // close file
1030 //
1031 for(i=0;i<mimesize;i++)if(mimedata[i]=='\t')mimedata[i]=' '; // translate \t to 1 space
1032 mimedata[mimesize]=0;
1033
1034 isok=0;
1035 mimeline=strtok(mimedata,"\n");
1036 while((mimeline=strtok(NULL,"\n")) && !isok) {
1037 if(mimeline[0]!='#') { // is not a comment
1038 tmp=mimeline;
1039 while((tmp=strstr(tmp,ext)) && !isok) {
1040 //fprintf(stderr,"extsize(%d),found in %s (%s) %x\n",extsize,mimeline,tmp,tmp[extsize]);
1041 if(tmp[-1]==' ' && (tmp[extsize]==' ' || tmp[extsize]=='\0') ) {
1042 if((tmp=strchr(mimeline,' '))) { // the first space?
1043 tmp[0]='\0';
1044 //fprintf(stderr,"content is: %s\n",mimeline);
1045 printf("Content-type: %s\r\n\r\n",mimeline);
1046 isok=1;
1047 };
1048 };
1049 tmp+=extsize;
1050 };
1051
1052 };
1053 };
1054 if(!isok) {
1055 printf("Content-type: text/plain\r\n\r\n");
1056 };
1057 //printf("%s\n",tmp);
1058 __ILWS_free(mimedata);
1059
1060 };
1061 };
1062};
1063
1064
1065/**********************************
1066 * internal directory generator
1067 */
1068
1069int __ILWS_lws_list(char *inpath) {
1070 /* for type directory */
1071 /* mime*/
1072 char *ext;
1073 struct dirent *dire;
1074 DIR *cd;
1075 struct stat cfstat;
1076 char *dirpath=NULL;
1077 char *filepath;
1078 char *tmp;
1079 char *readfile;
1080 float filesize;
1081 char filesizeu;
1082 ////
1083
1084
1085 //printf("ClientInfo->request=<B>%s</B><BR>\n",ClientInfo->request);
1086 //readfile=__ILWS_malloc(strlen(ClientInfo->request)+1);
1087 readfile=ClientInfo->request;
1088 while((tmp=strstr(readfile,"./"))) { // this skip ../ also
1089 readfile=tmp+1;
1090 };
1091 while((tmp=strstr(readfile,"//"))) {
1092 readfile=tmp+1;
1093 };
1094
1095 tmp=strstr(readfile,"/");
1096 if(tmp!=NULL) {
1097 readfile=tmp+1; // must be in the first
1098 };
1099 // skip beind dir
1100 if(strlen(readfile)) {
1101 filepath=__ILWS_malloc(strlen(inpath)+strlen(readfile)+3);
1102 snprintf(filepath,strlen(inpath)+strlen(readfile)+2,"%s%s%s",inpath,(inpath[strlen(inpath)-1]=='/')?"":"/",readfile);
1103 //printf("pum ->%s<BR>\n",filepath);
1104 if(readfile[strlen(readfile)-1]=='/') {
1105 dirpath=__ILWS_malloc(strlen(filepath)+1);
1106 memcpy(dirpath,filepath,strlen(filepath)+1); // the 0 included
1107 } else {
1108 if(!stat(filepath,&cfstat)) { // file must exist
1109 if((cfstat.st_mode & S_IFDIR) != S_IFDIR) {
1110 // search for mime
1111 ext=strrchr(filepath,'.');
1112 tmp=strrchr(filepath,'/');
1113 ext+=1;
1114 if(ext<=tmp) { // is not a extension
1115 ext=NULL;
1116 };
1117
1118 //Wed, 22 Oct 2003 16:04:04 GMT
1119 printf("Last-Modified: %s\r\n",__ILWS_date(mktime(gmtime(&cfstat.st_mtime)),"%a, %d %b %Y %H:%M:%S GMT")); // new on 0.5.3
1120 web_client_contenttype(ext);
1121 web_client_addfile(filepath); // fopen and write, maybe?
1122 __ILWS_free(filepath);
1123 return 1;
1124 } else {
1125 web_client_HTTPdirective("HTTP/1.1 404 File Not Found");
1126 printf("Content-type: text/html\r\n\r\n<HTML><title>file not found</title><body bgcolor=FFFFFF><font size=6>404 FILE NOT FOUND</font><BR><BR><small>The request \"%s\" wasn't found, try this <a href='%s/'>link</a></small><BR><HR><small><i>%s</i></small></body></html>\n\r",filepath,ClientInfo->request,_libwebserver_version);
1127 __ILWS_free(filepath);
1128 return 0;
1129 };
1130 }else {
1131 web_client_HTTPdirective("HTTP/1.1 404 File Not Found");
1132 printf("Content-type: text/html\r\n\r\n<HTML><title>file not found</title><body bgcolor=FFFFFF><font size=6>404 FILE NOT FOUND</font><BR><BR><small>The request \"%s\" wasn't found</small><BR><HR><small><i>%s</i></small></body></html>\n\r",filepath,_libwebserver_version);
1133 __ILWS_free(filepath);
1134 return 0;
1135 };
1136 };
1137 __ILWS_free(filepath);
1138 };
1139 //printf("Content-type: text/html\r\n\r\n");
1140 //fprintf(stderr,"dirpath=%s inpath=%s\n",dirpath,inpath);
1141 if(dirpath==NULL) {
1142 dirpath=__ILWS_malloc(strlen(inpath)+1);
1143 memcpy(dirpath,inpath,strlen(inpath)+1);
1144 };
1145 cd=opendir(dirpath);
1146 if(cd!=NULL) {
1147 printf("Content-type: text/html\r\n\r\n");
1148 printf("<HTML><HEAD><TITLE>Contents of %s</TITLE></HEAD><BODY>\n",dirpath);
1149 printf("<h1>Contents of directory %s</h1><HR>\n",dirpath);
1150 printf("<form><input type=text name=match value=\"%s\"><input type=submit name='send' value='wildcard'></form>\n",strlen(ClientInfo->Query("match"))?ClientInfo->Query("match"):"*");
1151 printf("<PRE>\n");
1152 while((dire=readdir(cd))) {
1153 if( ((dire->d_name[0]!='.') || (strcmp(dirpath,inpath) && !strcmp(dire->d_name,".."))) && (!fnmatch(ClientInfo->Query("match"),dire->d_name,0) || !strlen(ClientInfo->Query("match"))) ) {
1154 filepath=__ILWS_malloc(strlen(dirpath)+strlen(dire->d_name)+2);
1155 snprintf(filepath,strlen(dirpath)+strlen(dire->d_name)+2,"%s%s%s",dirpath,(dirpath[strlen(dirpath)-1]=='/')?"":"/",dire->d_name);
1156 //fprintf(stderr,"filename=%s\n",filepath);
1157 if(!stat(filepath,&cfstat)) {
1158 if((cfstat.st_mode & S_IFDIR) == S_IFDIR) {
1159 printf("%s &lt;DIR&gt; <a href=\"%s/\">%s</a>\n",__ILWS_date(cfstat.st_mtime,"%a, %d %b %Y %H:%M"),dire->d_name,dire->d_name);
1160 }else {
1161 filesize=(float)cfstat.st_size;
1162 filesizeu=0;
1163 while(filesize>1024) {
1164 filesize/=1024;
1165 filesizeu++;
1166 };
1167 printf("%s %.1f%c <a href=\"%s\">%s</a>\n",__ILWS_date(cfstat.st_mtime,"%a, %d %b %Y %H:%M"),filesize,(filesizeu==2)?'M':(filesizeu==1)?'K':'b',dire->d_name,dire->d_name);
1168 };
1169 };
1170 __ILWS_free(filepath);
1171 };
1172
1173 };
1174 printf("</PRE>\n");
1175 printf("<HR>\n");
1176 printf("<address>%s</address>\n",_libwebserver_version);
1177 printf("</BODY></HTML>\r\n");
1178 __ILWS_free(dirpath);
1179 closedir(cd);
1180 } else {
1181 web_client_HTTPdirective("HTTP/1.1 404 File Not Found");
1182 printf("Content-type: text/html\r\n\r\n<HTML><title>file not found</title><body bgcolor=FFFFFF><font size=6>404 FILE NOT FOUND</font><BR><BR><small>The request \"%s\" wasn't found</small><BR><HR><small><i>%s</i></small></body></html>\n\r",dirpath,_libwebserver_version);
1183 return 0;
1184 };
1185 return 1;
1186};
1187
1188
1189
1190
diff --git a/src/client.h b/src/client.h
new file mode 100644
index 00000000..32ec65b5
--- /dev/null
+++ b/src/client.h
@@ -0,0 +1,159 @@
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 *
12 * --
13 *
14 */
15
16#ifndef _CLIENT_H_
17#define _CLIENT_H_
18
19#ifdef HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#include <stdio.h>
24#include <fcntl.h>
25#include <string.h>
26#include <errno.h>
27
28
29
30#ifdef HAVE_OPENSSL
31
32#include <openssl/rsa.h> /* SSLeay stuff */
33#include <openssl/crypto.h>
34#include <openssl/x509.h>
35#include <openssl/pem.h>
36#include <openssl/ssl.h>
37#include <openssl/err.h>
38
39#endif
40
41
42#include "socket.h"
43
44#include "memory.h"
45#include "outstream.h"
46
47
48#include "gethandler.h"
49
50
51
52#include "weblog.h"
53#include "utils.h"
54#include "fnmatch.h"
55#include "outgif.h"
56#include "error.h"
57#include "debug.h"
58
59
60#include "clientinfo.h"
61
62
63#ifdef WIN32
64#include "flock.h" // my flock
65#include "dirent.h"
66#else
67#include <sys/file.h> // for flock
68#include <dirent.h>
69#endif
70
71#define READMAX 100000 // 1Mb upload
72#define WRITEMAX 100000 // 1Mb download 1mb per client? // smaller is better for multi read bigger is better for big downloads
73#define MAXURLSIZE 2000 //
74
75extern int WEBTIMEOUT; //to be changed externaly
76//#define WEBTIMEOUT 10000 // TIMEOUT WITHOUT RECEIVING DATA (not in seconds but in read tries)
77
78
79struct web_var {
80 char *name;
81 char *value;
82 struct web_var *next;
83};
84
85struct web_client {
86
87 int socket;
88 struct sockaddr_in sa;
89 unsigned int salen;
90 char *HTTPdirective;
91 unsigned char stat; /* 0001b idle,0010b down streaming, 0011 done down streaming, 0100b out streaming,0101 done out streaming */
92 // Read control
93 char *rbuf;
94 unsigned long rbufsize;
95 int newdata_try;
96 unsigned long contentlength; // for read propose (optimize speed 0.5.1)
97 unsigned long headersize;
98
99 // Write control
100 struct outstream *outstream;
101 struct web_var *varlist;
102 char *cookies; // cookie header (0.5.1)
103 long writelength;
104 long readsize;
105 long range;
106 int skipped;
107 long wheadersize;
108// clock_t oldcl,curcl;
109
110#ifdef HAVE_OPENSSL
111 SSL *ssl;
112 X509* cert;
113#else
114 void *pad[2];
115#endif
116 struct web_client *next;
117};
118extern struct web_client *current_web_client;
119
120struct web_client *__ILWS_init_client_list();
121int __ILWS_add_client(struct web_client *,struct web_client *);
122void __ILWS_delete_next_client(struct web_client *);
123void __ILWS_delete_client_list(struct web_client *);
124
125void __ILWS_read_client(struct web_client *);
126void __ILWS_process_client(struct web_client *,struct gethandler *);
127void __ILWS_output_client(struct web_client *);
128
129void __ILWS_web_client_writef(struct web_client *,const char *,...);
130
131int web_client_addfile(char *);
132void web_client_contenttype(char *); // new on 0.5.2
133
134void web_client_gifsetpalette(const char *);
135
136extern unsigned char __ILWS_GLOBALGIFPAL[256][3];
137
138int web_client_gifoutput(char *,int,int,int);
139
140void web_client_HTTPdirective(char *);
141
142char *__ILWS_web_client_getreqline();
143char *__ILWS_web_client_getreq();
144// new (0.5.1)
145int web_client_setvar(char *,char *);
146char *web_client_getvar(char *);
147int web_client_delvar(char *);
148
149// put in var.h
150struct web_var *__ILWS_init_var_list();
151int __ILWS_add_var(struct web_var *, char *, char *);
152int __ILWS_del_var(struct web_var *, char *);
153void __ILWS_delete_var_list(struct web_var *);
154char *__ILWS_get_var(struct web_var *list , char *name);
155
156int __ILWS_lws_list(char *); // new on 0.5.2
157
158#endif
159
diff --git a/src/clientinfo.c b/src/clientinfo.c
new file mode 100644
index 00000000..c640973c
--- /dev/null
+++ b/src/clientinfo.c
@@ -0,0 +1,1124 @@
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: Wed Oct 9 19:56:22 GMT 2002
10 *
11 * -- parse http header into "ClientInfo"
12 *
13 */
14
15#include "clientinfo.h"
16
17
18struct ClientInfo *ClientInfo; // tochange
19
20/*********************************************************************************************************/
21/*
22 * Initialize ClientInfo structure
23 */
24void __ILWS_init_clientinfo() {
25 char *t;
26 struct outstream *tstream=current_web_client->outstream;
27
28 ClientInfo=__ILWS_malloc(sizeof(struct ClientInfo));
29 if(ClientInfo==NULL) {
30 LWSERR(LE_MEMORY);
31 return;
32 };
33
34 while(tstream->next!=NULL) {
35 tstream=tstream->next;
36 };
37
38 if(tstream->fstream!=NULL) ClientInfo->outfd=fileno(tstream->fstream); //take it off?
39
40 ClientInfo->mem=__ILWS_init_buffer_list(); // First thing, other fuctions use this to allocate
41
42
43 ClientInfo->request=__ILWS_clientinfo_getreqname();
44
45 ClientInfo->inetname=NULL;
46 t=inet_ntoa(current_web_client->sa.sin_addr);
47 if((ClientInfo->inetname=__ILWS_add_buffer(ClientInfo->mem,strlen(t)+1))) {
48 memcpy(ClientInfo->inetname,t,strlen(t));
49 ClientInfo->inetname[strlen(t)]='\0';
50 };
51
52 ClientInfo->method=__ILWS_clientinfo_getmethod();
53 ClientInfo->user=__ILWS_clientinfo_getauthuser();
54 ClientInfo->pass=__ILWS_clientinfo_getauthpass();
55
56
57
58 /* Initialize List's */
59 ClientInfo->HeaderList=NULL;
60 ClientInfo->QueryList=NULL;
61 ClientInfo->PostList=NULL;
62 ClientInfo->MultiPartList=NULL;
63 ClientInfo->CookieList=NULL;
64
65 ClientInfo->Header=__ILWS_Header;
66 ClientInfo->Query=__ILWS_Query;
67 ClientInfo->QueryString=__ILWS_clientinfo_getquerystring();
68 ClientInfo->Post=__ILWS_Post;
69 ClientInfo->PostData=__ILWS_clientinfo_getpostdata();
70 ClientInfo->MultiPart=__ILWS_MultiPart;
71 ClientInfo->Cookie=__ILWS_Cookie;
72 ClientInfo->Conf=__ILWS_Conf;
73 ClientInfo->CookieString=__ILWS_Header("Cookie");
74
75}
76
77/*********************************************************************************************************/
78/*
79 * Free ClientInfo structure
80 */
81void __ILWS_free_clientinfo() {
82 if(ClientInfo==NULL) {
83 return;
84 };
85 __ILWS_delete_buffer_list(ClientInfo->mem);
86
87 __ILWS_free(ClientInfo);
88 ClientInfo=NULL;
89}
90
91
92/*********************************************************************************************************/
93/*
94 * Header function for ClientInfo->Header("x")
95 */
96char *__ILWS_Header(char *str) {
97 char *tmp1,*tmp2,*tmp3,*ret;
98 struct _Header *hl=ClientInfo->HeaderList;
99 char *defret="";
100 size_t size;
101 size_t strsize;
102 if(str==NULL) { // request is null return whole header
103 return current_web_client->rbuf;
104 };
105 if(ClientInfo->HeaderList==NULL) {
106
107 ClientInfo->HeaderList=__ILWS_add_buffer(ClientInfo->mem,sizeof(struct _Header));
108 if(ClientInfo->HeaderList==NULL) {
109 LWSERR(LE_MEMORY);
110 return defret;
111 };
112 ClientInfo->HeaderList->next=NULL;
113 ClientInfo->HeaderList->data=NULL;
114 ClientInfo->HeaderList->id=NULL;
115 hl=ClientInfo->HeaderList;
116 };
117 // First search if exists
118
119 while(hl->next!=NULL) {
120 if(hl->next->id!=NULL) {
121 if(!strcmp(hl->next->id,str)) {
122
123 return hl->next->data;
124 };
125 };
126 hl=hl->next;
127 };
128
129 /* Doesn't exists */
130 strsize=strlen(str);
131 if(!(hl->next=__ILWS_add_buffer(ClientInfo->mem,sizeof(struct _Header)))) {
132 LWSERR(LE_MEMORY);
133 return defret;
134 };
135 if(!(hl->next->id=__ILWS_add_buffer(ClientInfo->mem,strsize+1))) {
136 LWSERR(LE_MEMORY);
137 return defret;
138 };
139
140 memcpy(hl->next->id,str,strsize);
141 hl->next->id[strsize]=0;
142 hl->next->data=defret;
143 hl->next->next=NULL;
144
145 if(!(tmp3=__ILWS_malloc(strsize+3))) {
146 LWSERR(LE_MEMORY);
147 return defret;
148 };
149 snprintf(tmp3,strsize+3,"%s: ",str);
150 tmp1=__ILWS_stristr(current_web_client->rbuf,tmp3);
151 __ILWS_free(tmp3);
152 if(tmp1==NULL) {
153 return defret;
154 };
155
156 tmp1+=strsize+2;
157 if(!(tmp2=strstr(tmp1,"\r\n"))) { // Unexpected (security anyway)
158 return defret;
159 };
160 if((size=(unsigned int)(tmp2-tmp1))<0) {
161 return defret;
162 };
163 if(!(ret=__ILWS_add_buffer(ClientInfo->mem,size+1))) { //malloc & register
164 return defret;
165 };
166 memcpy(ret,tmp1,size);
167 ret[size]=0;
168 hl->next->data=ret;
169 return ret;
170}
171
172
173
174/*********************************************************************************************************/
175/*
176 * Function for Querydata
177 */
178char *__ILWS_Query(char *handle) {
179 char *tmp1,*tmp2,*tmp3,*tmp4,*ret;
180 char *defret="";
181 size_t strsize;
182 size_t size;
183 int j=0,ch;
184 int seek=1;
185 unsigned int i;
186 unsigned int *iddb=NULL;
187 unsigned int *iddb2=NULL;
188 unsigned int idf=0;
189 int rw=0; // 0 data 1 number of vars; (return what?)
190 struct _Query *ql=ClientInfo->QueryList;
191
192
193 if(handle==NULL) {
194 return ClientInfo->QueryString;
195 };
196 if(handle[0]=='#') rw=1;
197 // allocate first node from the list
198 if(ClientInfo->QueryList==NULL) {
199 ClientInfo->QueryList=__ILWS_add_buffer(ClientInfo->mem,sizeof(struct _Query));
200 if(ClientInfo->QueryList==NULL) {
201 LWSERR(LE_MEMORY);
202 if(rw) return 0;
203 return defret;
204 };
205 ClientInfo->QueryList->next=NULL;
206 ClientInfo->QueryList->data=NULL;
207 ClientInfo->QueryList->id=NULL;
208 ql=ClientInfo->QueryList;
209 };
210 // done allocating
211
212
213 // First search if exists and fetch values;
214
215 idf=1;
216 iddb=&idf;
217 seek=1;
218
219 while(ql->next!=NULL) {
220 if(ql->next->id!=NULL) {
221 if(!strcmp(ql->next->id,handle+rw) && *iddb >= 0) {
222 if(seek==1) {
223 iddb=&ql->next->index; // atribute iddb to first node
224 iddb2=&ql->next->idf; // atribute iddb2 to counting
225 if(rw) return (char *)*iddb2;
226 if(ql->next->idf==1) {
227 return ql->next->data;
228 };
229 j=*iddb;
230 seek++;
231 };
232 *iddb=*iddb-1;
233
234 if(*iddb<=0) {
235 *iddb=j-1;
236 if(j<=1) {
237 *iddb=*iddb2; // go to start if any
238 //return defret; // to be null
239 };
240 return ql->next->data; // Return existent
241 };
242
243 };
244 };
245 ql=ql->next;
246 };
247
248
249
250 /* Doesn't exists */
251 strsize=strlen(handle+rw);
252 tmp1=strstr(current_web_client->rbuf,"?");
253 tmp3=strstr(current_web_client->rbuf," HTTP"); // End of GET header
254 if(tmp1!=NULL && tmp1<tmp3) {
255 tmp1+=1;
256 } else {
257 if(rw)return 0;
258 return defret;
259 }
260
261 // Working here
262 idf=0;
263 ret=defret;
264 seek=1;
265 tmp4=tmp1;
266 while(seek==1) {
267 tmp1=tmp4;
268 do {
269 tmp2=strstr(tmp1,handle+rw);
270 if(tmp2==NULL) { // must be nonnull
271 if(iddb!=NULL && iddb2!=NULL) { // if iddb2 is null then is just one value;
272 *iddb2=*iddb;
273 if(!rw)*iddb=*iddb-1;
274 };
275 if(rw) {
276 if(ret==defret) return 0;
277 return (char *)*iddb2;
278 }
279 return ret; // if first null return defret (ret=defret);
280
281 };
282 tmp1=tmp2+strsize;
283 } while ((tmp2[-1]!='?' && tmp2[-1]!='&') || tmp2[strsize]!='='); // Johannes E. Schindelin Fix
284
285 if(tmp3<tmp2) {
286 if(iddb!=NULL && iddb2!=NULL) {
287 *iddb2=*iddb;
288 if(!rw)*iddb=*iddb-1;
289 };
290 if(rw) {
291 if(ret==defret) return 0;
292 return (char *)*iddb2;
293 }
294
295 return ret;
296 };
297
298 tmp4=tmp1;
299 // if not null, so add an node;
300
301 // Working here ^
302 ql->next=__ILWS_add_buffer(ClientInfo->mem,sizeof(struct _Query));
303 if(ql->next==NULL) {
304 LWSERR(LE_MEMORY);
305 if(handle[0]=='#') rw=1;
306 return defret;
307 };
308 ql->next->id=__ILWS_add_buffer(ClientInfo->mem,strsize+1);
309 if(ql->next->id==NULL) {
310 LWSERR(LE_MEMORY);
311 if(handle[0]=='#') rw=1;
312 return defret;
313 };
314 memcpy(ql->next->id,handle+rw,strsize);
315 ql->next->id[strsize]=0;
316 if(idf==0) {
317 ql->next->index=0;
318 iddb=&ql->next->index;
319 iddb2=&ql->next->idf; // second holds information about number of fetchs;
320
321 };
322 ql->next->data=defret;
323 ql->next->next=NULL;
324
325
326 tmp1=strstr(tmp2,"&"); // tmp1 goes to next '&'
327 tmp2+=strsize+1; // tmp2 goes to start of data
328 tmp3=strstr(tmp2," HTTP"); // tmp3 goes to the end of Get header
329 if(tmp1==NULL || ((unsigned int)tmp1>(unsigned int)tmp3)) {
330 size=tmp3-tmp2; // MUST HAVE (" HTTP") else, server don't let in
331 } else {
332 size=tmp1-tmp2;
333 };
334 if(size<1) {
335 if(handle[0]=='#') rw=1;
336 return defret;
337 };
338
339
340 ql->next->data=__ILWS_add_buffer(ClientInfo->mem,size+1);
341 if(ql->next->data==NULL) {
342 LWSERR(LE_MEMORY);
343 if(handle[0]=='#') rw=1;
344 return defret;
345 };
346 j=0;
347 for(i=0;i<size;i++) { // Hex translation here
348 switch (ch=tmp2[j]) {
349 case '+':
350 ch=' ';
351 break;
352 case '%':
353
354 tmp1=__ILWS_malloc(3);
355 if(tmp1==NULL) {
356 LWSERR(LE_MEMORY);
357 if(rw) return 0;
358 return defret;
359 };
360 strncpy(tmp1,&tmp2[j+1],2);
361 tmp1[2]=0;
362 ch=strtol(tmp1,NULL,16);
363 j+=2;
364 size-=2;
365
366 __ILWS_free(tmp1);
367 break;
368 };
369 ql->next->data[i]=ch;
370 j++;
371 };
372 ql->next->data[size]='\0';
373 ret=ql->next->data; // to the last
374 ql=ql->next;
375 *iddb=*iddb+1;
376 idf++;
377 };
378 return ret;
379}
380
381
382
383/*********************************************************************************************************/
384/*
385 * Function for Postdata
386 */
387char *__ILWS_Post(char *handle) {
388 char *tmp1,*tmp2,*tmp3,*ret;
389 struct _Post *pl=ClientInfo->PostList;
390 char *defret="";
391 int *iddb=NULL,*iddb2=NULL;
392 int idf;
393 int seek=1;
394 size_t strsize;
395 size_t size;
396 int j=0,ch;
397 unsigned int i;
398 int rw=0; //return what;
399
400 tmp1=strstr(current_web_client->rbuf,"Content-type: multipart/form-data"); // multipart this post doesn't work
401 if(tmp1!=NULL) {
402 return ClientInfo->MultiPart(handle).data;
403 };
404 if(handle==NULL) {
405 return ClientInfo->PostData;
406 };
407 if(handle[0]=='#')rw=1;
408 /* Allocate the list */
409 if(ClientInfo->PostList==NULL) {
410 if(!(ClientInfo->PostList=__ILWS_add_buffer(ClientInfo->mem,sizeof(struct _Post)))) {
411 LWSERR(LE_MEMORY);
412 if(rw) return 0;
413 return defret;
414 };
415 ClientInfo->PostList->next=NULL;
416 ClientInfo->PostList->data=NULL;
417 ClientInfo->PostList->id=NULL;
418 pl=ClientInfo->PostList;
419 };
420
421 // First search if exists
422 idf=1;
423 iddb=&idf;
424 seek=1;
425 while(pl->next!=NULL) {
426 if(pl->next->id!=NULL) {
427 if(!strcmp(pl->next->id,handle+rw) && iddb>=0) {
428 if(seek==1) {
429 iddb=&pl->next->index;
430 iddb2=&pl->next->idf;
431 if(rw) return (char *)(*iddb2);
432 if(pl->next->idf==1) {
433 return pl->next->data;
434 };
435 j=*iddb;
436 seek++;
437 };
438 *iddb=*iddb-1;
439
440 if(*iddb<=0) {
441 *iddb=j-1;
442 if(j<=1) {
443 *iddb=*iddb2;
444
445 //return defret;
446 };
447 return pl->next->data;
448 };
449 };
450 };
451 pl=pl->next;
452 };
453
454
455
456
457
458 /* Doesn't exists */
459 strsize=strlen(handle+rw);
460 tmp1=strstr(current_web_client->rbuf,"\r\n\r\n");
461 if(tmp1!=NULL)
462 tmp1+=4;
463 else {
464 if(rw) return 0;
465 return defret;
466 };
467 idf=0;
468 ret=defret;
469 seek=1;
470 tmp3=tmp1;
471 while(seek==1) {
472 tmp1=tmp3;
473 do {
474 tmp2=strstr(tmp1,handle+rw);
475 if(tmp2==NULL) { // mustn't be null
476 if(iddb!=NULL && iddb2!=NULL) { // if iddb2 is null then is just one value;
477 *iddb2=*iddb;
478 if(!rw)*iddb=*iddb-1;
479 };
480 if(rw) {
481 if(ret==defret) return 0;
482 return (char *)*iddb2;
483 }
484 return ret; // if first null return defret (ret=defret);
485
486 };
487 tmp1=tmp2+strsize;
488 } while ((tmp2[-1]!='\n' && tmp2[-1]!='&') || tmp2[strsize]!='='); // Johannes E. Schindelin Fix
489 tmp3=tmp1;
490
491
492 pl->next=__ILWS_add_buffer(ClientInfo->mem,sizeof(struct _Post));
493 if(pl->next==NULL) {
494 LWSERR(LE_MEMORY);
495 if(rw) return 0;
496 return defret;
497 };
498 pl->next->id=__ILWS_add_buffer(ClientInfo->mem,strsize+1);
499 if(pl->next->id==NULL) {
500 LWSERR(LE_MEMORY);
501 if(rw) return 0;
502 return defret;
503 };
504 memcpy(pl->next->id,handle+rw,strsize);
505 pl->next->id[strsize]=0;
506 if(idf==0) {
507 pl->next->index=0;
508 iddb=&pl->next->index;
509 iddb2=&pl->next->idf;
510 };
511
512 pl->next->data=defret;
513 pl->next->next=NULL;
514
515 tmp1=strstr(tmp2,"&"); // goes to the next & (end of data)
516 tmp2+=strsize+1; // tmp2 goes to start of data
517 if(tmp1==NULL) {
518 size=strlen(tmp2);
519 } else {
520 size=tmp1-tmp2;
521 };
522 if(size==0) {
523 if(rw) return 0;
524 return defret;
525 };
526
527 pl->next->data=__ILWS_add_buffer(ClientInfo->mem,size+1);
528 if(pl->next->data==NULL) {
529 LWSERR(LE_MEMORY);
530 return defret;
531 };
532 j=0;
533 for(i=0;i<size;i++) { // hex translation here
534 switch (ch=tmp2[j]) {
535 case '+':
536 ch=' ';
537 break;
538 case '%':
539
540 tmp1=__ILWS_malloc(3);
541 if(tmp1==NULL) {
542 LWSERR(LE_MEMORY);
543 if(rw) return 0;
544 return defret;
545 };
546 strncpy(tmp1,&tmp2[j+1],2);
547 tmp1[2]=0;
548
549 ch=strtol(tmp1,NULL,16);
550 j+=2;
551 size-=2;
552
553 __ILWS_free(tmp1);
554 break;
555 };
556 pl->next->data[i]=ch;
557 j++;
558 };
559 pl->next->data[size]='\0';
560 ret=pl->next->data; // to the last
561 *iddb=*iddb+1;
562 idf++;
563 pl=pl->next;
564 //pl->next->data=ret;
565 };
566 return ret;
567}
568
569
570
571/*********************************************************************************************************/
572/*
573 * Function for MultiPart formdata
574 */
575struct _MultiPart __ILWS_MultiPart(char *handle) {
576 char *tmp1,*tmp2,*tmp3;
577 int i;
578 char *name;
579 size_t namesize;
580 struct _MultiPart *ml=ClientInfo->MultiPartList;
581 struct _MultiPart defret={"","",0,""};
582 size_t strsize;
583 char *boundary; size_t boundarysize;
584 // IE C43o6Fn6Et74e65n6Et74-2DT54y79p70e65:3A 20m6Du75l6Ct74i69p70a61r72t74/2Ff66o6Fr72m6D-2Dd64a61t74a61
585 // NS C43o6Fn6Et74e65n6Et74-2Dt74y79p70e65:3A 20m6Du75l6Ct74i69p70a61r72t74/2Ff66o6Fr72m6D-2Dd64a61t74a61
586 tmp1=__ILWS_stristr(current_web_client->rbuf,"Content-type: multipart/form-data");
587 if(tmp1==NULL) return defret;
588 if(ClientInfo->MultiPartList==NULL) {
589 ClientInfo->MultiPartList=__ILWS_add_buffer(ClientInfo->mem,sizeof(struct _MultiPart));
590 if(ClientInfo->MultiPartList==NULL) {
591 LWSERR(LE_MEMORY);
592 return defret;
593 };
594 ClientInfo->MultiPartList->next=NULL;
595 ClientInfo->MultiPartList->id=NULL;
596 ClientInfo->MultiPartList->data=NULL;
597 ClientInfo->MultiPartList->filename=NULL;
598 ClientInfo->MultiPartList->size=0;
599 ml=ClientInfo->MultiPartList;
600 };
601 // Check if handle exists
602 while(ml->next!=NULL) {
603 if(ml->next->id!=NULL) {
604 if(!strcmp(ml->next->id,handle)) {
605
606 return *ml->next;
607 };
608 };
609 ml=ml->next;
610 };
611
612
613 strsize=strlen(handle);
614 ml->next=__ILWS_add_buffer(ClientInfo->mem,sizeof(struct _MultiPart));
615 if(ml->next==NULL) {
616 LWSERR(LE_MEMORY);
617 return defret;
618 };
619 ml->next->id=__ILWS_add_buffer(ClientInfo->mem,strsize+1);
620 if(ml->next->id==NULL) {
621 LWSERR(LE_MEMORY);
622 return defret;
623 };
624 memcpy(ml->next->id,handle,strsize);
625 ml->next->id[strsize]=0;
626 ml->next->data="";
627 ml->next->filename="";
628 ml->next->size=0;
629 ml->next->next=NULL;
630
631 tmp1=strstr(tmp1,"boundary=");
632 if(tmp1==NULL) return defret;
633 tmp1+=9;
634 tmp2=strstr(tmp1,"\r\n");
635 if(tmp2<tmp1 || tmp2==NULL) return defret;
636 /* boundary */
637 boundarysize=tmp2-tmp1;
638 boundary=__ILWS_add_buffer(ClientInfo->mem,boundarysize+3);
639 if(boundary==NULL) {
640 LWSERR(LE_MEMORY);
641 return defret;
642 };
643 memcpy(boundary,tmp1,boundarysize);
644 boundary[boundarysize]=0;
645
646
647 /* handle */
648 namesize=boundarysize+41+strlen(handle);
649 name=__ILWS_add_buffer(ClientInfo->mem,namesize+1);
650 if(name==NULL) {
651 LWSERR(LE_MEMORY);
652 return defret;
653 };
654 snprintf(name,namesize,"%s\r\nContent-Disposition: form-data; name=",boundary);
655 namesize=strlen(name);
656
657 tmp1=strstr(tmp1,"\r\n\r\n"); // go to data
658 if(tmp1==NULL) return defret;
659
660 do {
661 i=memcmp(tmp1,name,namesize);
662 if(i==0) {
663 tmp1+=namesize;
664 if(tmp1[0]=='\"')tmp1+=1;
665 if(strncmp(tmp1,handle,strlen(handle))){
666 i=1;
667 }else {
668 if((tmp1[strsize]!=' ') && (tmp1[strsize]!='\"') && (tmp1[strsize]!='\r') && (tmp1[strsize]!=';') ) i=1;
669 };
670
671 }else {
672 tmp1+=1;
673 };
674 } while(i!=0 && (tmp1+namesize<current_web_client->rbuf+current_web_client->rbufsize)); // Search init of data
675 if(i!=0) return defret;
676 //tmp1+=namesize;
677 tmp2=strstr(tmp1,"filename="); // get filename
678 if(tmp2!=NULL) {
679 tmp2+=9;
680 if(tmp2[0]=='\"')tmp2+=1;
681 tmp3=strstr(tmp2,"\r\n");
682 ml->next->filename=__ILWS_add_buffer(ClientInfo->mem,(tmp3-tmp2)+1);
683 if(ml->next->filename==NULL) {
684 LWSERR(LE_MEMORY);
685 return defret;
686 };
687 memcpy(ml->next->filename,tmp2,tmp3-tmp2);
688 ml->next->filename[tmp3-tmp2]='\0';
689 if(ml->next->filename[tmp3-tmp2-1]=='\"')
690 ml->next->filename[tmp3-tmp2-1]='\0';
691
692 };
693 tmp2=strstr(tmp1,"\r\n\r\n"); // data init
694 if(tmp2==NULL)return defret;
695 tmp2+=4;
696 tmp3=tmp2;
697 do {
698
699 i=memcmp(tmp3,boundary,boundarysize);
700 if(i!=0)tmp3+=1;
701 } while(i!=0 && (tmp3+boundarysize<current_web_client->rbuf+current_web_client->rbufsize)); // End of data
702 if(i!=0) return defret;
703 tmp3-=4; // back "\r\n\r\n"
704
705 // copy data to node
706 if(!(ml->next->data=__ILWS_add_buffer(ClientInfo->mem,(tmp3-tmp2)+1))) {
707 LWSERR(LE_MEMORY);
708 return defret;
709 };
710 memcpy(ml->next->data,tmp2,tmp3-tmp2);
711 ml->next->data[tmp3-tmp2]='\0';
712 ml->next->size=tmp3-tmp2;
713
714
715
716
717 return *ml->next;
718
719};
720
721/*********************************************************************************************************/
722/*
723 * Function for CookieData
724 */
725char *__ILWS_Cookie(char *handle) {
726 char *defret="";
727 char *tmp1,*tmp2,*ret;
728 int size;
729 int strsize;
730 struct _Cookie *cl=ClientInfo->CookieList;
731
732
733 tmp1=strstr(current_web_client->rbuf,"\nCookie: "); // start of cookie string
734 if(tmp1==NULL) { // no cookies
735 return defret;
736 };
737 tmp1+=8;
738 if(handle==NULL) {
739 return ClientInfo->CookieString;
740 };
741
742 if(ClientInfo->CookieList==NULL) {
743
744 ClientInfo->CookieList=__ILWS_add_buffer(ClientInfo->mem,sizeof(struct _Cookie));
745 if(ClientInfo->CookieList==NULL) {
746 LWSERR(LE_MEMORY);
747 return defret;
748 };
749 ClientInfo->CookieList->next=NULL;
750 ClientInfo->CookieList->data=NULL;
751 ClientInfo->CookieList->id=NULL;
752 cl=ClientInfo->CookieList;
753 }
754 // First search if exists
755 while(cl->next!=NULL) {
756 if(cl->next->id!=NULL) {
757 if(!strcmp(cl->next->id,handle)) {
758
759 return cl->next->data;
760 };
761 };
762 cl=cl->next;
763 };
764
765 strsize=strlen(handle);
766 if(!(cl->next=__ILWS_add_buffer(ClientInfo->mem,sizeof(struct _Cookie)))) {
767 LWSERR(LE_MEMORY);
768 return defret;
769 };
770 if(!(cl->next->id=__ILWS_add_buffer(ClientInfo->mem,strsize+1))) {
771 LWSERR(LE_MEMORY);
772 return defret;
773 };
774 memcpy(cl->next->id,handle,strsize);
775 cl->next->id[strsize]=0;
776 cl->next->data=defret;
777 cl->next->next=NULL;
778 do {
779 tmp2=strstr(tmp1,handle);
780 if(tmp2==NULL) {
781 return defret;
782 }else if(tmp2[strsize]==';' && tmp2[-1]==' ') {
783 cl->next->data=__ILWS_add_buffer(ClientInfo->mem,6);
784 snprintf(cl->next->data,5,"True");
785 return cl->next->data;
786 };
787 tmp1=tmp2+strsize;
788 }while(tmp2[-1]!=' ' || tmp2[strsize]!='=');
789
790 tmp1=strstr(tmp2,";"); // end of data
791 tmp2+=strsize+1; // start of data
792 if(tmp1==NULL) {
793 size=strstr(tmp2,"\r")-tmp2;
794
795 } else {
796 size=tmp1-tmp2;
797 };
798 if(size<1) {
799 return defret;
800 };
801
802 ret=__ILWS_add_buffer(ClientInfo->mem,size+1);
803 if(ret==NULL) {
804 LWSERR(LE_MEMORY);
805 return defret;
806 };
807
808 memcpy(ret,tmp2,size);
809 ret[size]='\0';
810 cl->next->data=ret;
811 return cl->next->data;
812};
813
814
815
816/*********************************************************************************************************/
817/*
818 * get whole query string
819 */
820char *__ILWS_clientinfo_getquerystring() {
821 char *tmp1,*tmp2,*ret;
822 char *defret="";
823 size_t size;
824 tmp1=strstr(current_web_client->rbuf,"?");
825 tmp2=strstr(current_web_client->rbuf,"HTTP");
826 if(tmp1!=NULL && tmp1<tmp2)
827 tmp1+=1;
828 else
829 return defret;
830 size=(tmp2-tmp1)-1;
831 ret=__ILWS_add_buffer(ClientInfo->mem,size+1);
832 if(ret==NULL) {
833 LWSERR(LE_MEMORY);
834 return defret;
835 };
836 memcpy(ret,tmp1,size);
837 ret[size]=0;
838 return ret;
839};
840
841
842/*********************************************************************************************************/
843/*
844 * get whole post data
845 */
846char *__ILWS_clientinfo_getpostdata() {
847 char *tmp1,*ret;
848 char *defret="";
849 size_t size;
850 tmp1=strstr(current_web_client->rbuf,"\r\n\r\n");
851 if(tmp1!=NULL && (tmp1+4)<(char*)(current_web_client->rbuf+current_web_client->rbufsize))
852 tmp1+=4;
853 else
854 return defret;
855 size=(current_web_client->rbuf+current_web_client->rbufsize)-tmp1;
856 ret=__ILWS_add_buffer(ClientInfo->mem,size+1);
857 if(ret==NULL) {
858 LWSERR(LE_MEMORY);
859 return defret;
860 };
861 memcpy(ret,tmp1,size);
862 ret[size]='\0';
863 return ret;
864}
865
866
867/*********************************************************************************************************/
868/*
869 * Get authorization username
870 */
871char *__ILWS_clientinfo_getauthuser() {
872 char *tmp1,*tmp2,*ret, *out=NULL;
873 char *defret="";
874 size_t size;
875
876 tmp1=strstr(current_web_client->rbuf,"Authorization: Basic");
877 if(tmp1==NULL) {
878
879 return defret;
880 };
881
882 tmp1+=21;
883 tmp2=strstr(tmp1,"\r\n");
884 if(tmp2==NULL) return defret;
885 size=(int)(tmp2-tmp1);
886
887 ret=__ILWS_malloc(size+1);
888 if(ret==NULL) {
889 LWSERR(LE_MEMORY);
890 return defret;
891 };
892 memcpy(ret,tmp1,size);
893 ret[size]=0;
894
895 out=__ILWS_malloc(size+1);
896 if(out==NULL) {
897 LWSERR(LE_MEMORY);
898 __ILWS_free(ret);
899 return defret;
900 };
901
902 size=__ILWS_base64decode(out,ret);
903 out[size]='\0';
904
905
906 __ILWS_free(ret);
907 tmp2=strstr(out,":");
908 if(tmp2==NULL) return defret;
909
910 ret=__ILWS_add_buffer(ClientInfo->mem,(tmp2-out)+1);
911 if(ret==NULL) {
912 LWSERR(LE_MEMORY);
913 __ILWS_free(out);
914 return defret;
915 };
916 memcpy(ret,out,tmp2-out);
917 ret[tmp2-out]=0;
918
919 __ILWS_free(out);
920 return ret;
921}
922
923
924/*********************************************************************************************************/
925/*
926 * get authorization password
927 */
928char *__ILWS_clientinfo_getauthpass() {
929 char *tmp1,*tmp2,*ret, *out=NULL;
930 char *defret="";
931 size_t size;
932
933 tmp1=strstr(current_web_client->rbuf,"Authorization: Basic");
934 if(tmp1==NULL) {
935
936 return defret;
937 };
938
939 tmp1+=21;
940 tmp2=strstr(tmp1,"\r\n");
941 if(tmp2==NULL) return defret;
942 size=(int)(tmp2-tmp1);
943
944 ret=__ILWS_malloc(size+1);
945 if(ret==NULL) {
946 LWSERR(LE_MEMORY);
947 return defret;
948 };
949 memcpy(ret,tmp1,size);
950 ret[size]=0;
951
952 out=__ILWS_malloc(size+1);
953 if(out==NULL) {
954 LWSERR(LE_MEMORY);
955 __ILWS_free(ret);
956 return defret;
957 };
958
959 size=__ILWS_base64decode(out,ret);
960 out[size]='\0';
961
962
963 __ILWS_free(ret);
964 tmp1=strstr(out,":")+1;
965 tmp2=out+strlen(out);
966
967 ret=__ILWS_add_buffer(ClientInfo->mem,(tmp2-tmp1)+1);
968 if(ret==NULL) {
969 LWSERR(LE_MEMORY);
970 __ILWS_free(out);
971 return defret;
972 };
973 memcpy(ret,tmp1,tmp2-tmp1);
974 ret[tmp2-tmp1]=0;
975
976 __ILWS_free(out);
977 return ret;
978}
979
980
981/*********************************************************************************************************/
982/*
983 * get method (GET POST HEAD etc)
984 */
985char *__ILWS_clientinfo_getmethod() {
986 char *tmp1,*ret;
987 char *defret="";
988 size_t size;
989 tmp1=strstr(current_web_client->rbuf," "); // first space
990 if(tmp1==NULL) {
991 return defret;
992 };
993 size=tmp1-current_web_client->rbuf;
994 ret=__ILWS_add_buffer(ClientInfo->mem,size+1);
995 if(ret==NULL) {
996 LWSERR(LE_MEMORY);
997 return defret;
998 };
999 memcpy(ret,current_web_client->rbuf,size);
1000 ret[size]=0;
1001 return ret;
1002}
1003
1004
1005/*********************************************************************************************************/
1006/*
1007 * get request name (GET /taltal HTTP/1.0) returning /taltal
1008 */
1009char *__ILWS_clientinfo_getreqname() {
1010 char *ret;
1011 char *tmp1=strstr(current_web_client->rbuf,"/"); // Must have /
1012 char *tmp2=strstr(tmp1,"?");
1013 char *tmp3=strstr(tmp1," HTTP");
1014 char *defret="";
1015 size_t i,j;
1016 int ch;
1017 size_t size=0;
1018 if(tmp1==NULL || tmp3==NULL) return defret;
1019 if(tmp2==NULL || tmp2>tmp3) {
1020 tmp2=tmp3;
1021 };
1022 //tmp1+=1;
1023 size=tmp2-tmp1;
1024 if(size<1)
1025 return defret;
1026 ret=__ILWS_add_buffer(ClientInfo->mem,size+1);
1027 if(ret==NULL) {
1028 LWSERR(LE_MEMORY);
1029 return defret;
1030 };
1031 j=0;
1032 for(i=0;i<size;i++) { // hex translation here
1033 switch (ch=tmp1[j]) {
1034 case '+':
1035 ch=' ';
1036 break;
1037 case '%':
1038
1039 tmp2=__ILWS_malloc(3);
1040 if(tmp2==NULL) {
1041 LWSERR(LE_MEMORY);
1042 return defret;
1043 };
1044 strncpy(tmp2,&tmp1[j+1],2);
1045 tmp2[2]=0;
1046
1047 ch=strtol(tmp2,NULL,16);
1048 j+=2;
1049 size-=2;
1050 __ILWS_free(tmp2);
1051 break;
1052 };
1053 ret[i]=ch;
1054 j++;
1055 };
1056 //pl->next->data[size]='\0';
1057 //memcpy(ret,tmp1,size);
1058 ret[size]=0;
1059 return ret;
1060}
1061/*********************************************************************************************************/
1062/*
1063 * Get config entry (new on 0.5.0)
1064 */
1065char *__ILWS_Conf(const char *topic,const char *key) {
1066 struct web_server *server=current_web_server;
1067 FILE *tmpf;
1068 struct stat statf; // tested only on WIN
1069 char *defret="";
1070 char *dataconf;
1071 char *tmp1,*tmp2,*tmp3;
1072 long tmpsize=0;
1073 int sizec;
1074 // Config revive tested only on WIN
1075 if(server->conffile!=NULL) {
1076 stat(server->conffile,&statf);
1077 if(statf.st_mtime>server->conffiletime) {
1078 tmpf=fopen(server->conffile,"r");
1079 if(tmpf!=NULL) {
1080 free(server->dataconf);
1081 fseek(tmpf,SEEK_SET,SEEK_END);
1082 sizec=ftell(tmpf);
1083 fseek(tmpf,0,SEEK_SET);
1084 server->dataconf=malloc(sizec+1);
1085 fread(server->dataconf,sizec,1,tmpf);
1086 server->dataconf[sizec-9]=0; // 9 is temporary
1087 server->conffiletime=statf.st_mtime;
1088 fclose(tmpf);
1089 };
1090 };
1091 };
1092
1093 dataconf=__ILWS_stristr(server->dataconf,topic);
1094 if(dataconf==NULL) {
1095 return defret;
1096 };
1097 dataconf+=strlen(topic);
1098
1099 do {
1100 tmp1=__ILWS_stristr(dataconf,key);
1101 dataconf+=1;
1102 if(dataconf[0]==0) {
1103 return defret;
1104 };
1105 if(dataconf[0]=='[' && dataconf[-1]=='\n') {
1106 return defret;
1107 };
1108 }while(!(tmp1!=NULL && tmp1[-1]=='\n' && tmp1[strlen(key)]=='='));
1109
1110
1111 tmp1+=strlen(key)+1;
1112 tmp2=__ILWS_stristr(tmp1,"\n");
1113 if(tmp2==NULL) {
1114 tmp2=tmp1+strlen(tmp1);
1115 };
1116 tmpsize=tmp2-tmp1;
1117 tmp3=__ILWS_add_buffer(ClientInfo->mem,tmpsize+1);
1118 memcpy(tmp3,tmp1,tmpsize);
1119 tmp3[tmpsize]=0;
1120 return tmp3;
1121
1122
1123
1124};
diff --git a/src/clientinfo.h b/src/clientinfo.h
new file mode 100644
index 00000000..6712f5ba
--- /dev/null
+++ b/src/clientinfo.h
@@ -0,0 +1,118 @@
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: Wed Oct 9 19:05:48 GMT 2002
10 *
11 *
12 * --
13 *
14 */
15
16#ifndef _CLIENTINFO_H_
17#define _CLIENTINFO_H_
18
19#ifdef HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#include <stdio.h>
24#include <fcntl.h>
25#include <string.h>
26
27#include "outstream.h"
28#include "client.h"
29#include "utils.h"
30#include "memory.h"
31#include "server.h"
32#include "error.h"
33
34
35
36/*
37 * Next's structs are redudant but it is an case of logic (spell)
38 */
39struct _Header {
40 char *id;
41 char *data;
42 struct _Header *next;
43};
44struct _Query {
45 unsigned int index;
46 unsigned int idf;
47 char *id;
48 char *data;
49 struct _Query *next;
50};
51struct _Post {
52 unsigned int index;
53 unsigned int idf;
54 char *id;
55 char *data;
56 struct _Post *next;
57};
58
59struct _MultiPart {
60 char *id;
61 char *data;
62 unsigned int size;
63 char *filename;
64 struct _MultiPart *next;
65};
66
67struct _Cookie {
68 char *id;
69 char *data;
70 struct _Cookie *next;
71};
72
73
74extern struct ClientInfo {
75 int outfd;
76 char *inetname;
77 char *request;
78 char *method;
79 char *user;
80 char *pass;
81
82 char *(*Header)(char *);
83 char *(*Query)(char *);
84 char *(*Post)(char *);
85 char *(*Cookie)(char *); // TODO
86 char *(*Conf)(const char *,const char *); // new on 0.5.0
87 struct _MultiPart (*MultiPart)(char *);
88 // not necessary for web_server.h
89 char *QueryString;
90 char *CookieString;
91 char *PostData;
92 struct memrequest *mem;
93 struct _Header *HeaderList; // Not necessary for web_server.h
94 struct _Query *QueryList; // Not necessary for web_server.h
95 struct _Post *PostList; // Not necessary for web_server.h
96 struct _MultiPart *MultiPartList; // Not necessary for web_server.h
97 struct _Cookie *CookieList; // Not necessary for web_server.h
98} *ClientInfo; //tochange
99
100
101void __ILWS_init_clientinfo();
102void __ILWS_free_clientinfo();
103char *__ILWS_clientinfo_getauthuser();
104char *__ILWS_clientinfo_getauthpass();
105char *__ILWS_clientinfo_getquerystring();
106char *__ILWS_clientinfo_getpostdata();
107char *__ILWS_clientinfo_getcookiestring();
108char *__ILWS_clientinfo_getmethod();
109char *__ILWS_clientinfo_getreqname();
110char *__ILWS_Header(char *);
111char *__ILWS_Query(char *);
112char *__ILWS_Post(char *);
113struct _MultiPart __ILWS_MultiPart(char *);
114char *__ILWS_Cookie(char *);
115char *__ILWS_Conf(const char *,const char *);
116
117#endif
118
diff --git a/src/config.h b/src/config.h
new file mode 100644
index 00000000..36b68449
--- /dev/null
+++ b/src/config.h
@@ -0,0 +1,133 @@
1/* include/config.h. Generated from config.h.in by configure. */
2/* include/config.h.in. Generated from configure.ac by autoheader. */
3
4/* Define to 1 if you have the <arpa/inet.h> header file. */
5#define HAVE_ARPA_INET_H 1
6
7/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
8/* #undef HAVE_DOPRNT */
9
10/* Define to 1 if you have the <fcntl.h> header file. */
11#define HAVE_FCNTL_H 1
12
13/* Define to 1 if you have the `inet_ntoa' function. */
14#define HAVE_INET_NTOA 1
15
16/* Define to 1 if you have the <inttypes.h> header file. */
17#define HAVE_INTTYPES_H 1
18
19/* Define to 1 if you have the <limits.h> header file. */
20#define HAVE_LIMITS_H 1
21
22/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
23 to 0 otherwise. */
24#define HAVE_MALLOC 1
25
26/* Define to 1 if you have the <memory.h> header file. */
27#define HAVE_MEMORY_H 1
28
29/* Define to 1 if you have the `memset' function. */
30#define HAVE_MEMSET 1
31
32/* Define to 1 if you have the <netinet/in.h> header file. */
33#define HAVE_NETINET_IN_H 1
34
35/* Define to 1 if your system has a GNU libc compatible `realloc' function,
36 and to 0 otherwise. */
37#define HAVE_REALLOC 1
38
39/* Define to 1 if you have the `select' function. */
40#define HAVE_SELECT 1
41
42/* Define to 1 if you have the `socket' function. */
43#define HAVE_SOCKET 1
44
45/* Define to 1 if you have the <stddef.h> header file. */
46#define HAVE_STDDEF_H 1
47
48/* Define to 1 if you have the <stdint.h> header file. */
49#define HAVE_STDINT_H 1
50
51/* Define to 1 if you have the <stdlib.h> header file. */
52#define HAVE_STDLIB_H 1
53
54/* Define to 1 if you have the `strchr' function. */
55#define HAVE_STRCHR 1
56
57/* Define to 1 if you have the `strerror' function. */
58#define HAVE_STRERROR 1
59
60/* Define to 1 if you have the `strftime' function. */
61#define HAVE_STRFTIME 1
62
63/* Define to 1 if you have the <strings.h> header file. */
64#define HAVE_STRINGS_H 1
65
66/* Define to 1 if you have the <string.h> header file. */
67#define HAVE_STRING_H 1
68
69/* Define to 1 if you have the `strncasecmp' function. */
70#define HAVE_STRNCASECMP 1
71
72/* Define to 1 if you have the `strstr' function. */
73#define HAVE_STRSTR 1
74
75/* Define to 1 if you have the `strtol' function. */
76#define HAVE_STRTOL 1
77
78/* Define to 1 if you have the <sys/socket.h> header file. */
79#define HAVE_SYS_SOCKET_H 1
80
81/* Define to 1 if you have the <sys/stat.h> header file. */
82#define HAVE_SYS_STAT_H 1
83
84/* Define to 1 if you have the <sys/time.h> header file. */
85#define HAVE_SYS_TIME_H 1
86
87/* Define to 1 if you have the <sys/types.h> header file. */
88#define HAVE_SYS_TYPES_H 1
89
90/* Define to 1 if you have the <unistd.h> header file. */
91#define HAVE_UNISTD_H 1
92
93/* Define to 1 if you have the `vprintf' function. */
94#define HAVE_VPRINTF 1
95
96/* Define to the address where bug reports for this package should be sent. */
97#define PACKAGE_BUGREPORT "bug-gnunet@gnu.org"
98
99/* Define to the full name of this package. */
100#define PACKAGE_NAME "libwebserver"
101
102/* Define to the full name and version of this package. */
103#define PACKAGE_STRING "libwebserver 0.5.3-GNUnet"
104
105/* Define to the one symbol short name of this package. */
106#define PACKAGE_TARNAME "libwebserver"
107
108/* Define to the version of this package. */
109#define PACKAGE_VERSION "0.5.3-GNUnet"
110
111/* Define as the return type of signal handlers (`int' or `void'). */
112#define RETSIGTYPE void
113
114/* Define to 1 if you have the ANSI C header files. */
115#define STDC_HEADERS 1
116
117/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
118#define TIME_WITH_SYS_TIME 1
119
120/* Define to 1 if your <sys/time.h> declares `struct tm'. */
121/* #undef TM_IN_SYS_TIME */
122
123/* Define to empty if `const' does not conform to ANSI C. */
124/* #undef const */
125
126/* Define to rpl_malloc if the replacement function should be used. */
127/* #undef malloc */
128
129/* Define to rpl_realloc if the replacement function should be used. */
130/* #undef realloc */
131
132/* Define to `unsigned int' if <sys/types.h> does not define. */
133/* #undef size_t */
diff --git a/src/debug.h b/src/debug.h
new file mode 100644
index 00000000..d128ab7a
--- /dev/null
+++ b/src/debug.h
@@ -0,0 +1,29 @@
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:16:05 GMT 2002
10 *
11 * DEBUG macros
12 *
13 */
14
15#ifndef _DEBUG_H_
16#define _DEBUG_H_
17
18#ifdef HAVE_CONFIG_H
19#include "config.h"
20#endif
21
22#ifdef DEBUG
23 #define IFDEBUG(x) x
24#else
25 #define IFDEBUG(x)
26#endif
27
28
29#endif
diff --git a/src/error.c b/src/error.c
new file mode 100644
index 00000000..43df1c30
--- /dev/null
+++ b/src/error.c
@@ -0,0 +1,34 @@
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: Wed Oct 9 19:56:22 GMT 2002
10 *
11 * -- Error functions
12 *
13 */
14
15
16#include "error.h"
17
18
19const char *libws_error_table[]={
20 "Memory error",
21 "Filesystem error",
22 "Network error"
23};
24
25
26void libws_error(unsigned int code, const char *fmt, ...) {
27 va_list args;
28
29 va_start(args,fmt);
30 fprintf(stderr,"%s: ",libws_error_table[code]);
31 vfprintf(stderr,fmt,args);
32 va_end(args);
33 fflush(stderr);
34};
diff --git a/src/error.h b/src/error.h
new file mode 100644
index 00000000..facac79d
--- /dev/null
+++ b/src/error.h
@@ -0,0 +1,33 @@
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: Tue 9 Sep 06:45:13 2003 GMT
10 *
11 * libwebserver error codes
12 *
13 */
14
15
16#ifndef _ERROR_H_
17#define _ERROR_H_
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <stdarg.h>
22
23
24#define LE_MEMORY 0 // memory error
25#define LE_FILESYS 1 // file error
26#define LE_NET 2 // net error
27
28#define LWSERR(x) libws_error(x,"file: %s - line: %d\n",__FILE__, __LINE__);
29
30void libws_error(unsigned int, const char *,...);
31
32
33#endif
diff --git a/src/fnmatch.c b/src/fnmatch.c
new file mode 100644
index 00000000..f2b6f6d4
--- /dev/null
+++ b/src/fnmatch.c
@@ -0,0 +1,195 @@
1/*
2 * Luis Figueiredo - why remake the wheel, this functions feets perfectly
3 * and the credits still here :)
4 */
5
6/*
7 * Copyright (c) 1989, 1993, 1994
8 * The Regents of the University of California. All rights reserved.
9 *
10 * This code is derived from software contributed to Berkeley by
11 * Guido van Rossum.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. All advertising materials mentioning features or use of this software
22 * must display the following acknowledgement:
23 * This product includes software developed by the University of
24 * California, Berkeley and its contributors.
25 * 4. Neither the name of the University nor the names of its contributors
26 * may be used to endorse or promote products derived from this software
27 * without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * SUCH DAMAGE.
40 */
41
42#if defined(LIBC_SCCS) && !defined(lint)
43static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94";
44#endif /* LIBC_SCCS and not lint */
45
46/*
47 * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
48 * Compares a filename or pathname to a pattern.
49 */
50
51#include "fnmatch.h"
52#include <string.h>
53
54#define EOS '\0'
55
56static const char *rangematch(const char *, int, int);
57
58int fnmatch(const char *pattern, const char *string, int flags) {
59 const char *stringstart;
60 char c, test;
61
62 for (stringstart = string;;) {
63 switch (c = *pattern++) {
64 case EOS:
65 return (*string == EOS ? 0 : FNM_NOMATCH);
66 case '?':
67 if (*string == EOS) {
68 return (FNM_NOMATCH);
69 }
70 if (*string == '/' && (flags & FNM_PATHNAME)) {
71 return (FNM_NOMATCH);
72 }
73 if (*string == '.' && (flags & FNM_PERIOD) &&
74 (string == stringstart ||
75 ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) {
76 return (FNM_NOMATCH);
77 }
78 ++string;
79 break;
80 case '*':
81 c = *pattern;
82 /* Collapse multiple stars. */
83 while (c == '*') {
84 c = *++pattern;
85 }
86
87 if (*string == '.' && (flags & FNM_PERIOD) &&
88 (string == stringstart ||
89 ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) {
90 return (FNM_NOMATCH);
91 }
92
93 /* Optimize for pattern with * at end or before /. */
94 if (c == EOS) {
95 if (flags & FNM_PATHNAME) {
96 return (strchr(string, '/') == NULL ? 0 : FNM_NOMATCH);
97 }
98 else {
99 return (0);
100 }
101 }
102 else if (c == '/' && flags & FNM_PATHNAME) {
103 if ((string = strchr(string, '/')) == NULL) {
104 return (FNM_NOMATCH);
105 }
106 break;
107 }
108
109 /* General case, use recursion. */
110 while ((test = *string) != EOS) {
111 if (!fnmatch(pattern, string, flags & ~FNM_PERIOD)) {
112 return (0);
113 }
114 if (test == '/' && flags & FNM_PATHNAME) {
115 break;
116 }
117 ++string;
118 }
119 return (FNM_NOMATCH);
120 case '[':
121 if (*string == EOS) {
122 return (FNM_NOMATCH);
123 }
124 if (*string == '/' && flags & FNM_PATHNAME) {
125 return (FNM_NOMATCH);
126 }
127 if (*string == '.' && (flags & FNM_PERIOD) &&
128 (string == stringstart ||
129 ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) {
130 return (FNM_NOMATCH);
131 }
132 if ((pattern = rangematch(pattern, *string, flags)) == NULL) {
133 return (FNM_NOMATCH);
134 }
135 ++string;
136 break;
137 case '\\':
138 if (!(flags & FNM_NOESCAPE)) {
139 if ((c = *pattern++) == EOS) {
140 c = '\\';
141 --pattern;
142 }
143 }
144 /* FALLTHROUGH */
145 default:
146 if (c != *string) {
147 return (FNM_NOMATCH);
148 }
149 string++;
150 break;
151 }
152 /* NOTREACHED */
153 }
154}
155
156static const char *rangematch(const char *pattern, int test, int flags) {
157 int negate, ok;
158 char c, c2;
159
160 /*
161 * A bracket expression starting with an unquoted circumflex
162 * character produces unspecified results (IEEE 1003.2-1992,
163 * 3.13.2). This implementation treats it like '!', for
164 * consistency with the regular expression syntax.
165 * J.T. Conklin (conklin@ngai.kaleida.com)
166 */
167 if ((negate = (*pattern == '!' || *pattern == '^'))) {
168 ++pattern;
169 }
170
171 for (ok = 0; (c = *pattern++) != ']';) {
172 if (c == '\\' && !(flags & FNM_NOESCAPE)) {
173 c = *pattern++;
174 }
175 if (c == EOS) {
176 return (NULL);
177 }
178 if (*pattern == '-' && (c2 = *(pattern + 1)) != EOS && c2 != ']') {
179 pattern += 2;
180 if (c2 == '\\' && !(flags & FNM_NOESCAPE)) {
181 c2 = *pattern++;
182 }
183 if (c2 == EOS) {
184 return (NULL);
185 }
186 if ((c <= test && test <= c2)) {
187 ok = 1;
188 }
189 }
190 else if ((c == test)) {
191 ok = 1;
192 }
193 }
194 return (ok == negate ? NULL : pattern);
195}
diff --git a/src/fnmatch.h b/src/fnmatch.h
new file mode 100644
index 00000000..1b0f3fc9
--- /dev/null
+++ b/src/fnmatch.h
@@ -0,0 +1,59 @@
1/*-
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)fnmatch.h 8.1 (Berkeley) 6/2/93
34 */
35
36/* This file has been modified by the Apache Group. */
37
38#ifndef _FNMATCH_H_
39#define _FNMATCH_H_
40
41#ifdef __cplusplus
42extern "C" {
43#endif
44
45#define FNM_NOMATCH 1 /* Match failed. */
46
47#define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */
48#define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */
49#define FNM_PERIOD 0x04 /* Period must be matched by period. */
50/* This flag is an Apache addition */
51#define FNM_CASE_BLIND 0x08 /* Compare characters case-insensitively. */
52
53int fnmatch(const char *, const char *, int);
54
55#ifdef __cplusplus
56}
57#endif
58
59#endif /* !_FNMATCH_H_ */
diff --git a/src/gethandler.c b/src/gethandler.c
new file mode 100644
index 00000000..297d53a6
--- /dev/null
+++ b/src/gethandler.c
@@ -0,0 +1,96 @@
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 * -- handlers functions
12 *
13 */
14
15
16
17#include "gethandler.h"
18
19
20/*********************************************************************************************************/
21/*
22 * initializate (allocate) handler list
23 */
24struct gethandler *__ILWS_init_handler_list() {
25 struct gethandler *ret;
26
27 ret=__ILWS_malloc(sizeof(struct gethandler));
28 if(ret==NULL) {
29 LWSERR(LE_MEMORY);
30 return NULL;
31 };
32 ret->next=NULL;
33 ret->hdl.func=NULL; // or path
34 ret->flag=0;
35 ret->str=NULL;
36 return ret;
37}
38
39/*********************************************************************************************************/
40/*
41 * add an handler to list
42 */
43int __ILWS_add_handler(struct gethandler *handler, const char *mstr, void (*func)(), char *path, int flag, int type) {
44 struct gethandler *temp=handler;
45 while(temp->next!=NULL)temp=temp->next;
46
47 temp->next=__ILWS_malloc(sizeof(struct gethandler));
48 if(temp->next==NULL) {
49 LWSERR(LE_MEMORY);
50 return 0;
51 };
52
53 temp->next->str=__ILWS_malloc(strlen(mstr)+1);
54 if(temp->next->str==NULL) {
55 __ILWS_free(temp->next); // free last malloced
56 LWSERR(LE_MEMORY);
57 return 0;
58 };
59 memcpy(temp->next->str,mstr,strlen(mstr));
60 temp->next->str[strlen(mstr)]='\0';
61
62 temp->next->type=type;
63 switch (temp->next->type) {
64 case 0:
65 temp->next->hdl.func=func; // for function
66 break;
67 case 1: // new on 0.5.2 // directory or cgi
68 case 2:
69 if(!(temp->next->hdl.path=strdup(path))) {
70 __ILWS_free(temp->next->str);
71 __ILWS_free(temp->next);
72 LWSERR(LE_MEMORY);
73 return 0;
74 };
75
76 break;
77 };
78
79 temp->next->flag=flag;
80 temp->next->next=NULL;
81 return 1;
82}
83
84/*********************************************************************************************************/
85/*
86 * Deletes the entire handler list
87 */
88void __ILWS_delete_handler_list(struct gethandler *handler) {
89 struct gethandler *next;
90
91 while(handler) {
92 next = handler->next;
93 __ILWS_free(handler);
94 handler = next;
95 }
96}
diff --git a/src/gethandler.h b/src/gethandler.h
new file mode 100644
index 00000000..dc0b66cb
--- /dev/null
+++ b/src/gethandler.h
@@ -0,0 +1,60 @@
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 *
12 * --
13 *
14 */
15
16
17#ifndef _GETHANDLER_H_
18#define _GETHANDLER_H_
19
20#ifdef HAVE_CONFIG_H
21#include "config.h"
22#endif
23#include <stdio.h>
24
25
26#include "memory.h"
27#include "error.h"
28
29
30#define MATCHMAX 200
31
32//#define WS_LOCAL 0x1
33#define WS_DYNVAR 0x8
34#define WS_USELEN 0x10
35
36
37/*********************
38 * get handler types *
39 *********************/
40#define GH_FUNCTION 0 // new on 0.5.2
41#define GH_DIRECTORY 1 // new on 0.5.2
42#define GH_CGI 2 // new on 0.5.2 (just the flag)
43
44
45struct gethandler {
46 char *str;
47 int type; // new on 0.5.2 types
48 union hdl_u{ // changed on 0.5.3 named union (Hilobok Andrew (han@km.if.ua) said that wasn't compiling on FreeBSD)
49 void (*func)(); // it is a function
50 char *path; // it is a path (dir or cgi)
51 }hdl;
52 int flag;
53 struct gethandler *next;
54};
55
56struct gethandler *__ILWS_init_handler_list();
57int __ILWS_add_handler(struct gethandler *,const char *,void (*func)(),char *, int,int);
58void __ILWS_delete_handler_list(struct gethandler *);
59
60#endif
diff --git a/src/logo.h b/src/logo.h
new file mode 100644
index 00000000..3fa5e31c
--- /dev/null
+++ b/src/logo.h
@@ -0,0 +1,396 @@
1/*
2 * by data2header by Luis Figueiredo (stdio@netc.pt)
3 */
4#ifndef __LOGO_H_
5#define __LOGO_H_
6
7char _logo[]="\x47\x49\x46\x38\x39\x61\x5\x1\x45\x0\xE7\x0\x0\x2\x2\x2\xFE\xFE\xFD\xF0\xF2\xF5\xE8\xED\xF0"
8"\xDC\xE8\xEE\xBD\xC1\xC6\x68\x71\x7C\x60\x16\x7\x7A\x1C\xA\xA9\xC8\xDD\x9E\xC3\xDA\x94\xBD\xD8\x8C\xBB"
9"\xD6\x86\xB6\xD6\x15\x26\x3F\x1B\x2C\x49\x1F\x32\x4D\x24\x38\x54\x30\x4A\x66\x4E\x5C\x68\x6E\x7E\x85\xAB"
10"\xAE\xB2\xF6\xF6\xF7\xD6\xE1\xE8\xC8\xDA\xE6\xC5\xC7\xC0\xB0\xBC\xC6\x97\xAA\xB5\x8E\x96\x9B\x5F\x60\x62"
11"\x39\x45\x48\x1F\x26\x23\x7\xA\xD\x4A\x10\x6\x34\xB\x3\x3D\xE\x6\x70\x1C\xB\x9F\x24\xE\xE7\x5C"
12"\x45\x3B\x5C\x78\xD3\xD4\xD4\x7C\x89\x90\xF\x12\x10\x54\x13\x6\xCA\x36\x1C\xB0\xD1\xE5\x5D\x94\xB3\x3D"
13"\x62\x7F\x1F\x22\x19\xD6\x4C\x35\x70\xB0\xD0\xA\x22\x43\x2C\x44\x60\x2E\x2F\x1F\xE9\x69\x4F\xBB\xD4\xE6"
14"\x80\xCA\xEB\x7D\xC6\xE8\x79\xC0\xE1\x73\xB8\xDA\x69\xAA\xCA\x66\xA4\xC6\x58\x9B\xC4\x4D\x8D\xB5\x51\x82"
15"\xA1\x4A\x76\x94\x33\x4E\x68\x28\x3E\x5A\x4D\x4D\x4F\x78\x80\x87\x3D\x3E\x3D\xF\x16\x1B\x8C\x20\xC\xFC"
16"\x7F\x64\x83\xD0\xF1\x41\x68\x85\x2A\x38\x3E\x3F\x45\x2F\x13\x1A\x23\x35\x54\x71\x62\x9C\xBD\x12\x1E\x2B"
17"\x49\x72\x8F\x4E\x7C\x9B\xD0\x41\x27\x58\x88\xA6\x28\x68\x93\x38\x53\x5E\x17\x22\x26\xDA\x56\x3B\x5B\x8E"
18"\xAB\xF6\x72\x5C\x6F\x6F\x42\xFC\xFC\xD1\xFD\xFE\xC6\x66\x4A\xC\x99\xEE\xFE\x45\x6E\x8C\xE0\xE1\x8C\xEE"
19"\xE9\x8B\x21\x6\x2\xA3\xFC\xFE\xC8\xFE\xFD\xFD\xFE\xDF\xFA\xFB\xB8\xFD\xFC\xA4\x86\xA6\x7A\xB0\xA8\x2E"
20"\xF4\xF0\x88\x9A\xA4\x72\x58\x3B\x1E\x18\x16\x2\xB3\xB0\x5D\xD0\xCF\x64\xFD\xFD\x71\xFE\xFD\x89\xFE\xFC"
21"\x5C\xFE\xFD\x49\xFE\xFD\x20\x70\x6B\x15\x3C\x39\x13\x89\x81\x1E\x4B\x4A\x2B\xB9\x2B\x10\xBC\xC0\x7E\x28"
22"\x26\xB\x9C\x98\x40\xF2\xEC\x69\xC7\xB8\x3E\x90\x8C\x3F\x7B\x7B\x32\x31\x2F\xB\x1A\x6\x2\x1C\x1A\x7"
23"\x7D\x98\x9F\xEC\xE2\x6A\x1F\x2E\x35\x90\xDD\xF9\x46\x56\x60\x88\xDF\xFE\x61\x5A\x13\x7C\x7E\x3E\x50\x49"
24"\xF\xFE\xFB\x32\xCC\xC5\x49\x7E\x71\x2E\xBC\xB5\x2C\x9A\x91\x17\xD2\xC5\x21\x97\xA8\x84\xFD\xEE\x1D\x6E"
25"\x7E\x4A\xDF\xD6\x3D\xF3\xE7\x41\x71\x6E\x2C\xB4\xD4\xAE\xFE\xD0\x5E\x82\x5C\x28\x20\x1E\x5\x51\x54\x2A"
26"\xD0\x98\x34\xFB\xF0\x4B\xD5\xA7\x2F\xFA\xC6\x5E\xB9\x9A\x1F\xFE\xBD\x3F\xFE\xD9\x37\x92\x91\x78\xF6\xAA"
27"\x3D\x8E\x5A\x1D\x38\x82\xB0\x5A\x6B\x69\xB5\x5E\x23\x42\x26\x1A\x51\x55\x44\xCE\xB7\x21\x25\x22\x7\xE5"
28"\xD9\x18\x7C\x32\x19\xAA\x5B\x2A\x8A\x38\x1C\x9E\x4A\x20\xA8\x3E\x26\xB6\x72\x26\xDC\x91\x26\xAE\x5A\x22"
29"\xCE\xC3\x67\xB7\x80\x28\x98\x6E\x22\x68\x30\x17\x56\x2A\xE\x4E\x26\xE\x96\x56\x1C\xAE\x70\x20\x2B\xB"
30"\x3\x36\x39\x2B\x16\x22\x3D\x17\x22\x2A\x9\xE\x11\x7E\xB0\xCF\x7A\xAF\xD1\x71\xA9\xCA\x31\x7B\xAB\x2E"
31"\x75\xA6\x1A\x48\x68\xD\x2E\x47\x42\x89\xB6\x84\xAF\xCA\x80\xB7\xD6\x73\x98\xB0\x4E\x98\xC5\x86\xA7\xAE"
32"\x63\x7E\x8C\x50\x6A\x7B\x65\x86\x7E\x75\x8B\x9A\xAA\xAA\x78\xCD\xD3\xC8\x5D\xB0\xE4\x8A\xA2\x66\xFE\xFE"
33"\xE6\xD9\xFE\xEF\xEA\xEA\xA8\xD8\xE2\xA4\x8A\xAA\x62\xD5\xD4\x87\x82\x80\x50\xCC\xC5\x84\x6C\x6F\x5E\xDC"
34"\xDB\x9F\x5B\x5B\x34\x28\x74\xA4\x23\x6E\xA0\x1B\x68\x9B\x19\x60\x8F\xF\x5F\x94\x1B\x54\x79\x22\x5F\x87"
35"\x9C\xD4\xF3\xC2\xE8\xF4\xC4\xF6\xFE\xA8\xE2\xFE\xA8\xE6\xF8\x54\xA8\xDD\xE2\xFC\xFE\x5E\x5E\x4B\xDE\xDD"
36"\xB6\xB8\xBF\xA8\xBB\xBF\x95\xFE\x42\x1E\xD9\xDA\xC0\x13\x39\x53\x34\x8C\xC5\xFE\xAE\x9A\xFF\xFF\xFF\xFF"
37"\xFF\xFF\x21\xFE\x12\x62\x79\x20\x4C\x75\x69\x73\x20\x46\x69\x67\x75\x65\x69\x72\x65\x64\x6F\x0\x21\xF9"
38"\x4\x1\xA\x0\xFF\x0\x2C\x0\x0\x0\x0\x5\x1\x45\x0\x0\x8\xFE\x0\xFF\x9\x1C\xF8\xF\x0\x80"
39"\x0\x6\x1\x8\x48\x38\x20\x21\x81\x84\x5\x12\x1A\x48\x78\x20\x21\x82\x84\x9\x12\x2A\xD0\x98\x70\x41"
40"\x42\x6\x9\x1B\x24\x3C\x96\x10\x59\x42\x19\x9\x93\x25\xEC\xB1\x32\xA1\x8B\x84\x53\x12\x3E\x49\x58\x2C"
41"\x61\x88\x84\x24\x12\xDA\x48\xA8\x8C\xA7\x4F\x83\x3D\xD\x2E\x4B\x38\x54\x28\xD1\x84\xE7\x90\x2A\x35\x98"
42"\xD4\x20\xBA\x84\x4F\x9D\x26\x4C\x37\x35\xA1\xBA\x84\xCC\x12\xEE\x4B\x38\x23\xA1\x57\x11\x38\x75\x26\x5C"
43"\x37\xB6\xAC\x41\xB2\x67\xCD\x2\x40\xBB\x36\x21\xC1\xB7\x70\x5\x3A\x78\x0\x21\x82\x84\x9\x14\x2A\x4"
44"\xB0\x20\xA0\xEF\x80\xBF\x4\x8\x5C\xC0\x90\x41\xC3\x6\xE\x14\x3A\x78\xF8\x0\x22\x84\x88\x11\x24\x4A"
45"\x98\x30\x91\xA0\xB2\x82\x4\xA\x32\x6B\x5E\xA0\x60\x81\xE7\x5\xC\x42\x33\x68\x40\x9A\xC1\xB1\xD3\xA7"
46"\x91\x21\x3B\x86\x2C\x99\xEB\xD7\xC9\x7A\xC8\x9E\xD\x5\x8A\xF\x17\x3F\x7E\x4C\x59\xB6\xE4\xC5\x13\x66"
47"\x11\x9A\x45\x1\x71\x60\xC5\x88\xC7\x2B\x10\xEC\x89\x91\x24\x8B\xB2\xE7\xD0\xA3\x3F\x5F\xA6\x6C\x99\x75"
48"\xEA\xD7\xAB\x5F\xB7\x7E\x6E\xD9\xB9\xEF\xE0\xC1\xFE\xA3\x3B\x37\x1E\x9D\xF9\xF3\xE4\xCF\xAB\x4F\x87\x8E"
49"\x7D\xBA\xF7\xEF\xD5\xC9\x5F\xC7\xAE\x3E\xB3\xFB\xFB\xF6\x35\x6B\x36\x63\xC6\x11\x63\x6\xAD\x10\xC2\x71"
50"\x8F\x85\x40\x2\x12\x7B\x50\x61\xC3\x16\x59\xB0\xB0\xCE\x83\x10\x46\x28\xE1\x84\x12\xB2\x33\x61\x5C\x70"
51"\x19\x74\x42\x42\xE\x24\xE4\x41\x42\x8\x19\xB4\x90\x41\x28\x24\x94\x42\x42\x2A\x24\xB4\x42\x42\x2C\x24"
52"\xD4\x2\x47\x6\x6D\x64\x90\x47\x33\x76\x14\xD2\x48\x25\xE5\x68\x90\x4A\x6\xB1\x64\x90\x16\x9\x2D\x91"
53"\x10\x4\x2A\xDA\x94\x90\x9\x9\xA9\xF2\x13\x0\x41\x31\xB9\x64\x93\x45\x1\x10\x65\x53\x0\x50\x69\xE5"
54"\x52\x0\x44\x55\x25\x96\x54\x19\xD4\x8E\x5A\x59\x19\xD4\x4C\x42\x0\x1A\x74\x93\x99\x9\xED\x91\x50\x16"
55"\x56\xA9\xC5\xD6\x9B\x6E\xAA\x85\xA1\x40\x2E\x25\xF4\x2\x87\x9\x49\x90\x90\x5\x9\x5D\x90\x10\x7\x9"
56"\xC1\x60\xA4\x41\x31\xB8\x68\xA8\x41\x19\xC5\x8\x23\x0\x34\x2\x0\x92\x41\x22\x19\x44\x92\x41\x26\xED"
57"\xD8\x92\x41\x2F\x19\x14\x44\x42\x34\x78\x95\x10\x58\x84\x26\xE4\x4C\x92\x4F\x96\xA\xD4\x51\x46\x31\x85"
58"\xE5\x95\xAA\x4A\xE5\x6A\x96\xFE\x55\x19\xC4\xE\x56\x9\x8D\x69\xD0\x11\x45\x1A\x4\x2A\x0\x48\x24\xB4"
59"\x45\xAC\x0\x5C\x95\xD6\xB0\x6D\x11\xB\xE7\x59\x73\x9E\x54\xA7\x41\x77\x1A\xD4\x95\x41\x9D\x1A\xD4\x90"
60"\x41\x15\x24\x54\xC3\xA7\x62\x19\x74\xC3\xA1\x0\x24\xDA\xED\xA2\x8D\x36\xFA\x28\x0\x91\x2\x30\x29\x0"
61"\x95\x2\xC0\x23\x0\x50\xC0\x94\x67\x42\x20\x60\x6B\x90\x9A\x6\xFD\x20\x2A\xA9\xA7\xE6\xEB\xA4\xBE\x51"
62"\xF6\xBB\xEA\xBF\xAF\x6A\xA9\x65\x97\xC1\xD2\x6A\xD0\x56\xCE\x52\x24\x2F\x0\x39\x19\xB4\x93\xB1\x71\x42"
63"\x2C\xF1\x5A\x18\xE2\x90\xC3\xC5\x3A\xE8\xB0\xC3\xE\x32\xF0\xD0\xC3\x6D\x3F\x0\x11\xC4\xB\x42\xF4\x37"
64"\xC3\x5C\x11\xC\x41\xC4\x4\x6\x54\xC0\x41\x11\x1D\x18\x71\xC4\x1\xC7\x85\x80\x4\xB\x49\xB0\x70\xC1"
65"\xCE\x18\xF4\x7C\xC3\xCF\x2D\x4\x9D\x40\xB\x95\x61\x86\x99\x66\x9D\x75\xF6\x19\x68\xA2\x91\xD6\x0\x3"
66"\xCF\x40\x83\x1A\x6B\xAC\xB9\x16\xD\x14\x2E\x54\x1\xC4\x14\x61\xF8\x46\x3\x13\xE\xE0\x2A\xA0\x8\x22"
67"\x18\x58\x2\xB\x5B\x98\xC0\x42\x6E\xB9\x39\xE3\xB6\xDB\xAA\x38\xA3\x8A\x2A\xD2\xD5\x4D\xDD\x74\xD6\x69"
68"\xB7\xDD\xFE\x75\xDD\x85\x27\x9E\xDF\xE9\xA5\xA7\x1E\x3A\x56\x58\xF1\x5E\x3B\xF2\xD5\xC7\xE\x7E\xFA\xF1"
69"\xE7\x1F\x80\xC5\xD\x48\xF6\x8\x2B\x1C\xB8\xDC\x82\xD\xA6\xB3\x8E\x3A\x9A\x6F\xDE\xF9\xE6\x14\x86\x7E"
70"\x21\x5C\x4A\x24\x84\x43\x42\x3A\x28\x6B\x90\xF\x41\x72\x95\x10\x13\x9\x35\xB1\xF0\xC3\x0\x3C\x64\x90"
71"\x9F\x6\x61\xC0\xED\x8B\x88\x2E\x2A\x23\xA3\x36\x42\x8A\xA3\xA5\x6\x55\x61\x27\x4D\x9\x8D\x60\xD1\x9A"
72"\x9\x49\x93\x90\xBD\x6\x8D\x6A\x90\x92\xFA\x36\x69\xFD\x92\xFE\xB6\xBA\xA5\xF6\xAC\xC2\x6A\x10\xC1\xC2"
73"\x2\x10\x26\x0\xB6\x2\x50\x26\x0\x67\xA2\x9F\x26\xF3\xDF\x3\x1B\xFE\xB1\xC5\xC6\x4F\x56\x86\xA5\x1B"
74"\x54\x3F\x0\xA7\x1B\x94\xBA\x41\x28\xAD\xDE\xBA\x41\x4E\x48\x8\xAE\xC\xA2\xBC\x50\x49\xCB\x21\x7D\x4A"
75"\x88\xEE\xC\xC2\xBB\x6F\xF5\x4E\x51\x10\x4\x9E\x41\xC6\x35\xAE\x73\x45\xE3\x7F\x0\x40\xC4\xA0\x18\x96"
76"\x2D\x0\x64\xA\x0\xD0\x3\xE1\xBD\xA2\x87\xAF\x7D\x99\xF0\x7A\xA9\x92\x12\xC0\xB6\xC7\x42\x2D\x59\xA1"
77"\x4D\x6\x19\x5F\xF9\x6\x8\x80\x15\xE9\x2A\x21\xBD\x32\xC8\xAF\xDA\x67\x90\xF0\x11\xC\x7C\xFE\x11\x2B"
78"\xD6\x5B\x0\x90\x83\x84\xDC\xEF\x7E\xF9\x3\xC0\xFE\x0\xD0\x3F\xF\xCA\x4\x5E\x1B\x6C\x91\x88\x18\x92"
79"\xC0\xDC\x25\x64\x5B\xC\xC4\x88\x16\x23\x18\xAE\x8F\x24\xE4\x19\x9\x69\x97\x41\xA4\x90\x90\x8\xE4\xAA"
80"\x86\xBE\x4A\x8\xEB\xFC\x57\xAF\xE7\x8D\x10\x0\xD4\x3B\xA1\xA9\x54\x98\xC2\x29\xAD\x90\x4A\x2F\xF4\x52"
81"\x42\x66\x75\x30\xD7\x19\xA4\x22\x37\x34\xC8\x45\x1C\x6\x2C\x82\xC1\xEF\x90\x72\x1A\x48\xC6\x32\x76\x31"
82"\x1C\x38\x12\x7\x4A\x88\xA4\x24\x1F\x99\x83\x45\x6E\x4C\x6\x3D\x80\x42\xC8\x96\x70\x2\x1A\x40\x60\x38"
83"\xE8\x7B\xCC\x1\x24\x63\x82\xBC\x58\x80\x2F\x7E\x1\x4C\x60\x4\xB3\xB3\xC1\xF4\xC\x3\x40\xBB\x81\xD0"
84"\x8A\x66\x19\xA4\x25\x6D\x69\xC\x58\xC0\xD3\x9E\xF1\x8C\x64\x4C\x23\x1A\x2E\xA0\x6\x35\xAA\x71\x2\x21"
85"\xD0\x0\x11\xC3\x39\x80\x63\x44\x89\x20\x13\x6C\x81\xA\xB3\xF1\xC1\xC7\x7C\x40\x4D\x1F\x48\x43\x1A\x3F"
86"\xC0\x26\xDB\xDE\x6\x37\xB8\xD1\xAD\x6E\xE0\xCC\xCE\xDE\xC6\x9\x38\xF2\xFC\xAD\x70\xE9\xB0\x82\x3A\xDA"
87"\xA1\xB8\xFB\x30\xA3\x71\xFD\xF9\xF\x0\x22\x47\x36\xE4\x44\xE6\x72\x5B\xFE\x88\xC1\x1E\xE0\xC3\xCF\x74"
88"\x70\x8E\x73\x9A\x8B\x8F\xE7\x20\xA4\x8E\x9\x19\x64\x20\x4A\x44\x5D\x42\x8A\x68\x3F\x23\x9A\x6E\xA1\x61"
89"\x7C\xD7\x1F\x71\x98\x90\x21\x24\x64\x3\x7B\xA2\xA2\x41\x6C\x7\x0\xDC\x1\x60\x81\x0\x68\x60\x3\xBD"
90"\xF5\xBB\xDF\x35\x6A\x1A\x9\xB1\x46\x42\x84\xE0\xA9\x40\x2\x80\xA\x97\x2\x80\x8F\xD8\xA5\xC6\xE6\xB9"
91"\x91\x84\x38\x95\x63\xF5\xB0\x87\x2A\x16\x76\x2F\x8F\x0\xE0\xA3\xF8\x6A\x45\xA6\xD\xA6\x8F\x5E\x0\x28"
92"\x14\xF\x1\xF0\xC3\x42\xBA\xCF\x53\x74\xDA\x81\x42\xF5\x7\xD1\x86\x5A\x15\x7F\x9\xE1\xC1\xF1\x26\x2A"
93"\x48\x3F\x2\xC0\x8C\x6\xC1\xA8\x41\xF8\x74\xC0\x8D\x56\xF1\xA3\xBB\xDB\x22\x0\x4A\xFA\xC5\x84\x5C\x23"
94"\x21\x8A\x40\xD1\xC2\x90\xBA\xAE\x99\xCE\x74\x8D\x0\xC0\xAB\xF3\xDA\x98\x53\xE9\xE9\xF4\xAF\x28\xA4\xA3"
95"\x4F\x13\x2\xD4\x2F\xC5\x90\xA8\xB7\x3A\xE3\xAE\x4A\x90\xC6\xA5\x36\x75\xA9\xE1\xF3\x21\x54\xB\xD2\xC4"
96"\x26\x4A\x95\xAA\x6\x61\x28\x56\xAF\x7A\x59\x0\x90\xB1\xA5\x80\xF4\xAC\x57\xC1\xA\x0\x40\x4D\xB1\xAC"
97"\xB5\x3B\x2B\x48\x47\xAA\xD6\xDF\x95\xEB\x82\x6\x99\xFE\x40\x42\x2\xE8\x52\xC6\x1A\x44\x8A\xEA\x8A\xE9"
98"\x4C\xC5\x8\x80\xBD\x8A\x90\xAF\x0\xF0\x6B\x1C\x3\x1B\xD8\xEC\x9\x96\x4A\x5A\x32\x6C\x50\xB5\xE2\xD5"
99"\xD0\xEE\x6A\x90\x0\xD8\x21\x53\x9D\xEA\x58\x18\xC6\xCF\x2D\x3D\xE0\x81\x76\x65\xC0\x5D\x19\x6C\xEC\xBB"
100"\x1A\x5B\x24\x23\x2D\xF6\x48\x25\x58\x4C\x7\x98\x74\xC1\x14\x96\x20\x4\x8\xCC\xAC\x66\x8\xC0\x19\x15"
101"\xB2\x6\x4\x29\x58\xA1\x64\xFD\x41\x19\xD\xAE\x60\x0\xE\x9C\x12\x95\x7F\x51\x25\x2B\x79\xF6\xCA\x9F"
102"\x1\x8D\x68\xB4\xB4\xCC\x2\x34\x0\xB5\x69\x18\x22\x1A\xD6\x18\xE6\x4\x3C\xC0\x4\x44\xA4\xC8\x38\x5"
103"\x42\x40\x9\x98\x93\x5\xD5\xB4\x6\x36\x3D\x88\xCD\x6C\x68\x53\x9B\x6A\xDE\xE6\x9A\xDA\xDC\x26\x37\xBD"
104"\xF9\x4D\x70\x56\x7\x3A\x77\x13\xE7\x76\xBE\xB3\xC\xC2\x11\xAE\x1D\x38\xB6\xF\x7E\xF6\x13\x4F\xC8\x85"
105"\x60\x99\x65\x4B\x4E\x9\xF0\xA9\xCF\x7E\x1A\xF9\xC8\xEF\x59\x87\x3F\xE3\xE3\x95\x82\xCC\x54\xAB\xFC\x4B"
106"\x48\x67\x97\xB8\x44\xCD\x2E\xD1\x78\x6\xC1\xC2\x6\xD9\x64\x10\xDE\x6E\x2A\x61\x6\x21\x6D\xA\xE2\xA5"
107"\x90\x84\x8C\x28\xB5\xB7\x53\xE0\xFE\x15\x5B\x9B\x10\x94\x1A\x84\x1A\xAF\xDB\x60\x68\xA5\x7B\xAE\x74\xD5"
108"\x55\xB7\x35\x35\x88\x6F\x43\xE8\x57\xBF\x12\x77\x8E\xC6\x4D\xAE\xC1\xC8\x57\x54\x34\x19\x1A\x0\x48\x55"
109"\xAA\xF7\xA6\x5B\xDD\x46\x37\x59\xA6\x31\x85\x32\x13\xA5\x3C\xD5\x84\x62\x16\x0\x40\x32\x88\x45\x9\xD8"
110"\x58\x22\x56\xFA\xCB\x0\x78\xD6\x57\x4D\x64\x66\x8D\xA2\xB9\xA3\x6A\xD6\x96\x5A\xC5\xA\x0\xA\x24\xE4"
111"\xA\xA\xB\x50\xA7\xA1\x31\x3C\x74\xA5\x4\xCF\x3D\xCA\x73\x6F\x6F\x1A\xDC\x37\xFE\x79\xA7\x29\x14\xF4"
112"\x61\xC5\x24\x40\xC5\x26\xC4\xB6\xD1\x5\xD6\xC0\xA8\xCB\xE8\x47\x7F\x90\xB7\x4F\x56\x1D\x0\x3A\x4B\xED"
113"\x84\x64\x1A\x0\x12\xE0\x42\x17\xBC\xF0\x85\x4E\x83\x21\x21\xDF\xCE\xB5\x41\x62\x2\x66\x0\x10\xC9\x20"
114"\x45\x28\x35\x6A\x39\xEA\xD1\xD5\x6\xF\x0\x6F\x35\x48\x35\x62\xD\x80\x2\x2\x80\xCB\xE4\xAA\xB5\x9D"
115"\x6F\x2D\x6E\x48\x77\x59\xD7\x21\xE4\x73\x9\x7F\x6D\x42\x3B\x1A\x4\xA8\x42\x45\x58\xA8\xE9\xFD\xDC\x4E"
116"\x2F\xDB\xD1\x8F\xF5\x94\x16\x5C\x40\x71\x17\x60\xAD\x36\x50\xE8\xC1\xE\x1A\xE9\x48\x49\x46\x12\xBD\xDE"
117"\xFD\x2E\x77\xFE\x33\xE9\x2\x20\x74\x4D\x8\x62\xF0\xC2\x18\xB8\x40\x86\x15\x90\x32\x92\x65\x30\xC3\x19"
118"\xBC\x80\x86\x34\xA8\x1\xA\xDC\xF5\x58\xF\x28\xBE\xB5\x30\xFC\xC6\x64\xCD\x88\x80\x5D\x26\x50\x84\xA"
119"\xFC\x37\x95\x3\x58\xE5\x80\x5D\x9\x4B\xA2\x69\x60\x1\x1B\x70\xF0\x35\xAE\x81\x8D\x33\x58\xDD\xB\x83"
120"\xF8\x31\xD9\x42\x30\x4A\x16\xD8\xC0\x6\x2C\x0\xCD\xD3\x46\xD3\x80\x63\x48\xD\x35\x1E\xFE\xB0\x6B\x42"
121"\x3C\x62\xD9\x64\xBC\xC4\xD4\x84\x2\x8A\x53\xDC\xB6\x1F\xAC\x78\x6E\xCA\x68\xB1\x8B\xF1\x66\x1D\xF3\x14"
122"\xE\xC7\xEC\x74\x67\x7E\x1C\x27\x4F\x65\x2\x99\xEB\x1A\xDE\x43\x16\xB6\x60\x83\x18\xA8\x87\x3C\xEC\x39"
123"\x7\x7C\xDA\xE3\x1E\x23\xB7\x14\xCB\x4E\xFC\xF7\x55\x8F\x28\xED\x26\x7E\x50\x8\x6B\x60\x43\x1B\xDC\x90"
124"\x10\x98\xDA\xEF\xD\x70\x10\x43\x1A\xE2\xF0\x81\x49\x1B\xA4\xB3\x33\x25\xF7\xC2\xC3\x9C\x10\x57\x9F\x16"
125"\x0\xD3\x3A\xB5\x47\x33\xF0\x27\x83\xA0\x5E\xF5\x71\xB8\x96\x4B\x91\x2A\x2E\x2F\x4A\xAA\xD6\xE7\x5A\x97"
126"\xA4\x77\xAB\xEB\x3D\xBF\xD1\xCF\x80\x86\x4A\x42\x94\x2B\x43\x28\x1E\xFA\xA8\x9\x51\xB4\xC0\xA4\xFE\xFF"
127"\x2A\x82\x79\xA\xF3\xD7\xCE\x94\x1C\xE6\x20\x87\xF2\xD3\xA1\xE\x76\x48\xFF\x1D\xC\x22\x69\xCF\xE7\x9"
128"\xF\x79\xD0\xC3\x1B\xD6\x77\xE9\x34\xF0\xA1\xF\xD3\x7E\xE8\xEB\x63\xA\x4\xAF\x3E\xA0\xF6\x19\xB5\x6E"
129"\xA9\x6\x0\xD5\x62\x10\x44\x0\x0\x73\xC0\x7\xC2\x57\x6F\x14\x65\x10\xA6\x27\x41\x8E\x62\x7C\x0\x40"
130"\x6B\xC7\x47\x29\xFC\x6\x0\xCB\x17\x53\x7A\xC5\x6B\x7D\x36\x70\x3C\xA5\x47\xB2\xC2\x5C\x89\x25\x6B\xB5"
131"\xD5\x41\x5A\x82\x5C\xCA\xD6\x52\xE3\x96\x10\x98\x87\x65\x70\xE0\x7\x6B\xF0\x7\x74\x0\x8\x81\x90\x7"
132"\x82\x70\x7\x83\xD0\x6F\x33\xF5\x79\x9\x41\x8\xC7\x56\x69\xAB\x57\x8\xF9\x67\x10\x49\xA4\x59\xB0\xE7"
133"\x2E\xE5\xF6\x7F\x6\x31\x11\x63\x5\x22\x67\xA5\x1\x0\x38\x7\xBA\x80\x7F\x9C\xD6\x55\x6\x81\x24\x11"
134"\xE4\xE\xE0\xA2\x6F\x55\x35\x81\xB8\x46\x53\x6C\x94\x57\x36\xD5\x57\xD1\x77\x70\x7B\x34\x68\xA2\x66\x43"
135"\x0\xD0\x70\x3A\xB4\x24\xDB\xD7\x7D\x2A\x38\x5\x72\x38\x87\x40\x50\x87\x5A\x23\x5\x12\x0\x1\x42\x60"
136"\x8\x87\x20\x8\x58\x10\x5\x51\x80\x5\x88\xF0\x4\x55\x80\x71\x24\x56\x1B\xFE\x25\x27\x5\x57\x0\x1"
137"\x2A\x20\x39\x36\x23\x5F\x19\x93\x8\x89\xB0\x7A\x8A\x0\x4\x8B\x50\x6\x98\x58\x6\x60\x90\x8\x91\x84"
138"\x3\x8B\x0\x6\xA0\x8\x6\x8B\xB0\x8\x4A\xB0\x3\x1E\x83\x35\x2E\xE0\x3\x5A\xA0\xC\x2F\xC0\x1F\xE"
139"\xD0\xC\xF\x10\x1\x34\x70\x2\x45\xA0\x1\x1\x70\x8B\xB8\x18\x0\x3\x80\x1\xD9\x50\x0\x1A\xE0\x32"
140"\x1C\x90\x2\x72\x0\x9\x78\xE0\x4\x2A\x40\x2\xCA\x34\x2\x5C\x87\x20\x8B\x17\x3\x97\xA1\x0\x2D\xF0"
141"\xE\xF0\xD0\xD\xF0\x50\x8D\xF1\x10\xF\xF2\xF0\xE\xF1\xC0\x34\x64\xD7\x0\xD0\xC0\x0\xEE\x80\x8D\xD7"
142"\x98\x8\xEE\x80\x3\x1A\xF3\x61\xB3\xB1\x71\xE7\xA5\x3\x3C\x0\x5\xDA\xB0\x71\x17\xB3\x3\xDA\x80\x4D"
143"\x3E\x30\xF\xF3\xA0\xD\xF6\x38\xF\xD8\xE4\xC\xFC\x30\x77\xD7\xC4\xF\x74\x53\x63\x85\x53\x38\x37\xD6"
144"\xE\xF7\xC1\x63\x47\x10\x2F\x86\x37\x2\xCA\x78\x0\x1A\x76\x36\x36\x90\x4\x49\x60\x3\xFC\x0\x90\xDF"
145"\x61\x1E\x82\x23\x38\xE5\xA1\x25\x9\x1\x6A\xB2\xD7\x7F\x6\x21\x24\x8C\x20\x7\x82\xB0\x55\x60\x78\x92"
146"\x4D\x24\x7B\x5E\xD1\x30\x43\x88\x80\x71\x90\x83\x65\x90\xFE\x10\x31\x79\x55\x33\x9\x0\x35\xB9\x44\x8B"
147"\x90\x10\xDA\xE0\x55\x16\x5\xB\x77\xC0\x7\x77\xC0\x8\x9E\x10\x22\x0\x90\xD\x9\x51\x2D\x74\x0\x9"
148"\x7A\xB0\x3C\x24\x8\x0\xB4\x13\xF\x9\x41\xF\x5C\x40\xE\x77\x80\x6\x9\xD1\xD\xEF\xA6\x85\x6\x61"
149"\x6\x77\xD0\x95\xF0\x0\xB\x16\x48\x3C\x0\x90\x93\xFB\x67\x10\x8B\xD0\x4\x9A\x50\xF\x5A\x9\x0\xF7"
150"\xD3\x59\x7E\xB5\x93\x6\x31\xF\x3D\xA5\x24\x3E\x9\xE\x41\x9\xB\xE5\x43\x66\xF3\x44\x6F\xF9\x60\x80"
151"\xFD\x60\x0\x1F\xD2\x3D\x6F\xD8\x52\x9F\x5\x0\x1E\x69\x6D\x0\x30\x92\x8D\xC0\x82\xCB\x92\x79\x4C\xE4"
152"\x8\xE9\xF7\x8\x75\x30\x99\x39\xD8\x94\x48\x35\x7\x7F\xB0\x94\x67\x30\x7E\x69\x30\x7\x90\xC0\x8\x0"
153"\x90\x8\x6\x1\x99\x93\x39\x7E\x73\x20\x3B\x4B\x64\x6\xE4\x37\x99\x76\x60\x9\x7D\x0\x6A\xDB\x50\x7"
154"\x74\x70\x7E\x93\x59\x7\xA1\x80\x7\x69\x66\x10\x11\x61\x7\x99\x50\x92\x93\x10\xA\xA6\x9\x9\xA9\xC0"
155"\x3E\x0\x40\xF\x0\xE0\x8\x73\xB0\x9A\x73\xC0\xD\x69\x10\xA\x75\x90\x6\xB8\x9\x81\x66\x0\x0\x77"
156"\x50\x7\x68\x10\x0\x69\x80\x7E\x69\xFE\x50\xE\xC3\x50\x67\x6\x61\xF\xB9\xB8\x9\x6\xA1\x9\x68\x20"
157"\x7\x76\x50\x7\x72\xE0\x7\x6\x1\x6\x5E\x90\x6\x72\x40\x7\x76\x40\x7\x9A\x10\x6\x6\x91\x8B\xB7"
158"\x78\x1\xD7\xD2\x24\xEE\x70\x6\x1\xC0\xD\xED\x39\x7\x75\x90\x9\xD1\x49\x43\x7\x80\x9\x5E\x80\x8B"
159"\xA7\x0\x0\x2C\x40\x1\xF6\xC9\x1\xCA\x25\x98\x2A\x8\x0\xF4\x39\x46\x1D\xC9\x98\x8C\x30\x7\x91\xC0"
160"\x98\xC5\xD3\x98\x5A\x30\x8\x92\x30\x9\x93\x40\x9\x76\x40\x9\x95\xA9\x3E\xE\x98\x10\xE5\x77\x7\xE5"
161"\xC7\x7\x7E\xE0\x7\x80\xC0\x6\x9E\xC9\x50\x78\x90\x9\xE9\x47\x9\x7E\xA0\x9\xF8\xB7\x44\xB\xA0\xB"
162"\xBA\x40\x7\xA1\xB0\x6\x77\xF0\x6\x58\x16\xB\x72\x90\x9\x7E\xF0\x9\x4D\x80\x7\x8C\x0\x8\xCE\x59"
163"\x92\x71\x65\x10\x46\x99\x7E\x6B\x60\x9\x8F\x0\x8\x20\xA\x8\x74\x30\x8C\xF3\x87\x5B\x1\xD0\x4\xED"
164"\xE9\x7\x7A\x80\x7\x4D\x90\x7\x90\x90\x6\x69\x0\x8\x54\xF8\x3B\x66\x30\x6\x5E\xC0\x6\x93\xF0\x9"
165"\x62\xCA\x5\x80\x60\x9\x73\xC0\x7B\x15\x58\x0\x15\x90\x1\xDC\x10\x0\xBA\x23\x6\xFE\x19\x7\x7C\x10"
166"\x7\x94\xB0\x6\xFE\x39\x38\xD\xE5\xE0\xD\x6D\xBA\x6\x82\x30\x8\x61\x32\xE\xF6\xC0\xD\xDC\x50\x0"
167"\xA7\x40\xE\x29\x22\x3D\x3\x10\x0\x2\xC0\x1\xE6\x40\x4\x4D\x50\xF\x7C\xD0\x99\x25\x19\x5\x14\x1"
168"\x8\x6B\xF0\xA\x72\x90\x6\x6D\x0\x0\xDE\x70\x8B\x28\x50\x0\x28\x80\x2\x15\xF0\xA4\x83\xA5\x3D\x5E"
169"\xB1\x4\x61\x60\xAB\x61\x90\xAB\x61\x20\x5\xBC\xCA\xAB\x53\xA0\x5\x95\x30\x7\x82\xF0\x0\x27\x20\x87"
170"\x75\x8\x4\x55\x90\xAC\xC9\xAA\x5\xC9\x1A\x4\x27\xE0\x5E\xE\xC0\x4\x96\x20\x9\xD7\xE2\x18\x23\x30"
171"\x4A\x93\xC1\x3\x19\xF3\x9E\x7C\x30\x9\x7A\xF0\x1\x51\x0\x1\x57\x70\x9\x98\x40\x7\x87\x90\x5D\x1F"
172"\x3\x9\x99\xA0\x9\x4D\x20\xAE\x3C\x80\x89\xA4\xE8\x3\x41\xA0\x5\x9\x0\x9\x9F\x80\x8\x42\x80\x3"
173"\x60\x0\xA0\x4A\x9\x88\x58\x80\x5\xD1\xEA\x7\x1\xEA\xA\xC4\x40\x17\x43\xA0\x8\xAB\x80\x7E\x1F\xEA"
174"\x8\xB4\xE5\x9\x5F\x10\x7\x74\x80\x9\x7\x42\x5\x8C\x17\x0\x5E\xE0\x5\xE2\x50\x3\x35\xC0\x4\xC3"
175"\x20\x4\x97\xB0\x6\x71\x10\x8\x13\xB0\xA\xCF\x0\x8D\xD3\x78\x8B\xE1\x40\x4\x1F\x0\x3\x4C\xC0\xFE"
176"\x4\x34\x50\xD\x70\x40\x7\x96\xB0\xD\xD1\x60\x76\xC7\x10\xD\x2F\xE0\x1\x52\x80\x1\xDC\x80\x1\x3"
177"\x20\x0\xA7\x40\x4\x1A\xDB\x4\x70\x8A\x8\x27\xD0\x1B\xD6\x20\x6\xE1\x70\x5\xE\x30\x88\x40\xA0\xA"
178"\x61\x60\xD\x1B\x30\xE\xF5\x50\xC\xE1\xFA\x2\xF7\x78\x8B\xD9\x40\x4\x4E\x60\xC\x47\xE0\x4\xE1\xDA"
179"\x6\x69\x80\x6\x9F\x30\x3\x51\x20\x4F\xC2\x40\x6\x64\xB0\x6\x75\x40\xA\xAF\xC0\x6\xA7\xE0\x6\xB0"
180"\xD0\xA\x6E\x40\x4\x46\xE0\x0\xCC\x60\x5\xE5\x64\x4E\xE3\xD1\x52\x42\x62\x10\x13\x2A\xA1\xEE\x72\xA1"
181"\x19\xBA\x82\x86\xB\x0\x98\x7\x92\x0\xB0\x21\x8F\x40\x9\x54\xB8\x86\x9D\x46\x7\xEB\x3A\x8\x1D\x12"
182"\x92\x0\x80\x7\x6C\x10\xA\x85\xAB\x3\x77\x10\xA\x7E\x0\x6B\x5B\xA9\x9\x42\xB8\x3F\x7C\x0\x9\xC2"
183"\x57\x6\x90\xF9\x8\x25\x89\x29\x30\x71\x8\x75\x0\x8\x9B\x6\x0\x1D\x12\xA0\x77\x0\x96\x0\x40\x43"
184"\x5F\x90\x9\xBD\x19\x5A\x26\x20\x7\x7F\xD0\x7\x4C\x8\x0\x50\xA8\x2\x6B\x10\x9\x9E\x90\x45\xC7\xB9"
185"\x6D\x1D\x0\x0\xF3\x66\x10\x6E\xE6\xD\x68\x0\x8\xB8\xF2\x5A\x0\x70\xF\x1\xFE\x70\xF\xA7\xE0\xA"
186"\x20\x50\xB9\xA3\xB6\xA1\x0\x0\x9\x87\xC0\x5\xC0\xA5\xD\xA1\x0\x7\xB0\xA0\x84\x0\xA0\xD\x44\x70"
187"\x8B\xC1\x4B\x7D\x3\x70\x6\xF8\xA0\x41\x6\xA1\x97\xBA\x70\x6\x34\xF8\x9\x64\xA6\x86\x6A\x68\x70\x82"
188"\xE5\x29\x7F\xB\x0\xFF\x1B\xB8\x31\xC1\x8\x6C\x50\xB8\x86\xA9\xA1\x0\xA0\xB8\x8A\x4B\x46\xAF\xFB\xB8"
189"\xBB\x22\x5D\x76\x10\x7\x8E\x80\x6D\x11\x5\x0\x70\x10\xA\x92\x0\x20\x3A\x30\x8\x75\x40\x9\xAB\x90"
190"\x10\xE4\x17\x7\x9E\x6\x0\xDC\x0\x7\x65\x52\x6\x22\x1A\xB\x2A\xB5\x9E\x9\xB1\x8\x8C\x90\x94\x1F"
191"\xC\x2D\x0\xD0\xC1\x13\x3C\x82\xF5\x36\xA5\x92\xF0\xB\xBE\xE2\xBB\x8E\x80\x45\x7\xE1\x7B\x5C\x40\x66"
192"\xBC\x13\x7\x76\x80\x9\x60\xE9\xC3\xD3\x99\x98\x72\x30\xE\xB2\xE3\x66\x0\xA0\x85\xF8\xC0\xD\xE4\x20"
193"\x7C\xCD\xB\x0\xB2\xD7\x3F\x8C\x10\xA\x80\x20\x28\x33\x25\xF\x75\x90\x7\x14\xFC\x7A\xD9\x10\x0\xF6"
194"\xF0\xBF\x21\x14\x6\x1D\x10\x0\x19\x20\x5B\x36\xFC\xA\x73\xC0\x5\xAD\xE0\x15\xD0\x95\xB\x3D\x65\x5C"
195"\x9E\xD2\x2C\x0\x80\xC7\xFF\x4B\x46\x8C\xF0\x7\x6\x5C\x98\xFE\x1F\x24\x7B\xB2\x47\x46\x33\xB8\x80\xBB"
196"\x82\x6F\x8D\x9B\x83\x81\xEB\x23\x78\x10\xB1\xB8\x29\x55\x87\x90\x9\x97\x90\x10\x92\x49\x8C\xA9\xC3\x5"
197"\xDC\x90\xA0\x6\x51\x6\x72\xD0\xC1\xA\xC0\x8\x5D\xD9\xD\x5D\x79\x7\xDD\xA0\x9\x72\x20\x9\xE2\x6B"
198"\x10\xFD\x97\x94\xD1\x9\x0\x7A\x19\x2\x83\x30\xA2\xDD\x66\x10\x49\xF0\x9B\x74\x30\x7\x79\x0\xCA\xDC"
199"\xB0\x7E\x4\xB8\x66\x8\x18\x0\x12\xCC\x8\x5D\xD0\x95\x1D\x70\x6\x9A\xA0\x9\x2A\x2A\x9\x13\xC\x5B"
200"\x4F\xC\x0\xF8\x60\x1\xF5\x70\x81\xDE\x69\x10\x45\xFA\x9\x98\x96\x10\xDC\xC0\x6\xD6\xFC\xBF\x3B\xD0"
201"\x5\x1\x80\x2\xD3\x50\xF\x1D\x40\xE\xEE\x40\xE\xE4\x60\x0\xE5\x7C\xBD\xD1\x6C\x10\xA2\x6A\x10\xA3"
202"\xC0\x6\x13\xEC\x83\x6\x91\x43\x0\x90\x4\x75\xDC\x53\x5E\x71\x2\xFA\xAC\xCF\x2F\xD0\xCF\x2F\xD0\x1B"
203"\x4B\xB0\x4\xBC\xDA\x6\x87\x10\x9\xE\x20\x4\xBA\x1A\x6\x40\xE0\x2\x9B\xF0\x7\x29\xF0\x2\x52\x10"
204"\x4\x12\xCD\xAB\x2\xBD\x4\x33\xD8\x7\x2A\x40\x1C\x8E\xF1\x88\x49\x10\x3\x3C\x30\xA2\x4D\x20\x1\x40"
205"\x50\x1B\x6E\xC7\x3\x32\x20\xB9\x5C\x70\xFE\x2\x1A\xB7\x9\x9E\x5B\x5\x60\xD0\xD\x35\x5A\x9\x39\x50"
206"\x6\x5D\x90\x6\xAE\x40\x3\x2E\x30\x8A\x73\x40\x7\x94\x80\x9\xE9\x77\x9E\x59\x5A\x7E\x72\xA0\xB\x82"
207"\x10\xD2\x55\x90\x5D\x50\x30\x8C\x35\x80\x5\x10\xF0\x0\x4E\x40\x66\xC5\xC1\x9B\x5F\x20\x2\xF1\x95\x5"
208"\xAC\xF0\xA\xB1\x20\x9B\x41\x6D\x9A\xDF\xA0\x1\x9\x30\x18\xF4\x40\xF\xE6\x9\x9\xE5\xE0\x9E\x76\x70"
209"\xAA\x17\xDB\x9E\xE3\x20\x8\x7A\xA0\x8\x86\xC0\x19\xB\x10\x34\x73\x80\x6\x37\x4D\xD\xD3\xD0\x8D\x65"
210"\x37\x35\x52\x83\xF\x73\x0\x7\xD5\xA0\x5\x3A\x90\x8\xF2\xE0\x5\xD8\x80\x8\x43\x0\x4\xB2\xB1\x31"
211"\x73\x90\x6\x8E\xBA\xA7\xF6\xC9\xAA\x6\x60\x4\x51\xF0\x0\xFB\xE0\x0\xFE\x1\x2\xF8\x80\x6\x6E\x40"
212"\x8\x64\x80\x1C\x7\x80\x4\x67\x63\x2\x49\x60\x2\x54\xA0\x37\x7A\x73\x1D\x2D\xB5\x21\x1A\x62\x92\xF4"
213"\xF9\x5\x9C\xD0\x9\x9\x11\xB8\x55\x0\x8\x72\xC0\x8\xD1\x72\xC0\x14\x3A\x83\xAD\x77\x68\x48\x35\xA2"
214"\xC7\xAB\xB8\xBC\x55\x7\x98\x30\xC1\xC6\x83\x7\xC2\x3D\x7F\x98\x50\x7\x77\x10\xB\x94\x50\x44\x72\xC0"
215"\x7\xC3\xD0\xC2\x69\xFE\x30\x6\x77\xF0\x9\x83\x80\x7\x83\xD0\x4\xD7\x2D\xA6\x83\x50\x3\x7D\x20\xBF"
216"\x9\x25\x7\x71\xF0\x21\xB4\xE7\x15\x8F\x10\xB\x35\x9C\x54\x0\xF0\x6\x9F\x10\x9\x79\x10\x8\x93\xE0"
217"\x7\x92\x10\x7\xA1\xF0\x7\xBC\x8C\x3B\x98\x79\x7\x78\x80\x7\x7A\x30\xC\xD8\x1D\xA6\xC3\x50\x3\x4D"
218"\xC0\x18\x0\xC0\x6A\x50\x29\x9\x96\x60\xE\xEF\x36\x2E\x14\x8\x0\xCF\x90\x6\x62\xA0\x7\x70\x6\x0"
219"\x6C\xAB\xE0\x8E\xB9\x3\x1\xAA\x9\x44\x80\x7\xC3\x30\xC\x46\x10\xE0\x1E\x5E\x3\xC3\xF0\x1\xB4\x65"
220"\x6E\x10\xC1\xD\x46\x0\xB9\x87\x86\x5B\xF\x18\x58\x9E\xA2\xDA\x8B\x9B\x10\x30\x4E\x9F\x9F\xF0\xDA\x18"
221"\x34\x5\xA0\xC0\x9\x8E\x70\x6E\xA2\x45\xA1\xA1\x20\xA\xB\xA8\x86\xC8\x36\xA2\xF8\x27\x7B\x62\x4\xB"
222"\x75\x20\x9\xB8\x9\x92\x93\x69\xCD\x75\x10\xB\x0\x40\x9\x96\x80\x3\x9E\x50\x7\x81\x0\x3B\xF6\xE3"
223"\xD\xDA\x4C\x5A\x58\xE\x0\xB1\xFB\xBF\xA5\x33\x7\x98\x20\xAB\xA0\xEB\xCA\x55\xAE\xE4\x9\xD1\x97\x0"
224"\xA4\x2\x6F\xF0\x6\x4D\xF0\x6\x78\xE0\x7\x99\x20\x9\x29\x62\x3B\x87\x70\x8\x4B\x9\x0\x29\x6E\x10"
225"\xFE\xD1\x6D\x10\xB2\xFA\x3B\xBA\x83\xF\x6C\x60\xE1\x6B\xF5\x6E\xE5\xF2\xC\x6D\x80\x6\x6D\x80\x65\x73"
226"\x0\x8\x42\x68\x6B\xAF\x17\xC9\x3B\x9E\x10\xE8\xCB\xBD\x3C\x1E\xBB\x19\xD0\xA5\xC\x58\x85\x88\x76\x24"
227"\x1F\xD8\x52\x33\x61\x10\xA1\x1E\xE3\x96\xFB\x5\xA3\x0\xDB\xCC\x2\x13\xA4\x50\xA\x78\x0\xDE\x81\x4B"
228"\x9F\x7F\x20\xA\xBB\xBD\x97\x56\x38\xC3\xA6\xB0\x7E\xA0\x26\x46\x93\x60\x7\x81\x90\x22\xE4\xB6\x6\x76"
229"\xA0\xE4\xA1\xB0\x98\x77\xF0\x8\xDF\x10\x9\xB1\xF0\x9\x5D\xAE\x3\x6D\x20\x0\xD8\x80\xC7\xD7\x46\x65"
230"\x9\x21\x9A\x9D\x19\x8\x32\x4E\x13\x81\x40\x7\x81\x30\x7F\xB7\xF5\x8\x93\x0\x0\xC8\xD6\xCE\x6F\xF0"
231"\x8\x6B\x80\x7F\xFA\x60\x10\x7E\x10\xA\xA9\x5A\xE0\xBD\x67\x10\xC6\x89\xBC\x0\xF0\xE\x0\x40\xDB\xEB"
232"\x5C\xE8\x35\x72\xEF\xE\xDE\xA\x68\x10\xE\x28\xE5\x7\x69\xB0\xBA\x90\x3E\x6D\x6D\x20\x7A\x65\x5E\x98"
233"\x8A\x8B\xC7\x7A\x62\x10\x99\x9E\xE2\xE9\xC3\x86\xF5\x3C\x47\x5E\x21\x4\x42\xF0\x4\x13\xFF\x4\x16\x7F"
234"\xF1\xFF\xBC\xAB\xA7\x80\xA\xA9\x40\xAC\x11\xED\xAB\xAA\x80\xA\xA8\xE0\x6\xF\xF0\xFE\x4\x2\x3D\x87"
235"\x53\x50\x5F\x99\x0\xA\x78\xE0\x0\xE\x10\x40\x2B\x20\x4A\x7B\xB0\x5\x5B\x10\xA0\xA2\xB0\xA\x41\x60"
236"\x71\x3D\xE0\x5D\x4A\x60\x7\xB1\xC0\x8\xF\x70\x5\x55\x40\x71\xE0\xF0\x8\x8F\xC0\x7\x6B\xA0\x7\x27"
237"\xA0\x6\x76\xF0\x7\x98\x30\x9\x46\xDD\x5D\xCF\x80\x6\x62\x60\x8\x3D\x10\x49\x8B\x90\x8\x97\x88\x89"
238"\x66\xD0\xD\x39\xB0\x3\x3A\xF0\x89\x60\xD0\x99\x7C\x60\xD\xC8\x6A\x72\x24\x73\x5\xD5\xCC\xD9\x90\x91"
239"\x4\x3E\x7A\xB\x31\xC0\xC\xFD\xD1\xC\x10\x30\x4\x34\x60\x7\x50\xDF\x1\x28\x60\x1\x3\x60\xF\x99"
240"\x80\x9\xD8\x30\xC6\x8F\x8D\x8B\xD9\xA0\x1\x37\xF0\xE\x4\x0\xF\xF4\xD0\xD\x73\x10\xA\x5C\x60\x0"
241"\x9\xF0\xE\x92\xDF\x2\x9B\xA1\x34\xA0\xA1\x4B\x4\xC0\xD\xDF\x20\xF\xDC\x10\xE\x4C\x60\x4\x55\x30"
242"\x35\xAD\xB1\x1\x54\x6F\x8\x2E\x0\xD\x3B\x80\xFA\x60\x5F\x49\x39\x90\x0\x40\xE0\xCF\x2F\x70\x2\xBF"
243"\xB1\xF7\xDA\x3B\x4F\x2\x72\x1C\xCA\x78\x20\x25\x40\x5\xA2\xAD\x36\xE0\xD4\x52\x9\xF\x0\xA3\x3E\xEA"
244"\x9B\xE2\x6\x49\xC0\xA\x48\x88\xB8\xA0\x80\xA\xAD\xC0\xBD\x1F\xFE\xD4\x7F\x99\x80\xA\xAE\x60\x7D\xB4"
245"\x6E\xEB\xAF\x20\xA\xD7\xB6\x3\xB0\x10\xB\x76\x90\x7\xDC\x7E\x6D\x46\x2F\x9\x9A\x80\xE5\x8F\x30\xA2"
246"\x77\x60\xC\x65\xCE\x12\xD8\x80\x6\xDE\x30\xFD\x0\x10\x6E\x0\x0\xD3\x76\xF0\x8\xEA\xB9\xC9\x0\xD0"
247"\x9E\xE1\xA0\xB\xC7\x2B\x46\x7D\xC0\x6\x72\xD0\xEB\x0\x41\x6\xC0\xC0\x60\x75\xEA\x40\x4A\x32\x10\xC0"
248"\x94\x81\xB1\xEC\x44\x2\x1\xC0\x88\x42\x4C\x7F\x32\x39\xA\xA0\x30\xA3\xA3\x47\x76\xE8\x70\x1\x70\x43"
249"\x23\x80\x38\x73\xB6\x29\xEC\xA6\x30\x81\x42\x5\xA\x17\x0\xD0\xD3\x85\x5B\x3D\x34\xE2\x10\x29\x6C\xA0"
250"\x30\x19\x80\x35\x6C\xD8\xB8\x1A\xE8\x4E\xE1\x3B\x39\x5E\xD2\x9C\x52\x8\x44\xE1\x80\x0\xE4\x0\x18\x53"
251"\x18\x22\xAA\x42\x2A\xA\x59\x28\x54\xA6\x50\x2B\x0\x9\xA\xBB\xE\x7C\x32\x50\xD6\x2C\x5A\xB5\xA8\xD8"
252"\x92\x55\xAB\xD6\xAD\x59\x6D\x71\x6D\xC9\xD5\xEA\xE6\x40\x5D\xB8\xEC\x8E\x42\x65\xAA\x14\x28\xBE\xA0\x44"
253"\xED\x7A\x3\xE0\x0\x0\x52\xA8\x32\x89\xE2\xF5\xCA\x94\x28\x46\x8C\xE\x59\x32\x95\x67\x90\xC2\x2A\xA"
254"\x21\xC5\x92\xC4\x68\xAE\xA4\x4C\x7E\x1C\x1\xFE\x78\xA1\xB0\x7\x80\x37\xD8\xC4\x74\xF1\x26\xCE\x8C\xA6"
255"\x40\x74\xE8\xD8\x59\xC3\x88\x89\xC2\x33\x62\xD2\x84\x6B\x63\x7B\xDC\x26\x4D\x70\xD2\xCC\xF1\xD3\x7\x80"
256"\x30\x85\xBC\x5C\x87\xA2\x13\x2B\xF\xA3\x77\x81\x3A\x92\xF2\x34\x70\x86\x42\xF\xA4\x30\xD5\x91\xB3\xFC"
257"\xCE\x99\x50\x72\xE8\xC4\x56\x1\xE0\x2\x80\x3E\xB1\xD2\x60\x9A\x33\x27\x9C\x24\x48\x25\x21\x89\x3\xD0"
258"\x72\xE0\xCA\x81\xF2\xC3\x75\xF9\xC6\xE1\x83\x7\x85\xC\x70\x2\x50\x61\x8D\x43\xE6\x18\x23\x5\x33\xC8"
259"\x9\xC4\x20\xD8\x34\xD3\xC9\x1E\x7D\xEC\x9\x20\x80\xC\x34\xB0\x27\x1B\x14\x32\x40\x6A\x20\xA9\x6\xDA"
260"\x43\x21\x13\x14\x52\x65\x2B\x85\x68\xF0\xAA\x44\x0\x7A\x71\xA3\x17\x5F\x7E\xF9\xC5\x97\x5E\x64\x81\x31"
261"\xC6\x5E\x56\x50\xE1\x3\x85\x58\x61\x25\x97\x5C\xDA\x2\xA6\x96\x54\x82\xB9\x65\x97\x5D\x6E\xF9\x2\x80"
262"\x11\xBE\x28\xE5\xAF\x2F\x3C\xF1\x65\x17\x51\x4C\xE1\xA4\x94\x5D\x1C\x51\xE1\x88\xA4\x14\xDA\xE6\x95\x49"
263"\x6\x99\x8B\x11\x4A\xF2\x10\x2E\x8\x85\xA0\x18\x48\x5\x72\xB0\x29\xA7\x8B\x2E\xBC\x98\x23\x8E\x40\x3E"
264"\x29\x4\x80\x21\x6\x62\xFE\x44\xE\x31\xE0\xE0\x62\x98\x26\xE0\xB0\x2D\xD\x36\xB0\x31\x27\x3C\x0\x36"
265"\x4\xC0\xD\x5D\x26\x69\x64\x8D\x38\xE8\xA8\xE3\x11\x4B\x0\x11\xA4\x6\x85\x42\x1B\xC8\x9\x63\x1C\x21"
266"\x85\x12\x4B\x1E\xA9\x23\x13\x48\x2\x71\x64\x98\xA5\x0\x0\xC4\xB\x31\x28\x91\xC4\xF\x3F\xE0\x88\x3"
267"\x12\x48\x0\xC9\x3\x80\x69\x54\xA2\x15\x0\x57\xF0\x69\xC3\x15\x10\x14\x71\xE9\xBF\xA7\x4\xF1\x3\x13"
268"\x3A\xD2\xF0\x2\x8D\x70\xDE\xF4\x4\x84\xB9\x0\xF8\x6\x8D\x6F\xB2\xC1\xF5\x94\x7B\xB2\xA1\x16\x9F\xC"
269"\x1\x10\x41\x21\x24\x14\x4A\x68\x20\x67\x44\x4\x80\x6\x71\xC7\x1D\x57\x2\x9\x68\x80\x0\x86\x23\xD6"
270"\x3D\xA2\xCA\x76\xDF\x3D\xE2\xD\x27\x9C\x78\x40\x82\x13\x84\x30\xE2\x3\x27\xDE\x88\x37\xDE\x37\xFE\x15"
271"\x46\x5\x15\xC8\x20\x78\x84\x15\x5B\x19\x21\xA\x44\x86\xC1\xA3\xE1\x3E\xA\x39\x2\xB\x1A\x5E\x98\xA2"
272"\x62\x8B\x97\xC8\xC3\x11\x2C\x86\x90\x2\x8\x29\x4\xD1\x98\x86\x29\x5C\x20\x19\xA\x17\xB4\xA8\xE6\x4"
273"\x9\x5C\x71\x85\x88\x26\x8C\x40\xE4\x3\x2C\x98\xB8\x22\x8\x28\x7A\xD0\x62\x95\x26\x10\xA9\x1\x91\x21"
274"\x3C\xFE\xB8\xC2\xE5\x1A\x9C\x10\xD8\x9\x2B\x57\x8\x41\x4\x11\x18\x19\x44\x98\x56\x7C\x71\xC4\x8D\x26"
275"\xF0\x60\x2\xB\x44\xAE\xA8\xC2\x7\x17\x7E\x0\x22\x8C\x13\xF6\x31\xC6\x9\x3C\xA6\xC6\x63\x10\x4F\xDE"
276"\x80\x81\x8\x3\x2A\x40\x61\x80\xB\x2A\x21\x47\xF\x23\x86\xA1\xBB\x6E\x3D\x87\x71\x65\x83\x1B\xF6\x6E"
277"\xA1\x85\x4\xFE\x56\xA0\x81\x14\x8A\x70\xA5\xF\x26\x28\x60\x60\x1\x5\x16\x60\x9C\xF1\x6\xA6\xB1\xA6"
278"\x1A\x45\x3E\xF9\x44\x8F\x97\x63\xB6\x5A\x82\x6A\x80\xA8\x62\x8A\x17\xF4\xA8\x1\x6\xD1\x61\x28\xA4\xF4"
279"\x7D\x7\x16\x61\x4\xA5\x47\x8\x81\x4\x4\xF6\xA0\xC2\x84\x2D\x4C\x60\xE1\x7\x67\xBE\xDD\x6A\xCE\x81"
280"\x48\xDC\x5D\x21\x62\x14\x2A\xC6\x77\x85\x1C\x50\x48\x77\x39\x87\x57\xC8\x9\x85\x22\x1A\x28\xDB\x81\x7A"
281"\x19\x51\x21\x2C\x14\x5A\x42\x21\x86\x6\xAA\x7E\xA0\x2B\x8A\xA7\x4C\x21\x17\xAC\x57\x68\x59\xDE\x1\x18"
282"\x6D\x20\x29\x14\xA\x6B\xA0\x65\x21\x50\x8\xAA\x81\x88\x1B\x68\xB0\x81\x8C\xBF\x1E\x0\x19\xBC\x57\x88"
283"\xFD\x81\x98\x7\x40\x7F\x0\x50\x50\x88\x53\x6\xD2\x1\x85\x10\x70\x20\x5\x50\x8\x6\xFE\x14\xD2\x2"
284"\x85\x18\x40\x21\x1B\x60\x49\x4\x7\x12\xD\x85\xCC\x66\x20\x42\x50\x8\x5\x7\x52\xD\xE4\xD\xC4\x4A"
285"\xFB\x53\xC8\x8\x14\xB2\x2\xAA\x58\x5\x5C\xC7\xEB\x5D\xA\x51\x8\x80\x8\x70\x4F\x85\x18\x4\x4B\xF4"
286"\xE6\xA7\x90\x28\x84\x50\x21\xB6\x98\x14\xFA\x14\x72\x3E\xF3\x29\x24\xC\x3B\xA4\x5E\xF7\x6\xF2\xBD\x21"
287"\x2\x71\x20\x95\x19\x48\xF9\x0\x40\xA6\x22\xE\xE4\x87\x3\x39\x1\xD\x15\xE2\x3C\x0\x6C\x6B\x20\x56"
288"\x4\x80\xE\x14\xA2\xC5\x81\xDC\x6F\x20\xF5\x83\x21\x0\xA6\x33\xC3\x81\x40\x70\x20\x19\x50\x8\x2\x7"
289"\x42\x0\x85\x8C\x67\x20\xA\x1C\xC8\x4B\x6\xC2\xC0\xF9\x48\x10\x0\x72\x4\xC0\x35\x14\x62\x8\x9D\x8"
290"\x11\x34\x2E\x4\xC0\x7\x7\x35\x15\xE\x79\xE8\x84\x2D\x1C\x8\x22\x57\x38\x3E\x46\x9A\x8\x0\x61\x4C"
291"\x1F\x0\x22\x39\x3E\xE2\x69\xC8\x84\xD8\xB\xA2\x13\x7D\x68\x44\x0\x88\xE9\x8B\x57\x3A\xA2\x42\xB4\x80"
292"\xBF\x81\x30\x71\x89\xA2\x41\xE5\x40\x46\x89\xC9\x81\x54\xD2\x48\xA\x41\x80\x42\xB2\xA0\x10\x25\x28\x4"
293"\x7\x5B\x54\x88\x17\x1\x40\x44\x0\x64\x4F\x8C\x80\xD4\x80\x42\x4\xFE\x30\xAA\x81\xB8\x51\x3C\xA\x11"
294"\xC9\x1C\x6B\x5\x0\xFA\xC4\xA7\x57\x71\x54\xC8\x33\x32\xA8\x10\x6A\x28\x64\x7B\x3\xB1\xD1\x40\x48\xD8"
295"\x3C\x6D\x29\x64\xB\xE0\x82\x40\x4\xC2\x19\x1\x72\x92\x73\x8\x11\x18\x42\x3A\xD3\x49\x2E\x1A\x9C\x4B"
296"\x5C\xE6\x32\x97\x10\x24\x20\x4\x7A\xD2\xF3\x9\x4F\xA0\xA7\xB9\xCE\x9\x1\x7\x58\x6A\x50\xA9\x3B\x40"
297"\x9\x4C\x60\x82\x17\x14\xF4\x5\x4B\x40\x68\x42\x11\x1A\x6\x86\x32\x54\xA\xF\x95\x42\x10\x22\x1A\x4"
298"\x8A\x5A\xAC\x62\x40\xC0\x28\xE7\xAA\xB0\xD1\x2A\x68\xC1\xA3\x24\x3\x29\x14\x44\x2A\xD2\x1E\xDC\x6C\xA4"
299"\x24\xEB\x5C\x10\x96\x70\x82\x2B\xC\x1\x11\x35\x3C\x40\xD2\x44\x10\x82\x3\x20\x81\x5\x26\xB0\x1\x15"
300"\x70\xB0\x53\x25\xF4\xB4\xA7\x38\x50\xC2\x4E\x73\x90\x3\x1D\xE8\x60\x7\x47\x95\x41\x49\xB5\x6\x84\x29"
301"\x78\x6D\x8\x33\x80\xEA\x3\x20\x30\x4\x9\x4C\x80\x2\x15\xB0\x80\x5\x4\xB0\xD5\x1\x74\x95\x0\x5F"
302"\x25\xC0\x5\xC4\x7A\x1\xC\x94\x15\x3\x7C\xBB\x41\xDF\xFE\xB6\xD6\x4\x28\xC0\xAD\x6F\x5D\x1C\xE3\x18"
303"\xC0\x80\x67\x3C\x63\x1A\xD3\x88\x46\x34\xAE\x51\xFE\x5\x6A\x48\xA1\x1A\x2F\x50\x84\x4\x86\x0\x1\x7D"
304"\x81\xE0\x0\x48\x53\x5D\xEA\x56\x40\x2\x24\xC0\xCE\x6\x5B\x98\xE5\x56\xFC\xA7\x48\x45\x1A\xCF\x78\x8D"
305"\x1C\xC8\x57\x1E\xA9\xC3\xCC\x86\x4F\x21\xF2\xAB\x62\xE\x7\x42\xA9\x5E\x66\x12\x0\x4F\x4\x0\xF\x3B"
306"\x9\xBE\x4F\x86\xD2\xB5\x0\x58\xE5\x2E\xC7\x34\x5B\x55\x6E\x32\x91\x23\xC4\xED\x40\xBE\x39\x90\x1C\xD0"
307"\xD2\xB7\x3\xB9\xE5\x40\xB8\x68\x3F\x85\xF8\x80\x93\x63\x5C\xA1\x19\x1\x60\x1\x62\x2\x80\x8D\xC5\x4C"
308"\xE0\x2\xA5\x5B\xC7\xFA\x3C\x13\x0\xC8\x50\x88\x1E\x37\x28\x43\x0\xF0\x4F\x84\xDA\x54\x48\xC\x4E\xF8"
309"\x80\xFC\x29\x84\xB2\xE6\x5\x24\x66\xB9\xE2\xC8\xF1\x91\x37\x7E\xB0\x54\x48\x14\x47\x6B\x5A\x5F\xFA\x12"
310"\xB5\xA8\x55\x6D\xFD\xEA\x87\x44\x0\xF0\x37\xB6\xBC\xE4\x65\x6C\x55\x6B\x3C\xD0\x12\xEA\x43\xC2\x55\x48"
311"\x6F\x7\x52\xCB\x5\xFF\x16\x0\xA\x26\x6E\x29\x8F\x8B\xDE\x32\x2A\x84\xB9\x3\x19\x80\x42\x9E\x7B\xCC"
312"\x37\x4E\x17\x0\x74\x64\xA6\x1D\x73\x32\x41\x6A\x52\x27\x79\x84\x1C\x64\x21\xC1\xE5\x5E\x0\xB0\xD8\x7F"
313"\x93\xA5\xF0\x22\xB9\xAB\x5E\xFE\x16\x6B\x5\xB4\xF2\x5\x0\x8E\x71\x4C\xDA\xFA\xDA\xF6\xB4\x9C\xF4\xE4"
314"\x42\x40\xD9\x5F\x51\x92\x92\xC8\x3D\x54\xA1\x56\xA8\x58\x95\x81\xEC\x0\x97\xBC\xB5\xA5\x83\x83\x9B\xC5"
315"\x5C\xD2\x36\xB5\xA\x41\xAE\x22\x39\x20\xCC\xE6\x6E\xD8\x98\x70\xFC\xF0\x32\xE5\x73\x47\x85\xCC\x6A\x20"
316"\xD5\x84\xA2\x42\xB2\x9\x80\x6D\x62\xAB\x9B\x22\x72\x40\x9C\x1D\xF0\x0\x3A\xD7\xB9\xCE\x10\xC0\xB3\x38"
317"\xF5\x5C\x4E\x3E\xAB\x73\x9D\xEC\x1C\xD7\x3E\x11\xE1\x80\x28\x84\xE7\x0\xAA\xB\x81\x4D\x93\xC0\x82\x7B"
318"\x3E\xE1\x4\x8E\x3E\x41\xA4\x23\xFD\x82\x13\x18\xB4\xA0\xA\xC5\x74\x43\xC3\x0\x51\x88\x52\xD4\xD3\x16"
319"\x9D\x42\x46\x39\xDA\x51\x8F\x72\x94\xA9\x53\x90\xC2\x12\x28\x2D\x4\x97\x16\x3A\xA6\xAA\x1B\xC1\xA\x5E"
320"\x17\x83\x24\x64\xE1\xA8\x47\x35\x6A\x51\x75\x9D\x3\x1C\xF0\x9A\xA7\x3E\x5\x76\xAF\x87\x5A\x54\xA4\xF2"
321"\xA0\xA4\x2E\xA8\x82\xC7\xAC\x20\x4\xA8\xCE\x60\xCE\x11\xA0\xC1\x15\xC\xC0\x81\xAC\x6A\x55\x0\x5D\xF5"
322"\xEA\x57\xC7\x4A\x56\xB3\xEE\x8D\x6F\x7E\xF3\x9B\x5B\x35\xB0\x0\x6\x6C\xC0\xAE\x86\xC8\x2B\x35\xA8\xB1"
323"\xA\xC9\xFE\x9\xC1\x3\x4C\x28\xEC\x61\x43\x90\xD8\x10\xC8\xBA\xB1\x70\xEE\x60\x8B\x15\xC2\x62\x16\x9F"
324"\xF7\xB6\x64\xC\x17\x20\x97\xE5\x5D\x43\xA6\xD9\xE0\x39\x16\xED\x1F\x59\x59\xDA\x85\xAB\x36\xC8\x41\xAE"
325"\x9F\x52\x5E\xCB\xDF\x20\x5F\x33\x90\x53\x54\x48\x9\x2E\x9\x0\x27\x23\xD8\xE3\xF\x8E\x72\x83\x81\xFB"
326"\x64\x8E\x5B\x39\xC8\x59\x56\x48\xA\x98\x37\xCC\x81\xB0\xDC\xB9\x6D\x8C\xEE\x40\x92\x19\xE2\x81\x8C\x18"
327"\x0\x7C\x1C\x88\x3\x55\x48\xF0\xF7\x82\xEB\x77\x3\xF9\xB9\xBE\x7\xE2\xE2\x7D\xC7\xD8\xDF\x2B\x34\x9E"
328"\xFF\xDC\xE7\x66\xDD\x72\x56\x92\xF1\x85\xFA\xC1\x7B\xAC\x49\xAA\xFF\x78\x20\xF\x67\x2D\x0\x24\xAE\x75"
329"\x4E\x46\x32\x78\x96\x1C\x48\x2C\x7\x72\xE0\x8\x97\xFC\xE3\xC3\x9D\x32\x83\x1\xA0\x76\xB5\x43\xB8\xE3"
330"\xE4\x53\xC8\xC9\x63\x9C\x2\x2E\x63\x58\xC3\x30\xEF\xB0\x32\x7\x12\xCC\x81\x98\x19\x0\x68\x6\x0\x11"
331"\x4E\xC\xF6\x14\x8B\x28\xE8\x87\xCF\x37\xBF\x8B\x3E\x10\x18\xFF\x9B\x85\x8B\x7\x10\xC6\x9B\x7E\x41\xA7"
332"\x47\x32\x92\x3A\x4E\xF8\xD4\x19\x6E\xF5\x2B\x5F\x3D\xEB\xF5\x53\x6D\x24\x5D\x49\x28\xD0\xEE\xFE\x16\x0"
333"\x3C\xA8\x72\x93\x15\xF2\xF6\xE1\x42\x38\xED\x21\xA7\xB2\xEA\x25\xDC\xDA\x5F\x32\x5E\x21\x45\xA8\x3B\x0"
334"\x32\xBC\x46\xBC\x87\x64\x99\x7E\xD7\x2E\x0\x78\x85\xCD\xDC\x32\x7D\x2B\x51\x20\x46\xF2\x95\xBF\x7C\xE6"
335"\xCB\x79\xCE\x76\x86\x0\x9D\xF1\x9C\xE7\xE9\xF3\x99\xCF\x10\x40\xC4\x3\x88\x51\xE8\x88\x24\x6D\x4\x1"
336"\x1D\x28\x3C\xE1\x59\x4F\x21\x34\xDA\xD1\x8D\x7E\xB4\xA4\x25\x4D\x69\xF6\x1B\x54\xA1\x61\x48\xA8\xA6\xA5"
337"\xB0\x69\x4E\x7B\xBA\xA2\x14\x7D\x28\x42\x23\x2D\x4\x1A\x30\x1\x2\xC5\x8\xF\xA4\x51\x9A\xD6\x29\x1"
338"\x2A\x98\x9D\x3D\xE8\x81\x4\x4C\x40\x1E\x60\x40\x1E\x90\x81\x7\x94\x81\x5B\xC3\xB5\x1D\xD0\xB5\xA2\xEA"
339"\xB5\x9D\xFA\x35\x60\xB\xAA\x5E\xD3\xB5\x62\x4B\x40\x92\x61\xAA\x30\x78\x2\x66\x68\xB6\x66\x20\xA7\xAA"
340"\x2A\x2\xAC\xCA\x2A\xAE\xCA\x36\x6D\x13\xAB\xB2\xBA\x81\x6C\xF8\x1B\xD\xD0\x80\xD\xD8\x0\x43\x30\x84"
341"\x6B\xA0\x6\x3\x58\x85\x9\x50\x84\x77\x8B\x37\x1\x1C\x40\xC3\x13\x1E\xA0\x2B\x42\x0\x70\x25\x57\x52"
342"\x3C\xDB\x63\xC2\xC7\x1B\x3A\x85\x10\x24\x42\x61\xB2\xF5\xA2\xBC\x2A\x7C\xFE\xBA\x18\x3A\xB8\x1D\xCB\x3C"
343"\xD3\xC2\xAF\xB8\xF3\xC2\xAA\xC3\x31\xFF\x1\xAD\xEF\x2\x80\xC8\x3A\xA5\x24\x52\x8\xD4\xEB\xA2\xD4\x8B"
344"\xBD\x36\x74\x3D\x7\x6B\xBB\xD5\x4B\x25\x21\x93\x8E\x18\xA3\x80\xDC\xDB\xBD\x97\xCB\x3B\x9A\x93\x95\x12"
345"\x1B\x8\xFE\x0\xA1\x81\x20\xC3\xAD\x40\x3C\x23\x34\x44\x0\x28\x44\x24\x84\x3C\xA2\x6B\x42\x16\x53\x1E"
346"\xC2\xEB\x10\x15\x1A\x1F\xCD\x82\x24\xA7\xC3\xBC\x83\xE3\x31\xFA\xF2\x31\xD5\x42\xAD\x48\x52\x24\x25\xDB"
347"\x38\x53\x32\x25\x25\x52\xC3\xB2\xD3\xA5\xE1\x6A\x3D\xD8\x63\x3B\xD8\x7B\x3B\x25\xDA\x3A\xE4\x62\xB1\x3B"
348"\x1C\x88\xB\xD3\xBD\xDE\xCB\x6\x85\xA8\x80\x94\x53\x88\xE1\x3\x80\x47\x2C\x3C\x42\x3C\xC2\x44\x14\xC6"
349"\xC4\x5B\x44\xC8\x13\xA4\x36\xD3\x38\x80\x53\x2F\x4A\xAC\x3C\x4B\x8C\x3A\x85\xDB\x3C\xCD\x43\x2D\x5F\xC2"
350"\x31\xB\x7A\xA\xC9\x3\x80\x48\x94\xAD\x26\x3A\x43\xB8\x43\xC3\x35\x4\x47\xB3\x73\x43\x55\x84\x3D\xB7"
351"\x9B\xC3\xFA\x81\xC5\x6\xB2\xB0\xE6\x2\x33\xBE\xBB\xB9\x2\x52\xB3\xE2\xD3\xA\xE4\x4B\x3E\x7A\xDC\x3E"
352"\xE5\xB3\x47\x7B\x64\xBE\x7D\x24\x6\xE7\x7B\x3E\x3B\xFE\xAB\x33\x7\xD8\x3E\xA2\x89\x88\x43\x9B\x29\x45"
353"\x63\x1\x3F\xA3\x81\x21\x0\xB4\x73\x11\xBF\x78\xAA\x27\xF3\x43\xBF\xF3\x53\x3F\xF5\xB3\x34\x4C\x7B\x3F"
354"\x4C\xA3\xB4\x47\x93\xA7\x73\x72\x80\x62\xB0\x92\x98\x5A\x9D\x9A\xDA\x3\xD9\xA1\x82\x8F\x2\x29\x17\x30"
355"\x99\x91\x22\x29\x5\x34\x36\x6\x4C\x6\x8\x8C\x40\x9\xC4\xB5\xA\x1C\x2A\x5F\x3\x2A\xD\xDC\xC0\x61"
356"\x23\xB6\x1D\x90\x1\x63\x33\x19\xAE\x91\x82\x65\x6B\xB6\x67\xA3\x1\x45\x98\xB6\x6A\xBB\xB6\x1\x20\x0"
357"\x7D\xC0\x80\x6C\xC8\x80\x2\xA8\x0\x1B\xE4\x80\xC1\x31\x80\xE\xF8\xC1\x61\x88\xB7\x10\x20\x94\x60\xF4"
358"\xCA\x43\x1C\xC6\x43\x54\xC2\x7C\xF3\x45\xAD\x20\x81\x18\xBB\x2C\xEE\xD2\x2C\x66\xC4\xC2\x2B\x44\xB8\x2C"
359"\x7C\x46\xCD\xA3\x46\x40\xAA\x21\xC2\x13\x3B\x0\x20\x3B\xFE\xE2\x25\x51\x9C\x43\x25\xD2\xA5\xB7\x63\xBD"
360"\x4\x23\x47\x91\x3\x39\xD9\xF3\x46\xAE\xAB\xC3\x27\x1C\x88\x55\xC8\x3D\x30\xCB\xC5\x81\xA0\xBB\x81\x10"
361"\xBC\x40\x24\x42\xB0\xFC\x4A\x44\xBC\xCC\x44\x4C\xC2\xC1\xDB\x8A\x36\xD3\xC6\xCA\x9A\x31\x47\x62\x4B\xB7"
362"\xBC\xBC\x67\x24\xAD\x4C\x5C\x38\xFE\x1C\xD3\xAC\xAF\x2B\x3C\xD0\xEA\x96\x23\x83\xCD\xBD\xB4\x32\x25\xF2"
363"\x4B\x39\x34\xCC\x54\x1C\x39\xC2\x54\xBB\x29\x1B\x2E\x57\x2C\x2F\xC5\x4\x0\xE\xE2\xBD\x3\x52\x88\x2D"
364"\x1B\x88\x9\x50\x88\x38\xF1\xB9\xCC\x64\x4E\xCB\x1C\x88\xBA\xC4\xCC\x43\x2C\x4B\x14\x9B\xC2\xA3\xB3\xAC"
365"\xD0\xEC\x2C\x2B\xB4\x3C\x67\xC4\xC4\x84\xC3\x31\x4A\x2A\x3E\x42\xB1\x81\xAC\xE3\x2F\xFF\x32\xB2\x51\x9C"
366"\x43\x5D\xFA\x4B\x92\x43\x3B\x38\x14\x4C\xC3\x54\x22\xDC\x1\x80\x7D\x80\x3C\xE4\x1C\x88\x5B\x1C\x88\x36"
367"\x50\x8\xC6\x54\x1F\x70\xF9\x7\x7C\x4\xD0\x7A\xC\xD0\x7B\x14\xD0\x2\x25\xD0\xE5\xCB\x47\x7C\x8C\x82"
368"\x75\x31\x6\x10\xE8\x3E\x80\x12\x28\x13\x90\xAA\xE9\x1B\x27\xEB\x33\x27\x3F\x63\x48\x76\x72\xA7\x87\x24"
369"\x3F\x7C\x92\xC8\x7B\x4A\xBF\x8A\xAC\xB4\x11\x95\xB4\x7B\x92\x27\x1A\x88\x80\xEC\x5B\x50\xC3\x9A\x37\xC5"
370"\x9A\xB5\x5A\xB\x2\x50\x13\x35\x8E\xD2\x2\x52\x4B\xC9\x92\x61\xC9\x9B\x51\xC0\x1E\x60\x40\x99\x8C\xC0"
371"\x99\xBC\xB5\xA\xD4\x81\x9B\xC4\xC0\x9C\xC\x36\xC\xAC\x40\x9F\x4C\x6\xA5\xD2\x82\x1F\x68\xAA\xAF\x29"
372"\x4A\xA9\x1A\xFE\x2\x45\x58\x85\x14\x90\xCA\xA\xA8\xCA\x22\x20\x87\xE\x20\x2\x23\x90\x94\xAD\xF8\x7"
373"\xE8\xC\xCB\xE8\x24\xD3\x31\x4D\x44\xE8\xF4\x45\xFE\xA1\xA2\xD7\x7C\x31\xA3\x4B\x2F\xEC\xA4\xC2\xCD\x6A"
374"\xCB\xED\xEC\xCE\x83\xD3\xAC\x81\xC3\xC6\xAB\xF0\x3C\xDA\xDB\x2F\x3F\x92\xCD\xD9\x3B\xCC\xDA\x34\xCC\xC0"
375"\x84\xB2\xDC\x5C\x3B\x7\x83\xB0\xDE\xF4\xA3\xF1\x9\x3A\x40\x4\x80\x6B\x99\x4C\xAD\xF8\x87\x49\x6D\xCE"
376"\x32\xAD\xD4\x31\x15\x24\x35\xF5\xA6\x62\x74\xBC\xA3\x53\x24\xF5\x1A\x9F\x30\xAA\xC4\xB6\xBC\x44\xB7\xD4"
377"\x2C\x45\xD2\xD4\x81\x48\xC6\x6C\xFC\x42\x3A\x44\x4C\xD8\x34\x4F\x6E\x44\xCF\x6F\x2C\x3B\xC0\x24\x39\x8"
378"\x5B\x45\xC2\x4C\xD4\x34\x1C\x32\x46\xAD\x20\x78\x4\x53\x4A\x75\x4E\x4B\x1D\x56\x33\x3D\xC2\x34\xC5\x46"
379"\x33\x1C\x4B\xE0\x6C\x3C\x27\x74\xD6\xB4\x54\xA1\xB5\x54\x88\x51\x25\x4D\x47\xF2\x1F\x41\x79\xA5\x2B\xA"
380"\x2F\x20\xFB\xBC\x21\x8B\xD5\x6D\xEC\x46\xDA\x64\xC3\xF5\x3C\xBB\xC1\x3C\xD4\x42\x15\x47\xDF\x4\x38\x5F"
381"\x5C\x16\x85\x98\xD4\x49\x3D\xD0\x4\x35\x50\x79\x8D\xD7\x1\xCD\xC7\x19\x88\x82\x19\x98\x17\x6\xFE\x75"
382"\x50\x36\x4B\x9A\x44\x63\x81\x45\xEB\x47\x39\x7B\x80\x7F\x84\xBE\x9\xCD\xB3\x3E\xBB\xD0\x75\x52\x27\x40"
383"\x7B\xA7\xF1\xEB\xD0\xF2\xFB\x50\x7C\x3A\xD1\x74\x4A\x51\x81\x3C\x2\xA8\x10\x42\x9A\x2A\x1\x16\x98\x1D"
384"\x16\x58\x2\xF9\xAB\xBF\x4F\xB3\x18\xA6\xC2\xA8\x51\xAB\x51\x94\xBC\xD1\x1C\xDD\xD1\x5\x74\x40\x1F\xA5"
385"\x49\xA\xB4\xC9\xA1\xC2\x40\x9D\xDC\x40\xE\x24\xB6\x9F\x14\x29\xAE\x51\x29\x95\xD9\x87\x8C\x5D\x3A\x49"
386"\x7D\x57\x78\xBD\xD4\xA2\x1D\x56\x64\x85\xC4\x23\x5C\x56\xA1\xEB\x9F\xDF\x74\x56\xD0\x54\x46\xB5\x9C\xD6"
387"\x66\xB4\x42\x45\xF2\xC5\x36\x6B\xB3\xD7\xBC\x2F\x6E\xE5\x53\x3F\xD2\xCB\xF3\xEC\x4B\x36\xB4\xD5\x8F\x7B"
388"\x43\xDD\x7C\x4F\x71\x34\xAE\x85\x13\x91\xA1\x65\xDB\x62\x35\x5A\x62\x25\x53\xE8\x5C\x3A\x64\xBC\xCC\xCD"
389"\x4\x4E\x46\x7C\xDA\x37\x95\x44\x47\x12\x55\x47\x32\x1E\xD6\x6C\x33\x3\xE3\xC2\x4D\x6C\x55\xFD\xF2\x5A"
390"\x23\xFB\xD3\x40\xED\xA3\x70\x24\xD4\x36\x7C\x3D\xC2\x1C\x2E\x5D\x3A\xA1\x81\x60\xDB\xB6\x9D\xDC\xCB\xC5"
391"\xDC\xCC\xD5\xDC\xCD\xE5\xDC\xCE\xF5\xDC\xCF\x5\xDD\xD0\x15\xDD\xD1\x25\xDD\x3E\xC9\xAD\xDC\xCA\x2D\xDD"
392"\xD4\x55\xDD\xD5\x65\xDD\xD6\x75\xDD\xD7\x65\xDD\xD3\x3D\x5D\xD8\xA5\xDD\xDA\xB5\xDD\xDB\xC5\xDD\xDC\x5"
393"\x0\xD9\xE5\x5D\xDD\xF5\xDD\xDF\x5\xDE\xE0\xC5\x5D\xDE\x25\xDE\xA1\x15\xDE\xE3\x45\xDE\xE4\x55\x5E\xA1"
394"\xE5\xDD\x80\x0\x0\x3B";
395
396#endif
diff --git a/src/memory.c b/src/memory.c
new file mode 100644
index 00000000..37ec1cba
--- /dev/null
+++ b/src/memory.c
@@ -0,0 +1,155 @@
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:25:25 GMT 2002
10 *
11 * -- memory functions
12 */
13#include "memory.h"
14
15IFDEBUG(int _t=0;)
16
17/*********************************************************************************************************/
18/*
19 * same as malloc with error reporting and libwebserver debug
20 */
21void * __ILWS_malloc(size_t s) {
22 void *ret;
23
24 ret=malloc(s);
25 if(ret==NULL) {
26 IFDEBUG(fprintf(stderr,"memory.c: malloc: %s (size %d)\n",strerror(errno),s);fflush(stderr));
27 return NULL;
28 };
29 IFDEBUG(_t++;);
30
31 IFDEBUG(fprintf(stderr,"memory.c (%d): Allocated %d bytes to %p\n",_t,s,ret);fflush(stderr));
32 return ret;
33}
34
35/*********************************************************************************************************/
36/*
37 * same as calloc with error reporting and libwebserver debug
38 */
39void * __ILWS_calloc(size_t nmemb,size_t s) {
40 void *ret;
41 ret=calloc(nmemb,s);
42 if(ret==NULL) {
43 IFDEBUG(fprintf(stderr,"memory.c: calloc %s\n",strerror(errno));fflush(stderr));
44 return NULL;
45 };
46 IFDEBUG(_t++;);
47 IFDEBUG(fprintf(stderr,"memory.c (%d): Allocated %d bytes to %p\n",_t,s*nmemb,ret);fflush(stderr));
48 return ret;
49}
50
51/*********************************************************************************************************/
52/*
53 * same as realloc with error reporting and libwebserver debug
54 */
55void * __ILWS_realloc(void *buf,size_t s) {
56 void *ret;
57 ret=realloc(buf,s);
58#ifdef DEBUG
59 if(buf==NULL) {
60 _t++;
61 IFDEBUG(fprintf(stderr,"memory.c (%d): Allocated %d bytes to %p\n",_t,s,ret);fflush(stderr));
62 };
63#endif
64 if(ret==NULL) {
65 IFDEBUG(fprintf(stderr,"memory.c: realloc: %s\n",strerror(errno));fflush(stderr));
66 return NULL;
67 };
68 IFDEBUG(fprintf(stderr,"memory.c: Realloc buffer %p to %d\n",buf,s);fflush(stderr));
69 return ret;
70}
71
72
73/*********************************************************************************************************/
74/*
75 * same as free with error report and libwebserver debug
76 */
77void __ILWS_free(void *ptr) {
78 if(ptr!=NULL) {
79 free(ptr);
80 IFDEBUG(fprintf(stderr,"memory.c (%d): Buffer %p freed\n",_t,ptr);fflush(stderr));
81 IFDEBUG(_t--;);
82 };
83}
84
85
86/*********************************************************************************************************/
87/*
88 * Add a buffer to memrequest list
89 */
90void *__ILWS_add_buffer(struct memrequest *list,unsigned int size) {
91 struct memrequest *tmem;
92 if(size==0) {
93 return NULL;
94 };
95 if(list!=NULL) {
96 tmem=list;
97 }else {
98 return NULL;
99 };
100 while(tmem->next!=NULL)tmem=tmem->next;
101 tmem->next=__ILWS_malloc(sizeof(struct memrequest));
102 if(tmem->next==NULL) return NULL; // ERROR
103 tmem->next->ptr=__ILWS_malloc(size);
104 tmem->next->next=NULL;
105 return tmem->next->ptr;
106}
107
108/*********************************************************************************************************/
109/*
110 * Initialize memrequest list of buffers
111 */
112struct memrequest *__ILWS_init_buffer_list() {
113 struct memrequest *newlist;
114 newlist=__ILWS_malloc(sizeof(struct memrequest));
115 if(newlist==NULL) return NULL;
116
117 newlist->next=NULL;
118 newlist->ptr=NULL;
119 return newlist;
120}
121
122/*********************************************************************************************************/
123/*
124 * Delete memrequest buffer node (free)
125 */
126void __ILWS_delete_buffer(struct memrequest *mem) {
127 __ILWS_free(mem->ptr);
128 __ILWS_free(mem);
129}
130
131/*********************************************************************************************************/
132/*
133 * Delete memrequest next buffer
134 */
135void __ILWS_delete_next_buffer(struct memrequest *mem) {
136 struct memrequest *tmem;
137 tmem=mem->next;
138 mem->next=mem->next->next;
139 __ILWS_delete_buffer(tmem);
140}
141
142/*********************************************************************************************************/
143/*
144 * Delete whole memrequest buffer list
145 */
146void __ILWS_delete_buffer_list(struct memrequest *list) {
147 struct memrequest *tmem=list;
148 if(tmem==NULL) return;
149
150 while(tmem->next!=NULL) {
151 __ILWS_delete_next_buffer(tmem);
152 };
153 __ILWS_delete_buffer(tmem);
154}
155
diff --git a/src/memory.h b/src/memory.h
new file mode 100644
index 00000000..8c759f3d
--- /dev/null
+++ b/src/memory.h
@@ -0,0 +1,46 @@
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:25:25 GMT 2002
10 *
11 * memory functions
12 */
13
14#ifndef _MEMORY_H_
15#define _MEMORY_H_
16
17#ifdef HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <errno.h> // Johannes E. Schindelin
26
27#include "debug.h"
28
29extern int errno;
30
31void *__ILWS_malloc(size_t);
32void *__ILWS_calloc(size_t,size_t);
33void *__ILWS_realloc(void *,size_t);
34void __ILWS_free(void *);
35
36struct memrequest {
37 char *ptr;
38 struct memrequest *next;
39};
40struct memrequest *__ILWS_init_buffer_list();
41void *__ILWS_add_buffer(struct memrequest *,unsigned int);
42void __ILWS_delete_buffer(struct memrequest *);
43void __ILWS_delete_next_buffer(struct memrequest *);
44void __ILWS_delete_buffer_list(struct memrequest *);
45
46#endif
diff --git a/src/module.c b/src/module.c
new file mode 100644
index 00000000..b809456f
--- /dev/null
+++ b/src/module.c
@@ -0,0 +1,22 @@
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: Wen Jul 30 06:57:42 GMT 2003
10 *
11 * -- module function
12 *
13 * Tested on WIN32 only
14 */
15#include "module.h"
16
17
18
19
20
21
22
diff --git a/src/module.h b/src/module.h
new file mode 100644
index 00000000..05b14d59
--- /dev/null
+++ b/src/module.h
@@ -0,0 +1,25 @@
1
2
3
4
5
6
7
8
9
10
11
12
13#ifndef _MODULE_H_
14#define _MODULE_H_
15
16struct module {
17 const char *handle;
18 void (func)();
19
20};
21
22
23
24
25#endif \ No newline at end of file
diff --git a/src/outgif.c b/src/outgif.c
new file mode 100644
index 00000000..4a8e9a62
--- /dev/null
+++ b/src/outgif.c
@@ -0,0 +1,587 @@
1/*
2 * Luis Figueiredo - why remake the wheel, this functions feets perfectly
3 * and the credits still here :)
4 */
5
6
7/*
8 * xvgifwr.c - handles writing of GIF files. based on flgife.c and
9 * flgifc.c from the FBM Library, by Michael Maudlin
10 *
11 * Contains:
12 * WriteGIF(fp, pic, ptype, w, h, rmap, gmap, bmap, numcols, colorstyle,
13 * comment)
14 *
15 * Note: slightly brain-damaged, in that it'll only write non-interlaced
16 * GIF files (in the interests of speed, or something)
17 *
18 */
19
20
21
22/*****************************************************************
23 * Portions of this code Copyright (C) 1989 by Michael Mauldin.
24 * Permission is granted to use this file in whole or in
25 * part for any purpose, educational, recreational or commercial,
26 * provided that this copyright notice is retained unchanged.
27 * This software is available to all free of charge by anonymous
28 * FTP and in the UUNET archives.
29 *
30 *
31 * Authors: Michael Mauldin (mlm@cs.cmu.edu)
32 * David Rowley (mgardi@watdcsu.waterloo.edu)
33 *
34 * Based on: compress.c - File compression ala IEEE Computer, June 1984.
35 *
36 * Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)
37 * Jim McKie (decvax!mcvax!jim)
38 * Steve Davies (decvax!vax135!petsd!peora!srd)
39 * Ken Turkowski (decvax!decwrl!turtlevax!ken)
40 * James A. Woods (decvax!ihnp4!ames!jaw)
41 * Joe Orost (decvax!vax135!petsd!joe)
42 *****************************************************************/
43
44
45#include "outgif.h"
46
47static int __ILWS_Width, __ILWS_Height;
48static int __ILWS_curx, __ILWS_cury;
49static long __ILWS_CountDown;
50static int __ILWS_Interlace;
51//static unsigned char bw[2] = {0, 0xff};
52
53static void __ILWS_putword PARM((int, FILE *));
54static void __ILWS_compress PARM((int, FILE *, unsigned char *, int));
55static void __ILWS_output PARM((int));
56static void __ILWS_cl_block PARM((void));
57static void __ILWS_cl_hash PARM((count_int));
58static void __ILWS_char_init PARM((void));
59static void __ILWS_char_out PARM((int));
60static void __ILWS_flush_char PARM((void));
61
62
63static unsigned char pc2nc[256],r1[256],g1[256],b1[256];
64
65
66/*************************************************************/
67int __ILWS_WriteGIF(FILE *fp, unsigned char *pic, int w, int h, unsigned char *rmap, unsigned char *gmap, unsigned char *bmap, int numcols, int colorstyle,int transparency,
68 char *comment)
69{
70 int RWidth, RHeight;
71 int LeftOfs, TopOfs;
72 int ColorMapSize, InitCodeSize, Background, BitsPerPixel;
73 int i,j,nc;
74 unsigned char *pic8;
75 //unsigned char rtemp[256],gtemp[256],btemp[256];
76
77 pic8 = pic;
78
79
80
81 __ILWS_Interlace = 0;
82 Background = 0;
83
84
85 for (i=0; i<256; i++) { pc2nc[i] = r1[i] = g1[i] = b1[i] = 0; }
86
87 /* compute number of unique colors */
88 nc = 0;
89
90 for (i=0; i<numcols; i++) {
91 /* see if color #i is already used */
92 for (j=0; j<i; j++) {
93 if (rmap[i] == rmap[j] && gmap[i] == gmap[j] &&
94 bmap[i] == bmap[j]) break;
95 }
96
97 if (j==i) { /* wasn't found */
98 pc2nc[i] = nc;
99 r1[nc] = rmap[i];
100 g1[nc] = gmap[i];
101 b1[nc] = bmap[i];
102 nc++;
103 }
104 else pc2nc[i] = pc2nc[j];
105 }
106
107
108 /* figure out 'BitsPerPixel' */
109 for (i=1; i<8; i++)
110 if ( (1<<i) >= nc) break;
111
112 BitsPerPixel = i;
113
114 ColorMapSize = 1 << BitsPerPixel;
115
116 RWidth = __ILWS_Width = w;
117 RHeight = __ILWS_Height = h;
118 LeftOfs = TopOfs = 0;
119
120 __ILWS_CountDown = w * h; /* # of pixels we'll be doing */
121
122 if (BitsPerPixel <= 1) InitCodeSize = 2;
123 else InitCodeSize = BitsPerPixel;
124
125 __ILWS_curx = __ILWS_cury = 0;
126
127 if (!fp) {
128 fprintf(stderr, "WriteGIF: file not open for writing\n" );
129 return (1);
130 }
131
132
133 if (comment && strlen(comment) > (size_t) 0)
134 fwrite("GIF89a", (size_t) 1, (size_t) 6, fp); /* the GIF magic number */
135 else
136 fwrite("GIF87a", (size_t) 1, (size_t) 6, fp); /* the GIF magic number */
137
138 __ILWS_putword(RWidth, fp); /* screen descriptor */
139 __ILWS_putword(RHeight, fp);
140
141 i = 0x80; /* Yes, there is a color map */
142 i |= (8-1)<<4; /* OR in the color resolution (hardwired 8) */
143 i |= (BitsPerPixel - 1); /* OR in the # of bits per pixel */
144 fputc(i,fp);
145
146 fputc(Background, fp); /* background color */
147
148 fputc(0, fp); /* future expansion unsigned char */
149
150
151 if (colorstyle == 1) { /* greyscale */
152 for (i=0; i<ColorMapSize; i++) {
153 j = MONO(r1[i], g1[i], b1[i]);
154 fputc(j, fp);
155 fputc(j, fp);
156 fputc(j, fp);
157 }
158 }
159 else {
160 for (i=0; i<ColorMapSize; i++) { /* write out Global colormap */
161 fputc(r1[i], fp);
162 fputc(g1[i], fp);
163 fputc(b1[i], fp);
164 }
165 }
166
167 if (comment && strlen(comment) > (size_t) 0) { /* write comment blocks */
168 char *sp;
169 int i, blen;
170
171 fputc(0x21, fp); /* EXTENSION block */
172 fputc(0xF9,fp); // graphic control extension// Luis Figueiredo
173 fputc(4,fp); // blocksize
174 fputc(0x1,fp); // transparency flag
175 fputc(100,fp);// delay (unsigned?)
176 fputc(100,fp);// delay (unsigned?)
177 fputc(transparency,fp); // Luis figueiredo
178 fputc(0, fp); /* zero-length data subblock to end extension */
179 fputc(0x21, fp); /* EXTENSION block */
180 fputc(0xFE, fp); /* comment extension */
181 sp = comment;
182 while ( (blen=strlen(sp)) > 0) {
183 if (blen>255) blen = 255;
184 fputc(blen, fp);
185 for (i=0; i<blen; i++, sp++) fputc(*sp, fp);
186 }
187 fputc(0, fp); /* zero-length data subblock to end extension */
188 }
189
190
191 fputc( ',', fp ); /* image separator */
192
193 /* Write the Image header */
194 __ILWS_putword(LeftOfs, fp);
195 __ILWS_putword(TopOfs, fp);
196 __ILWS_putword(__ILWS_Width, fp);
197 __ILWS_putword(__ILWS_Height, fp);
198 if (__ILWS_Interlace) fputc(0x40, fp); /* Use Global Colormap, maybe Interlace */
199 else fputc(0x00, fp);
200
201 fputc(InitCodeSize, fp);
202 __ILWS_compress(InitCodeSize+1, fp, pic8, w*h);
203
204 fputc(0,fp); /* Write out a Zero-length packet (EOF) */
205 fputc(';',fp); /* Write GIF file terminator */
206
207
208 if (ferror(fp)) return -1;
209 return (0);
210}
211
212
213
214
215/******************************/
216static void __ILWS_putword(int w, FILE *fp)
217{
218 /* writes a 16-bit integer in GIF order (LSB first) */
219 fputc(w & 0xff, fp);
220 fputc((w>>8)&0xff, fp);
221}
222
223
224
225
226/***********************************************************************/
227
228
229static unsigned long __ILWS_cur_accum = 0;
230static int __ILWS_cur_bits = 0;
231
232
233
234
235#define min(a,b) ((a>b) ? b : a)
236
237#define XV_BITS 12 /* BITS was already defined on some systems */
238#define MSDOS 1
239
240#define HSIZE 5003 /* 80% occupancy */
241
242typedef unsigned char char_type;
243
244
245static int __ILWS_n_bits; /* number of bits/code */
246static int __ILWS_maxbits = XV_BITS; /* user settable max # bits/code */
247static int __ILWS_maxcode; /* maximum code, given n_bits */
248static int __ILWS_maxmaxcode = 1 << XV_BITS; /* NEVER generate this */
249
250#define MAXCODE(n_bits) ( (1 << (n_bits)) - 1)
251
252static count_int __ILWS_htab [HSIZE];
253static unsigned short __ILWS_codetab [HSIZE];
254#define HashTabOf(i) __ILWS_htab[i]
255#define CodeTabOf(i) __ILWS_codetab[i]
256
257static int __ILWS_hsize = HSIZE; /* for dynamic table sizing */
258
259/*
260 * To save much memory, we overlay the table used by compress() with those
261 * used by decompress(). The tab_prefix table is the same size and type
262 * as the codetab. The tab_suffix table needs 2**BITS characters. We
263 * get this from the beginning of htab. The output stack uses the rest
264 * of htab, and contains characters. There is plenty of room for any
265 * possible stack (stack used to be 8000 characters).
266 */
267
268#define tab_prefixof(i) CodeTabOf(i)
269#define tab_suffixof(i) ((char_type *)(htab))[i]
270#define de_stack ((char_type *)&tab_suffixof(1<<XV_BITS))
271
272static int __ILWS_free_ent = 0; /* first unused entry */
273
274/*
275 * block compression parameters -- after all codes are used up,
276 * and compression rate changes, start over.
277 */
278static int __ILWS_clear_flg = 0;
279
280static long int __ILWS_in_count = 1; /* length of input */
281static long int __ILWS_out_count = 0; /* # of codes output (for debugging) */
282
283/*
284 * compress stdin to stdout
285 *
286 * Algorithm: use open addressing double hashing (no chaining) on the
287 * prefix code / next character combination. We do a variant of Knuth's
288 * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
289 * secondary probe. Here, the modular division first probe is gives way
290 * to a faster exclusive-or manipulation. Also do block compression with
291 * an adaptive reset, whereby the code table is cleared when the compression
292 * ratio decreases, but after the table fills. The variable-length output
293 * codes are re-sized at this point, and a special CLEAR code is generated
294 * for the decompressor. Late addition: construct the table according to
295 * file size for noticeable speed improvement on small files. Please direct
296 * questions about this implementation to ames!jaw.
297 */
298
299static int __ILWS_g_init_bits;
300static FILE *__ILWS_g_outfile;
301
302static int __ILWS_ClearCode;
303static int __ILWS_EOFCode;
304
305
306/********************************************************/
307static void __ILWS_compress(int init_bits, FILE *outfile, unsigned char *data, int len)
308
309{
310 register long fcode;
311 register int i = 0;
312 register int c;
313 register int ent;
314 register int disp;
315 register int hsize_reg;
316 register int hshift;
317
318 /*
319 * Set up the globals: g_init_bits - initial number of bits
320 * g_outfile - pointer to output file
321 */
322 __ILWS_g_init_bits = init_bits;
323 __ILWS_g_outfile = outfile;
324
325 /* initialize 'compress' globals */
326 __ILWS_maxbits = XV_BITS;
327 __ILWS_maxmaxcode = 1<<XV_BITS;
328 memset((char *) __ILWS_htab,0, sizeof(__ILWS_htab));
329 memset((char *) __ILWS_codetab,0, sizeof(__ILWS_codetab));
330 __ILWS_hsize = HSIZE;
331 __ILWS_free_ent = 0;
332 __ILWS_clear_flg = 0;
333 __ILWS_in_count = 1;
334 __ILWS_out_count = 0;
335 __ILWS_cur_accum = 0;
336 __ILWS_cur_bits = 0;
337
338
339 /*
340 * Set up the necessary values
341 */
342 __ILWS_out_count = 0;
343 __ILWS_clear_flg = 0;
344 __ILWS_in_count = 1;
345 __ILWS_maxcode = MAXCODE(__ILWS_n_bits = __ILWS_g_init_bits);
346
347 __ILWS_ClearCode = (1 << (init_bits - 1));
348 __ILWS_EOFCode = __ILWS_ClearCode + 1;
349 __ILWS_free_ent = __ILWS_ClearCode + 2;
350
351 __ILWS_char_init();
352 ent = pc2nc[*data++];
353 len--;
354
355 hshift = 0;
356 for ( fcode = (long) __ILWS_hsize; fcode < 65536L; fcode *= 2L )
357 hshift++;
358 hshift = 8 - hshift; /* set hash code range bound */
359
360 hsize_reg = __ILWS_hsize;
361 __ILWS_cl_hash( (count_int) hsize_reg); /* clear hash table */
362
363 __ILWS_output(__ILWS_ClearCode);
364
365 while (len) {
366 c = pc2nc[*data++]; len--;
367 __ILWS_in_count++;
368
369 fcode = (long) ( ( (long) c << __ILWS_maxbits) + ent);
370 i = (((int) c << hshift) ^ ent); /* xor hashing */
371
372 if ( HashTabOf (i) == fcode ) {
373 ent = CodeTabOf (i);
374 continue;
375 }
376
377 else if ( (long)HashTabOf (i) < 0 ) /* empty slot */
378 goto nomatch;
379
380 disp = hsize_reg - i; /* secondary hash (after G. Knott) */
381 if ( i == 0 )
382 disp = 1;
383
384probe:
385 if ( (i -= disp) < 0 )
386 i += hsize_reg;
387
388 if ( HashTabOf (i) == fcode ) {
389 ent = CodeTabOf (i);
390 continue;
391 }
392
393 if ( (long)HashTabOf (i) >= 0 )
394 goto probe;
395
396nomatch:
397 __ILWS_output(ent);
398 __ILWS_out_count++;
399 ent = c;
400
401 if ( __ILWS_free_ent < __ILWS_maxmaxcode ) {
402 CodeTabOf (i) = __ILWS_free_ent++; /* code -> hashtable */
403 HashTabOf (i) = fcode;
404 }
405 else
406 __ILWS_cl_block();
407 }
408
409 /* Put out the final code */
410 __ILWS_output(ent);
411 __ILWS_out_count++;
412 __ILWS_output(__ILWS_EOFCode);
413}
414
415
416/*****************************************************************
417 * TAG( output )
418 *
419 * Output the given code.
420 * Inputs:
421 * code: A n_bits-bit integer. If == -1, then EOF. This assumes
422 * that n_bits =< (long)wordsize - 1.
423 * Outputs:
424 * Outputs code to the file.
425 * Assumptions:
426 * Chars are 8 bits long.
427 * Algorithm:
428 * Maintain a BITS character long buffer (so that 8 codes will
429 * fit in it exactly). Use the VAX insv instruction to insert each
430 * code in turn. When the buffer fills up empty it and start over.
431 */
432
433static
434unsigned long __ILWS_masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F,
435 0x001F, 0x003F, 0x007F, 0x00FF,
436 0x01FF, 0x03FF, 0x07FF, 0x0FFF,
437 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
438
439static void __ILWS_output(int code)
440{
441 __ILWS_cur_accum &= __ILWS_masks[__ILWS_cur_bits];
442
443 if (__ILWS_cur_bits > 0)
444 __ILWS_cur_accum |= ((long)code << __ILWS_cur_bits);
445 else
446 __ILWS_cur_accum = code;
447
448 __ILWS_cur_bits += __ILWS_n_bits;
449
450 while( __ILWS_cur_bits >= 8 ) {
451 __ILWS_char_out( (int) (__ILWS_cur_accum & 0xff) );
452 __ILWS_cur_accum >>= 8;
453 __ILWS_cur_bits -= 8;
454 }
455
456 /*
457 * If the next entry is going to be too big for the code size,
458 * then increase it, if possible.
459 */
460
461 if (__ILWS_free_ent > __ILWS_maxcode || __ILWS_clear_flg) {
462
463 if( __ILWS_clear_flg ) {
464 __ILWS_maxcode = MAXCODE (__ILWS_n_bits = __ILWS_g_init_bits);
465 __ILWS_clear_flg = 0;
466 }
467 else {
468 __ILWS_n_bits++;
469 if ( __ILWS_n_bits == __ILWS_maxbits )
470 __ILWS_maxcode = __ILWS_maxmaxcode;
471 else
472 __ILWS_maxcode = MAXCODE(__ILWS_n_bits);
473 }
474 }
475
476 if( code == __ILWS_EOFCode ) {
477 /* At EOF, write the rest of the buffer */
478 while( __ILWS_cur_bits > 0 ) {
479 __ILWS_char_out( (int)(__ILWS_cur_accum & 0xff) );
480 __ILWS_cur_accum >>= 8;
481 __ILWS_cur_bits -= 8;
482 }
483
484 __ILWS_flush_char();
485
486 fflush( __ILWS_g_outfile );
487
488#ifdef FOO
489 if( ferror( g_outfile ) )
490 FatalError("unable to write GIF file");
491#endif
492 }
493}
494
495
496/********************************/
497static void __ILWS_cl_block () /* table clear for block compress */
498{
499 /* Clear out the hash table */
500
501 __ILWS_cl_hash ( (count_int) __ILWS_hsize );
502 __ILWS_free_ent = __ILWS_ClearCode + 2;
503 __ILWS_clear_flg = 1;
504
505 __ILWS_output(__ILWS_ClearCode);
506}
507
508
509/********************************/
510static void __ILWS_cl_hash(register count_int hsize) /* reset code table */
511{
512 register count_int *htab_p = __ILWS_htab+hsize;
513 register long i;
514 register long m1 = -1;
515
516 i = hsize - 16;
517 do { /* might use Sys V memset(3) here */
518 *(htab_p-16) = m1;
519 *(htab_p-15) = m1;
520 *(htab_p-14) = m1;
521 *(htab_p-13) = m1;
522 *(htab_p-12) = m1;
523 *(htab_p-11) = m1;
524 *(htab_p-10) = m1;
525 *(htab_p-9) = m1;
526 *(htab_p-8) = m1;
527 *(htab_p-7) = m1;
528 *(htab_p-6) = m1;
529 *(htab_p-5) = m1;
530 *(htab_p-4) = m1;
531 *(htab_p-3) = m1;
532 *(htab_p-2) = m1;
533 *(htab_p-1) = m1;
534 htab_p -= 16;
535 } while ((i -= 16) >= 0);
536
537 for ( i += 16; i > 0; i-- )
538 *--htab_p = m1;
539}
540
541
542/******************************************************************************
543 *
544 * GIF Specific routines
545 *
546 ******************************************************************************/
547
548/*
549 * Number of characters so far in this 'packet'
550 */
551static int __ILWS_a_count;
552
553/*
554 * Set up the 'unsigned char output' routine
555 */
556static void __ILWS_char_init()
557{
558 __ILWS_a_count = 0;
559}
560
561/*
562 * Define the storage for the packet accumulator
563 */
564static char __ILWS_accum[ 256 ];
565
566/*
567 * Add a character to the end of the current packet, and if it is 254
568 * characters, flush the packet to disk.
569 */
570static void __ILWS_char_out(int c)
571{
572 __ILWS_accum[ __ILWS_a_count++ ] = c;
573 if( __ILWS_a_count >= 254 )
574 __ILWS_flush_char();
575}
576
577/*
578 * Flush the packet to disk, and reset the accumulator
579 */
580static void __ILWS_flush_char()
581{
582 if( __ILWS_a_count > 0 ) {
583 fputc(__ILWS_a_count, __ILWS_g_outfile );
584 fwrite(__ILWS_accum, (size_t) 1, (size_t) __ILWS_a_count, __ILWS_g_outfile );
585 __ILWS_a_count = 0;
586 }
587}
diff --git a/src/outgif.h b/src/outgif.h
new file mode 100644
index 00000000..c904fa01
--- /dev/null
+++ b/src/outgif.h
@@ -0,0 +1,63 @@
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 * file: web_outgif.h
10 *
11 * description: output gif outgif.c is copyrighted by
12 */
13 /*****************************************************************
14 * Portions of this code Copyright (C) 1989 by Michael Mauldin.
15 * Permission is granted to use this file in whole or in
16 * part for any purpose, educational, recreational or commercial,
17 * provided that this copyright notice is retained unchanged.
18 * This software is available to all free of charge by anonymous
19 * FTP and in the UUNET archives.
20 *
21 *
22 * Authors: Michael Mauldin (mlm@cs.cmu.edu)
23 * David Rowley (mgardi@watdcsu.waterloo.edu)
24 *
25 * Based on: compress.c - File compression ala IEEE Computer, June 1984.
26 *
27 * Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)
28 * Jim McKie (decvax!mcvax!jim)
29 * Steve Davies (decvax!vax135!petsd!peora!srd)
30 * Ken Turkowski (decvax!decwrl!turtlevax!ken)
31 * James A. Woods (decvax!ihnp4!ames!jaw)
32 * Joe Orost (decvax!vax135!petsd!joe)
33 *****************************************************************/
34/*
35 *
36 * date: 20:57,13-57-2002
37 */
38
39#ifndef _WEB_OUTGIF_H_
40#define _WEB_OUTGIF_H_
41
42#include <stdio.h>
43#include <string.h>
44
45#include "debug.h"
46
47#undef PARM
48#ifdef __STDC__
49# define PARM(a) a
50#else
51# define PARM(a) ()
52# define const
53#endif
54
55/* MONO returns total intensity of r,g,b triple (i = .33R + .5G + .17B) */
56#define MONO(rd,gn,bl) ( ((int)(rd)*11 + (int)(gn)*16 + (int)(bl)*5) >> 5)
57
58typedef long int count_int;
59
60
61int __ILWS_WriteGIF(FILE *, unsigned char *, int, int, unsigned char *, unsigned char *, unsigned char *, int, int, int, char *);
62
63#endif
diff --git a/src/outstream.c b/src/outstream.c
new file mode 100644
index 00000000..10b5f981
--- /dev/null
+++ b/src/outstream.c
@@ -0,0 +1,122 @@
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:25:25 GMT 2002
10 *
11 * -- stream list functions
12 */
13
14
15#include "outstream.h"
16
17/*********************************************************************************************************/
18/*
19 * add_outstream, add a file to output (client) stream
20 */
21int __ILWS_add_outstream(struct outstream *list,char *fname,FILE* stream,int istmp){
22 struct outstream *temp=list;
23 FILE *tmp;
24 while(temp->next!=NULL)temp=temp->next;
25
26 if(!(temp->next=__ILWS_malloc(sizeof(struct outstream)))) {
27 LWSERR(LE_MEMORY);
28 return 0;
29 };
30 // file check (0.5.3);
31 tmp=fopen(fname,"rb");
32 if(tmp==NULL) {
33 __ILWS_free(temp->next);
34 temp->next=NULL;
35 return 0;
36 };
37 fclose(tmp);
38 // --
39 temp->next->fname=NULL;
40 if(fname!=NULL) {
41 if(!(temp->next->fname=__ILWS_malloc(strlen(fname)+1))) {
42 __ILWS_free(temp->next);
43 temp->next=NULL;
44 LWSERR(LE_MEMORY);
45 return 0;
46 };
47 memcpy(temp->next->fname,fname,strlen(fname));
48 temp->next->fname[strlen(fname)]='\0';
49 };
50 temp->next->todelete=istmp;
51 temp->next->fstream=stream;
52 temp->next->wsize=1;
53 temp->next->rsize=0;
54 temp->next->wrotesize=0;
55 temp->next->varsize=0;
56 temp->next->next=NULL;
57 return 1;
58}
59
60/*********************************************************************************************************/
61/*
62 * Initializate (allocate) outstream list
63 */
64struct outstream *__ILWS_init_outstream_list() {
65 struct outstream *ret;
66
67
68 if(!(ret=__ILWS_malloc(sizeof(struct outstream)))) {
69 LWSERR(LE_MEMORY);
70 return NULL;
71 };
72 ret->todelete=0;
73 ret->fname=NULL;
74 ret->flags=0;
75 ret->fstream=NULL;
76 ret->next=NULL;
77 return ret;
78}
79
80/*********************************************************************************************************/
81/*
82 * Delete a especific node
83 */
84void __ILWS_delete_outstream(struct outstream *node) { // Changed
85 int rt;
86 if(node->fstream!=NULL)fclose(node->fstream); // better here;
87 if(node->todelete) { // is temporary file
88 rt=unlink(node->fname);
89 if(rt==-1) {
90 LWSERR(LE_FILESYS);
91 };
92
93 };
94 if(node->fname!=NULL)__ILWS_free(node->fname);
95 __ILWS_free(node);
96}
97
98/*********************************************************************************************************/
99/*
100 * delete next node
101 */
102void __ILWS_delete_next_outstream(struct outstream *node) {
103 struct outstream *temp=node->next;
104 node->next=node->next->next;
105 __ILWS_delete_outstream(temp);
106}
107
108/*********************************************************************************************************/
109/*
110 * delete all nodes on the list (reset list)
111 */
112void __ILWS_delete_outstream_list(struct outstream *list) {
113 struct outstream *temp=list;
114 while(temp->next!=NULL) {
115
116 __ILWS_delete_next_outstream(temp);
117 };
118
119 __ILWS_delete_outstream(temp);
120
121}
122
diff --git a/src/outstream.h b/src/outstream.h
new file mode 100644
index 00000000..c6d25f50
--- /dev/null
+++ b/src/outstream.h
@@ -0,0 +1,53 @@
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:25:25 GMT 2002
10 *
11 * stream functions
12 */
13
14#ifndef _OUTSTREAM_H_
15#define _OUTSTREAM_H_
16
17#ifdef HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24
25#ifndef WIN32
26#include <unistd.h>
27#endif
28
29#include "debug.h"
30#include "memory.h"
31#include "error.h"
32
33
34
35
36
37struct outstream {
38 FILE *fstream;
39 char *fname;
40 int todelete;
41 int wsize,rsize;
42 long wrotesize;
43 long varsize;
44 int flags;
45 struct outstream *next;
46};
47
48int __ILWS_add_outstream(struct outstream *, char *,FILE *,int);
49struct outstream *__ILWS_init_outstream_list();
50void __ILWS_delete_next_outstream(struct outstream *);
51void __ILWS_delete_outstream_list(struct outstream *);
52void __ILWS_delete_outstream(struct outstream *);
53#endif
diff --git a/src/server.c b/src/server.c
new file mode 100644
index 00000000..f21e9697
--- /dev/null
+++ b/src/server.c
@@ -0,0 +1,448 @@
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 "server.h"
16#include "logo.h"
17
18#ifdef WIN32
19 #define _SERVER_VERSION "libwebserver/0.5.3(win32)" // update allways when changing version (damn win)
20#endif
21
22#ifndef _SERVER_VERSION
23 #define _SERVER_VERSION "libwebserver/(unknow)"
24#endif
25
26#ifdef DEBUG
27 char *_libwebserver_version= _SERVER_VERSION "(debug)";
28#else
29 char *_libwebserver_version= _SERVER_VERSION;
30#endif
31
32struct web_server *current_web_server;
33
34
35/*********************************************************************************************************/
36/*
37 * Define certificate file (open_ssl)
38 */
39void web_server_useSSLcert(struct web_server *server,const char *file) {
40#ifdef HAVE_OPENSSL
41 if(!(server->cert_file=__ILWS_malloc(strlen(file)+1))) {
42 LWSERR(LE_MEMORY);
43 return;
44 };
45 memcpy(server->cert_file,file,strlen(file));
46 server->cert_file[strlen(file)]=0;
47#else
48 printf("OpenSSL not supported in this compilation\n");
49#endif
50}
51
52void web_server_useMIMEfile(struct web_server *server,const char *file) {
53 if(!(server->mimefile=__ILWS_malloc(strlen(file)+1))) {
54 LWSERR(LE_MEMORY);
55 return;
56 };
57 memcpy(server->mimefile,file,strlen(file));
58 server->mimefile[strlen(file)]=0;
59};
60/*********************************************************************************************************/
61/*
62 * Handler for libwebserver logotipe
63 */
64void _web_server_logo() {
65 printf("Content-type: image/gif\r\n\r\n");
66 fwrite((char *)_logo,sizeof(_logo),1,stdout);
67}
68
69
70/*********************************************************************************************************/
71/*
72 * Add an handler to request data
73 */
74int web_server_addhandler(struct web_server *server,const char *mstr,void (*func)(),int flag) {
75 _logfile=server->weblog;
76 // xor?
77 flag ^= (server->flags & WS_LOCAL); // global flag to handler flag
78 flag ^= (server->flags & WS_DYNVAR); // global flag to handler flag
79 flag ^= (server->flags & WS_USELEN); // global flag to handler flag
80 web_log("[%s] Adding handler %s <--%s%s%s\n",__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),mstr, ((flag & WS_LOCAL) == WS_LOCAL && !((server->flags & WS_LOCAL) == WS_LOCAL))?"[LOCAL] ":"", ((flag & WS_DYNVAR) == WS_DYNVAR)?"[DYNVAR]":"", ((flag & WS_USELEN) == WS_USELEN)?"[USELEN]":"");
81 return __ILWS_add_handler((struct gethandler *)server->gethandler,mstr,func,NULL,flag,GH_FUNCTION);
82}
83
84/*********************************************************************************************************/
85/*
86 * Add an alias dir (new on 0.5.2)
87 */
88int web_server_aliasdir(struct web_server *server, const char *str, char *path,int flag) {
89 char *mstr;
90 int ret;
91 mstr=__ILWS_malloc(strlen(str)+7);
92 if(!strlen(str)) {
93 snprintf(mstr,strlen(str)+7,"* /*");
94 } else {
95 snprintf(mstr,strlen(str)+7,"* /%s/*",str);
96 };
97 _logfile=server->weblog;
98 flag ^= (server->flags & WS_LOCAL); // global flag to handler flag
99 flag ^= (server->flags & WS_DYNVAR); // global flag to handler flag
100 flag ^= (server->flags & WS_USELEN); // global flag to handler flag
101 web_log("[%s] Adding directory %s <--%s%s%s\n",__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),mstr, ((flag & WS_LOCAL) == WS_LOCAL && !((server->flags & WS_LOCAL) == WS_LOCAL))?"[LOCAL] ":"", ((flag & WS_DYNVAR) == WS_DYNVAR)?"[DYNVAR]":"", ((flag & WS_USELEN) == WS_USELEN)?"[USELEN]":"");
102 ret=__ILWS_add_handler((struct gethandler *)server->gethandler,mstr,NULL,path,flag,GH_DIRECTORY);
103 __ILWS_free(mstr);
104 return ret;
105};
106
107
108/*********************************************************************************************************/
109/*
110 * Personal config (new on 0.5.0)
111 */
112char *web_server_getconf(struct web_server *server, const char *topic,const char *key) {
113 char *dataconf;
114 char *tmp1,*tmp2,*tmp3;
115 long tmpsize=0;
116
117 dataconf=__ILWS_stristr(server->dataconf,topic);
118 if(dataconf==NULL) {
119 return NULL;
120 };
121 dataconf+=strlen(topic);
122 tmp1=__ILWS_stristr(dataconf,key);
123 do {
124 tmp1=__ILWS_stristr(dataconf,key);
125 dataconf+=1;
126 if(dataconf[0]==0) {
127 return NULL;
128 };
129 if(dataconf[0]=='[' && dataconf[-1]=='\n') {
130 return NULL;
131 };
132 }while(!(tmp1!=NULL && tmp1[-1]=='\n' && tmp1[strlen(key)]=='='));
133
134 tmp1+=strlen(key)+1;
135 tmp2=__ILWS_stristr(tmp1,"\n");
136 if(tmp2==NULL) {
137 tmp2=tmp1+strlen(tmp1);
138 };
139 tmpsize=tmp2-tmp1;
140 if(!(tmp3=__ILWS_malloc(tmpsize+1))) {
141 LWSERR(LE_MEMORY);
142 return NULL;
143 };
144 memcpy(tmp3,tmp1,tmpsize);
145 tmp3[tmpsize]=0;
146 return tmp3;
147};
148
149/*********************************************************************************************************/
150/*
151 * Define config file to setup server (new on 0.5.0)
152 */
153int web_server_setup(struct web_server *server,const char *conffile) {
154 FILE *tmpf;
155 char *tmp3;
156 //long tmpsize=0;
157 long sizec;
158 struct stat statf; // tested only on win
159
160 if(!(server->conffile=__ILWS_malloc(strlen(conffile)+1))) {
161 LWSERR(LE_MEMORY);
162 return 0;
163 };
164
165 memcpy(server->conffile,conffile,strlen(conffile));
166 server->conffile[strlen(conffile)]=0;
167
168 tmpf=fopen(server->conffile,"r");
169 if(tmpf==NULL) {
170 printf("no config file found\r\n");
171 server->dataconf="";
172 return(0);
173 };
174 fseek(tmpf,SEEK_SET,SEEK_END);
175 sizec=ftell(tmpf);
176 fseek(tmpf,0,SEEK_SET);
177 if(!(server->dataconf=__ILWS_malloc(sizec+1))) {
178 LWSERR(LE_MEMORY);
179 return 0;
180 };
181 fread(server->dataconf,sizec,1,tmpf);
182 server->dataconf[sizec]=0; // Hilobok Andrew (han@km.if.ua) said to remove the -9 :)
183 fclose(tmpf);
184
185 stat(server->conffile,&statf); // tested only on win
186 server->conffiletime=statf.st_mtime; // tested only on win
187
188 if((server->logfile=web_server_getconf(server,"LIBWEBSERVER","LOG"))) {
189 web_log("\nUsing logfile [%s]\n",server->logfile);
190 server->weblog=open_weblog(server->logfile);
191 } else {
192 web_log("\nLOG entry not found\r\n");
193 server->weblog=NULL;
194 };
195 if((tmp3=web_server_getconf(server,"LIBWEBSERVER","PORT"))) {
196 web_log("\nListen port [%s]\n",tmp3);
197 server->port=atoi(tmp3);
198 __ILWS_free(tmp3);
199 } else {
200 web_log("PORT entry not found\r\n");
201 server->port=0;
202 };
203#ifdef HAVE_OPENSSL
204 // Fetch SSL
205 if((tmp3=web_server_getconf(server,"LIBWEBSERVER","USESSL"))) {
206 if(tmp3[0]=='1') {
207 server->flags = server->flags | WS_USESSL;
208 }else if(tmp3[0]=='0') {
209 server->flags = server->flags & ~WS_USESSL;
210 } else {
211 fprintf(stderr,"[USESSL=] argument invalid\n");
212 };
213 __ILWS_free(tmp3);
214 }
215 // Fetch CERTFILE
216 server->cert_file=web_server_getconf(server,"LIBWEBSERVER","CERTFILE");
217 server->mimefile=web_server_getconf(server,"LIBWEBSERVER","MIMEFILE");
218#endif
219 // Fetch LOCAL
220 if((tmp3=web_server_getconf(server,"LIBWEBSERVER","LOCAL"))) {
221 if(tmp3[0]=='1') {
222 server->flags = server->flags | WS_LOCAL;
223 } else if(tmp3[0]=='0') {
224 server->flags=server->flags & ~WS_LOCAL;
225 }else {
226 fprintf(stderr,"[LOCAL=] argument invalid\n");
227 };
228 __ILWS_free(tmp3);
229 }
230
231 return 1;
232};
233
234/*********************************************************************************************************/
235/*
236 * This function initialize one web_server handler
237 */
238int web_server_init(struct web_server *server,int port,const char *logfile,int flags) {
239#ifdef WIN32
240 unsigned long t=IOC_INOUT;
241 WSADATA WSAinfo;
242 WSAStartup(2,&WSAinfo); // Damn w32 sockets
243#endif
244
245 current_web_server=server;
246 server->port=port;
247 server->conffile=NULL;
248 server->mimefile=NULL;
249 server->weblog=NULL;
250 server->usessl=0;
251 server->flags=flags;
252 server->dataconf="";
253 if((flags & WS_USEEXTCONF) == WS_USEEXTCONF) {
254 if(!(web_server_setup(server,logfile))) {
255#ifdef WIN32
256 WSACleanup();
257#endif
258 return 0;
259 };
260 _logfile=server->weblog; // Set current log stream
261 web_log("%s using config file %s\n",_libwebserver_version,logfile);
262 };
263 // Create a listen socket port 'port' and listen addr (0) (all interfaces)
264 server->socket=__ILWS_listensocket((short)server->port,0);
265 if(server->socket==-1) {
266 LWSERR(LE_NET);
267#ifdef WIN32
268 WSACleanup();
269#endif
270 return 0;
271 };
272#ifdef WIN32
273 ioctlsocket(server->socket,FIONBIO,&t); //non blocking sockets for win32
274#else
275 fcntl(server->socket,F_SETFL,O_NONBLOCK);
276#endif
277 // Setup FILE structure of logfile
278 if(logfile!=NULL && !((flags & WS_USEEXTCONF) == WS_USEEXTCONF)) {
279 server->logfile=__ILWS_malloc(strlen(logfile)+1);
280 memcpy(server->logfile,logfile,strlen(logfile));
281 server->logfile[strlen(logfile)]=0;
282 server->weblog=open_weblog(logfile); // Create File stream for log
283 };
284
285 web_log("\n[%s] Server started at port %d (%s)\n",__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),server->port,_libwebserver_version);
286
287 // Setup Flags
288
289 // openssl
290#ifdef HAVE_OPENSSL
291 if((server->flags & WS_USESSL) == WS_USESSL) {
292 web_log("[%s] (FLAG) Using SSL in connections\n",__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"));
293 web_log(" +-- %s certificate file\n",server->cert_file);
294 SSL_load_error_strings();
295 SSLeay_add_ssl_algorithms();
296 server->ctx=SSL_CTX_new (SSLv23_server_method());
297 if (SSL_CTX_use_certificate_file(server->ctx, server->cert_file, SSL_FILETYPE_PEM) <= 0) {
298 ERR_print_errors_fp(stderr);
299 exit(3);
300 }
301 if (SSL_CTX_use_PrivateKey_file(server->ctx, server->cert_file, SSL_FILETYPE_PEM) <= 0) {
302 ERR_print_errors_fp(stderr);
303 exit(4);
304 }
305 if (SSL_CTX_check_private_key(server->ctx)<= 0) {
306 ERR_print_errors_fp(stderr);
307 exit(4);
308 };
309 server->usessl=1;
310 };
311#endif
312 if((server->flags & WS_LOCAL) == WS_LOCAL) {
313 web_log("[%s] (FLAG) Accepting only local connections\n",__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"));
314 };
315 server->client=__ILWS_init_client_list(); // Initializate client list
316 server->gethandler=__ILWS_init_handler_list(); // Initializate handlers list
317 web_server_addhandler(server,"* /libwebserver.gif",_web_server_logo,0); // Add logo default handler
318
319#ifndef WIN32
320 signal(SIGPIPE,SIG_IGN);
321#endif
322 return 1;
323}
324
325
326/*********************************************************************************************************/
327/*
328 * This function shuts down a running web server, frees its allocated memory,
329 * and closes its socket. If called on a struct web_server that has already
330 * been shut down, this is a noop.
331 */
332void web_server_shutdown(struct web_server *server) {
333 // free and close things in opposite order of web_server_init
334
335 __ILWS_delete_handler_list(server->gethandler);
336 server->gethandler = NULL;
337 __ILWS_delete_client_list(server->client);
338 server->client = NULL;
339
340 if(server->socket > 0) {
341#ifdef WIN32
342 closesocket(server->socket);
343#else
344 close(server->socket);
345#endif
346 server->socket = -1;
347 }
348
349 if(server->weblog) {
350 fclose(server->weblog);
351 server->weblog = NULL;
352 __ILWS_free(server->logfile);
353 server->logfile = NULL;
354 }
355
356#ifdef WIN32
357 WSACleanup();
358#endif
359}
360
361/*********************************************************************************************************/
362/*
363 * Core function, return 2 if no client to process, 1 if some client processed, 0 if error
364 */
365int web_server_run(struct web_server *server) {
366 struct web_client *client;
367 int rt;
368 int tsalen=0;
369 int tsocket=0;
370 struct sockaddr_in tsa;
371 _logfile=server->weblog;
372 current_web_server=server;
373 if(server->client->next==NULL) {
374 //if(__ILWS_newdata(server->socket)); // does nothing but act like usleep
375 };
376// search for client
377 tsalen=sizeof(client->sa);
378 tsocket=accept(server->socket,(struct sockaddr *)&tsa,&tsalen);
379 if(tsocket==-1) {
380#ifdef WIN32
381 if(WSAGetLastError()!=WSAEWOULDBLOCK) {
382#else
383 if(errno!=EAGAIN) {
384#endif
385 fprintf(stderr,"What kind of error is this?\n"); // REMOVE
386 // client fucked up? warn somebody? (error or log or something?)
387 return 0; // don't process nothing
388 };
389 } else {
390 client=__ILWS_malloc(sizeof(struct web_client));
391 if(client==NULL) {
392 rt=shutdown(tsocket,SHUT_RDWR);
393#ifdef WIN32
394 rt=closesocket(tsocket);
395#else
396 rt=close(tsocket);
397#endif
398 LWSERR(LE_MEMORY);
399 return 0;
400 };
401 client->salen=tsalen;
402 client->socket=tsocket;
403 client->sa=tsa;
404#ifdef HAVE_OPENSSL
405 if((server->flags & WS_USESSL) == WS_USESSL) {
406 client->ssl = SSL_new(server->ctx);
407 SSL_set_fd(client->ssl,client->socket);
408 SSL_accept(client->ssl);
409 //client->cert = SSL_get_peer_certificate (client->ssl);
410 } else {
411 client->ssl=NULL;
412 };
413#endif
414 if(!__ILWS_add_client(server->client,client)) {
415 fprintf(stderr,"No client?\n"); // REMOVE
416 return 0;
417 }else {
418 web_log("%s - - [%s] Connected\n",inet_ntoa(client->sa.sin_addr),__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z")); //REMOBE
419 };
420 };
421 // end search for client
422 client=server->client; // init list
423 if(!client->next) { // think of Rocco Carbone (rocco@tecsiel.it)
424 return 2; // i don't need to process the list (nothing next) returns 2 if there is no client to process
425 };
426 while(client->next!=NULL) { // Process the client and swap to next;
427 current_web_client=client->next;
428 switch(client->next->stat) {
429 case 1: {
430 __ILWS_read_client(current_web_client);
431 };break;
432 case 2: {
433 __ILWS_process_client(current_web_client,server->gethandler);
434 };break;
435 case 4: {
436 __ILWS_output_client(current_web_client);
437 };break;
438 case 5: {
439 __ILWS_delete_next_client(client);
440 continue;
441 };break;
442 };
443 client=client->next;
444
445 };
446 return 1; // return 1 if something processed
447}
448
diff --git a/src/server.h b/src/server.h
new file mode 100644
index 00000000..be1abf8d
--- /dev/null
+++ b/src/server.h
@@ -0,0 +1,86 @@
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 *
12 * --
13 *
14 */
15
16#ifndef _SERVER_H_
17#define _SERVER_H_
18
19#ifdef HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#include <stdio.h>
24#include <signal.h>
25#include <time.h>
26
27
28#include "memory.h"
29#include "client.h"
30#include "gethandler.h"
31#include "socket.h"
32#include "error.h"
33
34#include "debug.h"
35
36#ifdef WIN32
37
38#define SHUT_RDWR SD_BOTH
39#endif
40
41
42
43
44extern char *_libwebserver_version;
45extern struct web_server *current_web_server;
46struct web_server {
47 int socket;
48 unsigned int port;
49 char *logfile;
50 char *conffile;
51 time_t conffiletime; // tested only on win
52 char *mimefile;
53 char *dataconf;
54 FILE *weblog;
55 int flags;
56 struct gethandler *gethandler;
57 struct web_client *client;
58 int usessl;
59#ifdef HAVE_OPENSSL
60 char *cert_file;
61 SSL_CTX *ctx;
62#else
63 void *pad[2];
64#endif
65
66};
67#define WS_LOCAL 1 // Can be only accessed by localhost
68#define WS_USESSL 2 // Use ssl conections (openssl lib required)
69#define WS_USEEXTCONF 4 // Use external config file (new 0.5.0)
70
71
72void web_server_useSSLcert(struct web_server *,const char *); // Mandatory if WS_USESSL set
73void web_server_useMIMEfile(struct web_server*,const char *); // new on 0.5.2
74int web_server_init(struct web_server *,int,const char *,int);
75void web_server_shutdown(struct web_server *);
76int web_server_addhandler(struct web_server *,const char *,void (*)(),int);
77int web_server_aliasdir(struct web_server *, const char *, char *,int );
78int web_server_run(struct web_server *);
79int web_server_setup(struct web_server *server,const char *conffile); // (new on 0.5.0)
80char *web_server_getconf(struct web_server *, const char *,const char *); // (new on 0.5.0)
81
82
83#include "weblog.h"
84
85#endif
86
diff --git a/src/socket.c b/src/socket.c
new file mode 100644
index 00000000..16e90f2f
--- /dev/null
+++ b/src/socket.c
@@ -0,0 +1,74 @@
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 * -- Basic socket operations
12 *
13 */
14
15
16#include "socket.h"
17
18
19/*********************************************************************************************************/
20/*
21 * socket operations
22 */
23int __ILWS_newdata(int sock) {
24 int ret;
25 struct timeval tv;
26 fd_set rfds;
27 FD_ZERO(&rfds);
28 FD_SET((unsigned)sock,&rfds);
29 tv.tv_usec=2;
30 tv.tv_sec=0;
31 ret=select(sock+1,&rfds,NULL,NULL,&tv);
32 FD_CLR((unsigned)sock,&rfds);
33 return ret;
34}
35
36/*********************************************************************************************************/
37/*
38 * to add a listen socket
39 */
40int __ILWS_listensocket(short port, int saddr) {
41 struct sockaddr_in sa;
42 int ret;
43 int sockopt=1; /* Rocco Was Here */
44 sa.sin_addr.s_addr=saddr;
45 sa.sin_port=htons((short)port);
46 sa.sin_family=AF_INET;
47 ret=socket(AF_INET,SOCK_STREAM,6); // tcp
48 if(ret==-1) {
49 return -1;
50 };
51 /* Rocco Was Here */
52 setsockopt(ret,SOL_SOCKET,SO_REUSEADDR,(char *)&sockopt,sizeof(sockopt)); // why? Rocco
53
54 if(bind(ret,(struct sockaddr *)&sa,sizeof(sa))==-1) {
55 close(ret); /* Rocco Was Here */
56 return -1;
57 };
58
59 if(listen(ret,512)==-1) { // 512 backlog
60 close(ret); /* Rocco Was Here */
61 return -1;
62 };
63 IFDEBUG(fprintf(stderr,"socket.c: Listen on port %d\n",port));
64 return ret;
65}
66
67/*********************************************************************************************************/
68/*
69 * as the read function
70 */
71int __ILWS_read(int sock,void *buf,size_t s) {
72 return recv(sock,buf,s,0);
73}
74
diff --git a/src/socket.h b/src/socket.h
new file mode 100644
index 00000000..81030fc7
--- /dev/null
+++ b/src/socket.h
@@ -0,0 +1,51 @@
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 *
12 * --
13 *
14 */
15
16#ifndef _SOCKET_H_
17#define _SOCKET_H_
18
19#ifdef HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#include <stdio.h>
24#include <stdarg.h>
25
26#ifdef WIN32
27#include <winsock2.h>
28#include <io.h>
29#else
30#include <sys/socket.h>
31#include <netinet/in.h>
32#include <arpa/inet.h>
33#include <unistd.h>
34#include <sys/time.h> // struct tv
35#include <sys/types.h> // freebsd need it i gues that is no problem if other system includes it
36#endif
37
38
39
40
41
42#include "debug.h"
43
44extern int errno;
45
46int __ILWS_newdata(int);
47int __ILWS_listensocket(short, int);
48int __ILWS_read(int,void *,size_t);
49
50#endif
51
diff --git a/src/utils.c b/src/utils.c
new file mode 100644
index 00000000..1ca797f7
--- /dev/null
+++ b/src/utils.c
@@ -0,0 +1,155 @@
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: 19:49,07-49-2002
10 *
11 * -- description: utilitys
12 *
13 */
14
15#include "utils.h"
16
17/*********************************************************************************************************/
18/*
19 * search a string in a string ignoring case
20 */
21char *__ILWS_stristr(char *str, const char *nedle) {
22 char *tmp1=str;
23 int ret=1;
24 int snedle=strlen(nedle),sstr=strlen(str);
25 if(strlen(str)<strlen(nedle))return NULL;
26 while((ret=strncasecmp(tmp1,nedle,snedle) && (unsigned int)(tmp1+snedle)<=(unsigned int) (str+sstr))) {
27 tmp1++;
28 };
29 if(strncasecmp(tmp1,nedle,snedle))
30 return NULL;
31 return tmp1;
32};
33
34/*********************************************************************************************************/
35/*
36 * gives a new temporary path(file) name that doesn't exists
37 */
38char *_tmpnameprefix="";
39
40char *__ILWS_tmpfname() {
41 char *ret=NULL;
42 char *tmpdir=NULL;
43 char nam[TMPNAMESIZE+1];
44 int i;
45 struct stat foostat;
46 if(tmpdir==NULL) {
47 tmpdir=getenv("TEMP");
48 };
49 if(tmpdir==NULL) {
50 tmpdir=getenv("TMP");
51 };
52 if(tmpdir==NULL) {
53 tmpdir=getenv("TMPDIR");
54 };
55 if(tmpdir==NULL) {
56 tmpdir=P_tmpdir; // defined in stdio.h
57 };
58 IFDEBUG(fprintf(stderr,"utils.c: Allocating temporary file name: "));
59 if(!(ret=__ILWS_malloc(strlen(tmpdir)+strlen(_tmpnameprefix)+TMPNAMESIZE+2))) {
60 LWSERR(LE_MEMORY);
61 return NULL;
62 };
63 srand(time(NULL)); // seed
64 do {
65 for(i=0;i<TMPNAMESIZE;i++) {
66
67 nam[i]=(rand()%2)?(rand()%26)+'A':(rand()%26)+'a';
68 }
69 nam[i]=0;
70 snprintf(ret,strlen(tmpdir)+strlen(_tmpnameprefix)+TMPNAMESIZE+2,"%s/%s%s",tmpdir,_tmpnameprefix,nam); // include '0'
71 IFDEBUG(fprintf(stderr,"Temporary filename is: %s, stat:%d\n",ret,stat(ret,&foostat)));
72 }while((stat(ret,&foostat)!=-1) && (lstat(ret,&foostat)!=-1)); // redundancy if win32 // <- race condition?
73 return ret;
74};
75
76
77
78/*********************************************************************************************************/
79/*
80 * an date function
81 */
82#define DATE_MAX 100
83char __ILWS_datem[DATE_MAX];
84
85char *__ILWS_date(time_t t,const char *format) {
86 struct tm *tm;
87 tm=localtime(&t);
88 strftime(__ILWS_datem,DATE_MAX,format,tm);
89 return __ILWS_datem;
90}
91
92/*********************************************************************************************************/
93/*
94 * wasn't me, base64decode
95 */
96static const unsigned char __ILWS_chtb[256] = {
97 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
98 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
99 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
100 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
101 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
102 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
103 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
104 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
105 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
106 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
107 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
108 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
109 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
110 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
111 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
112 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64};
113
114
115int __ILWS_base64decode(char *bufplain, const char *bufcoded){
116 int nb;
117 const unsigned char *in;
118 unsigned char *out;
119 int nprbytes;
120
121 in = (const unsigned char *) bufcoded;
122 while (__ILWS_chtb[*(in++)] <= 63);
123 nprbytes = (in - (const unsigned char *) bufcoded) - 1;
124 nb = ((nprbytes + 3) / 4) * 3;
125
126 out = (unsigned char *) bufplain;
127 in = (const unsigned char *) bufcoded;
128
129 while (nprbytes > 4) {
130 *(out++) =
131 (unsigned char) (__ILWS_chtb[*in] << 2 | __ILWS_chtb[in[1]] >> 4);
132 *(out++) =
133 (unsigned char) (__ILWS_chtb[in[1]] << 4 | __ILWS_chtb[in[2]] >> 2);
134 *(out++) =
135 (unsigned char) (__ILWS_chtb[in[2]] << 6 | __ILWS_chtb[in[3]]);
136 in += 4;
137 nprbytes -= 4;
138 }
139 if (nprbytes > 1) {
140 *(out++) =
141 (unsigned char) (__ILWS_chtb[*in] << 2 | __ILWS_chtb[in[1]] >> 4);
142 }
143 if (nprbytes > 2) {
144 *(out++) =
145 (unsigned char) (__ILWS_chtb[in[1]] << 4 | __ILWS_chtb[in[2]] >> 2);
146 }
147 if (nprbytes > 3) {
148 *(out++) =
149 (unsigned char) (__ILWS_chtb[in[2]] << 6 | __ILWS_chtb[in[3]]);
150 }
151
152 nb -= (4 - nprbytes) & 3;
153 return nb;
154}
155
diff --git a/src/utils.h b/src/utils.h
new file mode 100644
index 00000000..7f8a8348
--- /dev/null
+++ b/src/utils.h
@@ -0,0 +1,59 @@
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 * file: utils.h
10 *
11 * description: Header
12 *
13 * date: 19:50,07-50-2002
14 */
15
16#ifndef _UTILS_H_
17#define _UTILS_H_
18
19#ifdef HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <sys/stat.h>
27#include <ctype.h>
28
29#ifdef TM_IN_SYS_TIME
30#include <sys/time.h>
31#else
32#include <time.h>
33#endif
34
35#include "debug.h"
36#include "error.h"
37#include "memory.h"
38
39#ifdef WIN32
40
41#define strncasecmp strnicmp
42#define snprintf _snprintf
43#define lstat stat
44#define vsnprintf _vsnprintf
45
46#endif
47
48
49#define TMPNAMESIZE 8
50extern char *_tmpnameprefix;
51
52
53char *__ILWS_stristr(char *, const char *);
54char *__ILWS_tmpfname();
55int __ILWS_base64decode(char *, const char *);
56char *__ILWS_date(time_t,const char *);
57
58
59#endif
diff --git a/src/web_server.h b/src/web_server.h
new file mode 100644
index 00000000..d34036b5
--- /dev/null
+++ b/src/web_server.h
@@ -0,0 +1,129 @@
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 * Fri Dec 28 12:51:11 GMT 2001
10 * Luis Figueiredo -- I Corrected the input to handle only data when \n\r(twice) is arrived
11 *
12 * Mon Feb 25 06:27:58 GMT 2002
13 * Luis Figueiredo -- Many corrections and new functions were added, until today
14 *
15 * Mon Mar 25 14:46:13 GMT 2002
16 * Luis Figueiredo -- wow, one month later..., discard web_server_addstr, and now process the stdout to server
17 * using a tmpfile for streaming (not so good, but :o))
18 * Wed Mar 27 18:59:10 GMT 2002
19 * Luis Figueiredo -- using regex instead of fnmatch(fnmatch only appears becouse of apache, i didn't knew it)
20 * Mon Apr 8 15:04:31 GMT 2002
21 * Luis Figueiredo -- Oh my.. kurt cobain is dead :o), restructured the code, separated into various files
22 * Wed Apr 10 20:02:55 GMT 2002
23 * Luis Figueiredo -- Make use of autoconf , removed open_memstream (doesn't work well w/ stdout structure on netbsd portability)
24 * linux slack 7.1 uses "extern FILE *stdout", netbsd uses "extern FILE __sF[]" so i cannot make use of pointers
25 * Mon Oct 7 16:56:15 GMT 2002
26 * Luis Figueiredo -- Repaired some safe bugs, Added vars to stats proposes, inserted an liblogo, added debug instructions
27 *
28 * VERSION 0.5.3
29 */
30
31#ifndef _WEB_SERVER_H_
32#define _WEB_SERVER_H_
33
34#include <stdio.h> // for struct FILE
35#include <time.h> // for time_t
36
37#ifdef __cplusplus
38extern "C"{
39#endif
40
41extern char *_libwebserver_version;
42extern char *_tmpnameprefix;
43extern int WEBTIMEOUT;
44
45struct _MultiPart {
46 char *id;
47 char *data;
48 unsigned int size;
49 char *filename;
50 void *pad;
51};
52char *__Header(char *);
53char *__Query(char *);
54char *__Post(char *);
55struct _MultiPart __MultiPart(char *);
56char *__Cookie(char *);
57
58extern struct ClientInfo {
59 int outfd;
60 char *inetname;
61 char *request;
62 char *method;
63 char *user;
64 char *pass;
65 char *(*Header)(char *);
66 char *(*Query)(char *);
67 char *(*Post)(char *);
68 char *(*Cookie)(char *);
69 char *(*Conf)(char *,char *); // new on 0.5.0
70 struct _MultiPart (*MultiPart)(char *);
71 void *__pad[9];
72
73} *ClientInfo; // PROTOTYPE
74
75struct web_server {
76 int socket;
77 unsigned int port;
78 char *logfile;
79 char *conffile;
80 time_t conffiletime; // tested only on win
81 char *mimefile;
82 char *dataconf;
83 FILE *weblog;
84 int flags;
85 struct gethandler *gethandler;
86 struct web_client *client;
87 int usessl;
88 void *pad[2]; // SSL pad
89};
90
91#define WS_LOCAL 1 // Can be only accessed by localhost (usefull for local programs gui's)
92#define WS_USESSL 2 // Use ssl conections (openssl lib required) (security transation) (there is no sense using WS_LOCAL & WS_USESSL together)
93#define WS_USEEXTCONF 4 // Use external config file (new 0.5.0)
94#define WS_DYNVAR 8 // Use dynamic variables on output (new 0.5.1)
95#define WS_USELEN 16 //Use Content-length calculator(new 0.5.1)
96
97
98void web_server_useSSLcert(struct web_server *,const char *); // useless if not using openssl
99void web_server_useMIMEfile(struct web_server *,const char *); // new on 0.5.2
100int web_server_init(struct web_server *,int,const char *,int);
101void web_server_shutdown(struct web_server *);
102char *web_server_getconf(struct web_server *,char *,char *);
103int web_server_addhandler(struct web_server *,const char *,void (*)(),int);
104int web_server_aliasdir(struct web_server *, const char *,char *,int); // new on 0.5.2
105int web_server_run(struct web_server *);
106
107
108int web_client_addfile(char *);
109extern unsigned char GLOBALGIFPAL[256][3];
110void web_client_gifsetpalette(const char *);
111int web_client_gifoutput(char *,int,int,int);
112
113void web_client_setcookie(char *,char *,char *,char *, char *,int); // improved on 0.5.1
114void web_client_deletecookie(char *); // improved on 0.5.1
115int web_client_setvar(char *,char *); //(new (0.5.1)
116char *web_client_getvar(char *); //(new (0.5.1)
117int web_client_delvar(char *); //(new (0.5.1)
118
119void web_client_HTTPdirective(char *);
120void web_client_contenttype(char *); // 0.5.2
121void web_log(const char *,...);
122
123
124#ifdef __cplusplus
125}
126#endif
127
128#endif
129
diff --git a/src/weblog.c b/src/weblog.c
new file mode 100644
index 00000000..2d892179
--- /dev/null
+++ b/src/weblog.c
@@ -0,0 +1,43 @@
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 * -- web_log operations
12 *
13 */
14
15
16
17#include "weblog.h"
18
19FILE *_logfile=NULL;
20/*********************************************************************************************************/
21/*
22 * Open weblog file
23 */
24FILE *open_weblog(const char *logfile) {
25 FILE *ret;
26 ret=fopen(logfile,"a+");
27 _logfile=ret;
28 return ret;
29}
30
31/*********************************************************************************************************/
32/*
33 * Log to _logfile;
34 */
35void web_log(const char *fmt,...) {
36 va_list args;
37 if(_logfile) {
38 va_start(args,fmt);
39 vfprintf(_logfile,fmt,args);
40 va_end(args);
41 fflush(_logfile);
42 }
43}
diff --git a/src/weblog.h b/src/weblog.h
new file mode 100644
index 00000000..503c14f0
--- /dev/null
+++ b/src/weblog.h
@@ -0,0 +1,40 @@
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:25:25 GMT 2002
10 *
11 * memory functions
12 */
13
14#ifndef _WEBLOG_H_
15#define _WEBLOG_H_
16
17
18
19#ifdef HAVE_CONFIG_H
20#include "config.h"
21#endif
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <stdarg.h>
26
27#ifdef WIN32
28#define snprintf _snprintf
29#endif
30
31
32
33#include "debug.h"
34
35extern FILE *_logfile;
36
37void web_log(const char *,...);
38FILE *open_weblog(const char *);
39char *mydate();
40#endif