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