package/uhttpd/src/uhttpd-file.c |
29 | 29 | static const char * uh_file_mime_lookup(const char *path) |
30 | 30 | { |
31 | 31 | struct mimetype *m = &uh_mime_types[0]; |
32 | | char *e; |
| 32 | const char *e; |
33 | 33 | |
34 | 34 | while( m->extn ) |
35 | 35 | { |
... | ... | |
275 | 275 | strncat(filename, files[i]->d_name, |
276 | 276 | sizeof(filename) - strlen(files[i]->d_name)); |
277 | 277 | |
278 | | if( !stat(filename, &s) && (s.st_mode & S_IFDIR) ) |
| 278 | if( !stat(filename, &s) && |
| 279 | (s.st_mode & S_IFDIR) && (s.st_mode & S_IXOTH) |
| 280 | ) |
279 | 281 | uh_http_sendf(cl, req, |
280 | 282 | "<li><strong><a href='%s%s'>%s</a>/</strong><br />" |
281 | 283 | "<small>modified: %s<br />directory - %.02f kbyte" |
... | ... | |
293 | 295 | strncat(filename, files[i]->d_name, |
294 | 296 | sizeof(filename) - strlen(files[i]->d_name)); |
295 | 297 | |
296 | | if( !stat(filename, &s) && !(s.st_mode & S_IFDIR) ) |
| 298 | if( !stat(filename, &s) && |
| 299 | !(s.st_mode & S_IFDIR) && (s.st_mode & S_IROTH) |
| 300 | ) |
297 | 301 | uh_http_sendf(cl, req, |
298 | 302 | "<li><strong><a href='%s%s'>%s</a></strong><br />" |
299 | 303 | "<small>modified: %s<br />%s - %.02f kbyte<br />" |
... | ... | |
369 | 373 | } |
370 | 374 | |
371 | 375 | /* directory */ |
372 | | else if( pi->stat.st_mode & S_IFDIR ) |
| 376 | else if( (pi->stat.st_mode & S_IFDIR) && !cl->server->conf->no_dirlists ) |
373 | 377 | { |
374 | 378 | /* write status */ |
375 | 379 | uh_file_response_200(cl, req, NULL); |
package/uhttpd/src/uhttpd-utils.c |
464 | 464 | int i = 0; |
465 | 465 | struct stat s; |
466 | 466 | |
| 467 | /* back out early if url is undefined */ |
| 468 | if ( url == NULL ) |
| 469 | return NULL; |
467 | 470 | |
468 | 471 | memset(path_phys, 0, sizeof(path_phys)); |
469 | 472 | memset(path_info, 0, sizeof(path_info)); |
... | ... | |
550 | 553 | memcpy(buffer, path_phys, sizeof(buffer)); |
551 | 554 | pathptr = &buffer[strlen(buffer)]; |
552 | 555 | |
553 | | for( i = 0; i < array_size(uh_index_files); i++ ) |
| 556 | if( cl->server->conf->index_file ) |
554 | 557 | { |
555 | | strncat(buffer, uh_index_files[i], sizeof(buffer)); |
| 558 | strncat(buffer, cl->server->conf->index_file, sizeof(buffer)); |
556 | 559 | |
557 | 560 | if( !stat(buffer, &s) && (s.st_mode & S_IFREG) ) |
558 | 561 | { |
559 | 562 | memcpy(path_phys, buffer, sizeof(path_phys)); |
560 | 563 | memcpy(&p.stat, &s, sizeof(p.stat)); |
561 | | break; |
562 | 564 | } |
| 565 | } |
| 566 | else |
| 567 | { |
| 568 | for( i = 0; i < array_size(uh_index_files); i++ ) |
| 569 | { |
| 570 | strncat(buffer, uh_index_files[i], sizeof(buffer)); |
563 | 571 | |
564 | | *pathptr = 0; |
| 572 | if( !stat(buffer, &s) && (s.st_mode & S_IFREG) ) |
| 573 | { |
| 574 | memcpy(path_phys, buffer, sizeof(path_phys)); |
| 575 | memcpy(&p.stat, &s, sizeof(p.stat)); |
| 576 | break; |
| 577 | } |
| 578 | |
| 579 | *pathptr = 0; |
| 580 | } |
565 | 581 | } |
566 | 582 | |
567 | 583 | p.root = docroot; |
package/uhttpd/src/uhttpd.c |
47 | 47 | while( waitpid(-1, NULL, WNOHANG) > 0 ) { } |
48 | 48 | } |
49 | 49 | |
50 | | static void uh_config_parse(const char *path) |
| 50 | static void uh_config_parse(struct config *conf) |
51 | 51 | { |
52 | 52 | FILE *c; |
53 | 53 | char line[512]; |
... | ... | |
55 | 55 | char *pass = NULL; |
56 | 56 | char *eol = NULL; |
57 | 57 | |
58 | | if( (c = fopen(path ? path : "/etc/httpd.conf", "r")) != NULL ) |
| 58 | const char *path = conf->file ? conf->file : "/etc/httpd.conf"; |
| 59 | |
| 60 | |
| 61 | if( (c = fopen(path, "r")) != NULL ) |
59 | 62 | { |
60 | 63 | memset(line, 0, sizeof(line)); |
61 | 64 | |
... | ... | |
74 | 77 | "Notice: No password set for user %s, ignoring " |
75 | 78 | "authentication on %s\n", user, line |
76 | 79 | ); |
| 80 | } |
| 81 | } |
| 82 | else if( !strncmp(line, "I:", 2) ) |
| 83 | { |
| 84 | if( !(user = strchr(line, ':')) || (*user++ = 0) || |
| 85 | !(eol = strchr(user, '\n')) || (*eol++ = 0) ) |
| 86 | continue; |
77 | 87 | |
78 | | break; |
79 | | } |
| 88 | conf->index_file = strdup(user); |
| 89 | } |
| 90 | else if( !strncmp(line, "E404:", 5) ) |
| 91 | { |
| 92 | if( !(user = strchr(line, ':')) || (*user++ = 0) || |
| 93 | !(eol = strchr(user, '\n')) || (*eol++ = 0) ) |
| 94 | continue; |
| 95 | |
| 96 | conf->error_handler = strdup(user); |
80 | 97 | } |
81 | 98 | } |
82 | 99 | |
... | ... | |
302 | 319 | } |
303 | 320 | |
304 | 321 | /* valid enough */ |
| 322 | req.redirect_status = 200; |
305 | 323 | return &req; |
306 | 324 | } |
307 | 325 | |
... | ... | |
505 | 523 | } |
506 | 524 | #endif |
507 | 525 | |
508 | | while( (opt = getopt(argc, argv, "fSC:K:p:s:h:c:l:L:d:r:m:x:t:T:")) > 0 ) |
509 | | { |
| 526 | while( (opt = getopt(argc, argv, |
| 527 | "fSDC:K:E:I:p:s:h:c:l:L:d:r:m:x:t:T:")) > 0 |
| 528 | ) { |
510 | 529 | switch(opt) |
511 | 530 | { |
512 | 531 | /* [addr:]port */ |
... | ... | |
597 | 616 | } |
598 | 617 | break; |
599 | 618 | |
| 619 | /* error handler */ |
| 620 | case 'E': |
| 621 | if( (strlen(optarg) == 0) || (optarg[0] != '/') ) |
| 622 | { |
| 623 | fprintf(stderr, "Error: Invalid error handler: %s\n", |
| 624 | optarg); |
| 625 | exit(1); |
| 626 | } |
| 627 | conf.error_handler = optarg; |
| 628 | break; |
| 629 | |
| 630 | /* index file */ |
| 631 | case 'I': |
| 632 | if( (strlen(optarg) == 0) || (optarg[0] == '/') ) |
| 633 | { |
| 634 | fprintf(stderr, "Error: Invalid index page: %s\n", |
| 635 | optarg); |
| 636 | exit(1); |
| 637 | } |
| 638 | conf.index_file = optarg; |
| 639 | break; |
| 640 | |
600 | 641 | /* don't follow symlinks */ |
601 | 642 | case 'S': |
602 | 643 | conf.no_symlinks = 1; |
603 | 644 | break; |
604 | 645 | |
| 646 | /* don't list directories */ |
| 647 | case 'D': |
| 648 | conf.no_dirlists = 1; |
| 649 | break; |
| 650 | |
605 | 651 | #ifdef HAVE_CGI |
606 | 652 | /* cgi prefix */ |
607 | 653 | case 'x': |
... | ... | |
678 | 724 | " -K file ASN.1 server private key file\n" |
679 | 725 | #endif |
680 | 726 | " -h directory Specify the document root, default is '.'\n" |
| 727 | " -E string Use given virtual URL as 404 error handler\n" |
| 728 | " -I string Use given filename as index page for directories\n" |
681 | 729 | " -S Do not follow symbolic links outside of the docroot\n" |
| 730 | " -D Do not allow directory listings, send 403 instead\n" |
682 | 731 | #ifdef HAVE_LUA |
683 | 732 | " -l string URL prefix for Lua handler, default is '/lua'\n" |
684 | 733 | " -L file Lua handler script, omit to disable Lua\n" |
... | ... | |
727 | 776 | conf.realm = "Protected Area"; |
728 | 777 | |
729 | 778 | /* config file */ |
730 | | uh_config_parse(conf.file); |
| 779 | uh_config_parse(&conf); |
731 | 780 | |
732 | 781 | /* default network timeout */ |
733 | 782 | if( conf.network_timeout <= 0 ) |
... | ... | |
913 | 962 | /* 404 */ |
914 | 963 | else |
915 | 964 | { |
916 | | uh_http_sendhf(cl, 404, "Not Found", |
917 | | "No such file or directory"); |
| 965 | /* Try to invoke an error handler */ |
| 966 | pin = uh_path_lookup(cl, conf.error_handler); |
| 967 | |
| 968 | if( pin && uh_auth_check(cl, req, pin) ) |
| 969 | { |
| 970 | req->redirect_status = 404; |
| 971 | |
| 972 | #ifdef HAVE_CGI |
| 973 | if( uh_path_match(conf.cgi_prefix, pin->name) ) |
| 974 | { |
| 975 | uh_cgi_request(cl, req, pin); |
| 976 | } |
| 977 | else |
| 978 | #endif |
| 979 | { |
| 980 | uh_file_request(cl, req, pin); |
| 981 | } |
| 982 | } |
| 983 | else |
| 984 | { |
| 985 | uh_http_sendhf(cl, 404, "Not Found", |
| 986 | "No such file or directory"); |
| 987 | } |
918 | 988 | } |
919 | 989 | } |
920 | 990 | |