diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 21 | ||||
-rw-r--r-- | src/client.c | 1171 | ||||
-rw-r--r-- | src/client.h | 139 | ||||
-rw-r--r-- | src/clientinfo.c | 893 | ||||
-rw-r--r-- | src/clientinfo.h | 103 | ||||
-rw-r--r-- | src/fnmatch.c | 195 | ||||
-rw-r--r-- | src/fnmatch.h | 59 | ||||
-rw-r--r-- | src/memory.c | 85 | ||||
-rw-r--r-- | src/memory.h | 40 | ||||
-rw-r--r-- | src/outstream.c | 118 | ||||
-rw-r--r-- | src/outstream.h | 47 | ||||
-rw-r--r-- | src/server.c | 279 | ||||
-rw-r--r-- | src/socket.h | 37 | ||||
-rw-r--r-- | src/utils.c | 152 | ||||
-rw-r--r-- | src/utils.h | 50 | ||||
-rw-r--r-- | src/web_server.h | 129 |
16 files changed, 0 insertions, 3518 deletions
diff --git a/src/Makefile.am b/src/Makefile.am deleted file mode 100644 index a268789a..00000000 --- a/src/Makefile.am +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | SUBDIRS = . | ||
2 | |||
3 | INCLUDES = -I$(top_srcdir)/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 | memory.c \ | ||
16 | utils.c \ | ||
17 | fnmatch.c | ||
18 | |||
19 | libwebserver_gnunet_la_LDFLAGS = \ | ||
20 | -version-info 0:0:0 | ||
21 | |||
diff --git a/src/client.c b/src/client.c deleted file mode 100644 index 22862020..00000000 --- a/src/client.c +++ /dev/null | |||
@@ -1,1171 +0,0 @@ | |||
1 | /* Copyrights 2002 Luis Figueiredo (stdio@netc.pt) All rights reserved. | ||
2 | * | ||
3 | * See the LICENSE file | ||
4 | * | ||
5 | * The origin of this software must not be misrepresented, either by | ||
6 | * explicit claim or by omission. Since few users ever read sources, | ||
7 | * credits must appear in the documentation. | ||
8 | * | ||
9 | * date: Sat Mar 30 14:44:42 GMT 2002 | ||
10 | * | ||
11 | * -- client handler functions | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | |||
16 | #include "client.h" | ||
17 | #include "outstream.h" | ||
18 | #include "clientinfo.h" | ||
19 | |||
20 | int WEBTIMEOUT=10000; | ||
21 | |||
22 | /*********************************************************************************************************/ | ||
23 | /* | ||
24 | * initializate (allocate) client list | ||
25 | */ | ||
26 | struct web_client *__ILWS_init_client_list() { | ||
27 | struct web_client *ret; | ||
28 | ret=__ILWS_malloc(sizeof(struct web_client)); | ||
29 | if(ret==NULL) { | ||
30 | return NULL; | ||
31 | }; | ||
32 | #ifdef HAVE_OPENSSL | ||
33 | ret->ssl=NULL; // ssl handler for this client | ||
34 | #endif | ||
35 | ret->next=NULL; | ||
36 | return ret; | ||
37 | } | ||
38 | |||
39 | |||
40 | /*********************************************************************************************************/ | ||
41 | /* | ||
42 | * Add a client node to client list | ||
43 | */ | ||
44 | int __ILWS_add_client(struct web_client *list, struct web_client *node) { | ||
45 | struct web_client *temp=list; | ||
46 | |||
47 | #ifdef WIN32 | ||
48 | unsigned long t=IOC_INOUT; | ||
49 | #endif | ||
50 | while(temp->next!=NULL)temp=temp->next; // run to last client | ||
51 | temp->next=node; | ||
52 | temp->next->rbuf=NULL; | ||
53 | temp->next->rbufsize=0; | ||
54 | |||
55 | if(!(temp->next->outstream=__ILWS_init_outstream_list())) { | ||
56 | return 0; | ||
57 | }; | ||
58 | if(!(temp->next->varlist=__ILWS_init_var_list())) { | ||
59 | return 0; | ||
60 | }; | ||
61 | |||
62 | temp->next->contentlength=0; | ||
63 | temp->next->headersize=0; | ||
64 | |||
65 | temp->next->wheadersize=0; | ||
66 | temp->next->writelength=0; | ||
67 | temp->next->readsize=0; | ||
68 | temp->next->range=0; | ||
69 | temp->next->skipped=0; | ||
70 | temp->next->cookies=NULL; | ||
71 | //temp->next->oldcl=clock(); | ||
72 | |||
73 | |||
74 | temp->next->newdata_try=0; | ||
75 | #ifdef WIN32 | ||
76 | // should be optional | ||
77 | ioctlsocket(temp->next->socket,FIONBIO,&t); //non blocking sockets for win32 | ||
78 | #else | ||
79 | fcntl(temp->next->socket,F_SETFL,O_NONBLOCK); | ||
80 | #endif | ||
81 | temp->next->next=NULL; | ||
82 | temp->next->HTTPdirective=NULL; | ||
83 | temp->next->stat=1; // Add a connected client | ||
84 | |||
85 | return 1; | ||
86 | } | ||
87 | /*********************************************************************************************************/ | ||
88 | |||
89 | |||
90 | |||
91 | /*********************************************************************************************************/ | ||
92 | /* | ||
93 | * Delete client node | ||
94 | */ | ||
95 | void __ILWS_delete_client(struct web_client *node) { | ||
96 | int rt; | ||
97 | rt=shutdown(node->socket,SHUT_RDWR); | ||
98 | #ifdef WIN32 | ||
99 | rt=closesocket(node->socket); | ||
100 | #else | ||
101 | rt=close(node->socket); | ||
102 | #endif | ||
103 | __ILWS_free(node->cookies); // (0.5.1) | ||
104 | __ILWS_delete_outstream_list(node->outstream); | ||
105 | __ILWS_delete_var_list(node->varlist); | ||
106 | #ifdef HAVE_OPENSSL | ||
107 | SSL_free (node->ssl); | ||
108 | #endif | ||
109 | __ILWS_free(node->rbuf); // free's | ||
110 | __ILWS_free(node); // free's | ||
111 | |||
112 | } | ||
113 | |||
114 | |||
115 | /*********************************************************************************************************/ | ||
116 | /* | ||
117 | * Delete next client node | ||
118 | */ | ||
119 | void __ILWS_delete_next_client(struct web_client *node) { | ||
120 | struct web_client *temp=node->next; | ||
121 | node->next=node->next->next; | ||
122 | __ILWS_delete_client(temp); | ||
123 | } | ||
124 | |||
125 | /*********************************************************************************************************/ | ||
126 | /* | ||
127 | * Delete entire client list | ||
128 | */ | ||
129 | void __ILWS_delete_client_list(struct web_client *node) { | ||
130 | struct web_client *next; | ||
131 | |||
132 | while(node) { | ||
133 | next = node->next; | ||
134 | __ILWS_free(node); | ||
135 | node = next; | ||
136 | } | ||
137 | } | ||
138 | |||
139 | /*********************************************************************************************************/ | ||
140 | /* | ||
141 | * Read what client have to say | ||
142 | */ | ||
143 | void __ILWS_read_client(struct web_client *node) { | ||
144 | int tmp,tmp1; | ||
145 | char *tmp2,*tmp3=NULL; | ||
146 | char readtemp[READMAX+1]; | ||
147 | unsigned long datasize=0; | ||
148 | |||
149 | #ifdef HAVE_OPENSSL | ||
150 | if(node->ssl!=NULL) { | ||
151 | tmp=SSL_read(node->ssl,readtemp,READMAX); | ||
152 | } else { | ||
153 | tmp=__ILWS_read(node->socket,readtemp,READMAX); | ||
154 | }; | ||
155 | #else | ||
156 | tmp=__ILWS_read(node->socket,readtemp,READMAX); | ||
157 | #endif | ||
158 | //fprintf(stderr,"readed %d bytes\n",tmp); | ||
159 | if(tmp<1) { | ||
160 | |||
161 | #ifdef WIN32 | ||
162 | if(WSAGetLastError()!=WSAEWOULDBLOCK) { | ||
163 | #else | ||
164 | if(errno!=EAGAIN) { | ||
165 | #endif | ||
166 | node->stat=5;return; | ||
167 | |||
168 | }; | ||
169 | //fprintf(stderr,"try: %d (%s)\n",node->newdata_try,node->rbuf); | ||
170 | // check if it is over | ||
171 | node->newdata_try++; | ||
172 | //fprintf(stderr,"node->newdata_try:%d\n",node->newdata_try); | ||
173 | if(node->rbufsize >0) { //&& node->newdata_try>5) { | ||
174 | if(node->headersize==0) { // always reachs "\r\n\r\n" | ||
175 | if((tmp3=strstr(node->rbuf,"\r\n\r\n"))) { | ||
176 | node->headersize=(tmp3-node->rbuf); | ||
177 | }; | ||
178 | } else { | ||
179 | datasize=node->rbufsize-node->headersize; | ||
180 | if(node->contentlength==0) { // well if it 0 read all at once | ||
181 | __ILWS_init_clientinfo(); // always call this? | ||
182 | node->contentlength=atol(ClientInfo->Header("Content-Length")); | ||
183 | // range for resuming | ||
184 | if((tmp3=strstr(ClientInfo->Header("Range"),"bytes="))) { // if it is in bytes (i hope, always) | ||
185 | tmp3+=6; // go to end of "bytes=" | ||
186 | node->range=atol(tmp3); | ||
187 | //printf("Range is %d - %s - %s\n",node->range,ClientInfo->Header("Range"),tmp3); | ||
188 | }; | ||
189 | // end range | ||
190 | __ILWS_free_clientinfo(); | ||
191 | }; | ||
192 | if(node->contentlength==datasize-4) { | ||
193 | //fprintf(stderr,"client (%d) all readed (%d) (try's)-%d\n",node->socket,node->curcl-node->oldcl,node->newdata_try); | ||
194 | node->newdata_try=WEBTIMEOUT; // assume done reading | ||
195 | //fprintf(stderr,"Ended naturaly\n"); | ||
196 | |||
197 | } | ||
198 | }; | ||
199 | if((node->newdata_try>=WEBTIMEOUT)) { // All readed | ||
200 | node->rbuf[node->rbufsize]='\0'; | ||
201 | node->stat=2; // Next state | ||
202 | //fprintf(stderr,"%s\n",node->rbuf); | ||
203 | //fprintf(stderr,"%d\n",node->rbufsize); | ||
204 | } | ||
205 | }; | ||
206 | }else { | ||
207 | tmp1=node->rbufsize; | ||
208 | node->rbufsize+=tmp; | ||
209 | tmp2=__ILWS_realloc(node->rbuf,node->rbufsize+1); | ||
210 | if(tmp2==NULL) { | ||
211 | node->stat=5; | ||
212 | |||
213 | return; | ||
214 | }else { | ||
215 | node->rbuf=tmp2; | ||
216 | }; | ||
217 | memcpy(node->rbuf+tmp1,readtemp,tmp); | ||
218 | node->newdata_try=0; | ||
219 | }; | ||
220 | } | ||
221 | |||
222 | |||
223 | /*********************************************************************************************************/ | ||
224 | /* | ||
225 | * Process headers w/ get handlers | ||
226 | */ | ||
227 | void __ILWS_process_client(struct web_client *node,struct gethandler *list) { | ||
228 | struct gethandler *gettemp=list; | ||
229 | long secs=time(NULL); | ||
230 | // for determining content length | ||
231 | #define RTMPMAX 400 | ||
232 | struct outstream *tmpstream; // new on 0.5.1 | ||
233 | char rtmp[RTMPMAX+1]; | ||
234 | int rtmps=0; | ||
235 | char *thead=NULL; | ||
236 | char *tmpl; | ||
237 | /// | ||
238 | int tmp=0; | ||
239 | int oumask=0; // old usermask | ||
240 | char *tmp1=__ILWS_web_client_getreq(); | ||
241 | char matchbuf[MATCHMAX]; | ||
242 | FILE *nfile; // new file | ||
243 | char *fname; // new file name | ||
244 | |||
245 | |||
246 | while(gettemp->next!=NULL && tmp==0) { | ||
247 | gettemp=gettemp->next; | ||
248 | snprintf(matchbuf,MATCHMAX,"%s",gettemp->str); | ||
249 | if(!tmp1) { | ||
250 | __ILWS_web_client_writef(node,"HTTP/1.1 400 Invalid request\r\n"); | ||
251 | __ILWS_web_client_writef(node,"Server: %s\r\n",_libwebserver_version); | ||
252 | __ILWS_web_client_writef(node,"Date: %s\r\n",__ILWS_date(mktime(gmtime(&secs)),"%a, %d %b %Y %H:%M:%S GMT")); // Date header | ||
253 | __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); | ||
254 | tmpl=__ILWS_web_client_getreqline(); | ||
255 | 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); | ||
256 | __ILWS_free(tmpl); | ||
257 | node->stat=5; | ||
258 | return; | ||
259 | }; | ||
260 | if(strlen(tmp1)>MAXURLSIZE) { | ||
261 | __ILWS_web_client_writef(node,"HTTP/1.1 414 URL to large\r\n"); | ||
262 | __ILWS_web_client_writef(node,"Server: %s\r\n",_libwebserver_version); | ||
263 | __ILWS_web_client_writef(node,"Date: %s\r\n",__ILWS_date(mktime(gmtime(&secs)),"%a, %d %b %Y %H:%M:%S GMT")); // Date header | ||
264 | __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); | ||
265 | tmpl=__ILWS_web_client_getreqline(); | ||
266 | 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); | ||
267 | __ILWS_free(tmpl); | ||
268 | node->stat=5; | ||
269 | __ILWS_free(tmp1); | ||
270 | return; | ||
271 | }; | ||
272 | if(!fnmatch(matchbuf,tmp1,5)) { | ||
273 | if((gettemp->flag & WS_LOCAL) == WS_LOCAL) { | ||
274 | if(node->sa.sin_addr.s_addr!=0x0100007F) { | ||
275 | __ILWS_web_client_writef(node,"HTTP/1.1 403 Forbidden\r\n"); | ||
276 | __ILWS_web_client_writef(node,"Server: %s\r\n",_libwebserver_version); | ||
277 | __ILWS_web_client_writef(node,"Date: %s\r\n",__ILWS_date(mktime(gmtime(&secs)),"%a, %d %b %Y %H:%M:%S GMT")); // Date header | ||
278 | __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); | ||
279 | tmpl=__ILWS_web_client_getreqline(); | ||
280 | 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); | ||
281 | __ILWS_free(tmpl); | ||
282 | node->stat=5; | ||
283 | __ILWS_free(tmp1); | ||
284 | return; | ||
285 | }; | ||
286 | }; | ||
287 | tmp=1; // Was found | ||
288 | node->outstream->flags=(gettemp->flag & WS_DYNVAR); // pass to outstreams | ||
289 | }; | ||
290 | }; | ||
291 | __ILWS_free(tmp1); | ||
292 | if(!tmp) { // Nothing found | ||
293 | __ILWS_web_client_writef(node,"HTTP/1.1 404 Not Found\r\n"); | ||
294 | __ILWS_web_client_writef(node,"Server: %s\r\n",_libwebserver_version); | ||
295 | __ILWS_web_client_writef(node,"Date: %s\r\n",__ILWS_date(mktime(gmtime(&secs)),"%a, %d %b %Y %H:%M:%S GMT")); // Date header | ||
296 | __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); | ||
297 | tmpl=__ILWS_web_client_getreqline(); | ||
298 | 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); | ||
299 | __ILWS_free(tmpl); | ||
300 | node->stat=5; | ||
301 | }else { | ||
302 | |||
303 | // if cgi do something else, present headers | ||
304 | oumask=umask(077); | ||
305 | if(!(fname=__ILWS_tmpfname())) { | ||
306 | libws_error(LE_FILESYS,": Error giving a temp filename\n"); | ||
307 | node->stat=5; | ||
308 | return; | ||
309 | }; | ||
310 | if((nfile=freopen(fname,"wb+",stdout))!=NULL) { | ||
311 | flock(fileno(stdout),LOCK_EX); | ||
312 | tmp=dup(fileno(stdout)); | ||
313 | nfile=fdopen(tmp,"wb+"); | ||
314 | if(!__ILWS_add_outstream(node->outstream,fname,nfile,1)) { | ||
315 | node->stat=5; // (delete client) | ||
316 | return; // ERROR reported by add_outstream | ||
317 | |||
318 | }; | ||
319 | // THE PROCESS | ||
320 | |||
321 | // Setup Clientinfo before running function | ||
322 | if(gettemp->type==GH_FUNCTION) { | ||
323 | __ILWS_init_clientinfo(); | ||
324 | gettemp->hdl.func(); // changed (0.5.3) Access by named union (Hilobok Andrew (han@km.if.ua) said that wasn't compile on freeBSD) | ||
325 | __ILWS_free_clientinfo(); | ||
326 | }; | ||
327 | // new on 0.5.2 | ||
328 | if(gettemp->type==GH_DIRECTORY) { // as builtin function for directory listing | ||
329 | __ILWS_init_clientinfo(); | ||
330 | if(strcmp(gettemp->str,"* /*"))ClientInfo->request+=1; // skip '/' if not equal to "* /*" (used by default) | ||
331 | __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) | ||
332 | __ILWS_free_clientinfo(); | ||
333 | }; | ||
334 | |||
335 | fflush(stdout); | ||
336 | fclose(stdout); // it is a tempfile freopened | ||
337 | __ILWS_free(fname); // doesn't need anymore | ||
338 | #ifdef WIN32 | ||
339 | freopen("con","w",stdout); | ||
340 | #else | ||
341 | freopen("/dev/tty","w",stdout); | ||
342 | #endif | ||
343 | if((gettemp->flag & WS_USELEN) == WS_USELEN) { | ||
344 | // determine writelength (for content-length: header) (new on 0.5.1) | ||
345 | tmpstream=node->outstream; | ||
346 | tmp=0; | ||
347 | while(tmpstream->next!=NULL) { // end of header probably in the firsts outstream nodes check for that | ||
348 | if(tmpstream->next->fname!=NULL) { | ||
349 | if(tmpstream->next->fstream==NULL) { | ||
350 | nfile=fopen(tmpstream->next->fname,"rb"); | ||
351 | tmpstream->next->fstream=nfile; // here (corrected on 0.5.3); | ||
352 | } else { | ||
353 | fflush(tmpstream->next->fstream); // <- flush tha thing | ||
354 | nfile=tmpstream->next->fstream; | ||
355 | fseek(nfile,0,SEEK_SET); | ||
356 | }; | ||
357 | if(nfile!=NULL) { | ||
358 | rtmps=0; | ||
359 | while((!node->wheadersize) && (!feof(nfile))) { // wheadersize is 0, suposed to be fast, at least if is not malformed | ||
360 | if(rtmps>0) {tmp-=4;fseek(nfile,rtmps-4,SEEK_SET);} | ||
361 | if((rtmps=fread(rtmp,1,RTMPMAX,nfile))>0) { | ||
362 | rtmp[rtmps]=0; | ||
363 | if((tmp1=strstr(rtmp,"\r\n\r\n"))) { | ||
364 | node->wheadersize=(tmp+((tmp1+4)-rtmp)); | ||
365 | rtmps=((tmp1+4)-rtmp); | ||
366 | |||
367 | }; | ||
368 | if(node->range>0) { | ||
369 | tmp1=realloc(thead,tmp+rtmps+1); | ||
370 | thead=tmp1; | ||
371 | memcpy(thead+tmp,rtmp,rtmps); | ||
372 | thead[tmp+rtmps]=0; | ||
373 | }; | ||
374 | tmp+=rtmps; | ||
375 | }; | ||
376 | }; | ||
377 | fseek(nfile,SEEK_END,SEEK_END); | ||
378 | node->writelength+=(ftell(nfile)-2); | ||
379 | //fclose(nfile); // <- don't worry they close the file later | ||
380 | }; | ||
381 | }; | ||
382 | tmpstream=tmpstream->next; | ||
383 | |||
384 | }; | ||
385 | // end writelength | ||
386 | } else { | ||
387 | node->range=0; // no content-range | ||
388 | }; | ||
389 | |||
390 | if(node->range>node->writelength-node->wheadersize && node->range>0) { | ||
391 | __ILWS_web_client_writef(node,"HTTP/1.1 416 Requested Range Not Satisfiable\r\n"); | ||
392 | __ILWS_web_client_writef(node,"Server: %s\r\n",_libwebserver_version); | ||
393 | __ILWS_web_client_writef(node,"Date: %s\r\n",__ILWS_date(mktime(gmtime(&secs)),"%a, %d %b %Y %H:%M:%S GMT")); // Date header | ||
394 | __ILWS_web_client_writef(node,"Content-range: bytes */%d\r\n",node->writelength-node->wheadersize); | ||
395 | __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); | ||
396 | tmpl=__ILWS_web_client_getreqline(); | ||
397 | 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); | ||
398 | __ILWS_free(tmpl); | ||
399 | node->stat=5; | ||
400 | __ILWS_free(thead); | ||
401 | umask(oumask); | ||
402 | return; | ||
403 | }; | ||
404 | if(node->range>0 && ((node->outstream->flags & WS_DYNVAR)==WS_DYNVAR)) { // if request range interval and dynvar on than produces not implemented | ||
405 | __ILWS_web_client_writef(node,"HTTP/1.1 501 Not Implemented\r\n"); | ||
406 | __ILWS_web_client_writef(node,"Server: %s\r\n",_libwebserver_version); | ||
407 | __ILWS_web_client_writef(node,"Date: %s\r\n",__ILWS_date(mktime(gmtime(&secs)),"%a, %d %b %Y %H:%M:%S GMT")); // Date header | ||
408 | __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); | ||
409 | tmpl=__ILWS_web_client_getreqline(); | ||
410 | 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); | ||
411 | __ILWS_free(tmpl); | ||
412 | node->stat=5; | ||
413 | __ILWS_free(thead); | ||
414 | umask(oumask); | ||
415 | return; | ||
416 | }; | ||
417 | |||
418 | } | ||
419 | node->stat=4; | ||
420 | if(node->HTTPdirective==NULL) { | ||
421 | if(node->range>0) { | ||
422 | __ILWS_web_client_writef(node,"HTTP/1.1 206 Partial Content\r\n"); | ||
423 | tmpl=__ILWS_web_client_getreqline(); | ||
424 | 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); | ||
425 | __ILWS_free(tmpl); | ||
426 | } else { | ||
427 | __ILWS_web_client_writef(node,"HTTP/1.1 200 OK\r\n"); | ||
428 | tmpl=__ILWS_web_client_getreqline(); | ||
429 | 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); | ||
430 | __ILWS_free(tmpl); | ||
431 | }; | ||
432 | |||
433 | } else { | ||
434 | __ILWS_web_client_writef(node,"%s\r\n",node->HTTPdirective); | ||
435 | tmpl=__ILWS_web_client_getreqline(); | ||
436 | 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); | ||
437 | __ILWS_free(tmpl); | ||
438 | }; | ||
439 | __ILWS_web_client_writef(node,"Server: %s\r\n",_libwebserver_version); | ||
440 | __ILWS_web_client_writef(node,"Date: %s\r\n",__ILWS_date(mktime(gmtime(&secs)),"%a, %d %b %Y %H:%M:%S GMT")); // Date header | ||
441 | __ILWS_web_client_writef(node,"Accept-Ranges: bytes\r\n"); | ||
442 | 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); | ||
443 | if(node->cookies!=NULL)__ILWS_web_client_writef(node,"%s",node->cookies); // new (0.5.1) | ||
444 | if(node->range>0) { | ||
445 | __ILWS_web_client_writef(node,"Content-range: bytes %d-%d/%d\r\n",node->range,(node->writelength-node->wheadersize)-1,node->writelength-node->wheadersize); | ||
446 | __ILWS_web_client_writef(node,"%s",thead); // the rest of header | ||
447 | __ILWS_free(thead); | ||
448 | }; | ||
449 | umask(oumask); | ||
450 | |||
451 | }; | ||
452 | |||
453 | } | ||
454 | /*********************************************************************************************************/ | ||
455 | /* | ||
456 | * Process stream output | ||
457 | */ | ||
458 | void __ILWS_output_client(struct web_client *node) { | ||
459 | struct outstream *tstream=node->outstream; | ||
460 | char *tmp1,*tmp2,*tmp3; | ||
461 | char writetemp[WRITEMAX+1]; | ||
462 | int beginsize=0; | ||
463 | int endsize=0; | ||
464 | int varsize=0; | ||
465 | int namesize=0; | ||
466 | if(tstream->next!=NULL) { | ||
467 | if(tstream->next->fname!=NULL) { | ||
468 | if(tstream->next->fstream==NULL) { | ||
469 | if((tstream->next->fstream=fopen(tstream->next->fname,"rb"))==NULL) { | ||
470 | __ILWS_delete_next_outstream(tstream); | ||
471 | //node->outstream->next=tstream->next; | ||
472 | return; | ||
473 | } | ||
474 | }; | ||
475 | |||
476 | // read part (must always read) | ||
477 | if(tstream->next->rsize==0) { // start from 0 | ||
478 | fseek(tstream->next->fstream,0,SEEK_SET); | ||
479 | }; | ||
480 | memset(writetemp,0,WRITEMAX); | ||
481 | tstream->next->rsize=fread(writetemp,1,WRITEMAX,tstream->next->fstream); | ||
482 | writetemp[tstream->next->rsize]=0; | ||
483 | // if read make var changes on writetemp; | ||
484 | // new on 0.5.1 -- UNDERDEV // FIX - | ||
485 | if((node->outstream->flags & WS_DYNVAR) == WS_DYNVAR) { | ||
486 | |||
487 | tmp1=writetemp; | ||
488 | while(((tmp1=strstr(tmp1,"$")+1)!=(char*)1) && beginsize==0) { // check var found | ||
489 | for(namesize=0;namesize<50;namesize++) { | ||
490 | if(tmp1[namesize]==';') {namesize++;break;} | ||
491 | if((tmp1[namesize]<'a' || tmp1[namesize]>'z') && | ||
492 | (tmp1[namesize]<'A' || tmp1[namesize]>'Z') && | ||
493 | (tmp1[namesize]<'1' || tmp1[namesize]>'0') && | ||
494 | tmp1[namesize]!='_') {namesize=0;break;}; | ||
495 | |||
496 | }; | ||
497 | if(namesize>0) { | ||
498 | if(namesize==1) { // this is $; for sure | ||
499 | if(!(tmp3=__ILWS_malloc(2))) { | ||
500 | node->stat=5; | ||
501 | return; | ||
502 | }; | ||
503 | memcpy(tmp3,"$",namesize); | ||
504 | tmp3[namesize]=0; | ||
505 | } else { | ||
506 | if(!(tmp3=__ILWS_malloc(namesize))) { | ||
507 | node->stat=5; | ||
508 | return; | ||
509 | }; | ||
510 | memcpy(tmp3,tmp1,namesize-1); | ||
511 | tmp3[namesize-1]=0; | ||
512 | }; | ||
513 | |||
514 | tmp1-=1; | ||
515 | |||
516 | beginsize=tmp1-writetemp; | ||
517 | tmp1+=namesize; // get var from whateverwhere (client node probably) | ||
518 | |||
519 | endsize=strlen(tmp1); | ||
520 | |||
521 | //varsize=2; | ||
522 | |||
523 | if((tmp2=__ILWS_malloc(beginsize+1))) { | ||
524 | memcpy(tmp2,writetemp,beginsize); | ||
525 | tmp2[beginsize]=0; | ||
526 | if(namesize==1) { | ||
527 | varsize=strlen(tmp3); | ||
528 | snprintf(writetemp,WRITEMAX,"%s%s",tmp2,tmp3); | ||
529 | } else { | ||
530 | varsize=strlen(__ILWS_get_var(node->varlist,tmp3)); | ||
531 | snprintf(writetemp,WRITEMAX,"%s%s",tmp2,__ILWS_get_var(node->varlist,tmp3)); | ||
532 | }; | ||
533 | writetemp[strlen(tmp2)+varsize]=0; | ||
534 | __ILWS_free(tmp2); | ||
535 | __ILWS_free(tmp3); | ||
536 | tstream->next->rsize=(beginsize+varsize); | ||
537 | tstream->next->varsize+=(varsize-namesize)-1; | ||
538 | } else { | ||
539 | __ILWS_free(tmp3); | ||
540 | node->stat=5; | ||
541 | return; | ||
542 | }; | ||
543 | }; | ||
544 | }; | ||
545 | }; // dynvar | ||
546 | |||
547 | /* there is nothing more to read here */ | ||
548 | if(tstream->next->rsize<1){ // i guess rsize < 1 is eof (make sure that server writed last time) | ||
549 | //only change if everything written | ||
550 | if(feof(tstream->next->fstream) && (ftell(tstream->next->fstream)==tstream->next->wrotesize)) { | ||
551 | //fclose(tstream->next->fstream); | ||
552 | |||
553 | __ILWS_delete_next_outstream(tstream); | ||
554 | //node->outstream->next=tstream->next; | ||
555 | } | ||
556 | return; | ||
557 | } | ||
558 | node->readsize+=tstream->next->rsize; | ||
559 | if(!node->skipped && node->range>0) { | ||
560 | tstream->next->wsize=tstream->next->rsize; | ||
561 | tstream->next->wrotesize+=tstream->next->wsize; | ||
562 | if((node->readsize-node->wheadersize)<node->range) { // skip range bytes | ||
563 | return; // do nothing | ||
564 | }else { | ||
565 | node->skipped=1; | ||
566 | tstream->next->wrotesize-=(node->readsize-node->wheadersize)-node->range; // the right offset | ||
567 | fseek(tstream->next->fstream,tstream->next->wrotesize,SEEK_SET); | ||
568 | tstream->next->wsize=tstream->next->rsize; | ||
569 | return; | ||
570 | }; | ||
571 | }; | ||
572 | // write part | ||
573 | |||
574 | #ifdef HAVE_OPENSSL | ||
575 | if(node->ssl!=NULL) { | ||
576 | tstream->next->wsize=SSL_write(node->ssl,writetemp,tstream->next->rsize); | ||
577 | } else { | ||
578 | tstream->next->wsize=send(node->socket,writetemp,tstream->next->rsize,0); | ||
579 | }; | ||
580 | #else | ||
581 | tstream->next->wsize=send(node->socket,writetemp,tstream->next->rsize,0); | ||
582 | #endif | ||
583 | if(tstream->next->wsize>0) { | ||
584 | tstream->next->wrotesize+=tstream->next->wsize; | ||
585 | if(tstream->next->rsize!=tstream->next->wsize || beginsize>0) { // FIX | ||
586 | fseek(tstream->next->fstream,tstream->next->wrotesize-(tstream->next->varsize),SEEK_SET); // FIX | ||
587 | }; | ||
588 | }; | ||
589 | #ifdef WIN32 | ||
590 | if((tstream->next->wsize<=0) && (WSAGetLastError()!=WSAEWOULDBLOCK)) { // WIN32 only | ||
591 | #else | ||
592 | if(tstream->next->wsize<=0 && errno!=EAGAIN) { // linux only // *nix i guess | ||
593 | #endif | ||
594 | //fclose(tstream->next->fstream); | ||
595 | |||
596 | __ILWS_delete_next_outstream(tstream); | ||
597 | //node->outstream->next=tstream->next; | ||
598 | return; | ||
599 | }else { // broken pipe | ||
600 | if(tstream->next->wsize<0) { | ||
601 | fseek(tstream->next->fstream,tstream->next->wrotesize-(tstream->next->varsize),SEEK_SET); //didn't read must back to where it was | ||
602 | }; | ||
603 | }; | ||
604 | |||
605 | }else { // filename is null | ||
606 | |||
607 | __ILWS_delete_next_outstream(tstream); | ||
608 | return; | ||
609 | }; | ||
610 | }else { // End of streams | ||
611 | |||
612 | current_web_client->stat=5; // done | ||
613 | |||
614 | }; | ||
615 | } | ||
616 | |||
617 | /*********************************************************************************************************/ | ||
618 | /* | ||
619 | * Set http directive | ||
620 | */ | ||
621 | void web_client_HTTPdirective(char *str) { | ||
622 | current_web_client->HTTPdirective=str; | ||
623 | } | ||
624 | |||
625 | |||
626 | /*********************************************************************************************************/ | ||
627 | /* | ||
628 | * GET request name | ||
629 | */ | ||
630 | char *__ILWS_web_client_getreq() { | ||
631 | char *ret; | ||
632 | char *tmp1=strstr(current_web_client->rbuf,"?"); | ||
633 | char *tmp2=strstr(current_web_client->rbuf," HTTP"); | ||
634 | char *tmp3=strstr(current_web_client->rbuf,"\r\n"); | ||
635 | int size; | ||
636 | if(tmp1==NULL || tmp1>tmp2) { | ||
637 | tmp1=tmp2; | ||
638 | }; | ||
639 | if(tmp2>tmp3) { | ||
640 | return NULL; | ||
641 | }; | ||
642 | size=tmp1-current_web_client->rbuf; | ||
643 | if(size<1) return NULL; | ||
644 | |||
645 | if(!(ret=__ILWS_malloc(size+1))) { | ||
646 | return NULL; | ||
647 | }; | ||
648 | memcpy(ret,current_web_client->rbuf,size); | ||
649 | ret[size]=0; | ||
650 | return ret; | ||
651 | |||
652 | }; | ||
653 | |||
654 | /*********************************************************************************************************/ | ||
655 | /* | ||
656 | * GET request line | ||
657 | */ | ||
658 | char *__ILWS_web_client_getreqline() { | ||
659 | char *ret; | ||
660 | char *tmp1=strstr(current_web_client->rbuf,"\r\n"); | ||
661 | int size=0; | ||
662 | if(tmp1==NULL) return NULL; | ||
663 | size=tmp1-current_web_client->rbuf; | ||
664 | if(size<1) return NULL; | ||
665 | |||
666 | if(!(ret=__ILWS_malloc(size+1))) { | ||
667 | return NULL; | ||
668 | }; | ||
669 | memcpy(ret,current_web_client->rbuf,size); | ||
670 | ret[size]=0; | ||
671 | return ret; | ||
672 | } | ||
673 | |||
674 | |||
675 | /*********************************************************************************************************/ | ||
676 | /* | ||
677 | * Add a FILE stream type to client output | ||
678 | */ | ||
679 | int web_client_addfile(char *in) { | ||
680 | int ret=__ILWS_add_outstream(current_web_client->outstream,in,NULL,0); | ||
681 | int nfd=0; | ||
682 | char *fname; | ||
683 | FILE *nfile=NULL; | ||
684 | fname=__ILWS_tmpfname(); | ||
685 | fflush(stdout); | ||
686 | fclose(stdout); // oldstdout close it? | ||
687 | |||
688 | if((nfile=freopen(fname,"w+b",stdout))!=NULL){ // redirect | ||
689 | flock(fileno(stdout),LOCK_EX); // <- yah | ||
690 | nfd=dup(fileno(stdout)); | ||
691 | nfile=fdopen(nfd,"wb+"); | ||
692 | if(!__ILWS_add_outstream(current_web_client->outstream,fname,nfile,1)) { | ||
693 | return 0; | ||
694 | }; | ||
695 | }; | ||
696 | __ILWS_free(fname); | ||
697 | ClientInfo->outfd=fileno(nfile); | ||
698 | return ret; | ||
699 | } | ||
700 | |||
701 | |||
702 | /*********************************************************************************************************/ | ||
703 | /* | ||
704 | * Output data as gif (with width w and height h) | ||
705 | */ | ||
706 | unsigned char __ILWS_GLOBALGIFPAL[256][3]; | ||
707 | |||
708 | |||
709 | void web_client_gifsetpalette(const char *fname) { | ||
710 | int j; | ||
711 | FILE *palfile; | ||
712 | if(strcmp(fname,"EGA")==0) { | ||
713 | static int EGApalette[16][3] = { | ||
714 | {0,0,0}, {0,0,128}, {0,128,0}, {0,128,128}, | ||
715 | {128,0,0}, {128,0,128}, {128,128,0}, {200,200,200}, | ||
716 | {100,100,100}, {100,100,255}, {100,255,100}, {100,255,255}, | ||
717 | {255,100,100}, {255,100,255}, {255,255,100}, {255,255,255} }; | ||
718 | for (j=0; j<256; j++) { | ||
719 | __ILWS_GLOBALGIFPAL[j][0] = (unsigned char)EGApalette[j&15][0]; | ||
720 | __ILWS_GLOBALGIFPAL[j][1] = (unsigned char)EGApalette[j&15][1]; | ||
721 | __ILWS_GLOBALGIFPAL[j][2] = (unsigned char)EGApalette[j&15][2]; | ||
722 | } | ||
723 | } else { | ||
724 | if(!(palfile=fopen(fname,"rb"))) { | ||
725 | return; | ||
726 | }; | ||
727 | fread(__ILWS_GLOBALGIFPAL,sizeof(__ILWS_GLOBALGIFPAL),1,palfile); | ||
728 | fclose(palfile); | ||
729 | }; | ||
730 | }; | ||
731 | |||
732 | int web_client_gifoutput(char *data,int w,int h,int transparencyindex) { | ||
733 | int i; | ||
734 | unsigned char rm[256],gm[256],bm[256]; | ||
735 | for(i=0;i<256;i++) { | ||
736 | rm[i]=__ILWS_GLOBALGIFPAL[i][0]; | ||
737 | gm[i]=__ILWS_GLOBALGIFPAL[i][1]; | ||
738 | bm[i]=__ILWS_GLOBALGIFPAL[i][2]; | ||
739 | }; | ||
740 | |||
741 | i=__ILWS_WriteGIF(stdout,data,w,h,rm,gm,bm,256,0,transparencyindex,"libwebserver export gif (xvgifwr.c)"); | ||
742 | |||
743 | return i; | ||
744 | }; | ||
745 | |||
746 | |||
747 | /*********************************************************************************************************/ | ||
748 | /* | ||
749 | * an util to write with format on client_nodes | ||
750 | */ | ||
751 | void __ILWS_web_client_writef(struct web_client *node,const char *fmt,...) { | ||
752 | va_list args; | ||
753 | char buf[WRITEMAX]; | ||
754 | va_start(args,fmt); | ||
755 | vsnprintf(buf,512,fmt,args); | ||
756 | va_end(args); | ||
757 | |||
758 | #ifdef HAVE_OPENSSL | ||
759 | if(node->ssl!=NULL) { | ||
760 | SSL_write(node->ssl,buf,strlen(buf)); | ||
761 | } else { | ||
762 | send(node->socket,buf,strlen(buf),0); | ||
763 | }; | ||
764 | #else | ||
765 | send(node->socket,buf,strlen(buf),0); | ||
766 | #endif | ||
767 | } | ||
768 | |||
769 | |||
770 | /*********************************************************************************************************/ | ||
771 | /* | ||
772 | * function "web_client_setcookie" (improved on 0.5.1) to be called what ever were over handler function | ||
773 | * | ||
774 | * name = Name of the cookie | ||
775 | * value = Value of the cookie | ||
776 | * timeout = Timeout in second from current time on | ||
777 | * (0 = Until end of session) | ||
778 | * (-1 = Delete cookie) | ||
779 | * path = Subset of URLs in a domain for which the cookie is valid | ||
780 | * (If the path is not specified (path == NULL), it as assumed to be | ||
781 | * the same path as the document being described by the header which | ||
782 | * contains the cookie.) | ||
783 | * domain = Domain the cookie is valid for | ||
784 | * (If the domain is not set (domain == NULL), the default value of | ||
785 | * domain is the host name of the server which generated the cookie | ||
786 | * response.) | ||
787 | * secure = If a cookie is marked secure (secure == 1), it will only be | ||
788 | * transmitted if the communications channel with the host is a | ||
789 | * secure one. Currently this means that secure cookies will only be | ||
790 | * sent to HTTPS (HTTP over SSL) servers. | ||
791 | * (If secure is not specified (secure == 0), a cookie is considered | ||
792 | * safe to be sent in the clear over unsecured channels. ) | ||
793 | */ | ||
794 | void web_client_setcookie(char *name, char *value, char *timeoutf, char *path, char *domain, int secure) { | ||
795 | char *tmp1=timeoutf; | ||
796 | long toffset=0; | ||
797 | time_t secs; // to time offset | ||
798 | int timeout; | ||
799 | int offset=(current_web_client->cookies!=NULL)?strlen(current_web_client->cookies):0; | ||
800 | if(timeoutf==NULL) { | ||
801 | timeout=0; | ||
802 | } else if (!strcmp(timeoutf,"DEL")){ | ||
803 | timeout=-1; | ||
804 | } else { | ||
805 | while(*tmp1) { | ||
806 | if(*tmp1=='S')toffset=1; // seconds | ||
807 | if(*tmp1=='M')toffset=60; // minutes | ||
808 | if(*tmp1=='H')toffset=60*60; // hours | ||
809 | if(*tmp1=='d')toffset=60*60*24; // days | ||
810 | if(*tmp1=='m')toffset=60*60*24*30; // Month | ||
811 | if(*tmp1=='y')toffset=60*60*24*365; // years | ||
812 | tmp1++; | ||
813 | }; | ||
814 | timeout=atoi(timeoutf)*toffset; | ||
815 | }; | ||
816 | |||
817 | if (timeout < 0){ | ||
818 | current_web_client->cookies=__ILWS_realloc(current_web_client->cookies,offset+59+strlen(name)); | ||
819 | 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")); | ||
820 | offset+=59+strlen(name); | ||
821 | }else{ | ||
822 | current_web_client->cookies=__ILWS_realloc(current_web_client->cookies,offset+14+strlen(name)+strlen(value)); | ||
823 | snprintf(current_web_client->cookies+offset,14+strlen(name)+strlen(value),"Set-Cookie: %s=%s", name, value); | ||
824 | offset+=13+strlen(name)+strlen(value); | ||
825 | |||
826 | if (timeout != 0){ | ||
827 | //timeout += timezone; Hilobok Andrew (han@km.if.ua) removed this and use gmtime (thanks) | ||
828 | // exchanged by mktime(gmtime(&secs)) | ||
829 | current_web_client->cookies=__ILWS_realloc(current_web_client->cookies,offset+40); | ||
830 | secs=time(NULL); | ||
831 | snprintf(current_web_client->cookies+offset,40,"; expires=%s", __ILWS_date(mktime(gmtime(&secs))+timeout,"%a, %d-%b-%Y %H:%M:%S GMT")); | ||
832 | offset+=39; | ||
833 | } | ||
834 | if (path != NULL && *path!=0) { | ||
835 | current_web_client->cookies=__ILWS_realloc(current_web_client->cookies,offset+8+strlen(path)); | ||
836 | snprintf(current_web_client->cookies+offset,8+strlen(path),"; path=%s", path); | ||
837 | offset+=7+strlen(path); | ||
838 | } | ||
839 | if (domain != NULL && *domain!=0){ | ||
840 | current_web_client->cookies=__ILWS_realloc(current_web_client->cookies,offset+10+strlen(domain)); | ||
841 | snprintf(current_web_client->cookies+offset,10+strlen(domain),"; domain=%s", domain); | ||
842 | offset+=9+strlen(domain); | ||
843 | }; | ||
844 | if (secure == 1) { | ||
845 | current_web_client->cookies=__ILWS_realloc(current_web_client->cookies,offset+9); | ||
846 | snprintf(current_web_client->cookies+offset,9,"; secure"); | ||
847 | offset+=8; | ||
848 | }; | ||
849 | } | ||
850 | |||
851 | current_web_client->cookies=__ILWS_realloc(current_web_client->cookies,offset+3); | ||
852 | snprintf(current_web_client->cookies+offset,3,"\r\n"); // '\0' included | ||
853 | offset+=2; | ||
854 | // fprintf(stderr,"current_web_client->cookies=\"%s\"\n",current_web_client->cookies); // DEBUG TO REMOVE | ||
855 | |||
856 | |||
857 | } | ||
858 | |||
859 | |||
860 | |||
861 | |||
862 | /* | ||
863 | * function "web_client_deletecookie" | ||
864 | * | ||
865 | * name = Name of the cookie to delete | ||
866 | */ | ||
867 | |||
868 | void web_client_deletecookie(char *name){ | ||
869 | web_client_setcookie(name, NULL, "DEL", NULL, NULL, 0); | ||
870 | } | ||
871 | |||
872 | |||
873 | |||
874 | |||
875 | |||
876 | |||
877 | |||
878 | |||
879 | int web_client_setvar(char *name,char *value) { | ||
880 | return __ILWS_add_var(current_web_client->varlist,name,value); | ||
881 | }; | ||
882 | char *web_client_getvar(char *name) { | ||
883 | return __ILWS_get_var(current_web_client->varlist,name); | ||
884 | |||
885 | }; | ||
886 | int web_client_delvar(char *name) { | ||
887 | return __ILWS_del_var(current_web_client->varlist,name); | ||
888 | |||
889 | }; | ||
890 | |||
891 | |||
892 | /*************** | ||
893 | * variables | ||
894 | ***************/ | ||
895 | |||
896 | |||
897 | // prepare this to work in another file var.c | ||
898 | struct web_var *__ILWS_init_var_list() { | ||
899 | struct web_var *ret; | ||
900 | if(!(ret=__ILWS_malloc(sizeof(struct web_var)))) { | ||
901 | return NULL; | ||
902 | }; | ||
903 | ret->name=NULL; | ||
904 | ret->value=NULL; | ||
905 | ret->next=NULL; | ||
906 | return ret; | ||
907 | }; | ||
908 | |||
909 | int __ILWS_add_var(struct web_var *list, char *name, char *value) { | ||
910 | struct web_var *node=list; | ||
911 | int namesize=strlen(name); | ||
912 | int valuesize=strlen(value); | ||
913 | while(node->next!=NULL) { | ||
914 | if(!strcmp(node->next->name,name)) { | ||
915 | return 0; | ||
916 | }; | ||
917 | node=node->next; | ||
918 | }; | ||
919 | |||
920 | if(!(node->next=__ILWS_malloc(sizeof(struct web_var)))) { | ||
921 | return 0; | ||
922 | }; | ||
923 | |||
924 | if(!(node->next->name=__ILWS_malloc(namesize+1))) { | ||
925 | return 0; | ||
926 | }; | ||
927 | memcpy(node->next->name,name,namesize); | ||
928 | node->next->name[namesize]=0; | ||
929 | |||
930 | if(!(node->next->value=__ILWS_malloc(valuesize+1))) { | ||
931 | return 0; | ||
932 | }; | ||
933 | memcpy(node->next->value,value,valuesize); | ||
934 | node->next->value[valuesize]=0; | ||
935 | node->next->next=NULL; | ||
936 | return 1; | ||
937 | }; | ||
938 | |||
939 | int __ILWS_del_var(struct web_var *list, char *name) { | ||
940 | struct web_var *node=list; | ||
941 | struct web_var *tmp; | ||
942 | while(node->next!=NULL) { | ||
943 | if(!strcmp(node->next->name,name)) { | ||
944 | tmp=node->next; | ||
945 | node->next=node->next->next; | ||
946 | __ILWS_free(tmp->name); | ||
947 | __ILWS_free(tmp->value); | ||
948 | __ILWS_free(tmp); | ||
949 | return 1; | ||
950 | }; | ||
951 | }; | ||
952 | return 0; | ||
953 | }; | ||
954 | void __ILWS_delete_var_list(struct web_var *list) { | ||
955 | struct web_var *node=list; | ||
956 | struct web_var *tmp; | ||
957 | |||
958 | while(node->next!=NULL) { | ||
959 | tmp=node->next; | ||
960 | node->next=node->next->next; | ||
961 | __ILWS_free(tmp->name); | ||
962 | __ILWS_free(tmp->value); | ||
963 | |||
964 | __ILWS_free(tmp); | ||
965 | }; | ||
966 | __ILWS_free(node); | ||
967 | }; | ||
968 | |||
969 | |||
970 | char *__ILWS_get_var(struct web_var *list , char *name) { | ||
971 | struct web_var *node=list; | ||
972 | while(node->next!=NULL) { | ||
973 | if(!strcmp(node->next->name,name)) { | ||
974 | return node->next->value; | ||
975 | }; | ||
976 | node=node->next; | ||
977 | }; | ||
978 | return ""; | ||
979 | }; | ||
980 | |||
981 | |||
982 | /**************************** | ||
983 | * give mime by ext (mime file declared on server) | ||
984 | */ | ||
985 | |||
986 | void web_client_contenttype(char *ext) { | ||
987 | FILE *mimefileh; | ||
988 | char *mimedata; | ||
989 | char *mimeline; | ||
990 | size_t extsize; | ||
991 | size_t mimesize; | ||
992 | char *tmp; | ||
993 | /* -- mime */ | ||
994 | int isok=0; | ||
995 | size_t i; | ||
996 | |||
997 | if(ext==NULL || current_web_server->mimefile==NULL) { | ||
998 | printf("Content-type: text/plain\r\n\r\n"); // <- mime type, change this calculating mime with extension | ||
999 | } else { | ||
1000 | extsize=strlen(ext); | ||
1001 | if((mimefileh=fopen(current_web_server->mimefile,"r"))) { | ||
1002 | // retrieve file size | ||
1003 | fseek(mimefileh,SEEK_END,SEEK_END); | ||
1004 | mimesize=ftell(mimefileh); | ||
1005 | fseek(mimefileh,0,SEEK_SET); | ||
1006 | // | ||
1007 | // malloc and read data | ||
1008 | mimedata=__ILWS_malloc(mimesize+1); | ||
1009 | fread(mimedata,1,mimesize,mimefileh); | ||
1010 | fclose(mimefileh); // close file | ||
1011 | // | ||
1012 | for(i=0;i<mimesize;i++)if(mimedata[i]=='\t')mimedata[i]=' '; // translate \t to 1 space | ||
1013 | mimedata[mimesize]=0; | ||
1014 | |||
1015 | isok=0; | ||
1016 | mimeline=strtok(mimedata,"\n"); | ||
1017 | while((mimeline=strtok(NULL,"\n")) && !isok) { | ||
1018 | if(mimeline[0]!='#') { // is not a comment | ||
1019 | tmp=mimeline; | ||
1020 | while((tmp=strstr(tmp,ext)) && !isok) { | ||
1021 | //fprintf(stderr,"extsize(%d),found in %s (%s) %x\n",extsize,mimeline,tmp,tmp[extsize]); | ||
1022 | if(tmp[-1]==' ' && (tmp[extsize]==' ' || tmp[extsize]=='\0') ) { | ||
1023 | if((tmp=strchr(mimeline,' '))) { // the first space? | ||
1024 | tmp[0]='\0'; | ||
1025 | //fprintf(stderr,"content is: %s\n",mimeline); | ||
1026 | printf("Content-type: %s\r\n\r\n",mimeline); | ||
1027 | isok=1; | ||
1028 | }; | ||
1029 | }; | ||
1030 | tmp+=extsize; | ||
1031 | }; | ||
1032 | |||
1033 | }; | ||
1034 | }; | ||
1035 | if(!isok) { | ||
1036 | printf("Content-type: text/plain\r\n\r\n"); | ||
1037 | }; | ||
1038 | //printf("%s\n",tmp); | ||
1039 | __ILWS_free(mimedata); | ||
1040 | |||
1041 | }; | ||
1042 | }; | ||
1043 | }; | ||
1044 | |||
1045 | |||
1046 | /********************************** | ||
1047 | * internal directory generator | ||
1048 | */ | ||
1049 | |||
1050 | int __ILWS_lws_list(char *inpath) { | ||
1051 | /* for type directory */ | ||
1052 | /* mime*/ | ||
1053 | char *ext; | ||
1054 | struct dirent *dire; | ||
1055 | DIR *cd; | ||
1056 | struct stat cfstat; | ||
1057 | char *dirpath=NULL; | ||
1058 | char *filepath; | ||
1059 | char *tmp; | ||
1060 | char *readfile; | ||
1061 | float filesize; | ||
1062 | char filesizeu; | ||
1063 | //// | ||
1064 | |||
1065 | |||
1066 | //printf("ClientInfo->request=<B>%s</B><BR>\n",ClientInfo->request); | ||
1067 | //readfile=__ILWS_malloc(strlen(ClientInfo->request)+1); | ||
1068 | readfile=ClientInfo->request; | ||
1069 | while((tmp=strstr(readfile,"./"))) { // this skip ../ also | ||
1070 | readfile=tmp+1; | ||
1071 | }; | ||
1072 | while((tmp=strstr(readfile,"//"))) { | ||
1073 | readfile=tmp+1; | ||
1074 | }; | ||
1075 | |||
1076 | tmp=strstr(readfile,"/"); | ||
1077 | if(tmp!=NULL) { | ||
1078 | readfile=tmp+1; // must be in the first | ||
1079 | }; | ||
1080 | // skip beind dir | ||
1081 | if(strlen(readfile)) { | ||
1082 | filepath=__ILWS_malloc(strlen(inpath)+strlen(readfile)+3); | ||
1083 | snprintf(filepath,strlen(inpath)+strlen(readfile)+2,"%s%s%s",inpath,(inpath[strlen(inpath)-1]=='/')?"":"/",readfile); | ||
1084 | //printf("pum ->%s<BR>\n",filepath); | ||
1085 | if(readfile[strlen(readfile)-1]=='/') { | ||
1086 | dirpath=__ILWS_malloc(strlen(filepath)+1); | ||
1087 | memcpy(dirpath,filepath,strlen(filepath)+1); // the 0 included | ||
1088 | } else { | ||
1089 | if(!stat(filepath,&cfstat)) { // file must exist | ||
1090 | if((cfstat.st_mode & S_IFDIR) != S_IFDIR) { | ||
1091 | // search for mime | ||
1092 | ext=strrchr(filepath,'.'); | ||
1093 | tmp=strrchr(filepath,'/'); | ||
1094 | ext+=1; | ||
1095 | if(ext<=tmp) { // is not a extension | ||
1096 | ext=NULL; | ||
1097 | }; | ||
1098 | |||
1099 | //Wed, 22 Oct 2003 16:04:04 GMT | ||
1100 | 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 | ||
1101 | web_client_contenttype(ext); | ||
1102 | web_client_addfile(filepath); // fopen and write, maybe? | ||
1103 | __ILWS_free(filepath); | ||
1104 | return 1; | ||
1105 | } else { | ||
1106 | web_client_HTTPdirective("HTTP/1.1 404 File Not Found"); | ||
1107 | 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); | ||
1108 | __ILWS_free(filepath); | ||
1109 | return 0; | ||
1110 | }; | ||
1111 | }else { | ||
1112 | web_client_HTTPdirective("HTTP/1.1 404 File Not Found"); | ||
1113 | 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); | ||
1114 | __ILWS_free(filepath); | ||
1115 | return 0; | ||
1116 | }; | ||
1117 | }; | ||
1118 | __ILWS_free(filepath); | ||
1119 | }; | ||
1120 | //printf("Content-type: text/html\r\n\r\n"); | ||
1121 | //fprintf(stderr,"dirpath=%s inpath=%s\n",dirpath,inpath); | ||
1122 | if(dirpath==NULL) { | ||
1123 | dirpath=__ILWS_malloc(strlen(inpath)+1); | ||
1124 | memcpy(dirpath,inpath,strlen(inpath)+1); | ||
1125 | }; | ||
1126 | cd=opendir(dirpath); | ||
1127 | if(cd!=NULL) { | ||
1128 | printf("Content-type: text/html\r\n\r\n"); | ||
1129 | printf("<HTML><HEAD><TITLE>Contents of %s</TITLE></HEAD><BODY>\n",dirpath); | ||
1130 | printf("<h1>Contents of directory %s</h1><HR>\n",dirpath); | ||
1131 | 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"):"*"); | ||
1132 | printf("<PRE>\n"); | ||
1133 | while((dire=readdir(cd))) { | ||
1134 | if( ((dire->d_name[0]!='.') || (strcmp(dirpath,inpath) && !strcmp(dire->d_name,".."))) && (!fnmatch(ClientInfo->Query("match"),dire->d_name,0) || !strlen(ClientInfo->Query("match"))) ) { | ||
1135 | filepath=__ILWS_malloc(strlen(dirpath)+strlen(dire->d_name)+2); | ||
1136 | snprintf(filepath,strlen(dirpath)+strlen(dire->d_name)+2,"%s%s%s",dirpath,(dirpath[strlen(dirpath)-1]=='/')?"":"/",dire->d_name); | ||
1137 | //fprintf(stderr,"filename=%s\n",filepath); | ||
1138 | if(!stat(filepath,&cfstat)) { | ||
1139 | if((cfstat.st_mode & S_IFDIR) == S_IFDIR) { | ||
1140 | 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); | ||
1141 | }else { | ||
1142 | filesize=(float)cfstat.st_size; | ||
1143 | filesizeu=0; | ||
1144 | while(filesize>1024) { | ||
1145 | filesize/=1024; | ||
1146 | filesizeu++; | ||
1147 | }; | ||
1148 | 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); | ||
1149 | }; | ||
1150 | }; | ||
1151 | __ILWS_free(filepath); | ||
1152 | }; | ||
1153 | |||
1154 | }; | ||
1155 | printf("</PRE>\n"); | ||
1156 | printf("<HR>\n"); | ||
1157 | printf("<address>%s</address>\n",_libwebserver_version); | ||
1158 | printf("</BODY></HTML>\r\n"); | ||
1159 | __ILWS_free(dirpath); | ||
1160 | closedir(cd); | ||
1161 | } else { | ||
1162 | web_client_HTTPdirective("HTTP/1.1 404 File Not Found"); | ||
1163 | 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); | ||
1164 | return 0; | ||
1165 | }; | ||
1166 | return 1; | ||
1167 | }; | ||
1168 | |||
1169 | |||
1170 | |||
1171 | |||
diff --git a/src/client.h b/src/client.h deleted file mode 100644 index 6217b271..00000000 --- a/src/client.h +++ /dev/null | |||
@@ -1,139 +0,0 @@ | |||
1 | /* Copyrights 2002 Luis Figueiredo (stdio@netc.pt) All rights reserved. | ||
2 | * | ||
3 | * See the LICENSE file | ||
4 | * | ||
5 | * The origin of this software must not be misrepresented, either by | ||
6 | * explicit claim or by omission. Since few users ever read sources, | ||
7 | * credits must appear in the documentation. | ||
8 | * | ||
9 | * date: Sat Mar 30 14:44:42 GMT 2002 | ||
10 | * | ||
11 | * | ||
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 | #include "socket.h" | ||
29 | #include "memory.h" | ||
30 | #include "utils.h" | ||
31 | #include "fnmatch.h" | ||
32 | #include "clientinfo.h" | ||
33 | |||
34 | #ifdef WIN32 | ||
35 | #include "flock.h" // my flock | ||
36 | #include "dirent.h" | ||
37 | #else | ||
38 | #include <sys/file.h> // for flock | ||
39 | #include <dirent.h> | ||
40 | #endif | ||
41 | |||
42 | struct gethandler { | ||
43 | char * str; | ||
44 | void (*func)(); | ||
45 | void * ctx; | ||
46 | struct gethandler * next; | ||
47 | }; | ||
48 | |||
49 | |||
50 | |||
51 | #define READMAX 100000 // 1Mb upload | ||
52 | |||
53 | #define WRITEMAX 100000 // 1Mb download 1mb per client? // smaller is better for multi read bigger is better for big downloads | ||
54 | |||
55 | #define MAXURLSIZE 2000 // | ||
56 | |||
57 | extern int WEBTIMEOUT; //to be changed externaly | ||
58 | //#define WEBTIMEOUT 10000 // TIMEOUT WITHOUT RECEIVING DATA (not in seconds but in read tries) | ||
59 | |||
60 | struct web_var { | ||
61 | char *name; | ||
62 | char *value; | ||
63 | struct web_var *next; | ||
64 | }; | ||
65 | |||
66 | struct web_client { | ||
67 | int socket; | ||
68 | struct sockaddr_in sa; | ||
69 | unsigned int salen; | ||
70 | char *HTTPdirective; | ||
71 | unsigned char stat; /* 0001b idle,0010b down streaming, 0011 done down streaming, 0100b out streaming,0101 done out streaming */ | ||
72 | // Read control | ||
73 | char *rbuf; | ||
74 | unsigned long rbufsize; | ||
75 | int newdata_try; | ||
76 | unsigned long contentlength; // for read propose (optimize speed 0.5.1) | ||
77 | unsigned long headersize; | ||
78 | |||
79 | // Write control | ||
80 | struct outstream *outstream; | ||
81 | struct web_var *varlist; | ||
82 | char *cookies; // cookie header (0.5.1) | ||
83 | long writelength; | ||
84 | long readsize; | ||
85 | long range; | ||
86 | int skipped; | ||
87 | long wheadersize; | ||
88 | struct web_client * next; | ||
89 | }; | ||
90 | |||
91 | struct web_client *__ILWS_init_client_list(void); | ||
92 | |||
93 | int __ILWS_add_client(struct web_client *, | ||
94 | struct web_client *); | ||
95 | |||
96 | void __ILWS_delete_next_client(struct web_client *); | ||
97 | |||
98 | void __ILWS_delete_client_list(struct web_client *); | ||
99 | |||
100 | void __ILWS_read_client(struct web_client *); | ||
101 | |||
102 | void __ILWS_process_client(struct web_client *,struct gethandler *); | ||
103 | |||
104 | void __ILWS_output_client(struct web_client *); | ||
105 | |||
106 | void __ILWS_web_client_writef(struct web_client *,const char *,...); | ||
107 | |||
108 | int web_client_addfile(char *); | ||
109 | |||
110 | void web_client_contenttype(char *); // new on 0.5.2 | ||
111 | |||
112 | void web_client_HTTPdirective(char *); | ||
113 | |||
114 | char *__ILWS_web_client_getreqline(); | ||
115 | |||
116 | char *__ILWS_web_client_getreq(); | ||
117 | |||
118 | // new (0.5.1) | ||
119 | int web_client_setvar(char *,char *); | ||
120 | |||
121 | char *web_client_getvar(char *); | ||
122 | |||
123 | int web_client_delvar(char *); | ||
124 | |||
125 | // put in var.h | ||
126 | struct web_var *__ILWS_init_var_list(); | ||
127 | |||
128 | int __ILWS_add_var(struct web_var *, char *, char *); | ||
129 | |||
130 | int __ILWS_del_var(struct web_var *, char *); | ||
131 | |||
132 | void __ILWS_delete_var_list(struct web_var *); | ||
133 | |||
134 | char *__ILWS_get_var(struct web_var *list , char *name); | ||
135 | |||
136 | int __ILWS_lws_list(char *); // new on 0.5.2 | ||
137 | |||
138 | #endif | ||
139 | |||
diff --git a/src/clientinfo.c b/src/clientinfo.c deleted file mode 100644 index 0aa5e3b5..00000000 --- a/src/clientinfo.c +++ /dev/null | |||
@@ -1,893 +0,0 @@ | |||
1 | /* Copyrights 2002 Luis Figueiredo (stdio@netc.pt) All rights reserved. | ||
2 | * | ||
3 | * See the LICENSE file | ||
4 | * | ||
5 | * The origin of this software must not be misrepresented, either by | ||
6 | * explicit claim or by omission. Since few users ever read sources, | ||
7 | * credits must appear in the documentation. | ||
8 | * | ||
9 | * date: 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 | /* | ||
19 | * Initialize ClientInfo structure | ||
20 | */ | ||
21 | void __ILWS_init_clientinfo(struct ClientInfo *ClientInfo) { | ||
22 | char *t; | ||
23 | struct outstream *tstream=current_web_client->outstream; | ||
24 | |||
25 | ClientInfo=__ILWS_malloc(sizeof(struct ClientInfo)); | ||
26 | if(ClientInfo==NULL) { | ||
27 | return; | ||
28 | }; | ||
29 | |||
30 | while(tstream->next!=NULL) { | ||
31 | tstream=tstream->next; | ||
32 | }; | ||
33 | |||
34 | if(tstream->fstream!=NULL) ClientInfo->outfd=fileno(tstream->fstream); //take it off? | ||
35 | |||
36 | ClientInfo->mem=__ILWS_init_buffer_list(); // First thing, other fuctions use this to allocate | ||
37 | |||
38 | |||
39 | ClientInfo->request=__ILWS_clientinfo_getreqname(); | ||
40 | |||
41 | ClientInfo->inetname=NULL; | ||
42 | t=inet_ntoa(current_web_client->sa.sin_addr); | ||
43 | if((ClientInfo->inetname=__ILWS_add_buffer(ClientInfo->mem,strlen(t)+1))) { | ||
44 | memcpy(ClientInfo->inetname,t,strlen(t)); | ||
45 | ClientInfo->inetname[strlen(t)]='\0'; | ||
46 | }; | ||
47 | |||
48 | ClientInfo->method=__ILWS_clientinfo_getmethod(); | ||
49 | ClientInfo->user=__ILWS_clientinfo_getauthuser(); | ||
50 | ClientInfo->pass=__ILWS_clientinfo_getauthpass(); | ||
51 | |||
52 | |||
53 | |||
54 | /* Initialize List's */ | ||
55 | ClientInfo->HeaderList=NULL; | ||
56 | ClientInfo->QueryList=NULL; | ||
57 | ClientInfo->PostList=NULL; | ||
58 | ClientInfo->MultiPartList=NULL; | ||
59 | ClientInfo->CookieList=NULL; | ||
60 | |||
61 | ClientInfo->Header=__ILWS_Header; | ||
62 | ClientInfo->Query=__ILWS_Query; | ||
63 | ClientInfo->QueryString=__ILWS_clientinfo_getquerystring(); | ||
64 | ClientInfo->Post=__ILWS_Post; | ||
65 | ClientInfo->PostData=__ILWS_clientinfo_getpostdata(); | ||
66 | ClientInfo->MultiPart=__ILWS_MultiPart; | ||
67 | ClientInfo->Cookie=__ILWS_Cookie; | ||
68 | ClientInfo->Conf=__ILWS_Conf; | ||
69 | ClientInfo->CookieString=__ILWS_Header("Cookie"); | ||
70 | |||
71 | } | ||
72 | |||
73 | /* | ||
74 | * Free ClientInfo structure | ||
75 | */ | ||
76 | void __ILWS_free_clientinfo(struct ClientInfo *ClientInfo) { | ||
77 | if(ClientInfo==NULL) { | ||
78 | return; | ||
79 | }; | ||
80 | __ILWS_delete_buffer_list(ClientInfo->mem); | ||
81 | |||
82 | __ILWS_free(ClientInfo); | ||
83 | ClientInfo=NULL; | ||
84 | } | ||
85 | |||
86 | |||
87 | /* | ||
88 | * Header function for ClientInfo->Header("x") | ||
89 | */ | ||
90 | char *__ILWS_Header(struct ClientInfo *ClientInfo, char *str) { | ||
91 | char *tmp1,*tmp2,*tmp3,*ret; | ||
92 | struct _Header *hl=ClientInfo->HeaderList; | ||
93 | char *defret=""; | ||
94 | size_t size; | ||
95 | size_t strsize; | ||
96 | if(str==NULL) { // request is null return whole header | ||
97 | return current_web_client->rbuf; | ||
98 | }; | ||
99 | if(ClientInfo->HeaderList==NULL) { | ||
100 | |||
101 | ClientInfo->HeaderList=__ILWS_add_buffer(ClientInfo->mem,sizeof(struct _Header)); | ||
102 | if(ClientInfo->HeaderList==NULL) { | ||
103 | return defret; | ||
104 | }; | ||
105 | ClientInfo->HeaderList->next=NULL; | ||
106 | ClientInfo->HeaderList->data=NULL; | ||
107 | ClientInfo->HeaderList->id=NULL; | ||
108 | hl=ClientInfo->HeaderList; | ||
109 | }; | ||
110 | // First search if exists | ||
111 | |||
112 | while(hl->next!=NULL) { | ||
113 | if(hl->next->id!=NULL) { | ||
114 | if(!strcmp(hl->next->id,str)) { | ||
115 | |||
116 | return hl->next->data; | ||
117 | }; | ||
118 | }; | ||
119 | hl=hl->next; | ||
120 | }; | ||
121 | |||
122 | /* Doesn't exists */ | ||
123 | strsize=strlen(str); | ||
124 | if(!(hl->next=__ILWS_add_buffer(ClientInfo->mem,sizeof(struct _Header)))) { | ||
125 | return defret; | ||
126 | }; | ||
127 | if(!(hl->next->id=__ILWS_add_buffer(ClientInfo->mem,strsize+1))) { | ||
128 | return defret; | ||
129 | }; | ||
130 | |||
131 | memcpy(hl->next->id,str,strsize); | ||
132 | hl->next->id[strsize]=0; | ||
133 | hl->next->data=defret; | ||
134 | hl->next->next=NULL; | ||
135 | |||
136 | if(!(tmp3=__ILWS_malloc(strsize+3))) { | ||
137 | return defret; | ||
138 | }; | ||
139 | snprintf(tmp3,strsize+3,"%s: ",str); | ||
140 | tmp1=__ILWS_stristr(current_web_client->rbuf,tmp3); | ||
141 | __ILWS_free(tmp3); | ||
142 | if(tmp1==NULL) { | ||
143 | return defret; | ||
144 | }; | ||
145 | |||
146 | tmp1+=strsize+2; | ||
147 | if(!(tmp2=strstr(tmp1,"\r\n"))) { // Unexpected (security anyway) | ||
148 | return defret; | ||
149 | }; | ||
150 | if((size=(unsigned int)(tmp2-tmp1))<0) { | ||
151 | return defret; | ||
152 | }; | ||
153 | if(!(ret=__ILWS_add_buffer(ClientInfo->mem,size+1))) { //malloc & register | ||
154 | return defret; | ||
155 | }; | ||
156 | memcpy(ret,tmp1,size); | ||
157 | ret[size]=0; | ||
158 | hl->next->data=ret; | ||
159 | return ret; | ||
160 | } | ||
161 | |||
162 | /* | ||
163 | * Function for Querydata | ||
164 | */ | ||
165 | char *__ILWS_Query(struct ClientInfo *ClientInfo, char *handle) { | ||
166 | char *tmp1,*tmp2,*tmp3,*tmp4,*ret; | ||
167 | char *defret=""; | ||
168 | size_t strsize; | ||
169 | size_t size; | ||
170 | int j=0,ch; | ||
171 | int seek=1; | ||
172 | unsigned int i; | ||
173 | unsigned int *iddb=NULL; | ||
174 | unsigned int *iddb2=NULL; | ||
175 | unsigned int idf=0; | ||
176 | int rw=0; // 0 data 1 number of vars; (return what?) | ||
177 | struct _Query *ql=ClientInfo->QueryList; | ||
178 | |||
179 | |||
180 | if(handle==NULL) { | ||
181 | return ClientInfo->QueryString; | ||
182 | }; | ||
183 | if(handle[0]=='#') rw=1; | ||
184 | // allocate first node from the list | ||
185 | if(ClientInfo->QueryList==NULL) { | ||
186 | ClientInfo->QueryList=__ILWS_add_buffer(ClientInfo->mem,sizeof(struct _Query)); | ||
187 | if(ClientInfo->QueryList==NULL) { | ||
188 | if(rw) return 0; | ||
189 | return defret; | ||
190 | }; | ||
191 | ClientInfo->QueryList->next=NULL; | ||
192 | ClientInfo->QueryList->data=NULL; | ||
193 | ClientInfo->QueryList->id=NULL; | ||
194 | ql=ClientInfo->QueryList; | ||
195 | }; | ||
196 | // done allocating | ||
197 | |||
198 | |||
199 | // First search if exists and fetch values; | ||
200 | |||
201 | idf=1; | ||
202 | iddb=&idf; | ||
203 | seek=1; | ||
204 | |||
205 | while(ql->next!=NULL) { | ||
206 | if(ql->next->id!=NULL) { | ||
207 | if(!strcmp(ql->next->id,handle+rw) && *iddb >= 0) { | ||
208 | if(seek==1) { | ||
209 | iddb=&ql->next->index; // atribute iddb to first node | ||
210 | iddb2=&ql->next->idf; // atribute iddb2 to counting | ||
211 | if(rw) return (char *)*iddb2; | ||
212 | if(ql->next->idf==1) { | ||
213 | return ql->next->data; | ||
214 | }; | ||
215 | j=*iddb; | ||
216 | seek++; | ||
217 | }; | ||
218 | *iddb=*iddb-1; | ||
219 | |||
220 | if(*iddb<=0) { | ||
221 | *iddb=j-1; | ||
222 | if(j<=1) { | ||
223 | *iddb=*iddb2; // go to start if any | ||
224 | //return defret; // to be null | ||
225 | }; | ||
226 | return ql->next->data; // Return existent | ||
227 | }; | ||
228 | |||
229 | }; | ||
230 | }; | ||
231 | ql=ql->next; | ||
232 | }; | ||
233 | |||
234 | |||
235 | |||
236 | /* Doesn't exists */ | ||
237 | strsize=strlen(handle+rw); | ||
238 | tmp1=strstr(current_web_client->rbuf,"?"); | ||
239 | tmp3=strstr(current_web_client->rbuf," HTTP"); // End of GET header | ||
240 | if(tmp1!=NULL && tmp1<tmp3) { | ||
241 | tmp1+=1; | ||
242 | } else { | ||
243 | if(rw)return 0; | ||
244 | return defret; | ||
245 | } | ||
246 | |||
247 | // Working here | ||
248 | idf=0; | ||
249 | ret=defret; | ||
250 | seek=1; | ||
251 | tmp4=tmp1; | ||
252 | while(seek==1) { | ||
253 | tmp1=tmp4; | ||
254 | do { | ||
255 | tmp2=strstr(tmp1,handle+rw); | ||
256 | if(tmp2==NULL) { // must be nonnull | ||
257 | if(iddb!=NULL && iddb2!=NULL) { // if iddb2 is null then is just one value; | ||
258 | *iddb2=*iddb; | ||
259 | if(!rw)*iddb=*iddb-1; | ||
260 | }; | ||
261 | if(rw) { | ||
262 | if(ret==defret) return 0; | ||
263 | return (char *)*iddb2; | ||
264 | } | ||
265 | return ret; // if first null return defret (ret=defret); | ||
266 | |||
267 | }; | ||
268 | tmp1=tmp2+strsize; | ||
269 | } while ((tmp2[-1]!='?' && tmp2[-1]!='&') || tmp2[strsize]!='='); // Johannes E. Schindelin Fix | ||
270 | |||
271 | if(tmp3<tmp2) { | ||
272 | if(iddb!=NULL && iddb2!=NULL) { | ||
273 | *iddb2=*iddb; | ||
274 | if(!rw)*iddb=*iddb-1; | ||
275 | }; | ||
276 | if(rw) { | ||
277 | if(ret==defret) return 0; | ||
278 | return (char *)*iddb2; | ||
279 | } | ||
280 | |||
281 | return ret; | ||
282 | }; | ||
283 | |||
284 | tmp4=tmp1; | ||
285 | // if not null, so add an node; | ||
286 | |||
287 | // Working here ^ | ||
288 | ql->next=__ILWS_add_buffer(ClientInfo->mem,sizeof(struct _Query)); | ||
289 | if(ql->next==NULL) { | ||
290 | if(handle[0]=='#') rw=1; | ||
291 | return defret; | ||
292 | }; | ||
293 | ql->next->id=__ILWS_add_buffer(ClientInfo->mem,strsize+1); | ||
294 | if(ql->next->id==NULL) { | ||
295 | if(handle[0]=='#') rw=1; | ||
296 | return defret; | ||
297 | }; | ||
298 | memcpy(ql->next->id,handle+rw,strsize); | ||
299 | ql->next->id[strsize]=0; | ||
300 | if(idf==0) { | ||
301 | ql->next->index=0; | ||
302 | iddb=&ql->next->index; | ||
303 | iddb2=&ql->next->idf; // second holds information about number of fetchs; | ||
304 | |||
305 | }; | ||
306 | ql->next->data=defret; | ||
307 | ql->next->next=NULL; | ||
308 | |||
309 | |||
310 | tmp1=strstr(tmp2,"&"); // tmp1 goes to next '&' | ||
311 | tmp2+=strsize+1; // tmp2 goes to start of data | ||
312 | tmp3=strstr(tmp2," HTTP"); // tmp3 goes to the end of Get header | ||
313 | if(tmp1==NULL || ((unsigned int)tmp1>(unsigned int)tmp3)) { | ||
314 | size=tmp3-tmp2; // MUST HAVE (" HTTP") else, server don't let in | ||
315 | } else { | ||
316 | size=tmp1-tmp2; | ||
317 | }; | ||
318 | if(size<1) { | ||
319 | if(handle[0]=='#') rw=1; | ||
320 | return defret; | ||
321 | }; | ||
322 | |||
323 | |||
324 | ql->next->data=__ILWS_add_buffer(ClientInfo->mem,size+1); | ||
325 | if(ql->next->data==NULL) { | ||
326 | if(handle[0]=='#') rw=1; | ||
327 | return defret; | ||
328 | }; | ||
329 | j=0; | ||
330 | for(i=0;i<size;i++) { // Hex translation here | ||
331 | switch (ch=tmp2[j]) { | ||
332 | case '+': | ||
333 | ch=' '; | ||
334 | break; | ||
335 | case '%': | ||
336 | |||
337 | tmp1=__ILWS_malloc(3); | ||
338 | if(tmp1==NULL) { | ||
339 | if(rw) return 0; | ||
340 | return defret; | ||
341 | }; | ||
342 | strncpy(tmp1,&tmp2[j+1],2); | ||
343 | tmp1[2]=0; | ||
344 | ch=strtol(tmp1,NULL,16); | ||
345 | j+=2; | ||
346 | size-=2; | ||
347 | |||
348 | __ILWS_free(tmp1); | ||
349 | break; | ||
350 | }; | ||
351 | ql->next->data[i]=ch; | ||
352 | j++; | ||
353 | }; | ||
354 | ql->next->data[size]='\0'; | ||
355 | ret=ql->next->data; // to the last | ||
356 | ql=ql->next; | ||
357 | *iddb=*iddb+1; | ||
358 | idf++; | ||
359 | }; | ||
360 | return ret; | ||
361 | } | ||
362 | |||
363 | /* | ||
364 | * Function for Postdata | ||
365 | */ | ||
366 | char *__ILWS_Post(struct ClientInfo *ClientInfo, char *handle) { | ||
367 | char *tmp1,*tmp2,*tmp3,*ret; | ||
368 | struct _Post *pl=ClientInfo->PostList; | ||
369 | char *defret=""; | ||
370 | int *iddb=NULL,*iddb2=NULL; | ||
371 | int idf; | ||
372 | int seek=1; | ||
373 | size_t strsize; | ||
374 | size_t size; | ||
375 | int j=0,ch; | ||
376 | unsigned int i; | ||
377 | int rw=0; //return what; | ||
378 | |||
379 | tmp1=strstr(current_web_client->rbuf,"Content-type: multipart/form-data"); // multipart this post doesn't work | ||
380 | if(tmp1!=NULL) { | ||
381 | return ClientInfo->MultiPart(handle).data; | ||
382 | }; | ||
383 | if(handle==NULL) { | ||
384 | return ClientInfo->PostData; | ||
385 | }; | ||
386 | if(handle[0]=='#')rw=1; | ||
387 | /* Allocate the list */ | ||
388 | if(ClientInfo->PostList==NULL) { | ||
389 | if(!(ClientInfo->PostList=__ILWS_add_buffer(ClientInfo->mem,sizeof(struct _Post)))) { | ||
390 | if(rw) return 0; | ||
391 | return defret; | ||
392 | }; | ||
393 | ClientInfo->PostList->next=NULL; | ||
394 | ClientInfo->PostList->data=NULL; | ||
395 | ClientInfo->PostList->id=NULL; | ||
396 | pl=ClientInfo->PostList; | ||
397 | }; | ||
398 | |||
399 | // First search if exists | ||
400 | idf=1; | ||
401 | iddb=&idf; | ||
402 | seek=1; | ||
403 | while(pl->next!=NULL) { | ||
404 | if(pl->next->id!=NULL) { | ||
405 | if(!strcmp(pl->next->id,handle+rw) && iddb>=0) { | ||
406 | if(seek==1) { | ||
407 | iddb=&pl->next->index; | ||
408 | iddb2=&pl->next->idf; | ||
409 | if(rw) return (char *)(*iddb2); | ||
410 | if(pl->next->idf==1) { | ||
411 | return pl->next->data; | ||
412 | }; | ||
413 | j=*iddb; | ||
414 | seek++; | ||
415 | }; | ||
416 | *iddb=*iddb-1; | ||
417 | |||
418 | if(*iddb<=0) { | ||
419 | *iddb=j-1; | ||
420 | if(j<=1) { | ||
421 | *iddb=*iddb2; | ||
422 | |||
423 | //return defret; | ||
424 | }; | ||
425 | return pl->next->data; | ||
426 | }; | ||
427 | }; | ||
428 | }; | ||
429 | pl=pl->next; | ||
430 | }; | ||
431 | |||
432 | |||
433 | |||
434 | |||
435 | |||
436 | /* Doesn't exists */ | ||
437 | strsize=strlen(handle+rw); | ||
438 | tmp1=strstr(current_web_client->rbuf,"\r\n\r\n"); | ||
439 | if(tmp1!=NULL) | ||
440 | tmp1+=4; | ||
441 | else { | ||
442 | if(rw) return 0; | ||
443 | return defret; | ||
444 | }; | ||
445 | idf=0; | ||
446 | ret=defret; | ||
447 | seek=1; | ||
448 | tmp3=tmp1; | ||
449 | while(seek==1) { | ||
450 | tmp1=tmp3; | ||
451 | do { | ||
452 | tmp2=strstr(tmp1,handle+rw); | ||
453 | if(tmp2==NULL) { // mustn't be null | ||
454 | if(iddb!=NULL && iddb2!=NULL) { // if iddb2 is null then is just one value; | ||
455 | *iddb2=*iddb; | ||
456 | if(!rw)*iddb=*iddb-1; | ||
457 | }; | ||
458 | if(rw) { | ||
459 | if(ret==defret) return 0; | ||
460 | return (char *)*iddb2; | ||
461 | } | ||
462 | return ret; // if first null return defret (ret=defret); | ||
463 | |||
464 | }; | ||
465 | tmp1=tmp2+strsize; | ||
466 | } while ((tmp2[-1]!='\n' && tmp2[-1]!='&') || tmp2[strsize]!='='); // Johannes E. Schindelin Fix | ||
467 | tmp3=tmp1; | ||
468 | |||
469 | |||
470 | pl->next=__ILWS_add_buffer(ClientInfo->mem,sizeof(struct _Post)); | ||
471 | if(pl->next==NULL) { | ||
472 | if(rw) return 0; | ||
473 | return defret; | ||
474 | }; | ||
475 | pl->next->id=__ILWS_add_buffer(ClientInfo->mem,strsize+1); | ||
476 | if(pl->next->id==NULL) { | ||
477 | if(rw) return 0; | ||
478 | return defret; | ||
479 | }; | ||
480 | memcpy(pl->next->id,handle+rw,strsize); | ||
481 | pl->next->id[strsize]=0; | ||
482 | if(idf==0) { | ||
483 | pl->next->index=0; | ||
484 | iddb=&pl->next->index; | ||
485 | iddb2=&pl->next->idf; | ||
486 | }; | ||
487 | |||
488 | pl->next->data=defret; | ||
489 | pl->next->next=NULL; | ||
490 | |||
491 | tmp1=strstr(tmp2,"&"); // goes to the next & (end of data) | ||
492 | tmp2+=strsize+1; // tmp2 goes to start of data | ||
493 | if(tmp1==NULL) { | ||
494 | size=strlen(tmp2); | ||
495 | } else { | ||
496 | size=tmp1-tmp2; | ||
497 | }; | ||
498 | if(size==0) { | ||
499 | if(rw) return 0; | ||
500 | return defret; | ||
501 | }; | ||
502 | |||
503 | pl->next->data=__ILWS_add_buffer(ClientInfo->mem,size+1); | ||
504 | if(pl->next->data==NULL) { | ||
505 | return defret; | ||
506 | }; | ||
507 | j=0; | ||
508 | for(i=0;i<size;i++) { // hex translation here | ||
509 | switch (ch=tmp2[j]) { | ||
510 | case '+': | ||
511 | ch=' '; | ||
512 | break; | ||
513 | case '%': | ||
514 | |||
515 | tmp1=__ILWS_malloc(3); | ||
516 | if(tmp1==NULL) { | ||
517 | if(rw) return 0; | ||
518 | return defret; | ||
519 | }; | ||
520 | strncpy(tmp1,&tmp2[j+1],2); | ||
521 | tmp1[2]=0; | ||
522 | |||
523 | ch=strtol(tmp1,NULL,16); | ||
524 | j+=2; | ||
525 | size-=2; | ||
526 | |||
527 | __ILWS_free(tmp1); | ||
528 | break; | ||
529 | }; | ||
530 | pl->next->data[i]=ch; | ||
531 | j++; | ||
532 | }; | ||
533 | pl->next->data[size]='\0'; | ||
534 | ret=pl->next->data; // to the last | ||
535 | *iddb=*iddb+1; | ||
536 | idf++; | ||
537 | pl=pl->next; | ||
538 | //pl->next->data=ret; | ||
539 | }; | ||
540 | return ret; | ||
541 | } | ||
542 | |||
543 | /* | ||
544 | * Function for MultiPart formdata | ||
545 | */ | ||
546 | struct _MultiPart __ILWS_MultiPart(struct ClientInfo *ClientInfo, char *handle) { | ||
547 | char *tmp1,*tmp2,*tmp3; | ||
548 | int i; | ||
549 | char *name; | ||
550 | size_t namesize; | ||
551 | struct _MultiPart *ml=ClientInfo->MultiPartList; | ||
552 | struct _MultiPart defret={"","",0,""}; | ||
553 | size_t strsize; | ||
554 | char *boundary; size_t boundarysize; | ||
555 | // IE C43o6Fn6Et74e65n6Et74-2DT54y79p70e65:3A 20m6Du75l6Ct74i69p70a61r72t74/2Ff66o6Fr72m6D-2Dd64a61t74a61 | ||
556 | // NS C43o6Fn6Et74e65n6Et74-2Dt74y79p70e65:3A 20m6Du75l6Ct74i69p70a61r72t74/2Ff66o6Fr72m6D-2Dd64a61t74a61 | ||
557 | tmp1=__ILWS_stristr(current_web_client->rbuf,"Content-type: multipart/form-data"); | ||
558 | if(tmp1==NULL) return defret; | ||
559 | if(ClientInfo->MultiPartList==NULL) { | ||
560 | ClientInfo->MultiPartList=__ILWS_add_buffer(ClientInfo->mem,sizeof(struct _MultiPart)); | ||
561 | if(ClientInfo->MultiPartList==NULL) { | ||
562 | return defret; | ||
563 | }; | ||
564 | ClientInfo->MultiPartList->next=NULL; | ||
565 | ClientInfo->MultiPartList->id=NULL; | ||
566 | ClientInfo->MultiPartList->data=NULL; | ||
567 | ClientInfo->MultiPartList->filename=NULL; | ||
568 | ClientInfo->MultiPartList->size=0; | ||
569 | ml=ClientInfo->MultiPartList; | ||
570 | }; | ||
571 | // Check if handle exists | ||
572 | while(ml->next!=NULL) { | ||
573 | if(ml->next->id!=NULL) { | ||
574 | if(!strcmp(ml->next->id,handle)) { | ||
575 | |||
576 | return *ml->next; | ||
577 | }; | ||
578 | }; | ||
579 | ml=ml->next; | ||
580 | }; | ||
581 | |||
582 | |||
583 | strsize=strlen(handle); | ||
584 | ml->next=__ILWS_add_buffer(ClientInfo->mem,sizeof(struct _MultiPart)); | ||
585 | if(ml->next==NULL) { | ||
586 | return defret; | ||
587 | }; | ||
588 | ml->next->id=__ILWS_add_buffer(ClientInfo->mem,strsize+1); | ||
589 | if(ml->next->id==NULL) { | ||
590 | return defret; | ||
591 | }; | ||
592 | memcpy(ml->next->id,handle,strsize); | ||
593 | ml->next->id[strsize]=0; | ||
594 | ml->next->data=""; | ||
595 | ml->next->filename=""; | ||
596 | ml->next->size=0; | ||
597 | ml->next->next=NULL; | ||
598 | |||
599 | tmp1=strstr(tmp1,"boundary="); | ||
600 | if(tmp1==NULL) return defret; | ||
601 | tmp1+=9; | ||
602 | tmp2=strstr(tmp1,"\r\n"); | ||
603 | if(tmp2<tmp1 || tmp2==NULL) return defret; | ||
604 | /* boundary */ | ||
605 | boundarysize=tmp2-tmp1; | ||
606 | boundary=__ILWS_add_buffer(ClientInfo->mem,boundarysize+3); | ||
607 | if(boundary==NULL) { | ||
608 | return defret; | ||
609 | }; | ||
610 | memcpy(boundary,tmp1,boundarysize); | ||
611 | boundary[boundarysize]=0; | ||
612 | |||
613 | |||
614 | /* handle */ | ||
615 | namesize=boundarysize+41+strlen(handle); | ||
616 | name=__ILWS_add_buffer(ClientInfo->mem,namesize+1); | ||
617 | if(name==NULL) { | ||
618 | return defret; | ||
619 | }; | ||
620 | snprintf(name,namesize,"%s\r\nContent-Disposition: form-data; name=",boundary); | ||
621 | namesize=strlen(name); | ||
622 | |||
623 | tmp1=strstr(tmp1,"\r\n\r\n"); // go to data | ||
624 | if(tmp1==NULL) return defret; | ||
625 | |||
626 | do { | ||
627 | i=memcmp(tmp1,name,namesize); | ||
628 | if(i==0) { | ||
629 | tmp1+=namesize; | ||
630 | if(tmp1[0]=='\"')tmp1+=1; | ||
631 | if(strncmp(tmp1,handle,strlen(handle))){ | ||
632 | i=1; | ||
633 | }else { | ||
634 | if((tmp1[strsize]!=' ') && (tmp1[strsize]!='\"') && (tmp1[strsize]!='\r') && (tmp1[strsize]!=';') ) i=1; | ||
635 | }; | ||
636 | |||
637 | }else { | ||
638 | tmp1+=1; | ||
639 | }; | ||
640 | } while(i!=0 && (tmp1+namesize<current_web_client->rbuf+current_web_client->rbufsize)); // Search init of data | ||
641 | if(i!=0) return defret; | ||
642 | //tmp1+=namesize; | ||
643 | tmp2=strstr(tmp1,"filename="); // get filename | ||
644 | if(tmp2!=NULL) { | ||
645 | tmp2+=9; | ||
646 | if(tmp2[0]=='\"')tmp2+=1; | ||
647 | tmp3=strstr(tmp2,"\r\n"); | ||
648 | ml->next->filename=__ILWS_add_buffer(ClientInfo->mem,(tmp3-tmp2)+1); | ||
649 | if(ml->next->filename==NULL) { | ||
650 | return defret; | ||
651 | }; | ||
652 | memcpy(ml->next->filename,tmp2,tmp3-tmp2); | ||
653 | ml->next->filename[tmp3-tmp2]='\0'; | ||
654 | if(ml->next->filename[tmp3-tmp2-1]=='\"') | ||
655 | ml->next->filename[tmp3-tmp2-1]='\0'; | ||
656 | |||
657 | }; | ||
658 | tmp2=strstr(tmp1,"\r\n\r\n"); // data init | ||
659 | if(tmp2==NULL)return defret; | ||
660 | tmp2+=4; | ||
661 | tmp3=tmp2; | ||
662 | do { | ||
663 | |||
664 | i=memcmp(tmp3,boundary,boundarysize); | ||
665 | if(i!=0)tmp3+=1; | ||
666 | } while(i!=0 && (tmp3+boundarysize<current_web_client->rbuf+current_web_client->rbufsize)); // End of data | ||
667 | if(i!=0) return defret; | ||
668 | tmp3-=4; // back "\r\n\r\n" | ||
669 | |||
670 | // copy data to node | ||
671 | if(!(ml->next->data=__ILWS_add_buffer(ClientInfo->mem,(tmp3-tmp2)+1))) { | ||
672 | return defret; | ||
673 | }; | ||
674 | memcpy(ml->next->data,tmp2,tmp3-tmp2); | ||
675 | ml->next->data[tmp3-tmp2]='\0'; | ||
676 | ml->next->size=tmp3-tmp2; | ||
677 | |||
678 | |||
679 | |||
680 | |||
681 | return *ml->next; | ||
682 | |||
683 | }; | ||
684 | |||
685 | /* | ||
686 | * Function for CookieData | ||
687 | */ | ||
688 | char *__ILWS_Cookie(struct ClientInfo *ClientInfo, char *handle) { | ||
689 | char *defret=""; | ||
690 | char *tmp1,*tmp2,*ret; | ||
691 | int size; | ||
692 | int strsize; | ||
693 | struct _Cookie *cl=ClientInfo->CookieList; | ||
694 | |||
695 | |||
696 | tmp1=strstr(current_web_client->rbuf,"\nCookie: "); // start of cookie string | ||
697 | if(tmp1==NULL) { // no cookies | ||
698 | return defret; | ||
699 | }; | ||
700 | tmp1+=8; | ||
701 | if(handle==NULL) { | ||
702 | return ClientInfo->CookieString; | ||
703 | }; | ||
704 | |||
705 | if(ClientInfo->CookieList==NULL) { | ||
706 | |||
707 | ClientInfo->CookieList=__ILWS_add_buffer(ClientInfo->mem,sizeof(struct _Cookie)); | ||
708 | if(ClientInfo->CookieList==NULL) { | ||
709 | return defret; | ||
710 | }; | ||
711 | ClientInfo->CookieList->next=NULL; | ||
712 | ClientInfo->CookieList->data=NULL; | ||
713 | ClientInfo->CookieList->id=NULL; | ||
714 | cl=ClientInfo->CookieList; | ||
715 | } | ||
716 | // First search if exists | ||
717 | while(cl->next!=NULL) { | ||
718 | if(cl->next->id!=NULL) { | ||
719 | if(!strcmp(cl->next->id,handle)) { | ||
720 | |||
721 | return cl->next->data; | ||
722 | }; | ||
723 | }; | ||
724 | cl=cl->next; | ||
725 | }; | ||
726 | |||
727 | strsize=strlen(handle); | ||
728 | if(!(cl->next=__ILWS_add_buffer(ClientInfo->mem,sizeof(struct _Cookie)))) { | ||
729 | return defret; | ||
730 | }; | ||
731 | if(!(cl->next->id=__ILWS_add_buffer(ClientInfo->mem,strsize+1))) { | ||
732 | return defret; | ||
733 | }; | ||
734 | memcpy(cl->next->id,handle,strsize); | ||
735 | cl->next->id[strsize]=0; | ||
736 | cl->next->data=defret; | ||
737 | cl->next->next=NULL; | ||
738 | do { | ||
739 | tmp2=strstr(tmp1,handle); | ||
740 | if(tmp2==NULL) { | ||
741 | return defret; | ||
742 | }else if(tmp2[strsize]==';' && tmp2[-1]==' ') { | ||
743 | cl->next->data=__ILWS_add_buffer(ClientInfo->mem,6); | ||
744 | snprintf(cl->next->data,5,"True"); | ||
745 | return cl->next->data; | ||
746 | }; | ||
747 | tmp1=tmp2+strsize; | ||
748 | }while(tmp2[-1]!=' ' || tmp2[strsize]!='='); | ||
749 | |||
750 | tmp1=strstr(tmp2,";"); // end of data | ||
751 | tmp2+=strsize+1; // start of data | ||
752 | if(tmp1==NULL) { | ||
753 | size=strstr(tmp2,"\r")-tmp2; | ||
754 | |||
755 | } else { | ||
756 | size=tmp1-tmp2; | ||
757 | }; | ||
758 | if(size<1) { | ||
759 | return defret; | ||
760 | }; | ||
761 | |||
762 | ret=__ILWS_add_buffer(ClientInfo->mem,size+1); | ||
763 | if(ret==NULL) { | ||
764 | return defret; | ||
765 | }; | ||
766 | |||
767 | memcpy(ret,tmp2,size); | ||
768 | ret[size]='\0'; | ||
769 | cl->next->data=ret; | ||
770 | return cl->next->data; | ||
771 | }; | ||
772 | |||
773 | /* | ||
774 | * get whole query string | ||
775 | */ | ||
776 | char *__ILWS_clientinfo_getquerystring(struct ClientInfo *ClientInfo) { | ||
777 | char *tmp1,*tmp2,*ret; | ||
778 | char *defret=""; | ||
779 | size_t size; | ||
780 | tmp1=strstr(current_web_client->rbuf,"?"); | ||
781 | tmp2=strstr(current_web_client->rbuf,"HTTP"); | ||
782 | if(tmp1!=NULL && tmp1<tmp2) | ||
783 | tmp1+=1; | ||
784 | else | ||
785 | return defret; | ||
786 | size=(tmp2-tmp1)-1; | ||
787 | ret=__ILWS_add_buffer(ClientInfo->mem,size+1); | ||
788 | if(ret==NULL) { | ||
789 | return defret; | ||
790 | }; | ||
791 | memcpy(ret,tmp1,size); | ||
792 | ret[size]=0; | ||
793 | return ret; | ||
794 | }; | ||
795 | |||
796 | /* | ||
797 | * get whole post data | ||
798 | */ | ||
799 | char *__ILWS_clientinfo_getpostdata(struct ClientInfo *ClientInfo) { | ||
800 | char *tmp1,*ret; | ||
801 | char *defret=""; | ||
802 | size_t size; | ||
803 | tmp1=strstr(current_web_client->rbuf,"\r\n\r\n"); | ||
804 | if(tmp1!=NULL && (tmp1+4)<(char*)(current_web_client->rbuf+current_web_client->rbufsize)) | ||
805 | tmp1+=4; | ||
806 | else | ||
807 | return defret; | ||
808 | size=(current_web_client->rbuf+current_web_client->rbufsize)-tmp1; | ||
809 | ret=__ILWS_add_buffer(ClientInfo->mem,size+1); | ||
810 | if(ret==NULL) { | ||
811 | return defret; | ||
812 | }; | ||
813 | memcpy(ret,tmp1,size); | ||
814 | ret[size]='\0'; | ||
815 | return ret; | ||
816 | } | ||
817 | |||
818 | /* | ||
819 | * get method (GET POST HEAD etc) | ||
820 | */ | ||
821 | char *__ILWS_clientinfo_getmethod(struct ClientInfo *ClientInfo) { | ||
822 | char *tmp1,*ret; | ||
823 | char *defret=""; | ||
824 | size_t size; | ||
825 | tmp1=strstr(current_web_client->rbuf," "); // first space | ||
826 | if(tmp1==NULL) { | ||
827 | return defret; | ||
828 | }; | ||
829 | size=tmp1-current_web_client->rbuf; | ||
830 | ret=__ILWS_add_buffer(ClientInfo->mem,size+1); | ||
831 | if(ret==NULL) { | ||
832 | return defret; | ||
833 | }; | ||
834 | memcpy(ret,current_web_client->rbuf,size); | ||
835 | ret[size]=0; | ||
836 | return ret; | ||
837 | } | ||
838 | |||
839 | /* | ||
840 | * get request name (GET /taltal HTTP/1.0) returning /taltal | ||
841 | */ | ||
842 | char *__ILWS_clientinfo_getreqname(struct ClientInfo *ClientInfo) { | ||
843 | char *ret; | ||
844 | char *tmp1=strstr(current_web_client->rbuf,"/"); // Must have / | ||
845 | char *tmp2=strstr(tmp1,"?"); | ||
846 | char *tmp3=strstr(tmp1," HTTP"); | ||
847 | char *defret=""; | ||
848 | size_t i,j; | ||
849 | int ch; | ||
850 | size_t size=0; | ||
851 | if(tmp1==NULL || tmp3==NULL) return defret; | ||
852 | if(tmp2==NULL || tmp2>tmp3) { | ||
853 | tmp2=tmp3; | ||
854 | }; | ||
855 | //tmp1+=1; | ||
856 | size=tmp2-tmp1; | ||
857 | if(size<1) | ||
858 | return defret; | ||
859 | ret=__ILWS_add_buffer(ClientInfo->mem,size+1); | ||
860 | if(ret==NULL) { | ||
861 | return defret; | ||
862 | }; | ||
863 | j=0; | ||
864 | for(i=0;i<size;i++) { // hex translation here | ||
865 | switch (ch=tmp1[j]) { | ||
866 | case '+': | ||
867 | ch=' '; | ||
868 | break; | ||
869 | case '%': | ||
870 | |||
871 | tmp2=__ILWS_malloc(3); | ||
872 | if(tmp2==NULL) { | ||
873 | return defret; | ||
874 | }; | ||
875 | strncpy(tmp2,&tmp1[j+1],2); | ||
876 | tmp2[2]=0; | ||
877 | |||
878 | ch=strtol(tmp2,NULL,16); | ||
879 | j+=2; | ||
880 | size-=2; | ||
881 | __ILWS_free(tmp2); | ||
882 | break; | ||
883 | }; | ||
884 | ret[i]=ch; | ||
885 | j++; | ||
886 | }; | ||
887 | //pl->next->data[size]='\0'; | ||
888 | //memcpy(ret,tmp1,size); | ||
889 | ret[size]=0; | ||
890 | return ret; | ||
891 | } | ||
892 | |||
893 | |||
diff --git a/src/clientinfo.h b/src/clientinfo.h deleted file mode 100644 index c3315bbd..00000000 --- a/src/clientinfo.h +++ /dev/null | |||
@@ -1,103 +0,0 @@ | |||
1 | /* Copyrights 2002 Luis Figueiredo (stdio@netc.pt) All rights reserved. | ||
2 | * | ||
3 | * See the LICENSE file | ||
4 | * | ||
5 | * The origin of this software must not be misrepresented, either by | ||
6 | * explicit claim or by omission. Since few users ever read sources, | ||
7 | * credits must appear in the documentation. | ||
8 | * | ||
9 | * date: Wed Oct 9 19:05:48 GMT 2002 | ||
10 | * | ||
11 | * | ||
12 | * -- | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #ifndef _CLIENTINFO_H_ | ||
17 | #define _CLIENTINFO_H_ | ||
18 | |||
19 | #include <stdio.h> | ||
20 | #include <fcntl.h> | ||
21 | #include <string.h> | ||
22 | #include "client.h" | ||
23 | #include "utils.h" | ||
24 | #include "memory.h" | ||
25 | |||
26 | /* | ||
27 | * Next's structs are redudant but it is an case of logic (spell) | ||
28 | */ | ||
29 | struct _Header { | ||
30 | char *id; | ||
31 | char *data; | ||
32 | struct _Header *next; | ||
33 | }; | ||
34 | struct _Query { | ||
35 | unsigned int index; | ||
36 | unsigned int idf; | ||
37 | char *id; | ||
38 | char *data; | ||
39 | struct _Query *next; | ||
40 | }; | ||
41 | struct _Post { | ||
42 | unsigned int index; | ||
43 | unsigned int idf; | ||
44 | char *id; | ||
45 | char *data; | ||
46 | struct _Post *next; | ||
47 | }; | ||
48 | |||
49 | struct _MultiPart { | ||
50 | char *id; | ||
51 | char *data; | ||
52 | unsigned int size; | ||
53 | char *filename; | ||
54 | struct _MultiPart *next; | ||
55 | }; | ||
56 | |||
57 | struct _Cookie { | ||
58 | char *id; | ||
59 | char *data; | ||
60 | struct _Cookie *next; | ||
61 | }; | ||
62 | |||
63 | struct ClientInfo { | ||
64 | int outfd; | ||
65 | char *inetname; | ||
66 | char *request; | ||
67 | char *method; | ||
68 | char *user; | ||
69 | char *pass; | ||
70 | |||
71 | char *(*Header)(char *); | ||
72 | char *(*Query)(char *); | ||
73 | char *(*Post)(char *); | ||
74 | char *(*Cookie)(char *); // TODO | ||
75 | struct _MultiPart (*MultiPart)(char *); | ||
76 | // not necessary for web_server.h | ||
77 | char *QueryString; | ||
78 | char *CookieString; | ||
79 | char *PostData; | ||
80 | struct memrequest *mem; | ||
81 | struct _Header *HeaderList; // Not necessary for web_server.h | ||
82 | struct _Query *QueryList; // Not necessary for web_server.h | ||
83 | struct _Post *PostList; // Not necessary for web_server.h | ||
84 | struct _MultiPart *MultiPartList; // Not necessary for web_server.h | ||
85 | struct _Cookie *CookieList; // Not necessary for web_server.h | ||
86 | }; | ||
87 | |||
88 | |||
89 | void __ILWS_init_clientinfo(struct ClientInfo *ClientInfo); | ||
90 | void __ILWS_free_clientinfo(struct ClientInfo *ClientInfo); | ||
91 | char *__ILWS_clientinfo_getquerystring(struct ClientInfo *ClientInfo); | ||
92 | char *__ILWS_clientinfo_getpostdata(struct ClientInfo *ClientInfo); | ||
93 | char *__ILWS_clientinfo_getcookiestring(struct ClientInfo *ClientInfo); | ||
94 | char *__ILWS_clientinfo_getmethod(struct ClientInfo *ClientInfo); | ||
95 | char *__ILWS_clientinfo_getreqname(struct ClientInfo *ClientInfo); | ||
96 | char *__ILWS_Header(struct ClientInfo *ClientInfo, char *); | ||
97 | char *__ILWS_Query(struct ClientInfo *ClientInfo, char *); | ||
98 | char *__ILWS_Post(struct ClientInfo *ClientInfo, char *); | ||
99 | struct _MultiPart __ILWS_MultiPart(struct ClientInfo *ClientInfo, char *); | ||
100 | char *__ILWS_Cookie(struct ClientInfo *ClientInfo, char *); | ||
101 | |||
102 | #endif | ||
103 | |||
diff --git a/src/fnmatch.c b/src/fnmatch.c deleted file mode 100644 index f2b6f6d4..00000000 --- a/src/fnmatch.c +++ /dev/null | |||
@@ -1,195 +0,0 @@ | |||
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 deleted file mode 100644 index 1b0f3fc9..00000000 --- a/src/fnmatch.h +++ /dev/null | |||
@@ -1,59 +0,0 @@ | |||
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/memory.c b/src/memory.c deleted file mode 100644 index ca7e6f51..00000000 --- a/src/memory.c +++ /dev/null | |||
@@ -1,85 +0,0 @@ | |||
1 | /* Copyrights 2002 Luis Figueiredo (stdio@netc.pt) All rights reserved. | ||
2 | * | ||
3 | * See the LICENSE file | ||
4 | * | ||
5 | * The origin of this software must not be misrepresented, either by | ||
6 | * explicit claim or by omission. Since few users ever read sources, | ||
7 | * credits must appear in the documentation. | ||
8 | * | ||
9 | * date: Sat Mar 30 14:25:25 GMT 2002 | ||
10 | * | ||
11 | * -- memory functions | ||
12 | */ | ||
13 | #include "memory.h" | ||
14 | |||
15 | struct memrequest { | ||
16 | char *ptr; | ||
17 | struct memrequest *next; | ||
18 | }; | ||
19 | |||
20 | /* | ||
21 | * Add a buffer to memrequest list | ||
22 | */ | ||
23 | void *__ILWS_add_buffer(struct memrequest *list,unsigned int size) { | ||
24 | struct memrequest *tmem; | ||
25 | if(size==0) { | ||
26 | return NULL; | ||
27 | }; | ||
28 | if(list!=NULL) { | ||
29 | tmem=list; | ||
30 | }else { | ||
31 | return NULL; | ||
32 | }; | ||
33 | while(tmem->next!=NULL)tmem=tmem->next; | ||
34 | tmem->next=__ILWS_malloc(sizeof(struct memrequest)); | ||
35 | if(tmem->next==NULL) return NULL; // ERROR | ||
36 | tmem->next->ptr=__ILWS_malloc(size); | ||
37 | tmem->next->next=NULL; | ||
38 | return tmem->next->ptr; | ||
39 | } | ||
40 | |||
41 | /* | ||
42 | * Initialize memrequest list of buffers | ||
43 | */ | ||
44 | struct memrequest *__ILWS_init_buffer_list() { | ||
45 | struct memrequest *newlist; | ||
46 | newlist=__ILWS_malloc(sizeof(struct memrequest)); | ||
47 | if(newlist==NULL) | ||
48 | return NULL; | ||
49 | newlist->next=NULL; | ||
50 | newlist->ptr=NULL; | ||
51 | return newlist; | ||
52 | } | ||
53 | |||
54 | /* | ||
55 | * Delete memrequest buffer node (free) | ||
56 | */ | ||
57 | void __ILWS_delete_buffer(struct memrequest *mem) { | ||
58 | __ILWS_free(mem->ptr); | ||
59 | __ILWS_free(mem); | ||
60 | } | ||
61 | |||
62 | /* | ||
63 | * Delete memrequest next buffer | ||
64 | */ | ||
65 | void __ILWS_delete_next_buffer(struct memrequest *mem) { | ||
66 | struct memrequest *tmem; | ||
67 | tmem=mem->next; | ||
68 | mem->next=mem->next->next; | ||
69 | __ILWS_delete_buffer(tmem); | ||
70 | } | ||
71 | |||
72 | /* | ||
73 | * Delete whole memrequest buffer list | ||
74 | */ | ||
75 | void __ILWS_delete_buffer_list(struct memrequest *list) { | ||
76 | struct memrequest *tmem=list; | ||
77 | if (tmem==NULL) | ||
78 | return; | ||
79 | |||
80 | while(tmem->next!=NULL) { | ||
81 | __ILWS_delete_next_buffer(tmem); | ||
82 | }; | ||
83 | __ILWS_delete_buffer(tmem); | ||
84 | } | ||
85 | |||
diff --git a/src/memory.h b/src/memory.h deleted file mode 100644 index 6e8f72f2..00000000 --- a/src/memory.h +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | /* Copyrights 2002 Luis Figueiredo (stdio@netc.pt) All rights reserved. | ||
2 | * | ||
3 | * See the LICENSE file | ||
4 | * | ||
5 | * The origin of this software must not be misrepresented, either by | ||
6 | * explicit claim or by omission. Since few users ever read sources, | ||
7 | * credits must appear in the documentation. | ||
8 | * | ||
9 | * date: Sat Mar 30 14:25:25 GMT 2002 | ||
10 | * | ||
11 | * memory functions | ||
12 | */ | ||
13 | |||
14 | #ifndef _MEMORY_H_ | ||
15 | #define _MEMORY_H_ | ||
16 | |||
17 | #include <stdio.h> | ||
18 | #include <stdlib.h> | ||
19 | #include <string.h> | ||
20 | #include <errno.h> | ||
21 | |||
22 | #define __ILWS_malloc malloc | ||
23 | #define __ILWS_calloc calloc | ||
24 | #define __ILWS_realloc realloc | ||
25 | #define __ILWS_free free | ||
26 | |||
27 | struct memrequest; | ||
28 | |||
29 | struct memrequest *__ILWS_init_buffer_list(); | ||
30 | |||
31 | void *__ILWS_add_buffer(struct memrequest *, | ||
32 | unsigned int); | ||
33 | |||
34 | void __ILWS_delete_buffer(struct memrequest *); | ||
35 | |||
36 | void __ILWS_delete_next_buffer(struct memrequest *); | ||
37 | |||
38 | void __ILWS_delete_buffer_list(struct memrequest *); | ||
39 | |||
40 | #endif | ||
diff --git a/src/outstream.c b/src/outstream.c deleted file mode 100644 index 9ad33715..00000000 --- a/src/outstream.c +++ /dev/null | |||
@@ -1,118 +0,0 @@ | |||
1 | /* Copyrights 2002 Luis Figueiredo (stdio@netc.pt) All rights reserved. | ||
2 | * | ||
3 | * See the LICENSE file | ||
4 | * | ||
5 | * The origin of this software must not be misrepresented, either by | ||
6 | * explicit claim or by omission. Since few users ever read sources, | ||
7 | * credits must appear in the documentation. | ||
8 | * | ||
9 | * date: Sat Mar 30 14: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 | return 0; | ||
28 | }; | ||
29 | // file check (0.5.3); | ||
30 | tmp=fopen(fname,"rb"); | ||
31 | if(tmp==NULL) { | ||
32 | __ILWS_free(temp->next); | ||
33 | temp->next=NULL; | ||
34 | return 0; | ||
35 | }; | ||
36 | fclose(tmp); | ||
37 | // -- | ||
38 | temp->next->fname=NULL; | ||
39 | if(fname!=NULL) { | ||
40 | if(!(temp->next->fname=__ILWS_malloc(strlen(fname)+1))) { | ||
41 | __ILWS_free(temp->next); | ||
42 | temp->next=NULL; | ||
43 | return 0; | ||
44 | }; | ||
45 | memcpy(temp->next->fname,fname,strlen(fname)); | ||
46 | temp->next->fname[strlen(fname)]='\0'; | ||
47 | }; | ||
48 | temp->next->todelete=istmp; | ||
49 | temp->next->fstream=stream; | ||
50 | temp->next->wsize=1; | ||
51 | temp->next->rsize=0; | ||
52 | temp->next->wrotesize=0; | ||
53 | temp->next->varsize=0; | ||
54 | temp->next->next=NULL; | ||
55 | return 1; | ||
56 | } | ||
57 | |||
58 | /*********************************************************************************************************/ | ||
59 | /* | ||
60 | * Initializate (allocate) outstream list | ||
61 | */ | ||
62 | struct outstream *__ILWS_init_outstream_list() { | ||
63 | struct outstream *ret; | ||
64 | |||
65 | |||
66 | if(!(ret=__ILWS_malloc(sizeof(struct outstream)))) { | ||
67 | return NULL; | ||
68 | }; | ||
69 | ret->todelete=0; | ||
70 | ret->fname=NULL; | ||
71 | ret->flags=0; | ||
72 | ret->fstream=NULL; | ||
73 | ret->next=NULL; | ||
74 | return ret; | ||
75 | } | ||
76 | |||
77 | /*********************************************************************************************************/ | ||
78 | /* | ||
79 | * Delete a especific node | ||
80 | */ | ||
81 | void __ILWS_delete_outstream(struct outstream *node) { // Changed | ||
82 | int rt; | ||
83 | if(node->fstream!=NULL)fclose(node->fstream); // better here; | ||
84 | if(node->todelete) { // is temporary file | ||
85 | rt=unlink(node->fname); | ||
86 | if(rt==-1) { | ||
87 | }; | ||
88 | |||
89 | }; | ||
90 | if(node->fname!=NULL)__ILWS_free(node->fname); | ||
91 | __ILWS_free(node); | ||
92 | } | ||
93 | |||
94 | /*********************************************************************************************************/ | ||
95 | /* | ||
96 | * delete next node | ||
97 | */ | ||
98 | void __ILWS_delete_next_outstream(struct outstream *node) { | ||
99 | struct outstream *temp=node->next; | ||
100 | node->next=node->next->next; | ||
101 | __ILWS_delete_outstream(temp); | ||
102 | } | ||
103 | |||
104 | /*********************************************************************************************************/ | ||
105 | /* | ||
106 | * delete all nodes on the list (reset list) | ||
107 | */ | ||
108 | void __ILWS_delete_outstream_list(struct outstream *list) { | ||
109 | struct outstream *temp=list; | ||
110 | while(temp->next!=NULL) { | ||
111 | |||
112 | __ILWS_delete_next_outstream(temp); | ||
113 | }; | ||
114 | |||
115 | __ILWS_delete_outstream(temp); | ||
116 | |||
117 | } | ||
118 | |||
diff --git a/src/outstream.h b/src/outstream.h deleted file mode 100644 index 8ef92c4f..00000000 --- a/src/outstream.h +++ /dev/null | |||
@@ -1,47 +0,0 @@ | |||
1 | /* Copyrights 2002 Luis Figueiredo (stdio@netc.pt) All rights reserved. | ||
2 | * | ||
3 | * See the LICENSE file | ||
4 | * | ||
5 | * The origin of this software must not be misrepresented, either by | ||
6 | * explicit claim or by omission. Since few users ever read sources, | ||
7 | * credits must appear in the documentation. | ||
8 | * | ||
9 | * date: Sat Mar 30 14: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 "memory.h" | ||
30 | |||
31 | struct outstream { | ||
32 | FILE *fstream; | ||
33 | char *fname; | ||
34 | int todelete; | ||
35 | int wsize,rsize; | ||
36 | long wrotesize; | ||
37 | long varsize; | ||
38 | int flags; | ||
39 | struct outstream *next; | ||
40 | }; | ||
41 | |||
42 | int __ILWS_add_outstream(struct outstream *, char *,FILE *,int); | ||
43 | struct outstream *__ILWS_init_outstream_list(); | ||
44 | void __ILWS_delete_next_outstream(struct outstream *); | ||
45 | void __ILWS_delete_outstream_list(struct outstream *); | ||
46 | void __ILWS_delete_outstream(struct outstream *); | ||
47 | #endif | ||
diff --git a/src/server.c b/src/server.c deleted file mode 100644 index d028330b..00000000 --- a/src/server.c +++ /dev/null | |||
@@ -1,279 +0,0 @@ | |||
1 | /* Copyrights 2002 Luis Figueiredo (stdio@netc.pt) All rights reserved. | ||
2 | * | ||
3 | * See the LICENSE file | ||
4 | * | ||
5 | * The origin of this software must not be misrepresented, either by | ||
6 | * explicit claim or by omission. Since few users ever read sources, | ||
7 | * credits must appear in the documentation. | ||
8 | * | ||
9 | * date: Sat Mar 30 14:44:42 GMT 2002 | ||
10 | * | ||
11 | * -- core server functions | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #include "webserver_gnunet.h" | ||
16 | #include <stdio.h> | ||
17 | #include <signal.h> | ||
18 | #include <time.h> | ||
19 | |||
20 | #include "memory.h" | ||
21 | #include "client.h" | ||
22 | #include "socket.h" | ||
23 | |||
24 | #ifdef WIN32 | ||
25 | #define SHUT_RDWR SD_BOTH | ||
26 | #endif | ||
27 | |||
28 | struct web_server { | ||
29 | int socket; | ||
30 | unsigned int port; | ||
31 | struct gethandler * gethandler; | ||
32 | struct web_client *client; | ||
33 | }; | ||
34 | |||
35 | |||
36 | /* | ||
37 | * initializate (allocate) handler list | ||
38 | */ | ||
39 | struct gethandler *__ILWS_init_handler_list() { | ||
40 | struct gethandler *ret; | ||
41 | |||
42 | ret = __ILWS_malloc(sizeof(struct gethandler)); | ||
43 | if (ret==NULL) | ||
44 | return NULL; | ||
45 | ret->next = NULL; | ||
46 | ret->func = NULL; | ||
47 | ret->ctx = NULL; | ||
48 | ret->str = NULL; | ||
49 | return ret; | ||
50 | } | ||
51 | |||
52 | /* | ||
53 | * add an handler to list | ||
54 | */ | ||
55 | static int __ILWS_add_handler(struct gethandler * head, | ||
56 | const char * mstr, | ||
57 | void (*func)(), | ||
58 | void * ctx) { | ||
59 | struct gethandler * temp = head; | ||
60 | while (temp->next != NULL) | ||
61 | temp = temp->next; | ||
62 | |||
63 | temp->next = __ILWS_malloc(sizeof(struct gethandler)); | ||
64 | if (temp->next==NULL) | ||
65 | return 0; | ||
66 | temp = temp->next; | ||
67 | temp->str=__ILWS_malloc(strlen(mstr)+1); | ||
68 | if (temp->str==NULL) { | ||
69 | __ILWS_free(temp); | ||
70 | return 0; | ||
71 | }; | ||
72 | memcpy(temp->str, | ||
73 | mstr, | ||
74 | strlen(mstr) + 1); | ||
75 | temp->func = func; | ||
76 | temp->ctx = ctx; | ||
77 | temp->next = NULL; | ||
78 | return 1; | ||
79 | } | ||
80 | |||
81 | /* | ||
82 | * Deletes the entire handler list including the head | ||
83 | */ | ||
84 | static void __ILWS_delete_handler_list(struct gethandler * handler) { | ||
85 | struct gethandler * next; | ||
86 | |||
87 | while (handler) { | ||
88 | next = handler->next; | ||
89 | if (handler->str != NULL) | ||
90 | __ILWS_free(handler->str); | ||
91 | __ILWS_free(handler); | ||
92 | handler = next; | ||
93 | } | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * to add a listen socket | ||
98 | */ | ||
99 | static int __ILWS_listensocket(short port, | ||
100 | int saddr) { | ||
101 | struct sockaddr_in sa; | ||
102 | int ret; | ||
103 | int sockopt=1; | ||
104 | |||
105 | sa.sin_addr.s_addr=saddr; | ||
106 | sa.sin_port=htons((short)port); | ||
107 | sa.sin_family=AF_INET; | ||
108 | ret=socket(AF_INET,SOCK_STREAM,6); // tcp | ||
109 | if(ret==-1) | ||
110 | return -1; | ||
111 | |||
112 | setsockopt(ret, | ||
113 | SOL_SOCKET, | ||
114 | SO_REUSEADDR, | ||
115 | (char *)&sockopt, | ||
116 | sizeof(sockopt)); | ||
117 | |||
118 | if (bind(ret, | ||
119 | (struct sockaddr *)&sa, | ||
120 | sizeof(sa))==-1) { | ||
121 | close(ret); | ||
122 | return -1; | ||
123 | } | ||
124 | |||
125 | if (listen(ret,512)==-1) { // 512 backlog | ||
126 | close(ret); | ||
127 | return -1; | ||
128 | } | ||
129 | return ret; | ||
130 | } | ||
131 | |||
132 | |||
133 | /* | ||
134 | * Add an handler to request data | ||
135 | */ | ||
136 | int web_server_addhandler(struct web_server *server, | ||
137 | const char *mstr, | ||
138 | void (*func)(), | ||
139 | void * hctx) { | ||
140 | return __ILWS_add_handler(server->gethandler, | ||
141 | mstr, | ||
142 | func, | ||
143 | hctx); | ||
144 | } | ||
145 | |||
146 | /* | ||
147 | * This function initialize one web_server handler | ||
148 | */ | ||
149 | int web_server_init(struct web_server *server, | ||
150 | int port, | ||
151 | int flags) { | ||
152 | #ifdef WIN32 | ||
153 | unsigned long t=IOC_INOUT; | ||
154 | WSADATA WSAinfo; | ||
155 | WSAStartup(2,&WSAinfo); // Damn w32 sockets | ||
156 | #endif | ||
157 | server->port=port; | ||
158 | // Create a listen socket port 'port' and listen addr (0) (all interfaces) | ||
159 | server->socket=__ILWS_listensocket((short)server->port,0); | ||
160 | if (server->socket==-1) { | ||
161 | #ifdef WIN32 | ||
162 | WSACleanup(); | ||
163 | #endif | ||
164 | return 0; | ||
165 | }; | ||
166 | #ifdef WIN32 | ||
167 | ioctlsocket(server->socket, | ||
168 | FIONBIO, | ||
169 | &t); //non blocking sockets for win32 | ||
170 | #else | ||
171 | fcntl(server->socket, | ||
172 | F_SETFL, | ||
173 | O_NONBLOCK); | ||
174 | #endif | ||
175 | |||
176 | // Setup Flags | ||
177 | server->client = __ILWS_init_client_list(); | ||
178 | server->gethandler = __ILWS_init_handler_list(); | ||
179 | |||
180 | #ifndef WIN32 | ||
181 | signal(SIGPIPE, SIG_IGN); | ||
182 | #endif | ||
183 | return 1; | ||
184 | } | ||
185 | |||
186 | /* | ||
187 | * This function shuts down a running web server, frees its allocated memory, | ||
188 | * and closes its socket. If called on a struct web_server that has already | ||
189 | * been shut down, this is a noop. | ||
190 | */ | ||
191 | void web_server_shutdown(struct web_server * server) { | ||
192 | // free and close things in opposite order of web_server_init | ||
193 | __ILWS_delete_handler_list(server->gethandler); | ||
194 | server->gethandler = NULL; | ||
195 | __ILWS_delete_client_list(server->client); | ||
196 | server->client = NULL; | ||
197 | if(server->socket > 0) { | ||
198 | #ifdef WIN32 | ||
199 | closesocket(server->socket); | ||
200 | #else | ||
201 | close(server->socket); | ||
202 | #endif | ||
203 | server->socket = -1; | ||
204 | } | ||
205 | #ifdef WIN32 | ||
206 | WSACleanup(); | ||
207 | #endif | ||
208 | } | ||
209 | |||
210 | /* | ||
211 | * Core function, return 2 if no client to process, 1 if some client processed, 0 if error | ||
212 | */ | ||
213 | int web_server_run(struct web_server *server) { | ||
214 | struct web_client * client; | ||
215 | struct web_client * pos; | ||
216 | int rt; | ||
217 | size_t tsalen=0; | ||
218 | int tsocket=0; | ||
219 | int cond; | ||
220 | struct sockaddr_in tsa; | ||
221 | |||
222 | tsalen = sizeof(client->sa); | ||
223 | tsocket = accept(server->socket, | ||
224 | (struct sockaddr *)&tsa, | ||
225 | &tsalen); | ||
226 | if (tsocket == -1) { | ||
227 | #ifdef WIN32 | ||
228 | cond = WSAGetLastError() != WSAEWOULDBLOCK; | ||
229 | #else | ||
230 | cond = errno!=EAGAIN; | ||
231 | #endif | ||
232 | if (cond) { | ||
233 | // client fucked up? warn somebody? (error or log or something?) | ||
234 | return 0; | ||
235 | } | ||
236 | } else { | ||
237 | client = __ILWS_malloc(sizeof(struct web_client)); | ||
238 | if (client == NULL) { | ||
239 | rt = shutdown(tsocket, | ||
240 | SHUT_RDWR); | ||
241 | #ifdef WIN32 | ||
242 | rt=closesocket(tsocket); | ||
243 | #else | ||
244 | rt=close(tsocket); | ||
245 | #endif | ||
246 | return 0; | ||
247 | }; | ||
248 | client->salen=tsalen; | ||
249 | client->socket=tsocket; | ||
250 | client->sa=tsa; | ||
251 | if(!__ILWS_add_client(server->client,client)) | ||
252 | return 0; | ||
253 | }; | ||
254 | // end search for client | ||
255 | client = server->client; // init list | ||
256 | if(!client->next) { // think of Rocco Carbone (rocco@tecsiel.it) | ||
257 | return 2; // i don't need to process the list (nothing next) returns 2 if there is no client to process | ||
258 | } | ||
259 | while (client->next != NULL) { // Process the client and swap to next; | ||
260 | pos = client->next; | ||
261 | switch (pos->stat) { | ||
262 | case 1: | ||
263 | __ILWS_read_client(pos); | ||
264 | break; | ||
265 | case 2: | ||
266 | __ILWS_process_client(pos, server->gethandler); | ||
267 | break; | ||
268 | case 4: | ||
269 | __ILWS_output_client(pos); | ||
270 | break; | ||
271 | case 5: | ||
272 | __ILWS_delete_next_client(client); | ||
273 | continue; | ||
274 | } | ||
275 | client=client->next; | ||
276 | } | ||
277 | return 1; // return 1 if something processed | ||
278 | } | ||
279 | |||
diff --git a/src/socket.h b/src/socket.h deleted file mode 100644 index b7af25b0..00000000 --- a/src/socket.h +++ /dev/null | |||
@@ -1,37 +0,0 @@ | |||
1 | /* Copyrights 2002 Luis Figueiredo (stdio@netc.pt) All rights reserved. | ||
2 | * | ||
3 | * See the LICENSE file | ||
4 | * | ||
5 | * The origin of this software must not be misrepresented, either by | ||
6 | * explicit claim or by omission. Since few users ever read sources, | ||
7 | * credits must appear in the documentation. | ||
8 | * | ||
9 | * date: Sat Mar 30 14:44:42 GMT 2002 | ||
10 | * | ||
11 | * | ||
12 | * -- | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #ifndef _SOCKET_H_ | ||
17 | #define _SOCKET_H_ | ||
18 | |||
19 | #include <stdio.h> | ||
20 | #include <stdarg.h> | ||
21 | |||
22 | #ifdef WIN32 | ||
23 | #include <winsock2.h> | ||
24 | #include <io.h> | ||
25 | #else | ||
26 | #include <sys/socket.h> | ||
27 | #include <netinet/in.h> | ||
28 | #include <arpa/inet.h> | ||
29 | #include <unistd.h> | ||
30 | #include <sys/time.h> // struct tv | ||
31 | #include <sys/types.h> // freebsd need it i gues that is no problem if other system includes it | ||
32 | #endif | ||
33 | |||
34 | #define __ILWS_read recv | ||
35 | |||
36 | #endif | ||
37 | |||
diff --git a/src/utils.c b/src/utils.c deleted file mode 100644 index 3552189c..00000000 --- a/src/utils.c +++ /dev/null | |||
@@ -1,152 +0,0 @@ | |||
1 | /* Copyrights 2002 Luis Figueiredo (stdio@netc.pt) All rights reserved. | ||
2 | * | ||
3 | * See the LICENSE file | ||
4 | * | ||
5 | * The origin of this software must not be misrepresented, either by | ||
6 | * explicit claim or by omission. Since few users ever read sources, | ||
7 | * credits must appear in the documentation. | ||
8 | * | ||
9 | * date: 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 | if(!(ret=__ILWS_malloc(strlen(tmpdir)+strlen(_tmpnameprefix)+TMPNAMESIZE+2))) { | ||
59 | return NULL; | ||
60 | }; | ||
61 | srand(time(NULL)); // seed | ||
62 | do { | ||
63 | for(i=0;i<TMPNAMESIZE;i++) { | ||
64 | |||
65 | nam[i]=(rand()%2)?(rand()%26)+'A':(rand()%26)+'a'; | ||
66 | } | ||
67 | nam[i]=0; | ||
68 | snprintf(ret,strlen(tmpdir)+strlen(_tmpnameprefix)+TMPNAMESIZE+2,"%s/%s%s",tmpdir,_tmpnameprefix,nam); // include '0' | ||
69 | }while((stat(ret,&foostat)!=-1) && (lstat(ret,&foostat)!=-1)); // redundancy if win32 // <- race condition? | ||
70 | return ret; | ||
71 | }; | ||
72 | |||
73 | |||
74 | |||
75 | /*********************************************************************************************************/ | ||
76 | /* | ||
77 | * an date function | ||
78 | */ | ||
79 | #define DATE_MAX 100 | ||
80 | char __ILWS_datem[DATE_MAX]; | ||
81 | |||
82 | char *__ILWS_date(time_t t,const char *format) { | ||
83 | struct tm *tm; | ||
84 | tm=localtime(&t); | ||
85 | strftime(__ILWS_datem,DATE_MAX,format,tm); | ||
86 | return __ILWS_datem; | ||
87 | } | ||
88 | |||
89 | /*********************************************************************************************************/ | ||
90 | /* | ||
91 | * wasn't me, base64decode | ||
92 | */ | ||
93 | static const unsigned char __ILWS_chtb[256] = { | ||
94 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | ||
95 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | ||
96 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, | ||
97 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, | ||
98 | 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, | ||
99 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, | ||
100 | 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, | ||
101 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, | ||
102 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | ||
103 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | ||
104 | 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 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 | |||
111 | |||
112 | int __ILWS_base64decode(char *bufplain, const char *bufcoded){ | ||
113 | int nb; | ||
114 | const unsigned char *in; | ||
115 | unsigned char *out; | ||
116 | int nprbytes; | ||
117 | |||
118 | in = (const unsigned char *) bufcoded; | ||
119 | while (__ILWS_chtb[*(in++)] <= 63); | ||
120 | nprbytes = (in - (const unsigned char *) bufcoded) - 1; | ||
121 | nb = ((nprbytes + 3) / 4) * 3; | ||
122 | |||
123 | out = (unsigned char *) bufplain; | ||
124 | in = (const unsigned char *) bufcoded; | ||
125 | |||
126 | while (nprbytes > 4) { | ||
127 | *(out++) = | ||
128 | (unsigned char) (__ILWS_chtb[*in] << 2 | __ILWS_chtb[in[1]] >> 4); | ||
129 | *(out++) = | ||
130 | (unsigned char) (__ILWS_chtb[in[1]] << 4 | __ILWS_chtb[in[2]] >> 2); | ||
131 | *(out++) = | ||
132 | (unsigned char) (__ILWS_chtb[in[2]] << 6 | __ILWS_chtb[in[3]]); | ||
133 | in += 4; | ||
134 | nprbytes -= 4; | ||
135 | } | ||
136 | if (nprbytes > 1) { | ||
137 | *(out++) = | ||
138 | (unsigned char) (__ILWS_chtb[*in] << 2 | __ILWS_chtb[in[1]] >> 4); | ||
139 | } | ||
140 | if (nprbytes > 2) { | ||
141 | *(out++) = | ||
142 | (unsigned char) (__ILWS_chtb[in[1]] << 4 | __ILWS_chtb[in[2]] >> 2); | ||
143 | } | ||
144 | if (nprbytes > 3) { | ||
145 | *(out++) = | ||
146 | (unsigned char) (__ILWS_chtb[in[2]] << 6 | __ILWS_chtb[in[3]]); | ||
147 | } | ||
148 | |||
149 | nb -= (4 - nprbytes) & 3; | ||
150 | return nb; | ||
151 | } | ||
152 | |||
diff --git a/src/utils.h b/src/utils.h deleted file mode 100644 index 7364a519..00000000 --- a/src/utils.h +++ /dev/null | |||
@@ -1,50 +0,0 @@ | |||
1 | /* Copyrights 2002 Luis Figueiredo (stdio@netc.pt) All rights reserved. | ||
2 | * | ||
3 | * See the LICENSE file | ||
4 | * | ||
5 | * The origin of this software must not be misrepresented, either by | ||
6 | * explicit claim or by omission. Since few users ever read sources, | ||
7 | * credits must appear in the documentation. | ||
8 | * | ||
9 | * 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 | #include <stdio.h> | ||
20 | #include <stdlib.h> | ||
21 | #include <string.h> | ||
22 | #include <sys/stat.h> | ||
23 | #include <ctype.h> | ||
24 | |||
25 | #ifdef TM_IN_SYS_TIME | ||
26 | #include <sys/time.h> | ||
27 | #else | ||
28 | #include <time.h> | ||
29 | #endif | ||
30 | |||
31 | #include "memory.h" | ||
32 | |||
33 | #ifdef WIN32 | ||
34 | #define strncasecmp strnicmp | ||
35 | #define snprintf _snprintf | ||
36 | #define lstat stat | ||
37 | #define vsnprintf _vsnprintf | ||
38 | #endif | ||
39 | |||
40 | #define TMPNAMESIZE 8 | ||
41 | extern char *_tmpnameprefix; | ||
42 | |||
43 | |||
44 | char *__ILWS_stristr(char *, const char *); | ||
45 | char *__ILWS_tmpfname(); | ||
46 | int __ILWS_base64decode(char *, const char *); | ||
47 | char *__ILWS_date(time_t,const char *); | ||
48 | |||
49 | |||
50 | #endif | ||
diff --git a/src/web_server.h b/src/web_server.h deleted file mode 100644 index d34036b5..00000000 --- a/src/web_server.h +++ /dev/null | |||
@@ -1,129 +0,0 @@ | |||
1 | /* Copyrights 2002 Luis Figueiredo (stdio@netc.pt) All rights reserved. | ||
2 | * | ||
3 | * See the LICENSE file | ||
4 | * | ||
5 | * The origin of this software must not be misrepresented, either by | ||
6 | * explicit claim or by omission. Since few users ever read sources, | ||
7 | * credits must appear in the documentation. | ||
8 | * | ||
9 | * 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 | |||