diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 26 | ||||
-rw-r--r-- | src/client.c | 1190 | ||||
-rw-r--r-- | src/client.h | 159 | ||||
-rw-r--r-- | src/clientinfo.c | 1124 | ||||
-rw-r--r-- | src/clientinfo.h | 118 | ||||
-rw-r--r-- | src/config.h | 133 | ||||
-rw-r--r-- | src/debug.h | 29 | ||||
-rw-r--r-- | src/error.c | 34 | ||||
-rw-r--r-- | src/error.h | 33 | ||||
-rw-r--r-- | src/fnmatch.c | 195 | ||||
-rw-r--r-- | src/fnmatch.h | 59 | ||||
-rw-r--r-- | src/gethandler.c | 96 | ||||
-rw-r--r-- | src/gethandler.h | 60 | ||||
-rw-r--r-- | src/logo.h | 396 | ||||
-rw-r--r-- | src/memory.c | 155 | ||||
-rw-r--r-- | src/memory.h | 46 | ||||
-rw-r--r-- | src/module.c | 22 | ||||
-rw-r--r-- | src/module.h | 25 | ||||
-rw-r--r-- | src/outgif.c | 587 | ||||
-rw-r--r-- | src/outgif.h | 63 | ||||
-rw-r--r-- | src/outstream.c | 122 | ||||
-rw-r--r-- | src/outstream.h | 53 | ||||
-rw-r--r-- | src/server.c | 448 | ||||
-rw-r--r-- | src/server.h | 86 | ||||
-rw-r--r-- | src/socket.c | 74 | ||||
-rw-r--r-- | src/socket.h | 51 | ||||
-rw-r--r-- | src/utils.c | 155 | ||||
-rw-r--r-- | src/utils.h | 59 | ||||
-rw-r--r-- | src/web_server.h | 129 | ||||
-rw-r--r-- | src/weblog.c | 43 | ||||
-rw-r--r-- | src/weblog.h | 40 |
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 @@ | |||
1 | SUBDIRS = . | ||
2 | |||
3 | INCLUDES = -I$(top_srcdir)/src/include | ||
4 | |||
5 | lib_LTLIBRARIES = libwebserver_gnunet.la | ||
6 | |||
7 | AM_CFLAGS = \ | ||
8 | -D_SERVER_VERSION="\"0.6.3-GNUnet\"" | ||
9 | |||
10 | libwebserver_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 | |||
24 | libwebserver_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 | |||
19 | extern char *_libwebserver_version; // Defined in server.c | ||
20 | |||
21 | |||
22 | struct web_client *current_web_client; | ||
23 | int WEBTIMEOUT=10000; | ||
24 | |||
25 | /*********************************************************************************************************/ | ||
26 | /* | ||
27 | * initializate (allocate) client list | ||
28 | */ | ||
29 | struct 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 | */ | ||
48 | int __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 | */ | ||
99 | void __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 | */ | ||
123 | void __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 | */ | ||
133 | void __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 | */ | ||
147 | void __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 | */ | ||
232 | void __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 | */ | ||
466 | void __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 | */ | ||
633 | void web_client_HTTPdirective(char *str) { | ||
634 | current_web_client->HTTPdirective=str; | ||
635 | } | ||
636 | |||
637 | |||
638 | /*********************************************************************************************************/ | ||
639 | /* | ||
640 | * GET request name | ||
641 | */ | ||
642 | char *__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 | */ | ||
671 | char *__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 | */ | ||
693 | int 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 | */ | ||
721 | unsigned char __ILWS_GLOBALGIFPAL[256][3]; | ||
722 | |||
723 | |||
724 | void 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 | |||
747 | int 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 | */ | ||
766 | void __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 | */ | ||
809 | void 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 | |||
883 | void web_client_deletecookie(char *name){ | ||
884 | web_client_setcookie(name, NULL, "DEL", NULL, NULL, 0); | ||
885 | } | ||
886 | |||
887 | |||
888 | |||
889 | |||
890 | |||
891 | |||
892 | |||
893 | |||
894 | int web_client_setvar(char *name,char *value) { | ||
895 | return __ILWS_add_var(current_web_client->varlist,name,value); | ||
896 | }; | ||
897 | char *web_client_getvar(char *name) { | ||
898 | return __ILWS_get_var(current_web_client->varlist,name); | ||
899 | |||
900 | }; | ||
901 | int 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 | ||
913 | struct 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 | |||
925 | int __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 | |||
958 | int __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 | }; | ||
973 | void __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 | |||
989 | char *__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 | |||
1005 | void 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 | |||
1069 | int __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 <DIR> <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 | |||
75 | extern int WEBTIMEOUT; //to be changed externaly | ||
76 | //#define WEBTIMEOUT 10000 // TIMEOUT WITHOUT RECEIVING DATA (not in seconds but in read tries) | ||
77 | |||
78 | |||
79 | struct web_var { | ||
80 | char *name; | ||
81 | char *value; | ||
82 | struct web_var *next; | ||
83 | }; | ||
84 | |||
85 | struct 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 | }; | ||
118 | extern struct web_client *current_web_client; | ||
119 | |||
120 | struct web_client *__ILWS_init_client_list(); | ||
121 | int __ILWS_add_client(struct web_client *,struct web_client *); | ||
122 | void __ILWS_delete_next_client(struct web_client *); | ||
123 | void __ILWS_delete_client_list(struct web_client *); | ||
124 | |||
125 | void __ILWS_read_client(struct web_client *); | ||
126 | void __ILWS_process_client(struct web_client *,struct gethandler *); | ||
127 | void __ILWS_output_client(struct web_client *); | ||
128 | |||
129 | void __ILWS_web_client_writef(struct web_client *,const char *,...); | ||
130 | |||
131 | int web_client_addfile(char *); | ||
132 | void web_client_contenttype(char *); // new on 0.5.2 | ||
133 | |||
134 | void web_client_gifsetpalette(const char *); | ||
135 | |||
136 | extern unsigned char __ILWS_GLOBALGIFPAL[256][3]; | ||
137 | |||
138 | int web_client_gifoutput(char *,int,int,int); | ||
139 | |||
140 | void web_client_HTTPdirective(char *); | ||
141 | |||
142 | char *__ILWS_web_client_getreqline(); | ||
143 | char *__ILWS_web_client_getreq(); | ||
144 | // new (0.5.1) | ||
145 | int web_client_setvar(char *,char *); | ||
146 | char *web_client_getvar(char *); | ||
147 | int web_client_delvar(char *); | ||
148 | |||
149 | // put in var.h | ||
150 | struct web_var *__ILWS_init_var_list(); | ||
151 | int __ILWS_add_var(struct web_var *, char *, char *); | ||
152 | int __ILWS_del_var(struct web_var *, char *); | ||
153 | void __ILWS_delete_var_list(struct web_var *); | ||
154 | char *__ILWS_get_var(struct web_var *list , char *name); | ||
155 | |||
156 | int __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 | |||
18 | struct ClientInfo *ClientInfo; // tochange | ||
19 | |||
20 | /*********************************************************************************************************/ | ||
21 | /* | ||
22 | * Initialize ClientInfo structure | ||
23 | */ | ||
24 | void __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 | */ | ||
81 | void __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 | */ | ||
96 | char *__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 | */ | ||
178 | char *__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 | */ | ||
387 | char *__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 | */ | ||
575 | struct _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 | */ | ||
725 | char *__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 | */ | ||
820 | char *__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 | */ | ||
846 | char *__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 | */ | ||
871 | char *__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 | */ | ||
928 | char *__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 | */ | ||
985 | char *__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 | */ | ||
1009 | char *__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 | */ | ||
1065 | char *__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 | */ | ||
39 | struct _Header { | ||
40 | char *id; | ||
41 | char *data; | ||
42 | struct _Header *next; | ||
43 | }; | ||
44 | struct _Query { | ||
45 | unsigned int index; | ||
46 | unsigned int idf; | ||
47 | char *id; | ||
48 | char *data; | ||
49 | struct _Query *next; | ||
50 | }; | ||
51 | struct _Post { | ||
52 | unsigned int index; | ||
53 | unsigned int idf; | ||
54 | char *id; | ||
55 | char *data; | ||
56 | struct _Post *next; | ||
57 | }; | ||
58 | |||
59 | struct _MultiPart { | ||
60 | char *id; | ||
61 | char *data; | ||
62 | unsigned int size; | ||
63 | char *filename; | ||
64 | struct _MultiPart *next; | ||
65 | }; | ||
66 | |||
67 | struct _Cookie { | ||
68 | char *id; | ||
69 | char *data; | ||
70 | struct _Cookie *next; | ||
71 | }; | ||
72 | |||
73 | |||
74 | extern 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 | |||
101 | void __ILWS_init_clientinfo(); | ||
102 | void __ILWS_free_clientinfo(); | ||
103 | char *__ILWS_clientinfo_getauthuser(); | ||
104 | char *__ILWS_clientinfo_getauthpass(); | ||
105 | char *__ILWS_clientinfo_getquerystring(); | ||
106 | char *__ILWS_clientinfo_getpostdata(); | ||
107 | char *__ILWS_clientinfo_getcookiestring(); | ||
108 | char *__ILWS_clientinfo_getmethod(); | ||
109 | char *__ILWS_clientinfo_getreqname(); | ||
110 | char *__ILWS_Header(char *); | ||
111 | char *__ILWS_Query(char *); | ||
112 | char *__ILWS_Post(char *); | ||
113 | struct _MultiPart __ILWS_MultiPart(char *); | ||
114 | char *__ILWS_Cookie(char *); | ||
115 | char *__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 | |||
19 | const char *libws_error_table[]={ | ||
20 | "Memory error", | ||
21 | "Filesystem error", | ||
22 | "Network error" | ||
23 | }; | ||
24 | |||
25 | |||
26 | void 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 | |||
30 | void 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) | ||
43 | static 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 | |||
56 | static const char *rangematch(const char *, int, int); | ||
57 | |||
58 | int 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 | |||
156 | static 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 | ||
42 | extern "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 | |||
53 | int 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 | */ | ||
24 | struct 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 | */ | ||
43 | int __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 | */ | ||
88 | void __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 | |||
45 | struct 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 | |||
56 | struct gethandler *__ILWS_init_handler_list(); | ||
57 | int __ILWS_add_handler(struct gethandler *,const char *,void (*func)(),char *, int,int); | ||
58 | void __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 | |||
7 | char _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 | |||
15 | IFDEBUG(int _t=0;) | ||
16 | |||
17 | /*********************************************************************************************************/ | ||
18 | /* | ||
19 | * same as malloc with error reporting and libwebserver debug | ||
20 | */ | ||
21 | void * __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 | */ | ||
39 | void * __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 | */ | ||
55 | void * __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 | */ | ||
77 | void __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 | */ | ||
90 | void *__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 | */ | ||
112 | struct 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 | */ | ||
126 | void __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 | */ | ||
135 | void __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 | */ | ||
146 | void __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 | |||
29 | extern int errno; | ||
30 | |||
31 | void *__ILWS_malloc(size_t); | ||
32 | void *__ILWS_calloc(size_t,size_t); | ||
33 | void *__ILWS_realloc(void *,size_t); | ||
34 | void __ILWS_free(void *); | ||
35 | |||
36 | struct memrequest { | ||
37 | char *ptr; | ||
38 | struct memrequest *next; | ||
39 | }; | ||
40 | struct memrequest *__ILWS_init_buffer_list(); | ||
41 | void *__ILWS_add_buffer(struct memrequest *,unsigned int); | ||
42 | void __ILWS_delete_buffer(struct memrequest *); | ||
43 | void __ILWS_delete_next_buffer(struct memrequest *); | ||
44 | void __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 | |||
16 | struct 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 | |||
47 | static int __ILWS_Width, __ILWS_Height; | ||
48 | static int __ILWS_curx, __ILWS_cury; | ||
49 | static long __ILWS_CountDown; | ||
50 | static int __ILWS_Interlace; | ||
51 | //static unsigned char bw[2] = {0, 0xff}; | ||
52 | |||
53 | static void __ILWS_putword PARM((int, FILE *)); | ||
54 | static void __ILWS_compress PARM((int, FILE *, unsigned char *, int)); | ||
55 | static void __ILWS_output PARM((int)); | ||
56 | static void __ILWS_cl_block PARM((void)); | ||
57 | static void __ILWS_cl_hash PARM((count_int)); | ||
58 | static void __ILWS_char_init PARM((void)); | ||
59 | static void __ILWS_char_out PARM((int)); | ||
60 | static void __ILWS_flush_char PARM((void)); | ||
61 | |||
62 | |||
63 | static unsigned char pc2nc[256],r1[256],g1[256],b1[256]; | ||
64 | |||
65 | |||
66 | /*************************************************************/ | ||
67 | int __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 | /******************************/ | ||
216 | static 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 | |||
229 | static unsigned long __ILWS_cur_accum = 0; | ||
230 | static 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 | |||
242 | typedef unsigned char char_type; | ||
243 | |||
244 | |||
245 | static int __ILWS_n_bits; /* number of bits/code */ | ||
246 | static int __ILWS_maxbits = XV_BITS; /* user settable max # bits/code */ | ||
247 | static int __ILWS_maxcode; /* maximum code, given n_bits */ | ||
248 | static int __ILWS_maxmaxcode = 1 << XV_BITS; /* NEVER generate this */ | ||
249 | |||
250 | #define MAXCODE(n_bits) ( (1 << (n_bits)) - 1) | ||
251 | |||
252 | static count_int __ILWS_htab [HSIZE]; | ||
253 | static unsigned short __ILWS_codetab [HSIZE]; | ||
254 | #define HashTabOf(i) __ILWS_htab[i] | ||
255 | #define CodeTabOf(i) __ILWS_codetab[i] | ||
256 | |||
257 | static 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 | |||
272 | static 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 | */ | ||
278 | static int __ILWS_clear_flg = 0; | ||
279 | |||
280 | static long int __ILWS_in_count = 1; /* length of input */ | ||
281 | static 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 | |||
299 | static int __ILWS_g_init_bits; | ||
300 | static FILE *__ILWS_g_outfile; | ||
301 | |||
302 | static int __ILWS_ClearCode; | ||
303 | static int __ILWS_EOFCode; | ||
304 | |||
305 | |||
306 | /********************************************************/ | ||
307 | static 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 | |||
384 | probe: | ||
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 | |||
396 | nomatch: | ||
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 | |||
433 | static | ||
434 | unsigned long __ILWS_masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, | ||
435 | 0x001F, 0x003F, 0x007F, 0x00FF, | ||
436 | 0x01FF, 0x03FF, 0x07FF, 0x0FFF, | ||
437 | 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF }; | ||
438 | |||
439 | static 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 | /********************************/ | ||
497 | static 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 | /********************************/ | ||
510 | static 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 | */ | ||
551 | static int __ILWS_a_count; | ||
552 | |||
553 | /* | ||
554 | * Set up the 'unsigned char output' routine | ||
555 | */ | ||
556 | static void __ILWS_char_init() | ||
557 | { | ||
558 | __ILWS_a_count = 0; | ||
559 | } | ||
560 | |||
561 | /* | ||
562 | * Define the storage for the packet accumulator | ||
563 | */ | ||
564 | static 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 | */ | ||
570 | static 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 | */ | ||
580 | static 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 | |||
58 | typedef long int count_int; | ||
59 | |||
60 | |||
61 | int __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 | */ | ||
21 | int __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 | */ | ||
64 | struct 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 | */ | ||
84 | void __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 | */ | ||
102 | void __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 | */ | ||
112 | void __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 | |||
37 | struct 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 | |||
48 | int __ILWS_add_outstream(struct outstream *, char *,FILE *,int); | ||
49 | struct outstream *__ILWS_init_outstream_list(); | ||
50 | void __ILWS_delete_next_outstream(struct outstream *); | ||
51 | void __ILWS_delete_outstream_list(struct outstream *); | ||
52 | void __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 | |||
32 | struct web_server *current_web_server; | ||
33 | |||
34 | |||
35 | /*********************************************************************************************************/ | ||
36 | /* | ||
37 | * Define certificate file (open_ssl) | ||
38 | */ | ||
39 | void 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 | |||
52 | void 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 | */ | ||
64 | void _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 | */ | ||
74 | int 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 | */ | ||
88 | int 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 | */ | ||
112 | char *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 | */ | ||
153 | int 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 | */ | ||
238 | int 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 | */ | ||
332 | void 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 | */ | ||
365 | int 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 | |||
44 | extern char *_libwebserver_version; | ||
45 | extern struct web_server *current_web_server; | ||
46 | struct 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 | |||
72 | void web_server_useSSLcert(struct web_server *,const char *); // Mandatory if WS_USESSL set | ||
73 | void web_server_useMIMEfile(struct web_server*,const char *); // new on 0.5.2 | ||
74 | int web_server_init(struct web_server *,int,const char *,int); | ||
75 | void web_server_shutdown(struct web_server *); | ||
76 | int web_server_addhandler(struct web_server *,const char *,void (*)(),int); | ||
77 | int web_server_aliasdir(struct web_server *, const char *, char *,int ); | ||
78 | int web_server_run(struct web_server *); | ||
79 | int web_server_setup(struct web_server *server,const char *conffile); // (new on 0.5.0) | ||
80 | char *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 | */ | ||
23 | int __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 | */ | ||
40 | int __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 | */ | ||
71 | int __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 | |||
44 | extern int errno; | ||
45 | |||
46 | int __ILWS_newdata(int); | ||
47 | int __ILWS_listensocket(short, int); | ||
48 | int __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 | */ | ||
21 | char *__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 | */ | ||
38 | char *_tmpnameprefix=""; | ||
39 | |||
40 | char *__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 | ||
83 | char __ILWS_datem[DATE_MAX]; | ||
84 | |||
85 | char *__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 | */ | ||
96 | static 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 | |||
115 | int __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 | ||
50 | extern char *_tmpnameprefix; | ||
51 | |||
52 | |||
53 | char *__ILWS_stristr(char *, const char *); | ||
54 | char *__ILWS_tmpfname(); | ||
55 | int __ILWS_base64decode(char *, const char *); | ||
56 | char *__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 | ||
38 | extern "C"{ | ||
39 | #endif | ||
40 | |||
41 | extern char *_libwebserver_version; | ||
42 | extern char *_tmpnameprefix; | ||
43 | extern int WEBTIMEOUT; | ||
44 | |||
45 | struct _MultiPart { | ||
46 | char *id; | ||
47 | char *data; | ||
48 | unsigned int size; | ||
49 | char *filename; | ||
50 | void *pad; | ||
51 | }; | ||
52 | char *__Header(char *); | ||
53 | char *__Query(char *); | ||
54 | char *__Post(char *); | ||
55 | struct _MultiPart __MultiPart(char *); | ||
56 | char *__Cookie(char *); | ||
57 | |||
58 | extern 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 | |||
75 | struct 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 | |||
98 | void web_server_useSSLcert(struct web_server *,const char *); // useless if not using openssl | ||
99 | void web_server_useMIMEfile(struct web_server *,const char *); // new on 0.5.2 | ||
100 | int web_server_init(struct web_server *,int,const char *,int); | ||
101 | void web_server_shutdown(struct web_server *); | ||
102 | char *web_server_getconf(struct web_server *,char *,char *); | ||
103 | int web_server_addhandler(struct web_server *,const char *,void (*)(),int); | ||
104 | int web_server_aliasdir(struct web_server *, const char *,char *,int); // new on 0.5.2 | ||
105 | int web_server_run(struct web_server *); | ||
106 | |||
107 | |||
108 | int web_client_addfile(char *); | ||
109 | extern unsigned char GLOBALGIFPAL[256][3]; | ||
110 | void web_client_gifsetpalette(const char *); | ||
111 | int web_client_gifoutput(char *,int,int,int); | ||
112 | |||
113 | void web_client_setcookie(char *,char *,char *,char *, char *,int); // improved on 0.5.1 | ||
114 | void web_client_deletecookie(char *); // improved on 0.5.1 | ||
115 | int web_client_setvar(char *,char *); //(new (0.5.1) | ||
116 | char *web_client_getvar(char *); //(new (0.5.1) | ||
117 | int web_client_delvar(char *); //(new (0.5.1) | ||
118 | |||
119 | void web_client_HTTPdirective(char *); | ||
120 | void web_client_contenttype(char *); // 0.5.2 | ||
121 | void 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 | |||
19 | FILE *_logfile=NULL; | ||
20 | /*********************************************************************************************************/ | ||
21 | /* | ||
22 | * Open weblog file | ||
23 | */ | ||
24 | FILE *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 | */ | ||
35 | void 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 | |||
35 | extern FILE *_logfile; | ||
36 | |||
37 | void web_log(const char *,...); | ||
38 | FILE *open_weblog(const char *); | ||
39 | char *mydate(); | ||
40 | #endif | ||