aboutsummaryrefslogtreecommitdiff
path: root/src/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/client.c')
-rw-r--r--src/client.c1171
1 files changed, 0 insertions, 1171 deletions
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
20int WEBTIMEOUT=10000;
21
22/*********************************************************************************************************/
23/*
24 * initializate (allocate) client list
25 */
26struct 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 */
44int __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 */
95void __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 */
119void __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 */
129void __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 */
143void __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 */
227void __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 */
458void __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 */
621void web_client_HTTPdirective(char *str) {
622 current_web_client->HTTPdirective=str;
623}
624
625
626/*********************************************************************************************************/
627/*
628 * GET request name
629 */
630char *__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 */
658char *__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 */
679int 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 */
706unsigned char __ILWS_GLOBALGIFPAL[256][3];
707
708
709void 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
732int 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 */
751void __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 */
794void 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
868void web_client_deletecookie(char *name){
869 web_client_setcookie(name, NULL, "DEL", NULL, NULL, 0);
870}
871
872
873
874
875
876
877
878
879int web_client_setvar(char *name,char *value) {
880 return __ILWS_add_var(current_web_client->varlist,name,value);
881};
882char *web_client_getvar(char *name) {
883 return __ILWS_get_var(current_web_client->varlist,name);
884
885};
886int 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
898struct 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
909int __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
939int __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};
954void __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
970char *__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
986void 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
1050int __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 &lt;DIR&gt; <a href=\"%s/\">%s</a>\n",__ILWS_date(cfstat.st_mtime,"%a, %d %b %Y %H:%M"),dire->d_name,dire->d_name);
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