diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-08-17 19:20:07 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-08-17 19:20:07 +0000 |
commit | 073214f89409a8b2a01bae70f7ce699944b2a3be (patch) | |
tree | 8a8ed39b502c8a67612790274300a3edb6c8f9ab | |
parent | 91adf7d5877ecc7587556b993808b63f6f249080 (diff) | |
download | busybox-w32-073214f89409a8b2a01bae70f7ce699944b2a3be.tar.gz busybox-w32-073214f89409a8b2a01bae70f7ce699944b2a3be.tar.bz2 busybox-w32-073214f89409a8b2a01bae70f7ce699944b2a3be.zip |
httpd shrink and logging update, part 5 of 7
text data bss dec hex filename
9836 0 0 9836 266c busybox.t1/networking/httpd.o.orig
9724 0 0 9724 25fc busybox.t2/networking/httpd.o
9657 0 0 9657 25b9 busybox.t3/networking/httpd.o
9342 0 0 9342 247e busybox.t4/networking/httpd.o
9342 0 0 9342 247e busybox.t5/networking/httpd.o
9262 0 0 9262 242e busybox.t6/networking/httpd.o
9283 0 0 9283 2443 busybox.t7/networking/httpd.o
9334 0 0 9334 2476 busybox.t8/networking/httpd.o
-rw-r--r-- | networking/httpd.c | 412 |
1 files changed, 198 insertions, 214 deletions
diff --git a/networking/httpd.c b/networking/httpd.c index 69d994a47..81660b2e6 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
@@ -20,7 +20,7 @@ | |||
20 | * httpd -p 80 -u 80 -h /www -c /etc/httpd.conf -r "Web Server Authentication" | 20 | * httpd -p 80 -u 80 -h /www -c /etc/httpd.conf -r "Web Server Authentication" |
21 | * | 21 | * |
22 | * | 22 | * |
23 | * When a url contains "cgi-bin" it is assumed to be a cgi script. The | 23 | * When a url starts by "/cgi-bin/" it is assumed to be a cgi script. The |
24 | * server changes directory to the location of the script and executes it | 24 | * server changes directory to the location of the script and executes it |
25 | * after setting QUERY_STRING and other environment variables. | 25 | * after setting QUERY_STRING and other environment variables. |
26 | * | 26 | * |
@@ -89,44 +89,45 @@ | |||
89 | * root configuration file. If -c is set and the file is not found, the | 89 | * root configuration file. If -c is set and the file is not found, the |
90 | * server exits with an error. | 90 | * server exits with an error. |
91 | * | 91 | * |
92 | */ | 92 | */ |
93 | 93 | ||
94 | #include "libbb.h" | 94 | #include "libbb.h" |
95 | #if ENABLE_FEATURE_HTTPD_USE_SENDFILE | 95 | #if ENABLE_FEATURE_HTTPD_USE_SENDFILE |
96 | #include <sys/sendfile.h> | 96 | #include <sys/sendfile.h> |
97 | #endif | 97 | #endif |
98 | 98 | ||
99 | //#define DEBUG 1 | ||
100 | #define DEBUG 0 | ||
101 | |||
99 | /* amount of buffering in a pipe */ | 102 | /* amount of buffering in a pipe */ |
100 | #ifndef PIPE_BUF | 103 | #ifndef PIPE_BUF |
101 | # define PIPE_BUF 4096 | 104 | # define PIPE_BUF 4096 |
102 | #endif | 105 | #endif |
103 | 106 | ||
104 | static const char default_path_httpd_conf[] ALIGN1 = "/etc"; | 107 | #define MAX_MEMORY_BUF 8192 /* IO buffer */ |
105 | static const char httpd_conf[] ALIGN1 = "httpd.conf"; | ||
106 | |||
107 | #define TIMEOUT 60 | ||
108 | 108 | ||
109 | // Note: busybox xfuncs are not used because we want the server to keep running | 109 | #define HEADER_READ_TIMEOUT 60 |
110 | // if something bad happens due to a malformed user request. | ||
111 | // As a result, all memory allocations after daemonize | ||
112 | // are checked rigorously | ||
113 | 110 | ||
114 | //#define DEBUG 1 | 111 | static const char default_path_httpd_conf[] ALIGN1 = "/etc"; |
115 | #define DEBUG 0 | 112 | static const char httpd_conf[] ALIGN1 = "httpd.conf"; |
116 | 113 | ||
117 | #define MAX_MEMORY_BUF 8192 /* IO buffer */ | 114 | typedef struct has_next_ptr { |
115 | struct has_next_ptr *next; | ||
116 | } has_next_ptr; | ||
118 | 117 | ||
118 | /* Must have "next" as a first member */ | ||
119 | typedef struct Htaccess { | 119 | typedef struct Htaccess { |
120 | char *after_colon; | ||
121 | struct Htaccess *next; | 120 | struct Htaccess *next; |
121 | char *after_colon; | ||
122 | char before_colon[1]; /* really bigger, must be last */ | 122 | char before_colon[1]; /* really bigger, must be last */ |
123 | } Htaccess; | 123 | } Htaccess; |
124 | 124 | ||
125 | /* Must have "next" as a first member */ | ||
125 | typedef struct Htaccess_IP { | 126 | typedef struct Htaccess_IP { |
127 | struct Htaccess_IP *next; | ||
126 | unsigned ip; | 128 | unsigned ip; |
127 | unsigned mask; | 129 | unsigned mask; |
128 | int allow_deny; | 130 | int allow_deny; |
129 | struct Htaccess_IP *next; | ||
130 | } Htaccess_IP; | 131 | } Htaccess_IP; |
131 | 132 | ||
132 | struct globals { | 133 | struct globals { |
@@ -199,30 +200,6 @@ struct globals { | |||
199 | ContentLength = -1; \ | 200 | ContentLength = -1; \ |
200 | } while (0) | 201 | } while (0) |
201 | 202 | ||
202 | static const char request_GET[] ALIGN1 = "GET"; /* size algorithmic optimize */ | ||
203 | |||
204 | static const char *const suffixTable[] = { | ||
205 | /* Warning: shorter equivalent suffix in one line must be first */ | ||
206 | ".htm.html", "text/html", | ||
207 | ".jpg.jpeg", "image/jpeg", | ||
208 | ".gif", "image/gif", | ||
209 | ".png", "image/png", | ||
210 | ".txt.h.c.cc.cpp", "text/plain", | ||
211 | ".css", "text/css", | ||
212 | ".wav", "audio/wav", | ||
213 | ".avi", "video/x-msvideo", | ||
214 | ".qt.mov", "video/quicktime", | ||
215 | ".mpe.mpeg", "video/mpeg", | ||
216 | ".mid.midi", "audio/midi", | ||
217 | ".mp3", "audio/mpeg", | ||
218 | #if 0 /* unpopular */ | ||
219 | ".au", "audio/basic", | ||
220 | ".pac", "application/x-ns-proxy-autoconfig", | ||
221 | ".vrml.wrl", "model/vrml", | ||
222 | #endif | ||
223 | 0, "application/octet-stream" /* default */ | ||
224 | }; | ||
225 | |||
226 | typedef enum { | 203 | typedef enum { |
227 | HTTP_OK = 200, | 204 | HTTP_OK = 200, |
228 | HTTP_MOVED_TEMPORARILY = 302, | 205 | HTTP_MOVED_TEMPORARILY = 302, |
@@ -285,11 +262,32 @@ static const HttpEnumString httpResponseNames[] = { | |||
285 | }; | 262 | }; |
286 | 263 | ||
287 | 264 | ||
288 | static const char RFC1123FMT[] ALIGN1 = "%a, %d %b %Y %H:%M:%S GMT"; | 265 | #define STRNCASECMP(a, str) strncasecmp((a), (str), sizeof(str)-1) |
289 | 266 | ||
267 | static void free_llist(has_next_ptr **pptr) | ||
268 | { | ||
269 | has_next_ptr *cur = *pptr; | ||
270 | while (cur) { | ||
271 | has_next_ptr *t = cur; | ||
272 | cur = cur->next; | ||
273 | free(t); | ||
274 | } | ||
275 | *pptr = NULL; | ||
276 | } | ||
290 | 277 | ||
291 | #define STRNCASECMP(a, str) strncasecmp((a), (str), sizeof(str)-1) | 278 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH \ |
279 | || ENABLE_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES \ | ||
280 | || ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR | ||
281 | static ALWAYS_INLINE void free_Htaccess_list(Htaccess **pptr) | ||
282 | { | ||
283 | free_llist((has_next_ptr**)pptr); | ||
284 | } | ||
285 | #endif | ||
292 | 286 | ||
287 | static ALWAYS_INLINE void free_Htaccess_IP_list(Htaccess_IP **pptr) | ||
288 | { | ||
289 | free_llist((has_next_ptr**)pptr); | ||
290 | } | ||
293 | 291 | ||
294 | static int scan_ip(const char **ep, unsigned *ip, unsigned char endc) | 292 | static int scan_ip(const char **ep, unsigned *ip, unsigned char endc) |
295 | { | 293 | { |
@@ -365,33 +363,8 @@ static int scan_ip_mask(const char *ipm, unsigned *ip, unsigned *mask) | |||
365 | return 0; | 363 | return 0; |
366 | } | 364 | } |
367 | 365 | ||
368 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH \ | 366 | /* |
369 | || ENABLE_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES \ | 367 | * Parse configuration file into in-memory linked list. |
370 | || ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR | ||
371 | static void free_config_lines(Htaccess **pprev) | ||
372 | { | ||
373 | Htaccess *prev = *pprev; | ||
374 | |||
375 | while (prev) { | ||
376 | Htaccess *cur = prev; | ||
377 | |||
378 | prev = cur->next; | ||
379 | free(cur); | ||
380 | } | ||
381 | *pprev = NULL; | ||
382 | } | ||
383 | #endif | ||
384 | |||
385 | /* flag */ | ||
386 | #define FIRST_PARSE 0 | ||
387 | #define SUBDIR_PARSE 1 | ||
388 | #define SIGNALED_PARSE 2 | ||
389 | #define FIND_FROM_HTTPD_ROOT 3 | ||
390 | /**************************************************************************** | ||
391 | * | ||
392 | > $Function: parse_conf() | ||
393 | * | ||
394 | * $Description: parse configuration file into in-memory linked list. | ||
395 | * | 368 | * |
396 | * The first non-white character is examined to determine if the config line | 369 | * The first non-white character is examined to determine if the config line |
397 | * is one of the following: | 370 | * is one of the following: |
@@ -404,14 +377,14 @@ static void free_config_lines(Htaccess **pprev) | |||
404 | * are also discarded. That is, previous settings are retained if flag is | 377 | * are also discarded. That is, previous settings are retained if flag is |
405 | * SUBDIR_PARSE. | 378 | * SUBDIR_PARSE. |
406 | * | 379 | * |
407 | * $Parameters: | 380 | * path Path where to look for httpd.conf (without filename). |
408 | * (const char *) path . . null for ip address checks, path for password | 381 | * flag Type of the parse request. |
409 | * checks. | 382 | */ |
410 | * (int) flag . . . . . . the source of the parse request. | 383 | /* flag */ |
411 | * | 384 | #define FIRST_PARSE 0 |
412 | * $Return: (None) | 385 | #define SUBDIR_PARSE 1 |
413 | * | 386 | #define SIGNALED_PARSE 2 |
414 | ****************************************************************************/ | 387 | #define FIND_FROM_HTTPD_ROOT 3 |
415 | static void parse_conf(const char *path, int flag) | 388 | static void parse_conf(const char *path, int flag) |
416 | { | 389 | { |
417 | FILE *f; | 390 | FILE *f; |
@@ -423,38 +396,28 @@ static void parse_conf(const char *path, int flag) | |||
423 | || ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR | 396 | || ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR |
424 | Htaccess *cur; | 397 | Htaccess *cur; |
425 | #endif | 398 | #endif |
426 | |||
427 | const char *cf = configFile; | 399 | const char *cf = configFile; |
428 | char buf[160]; | 400 | char buf[160]; |
429 | char *p0 = NULL; | 401 | char *p0 = NULL; |
430 | char *c, *p; | 402 | char *c, *p; |
403 | Htaccess_IP *pip; | ||
431 | 404 | ||
432 | /* free previous ip setup if present */ | 405 | /* discard old rules */ |
433 | Htaccess_IP *pip = ip_a_d; | 406 | free_Htaccess_IP_list(&ip_a_d); |
434 | |||
435 | while (pip) { | ||
436 | Htaccess_IP *cur_ipl = pip; | ||
437 | |||
438 | pip = cur_ipl->next; | ||
439 | free(cur_ipl); | ||
440 | } | ||
441 | ip_a_d = NULL; | ||
442 | |||
443 | flg_deny_all = 0; | 407 | flg_deny_all = 0; |
444 | |||
445 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH \ | 408 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH \ |
446 | || ENABLE_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES \ | 409 | || ENABLE_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES \ |
447 | || ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR | 410 | || ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR |
448 | /* retain previous auth and mime config only for subdir parse */ | 411 | /* retain previous auth and mime config only for subdir parse */ |
449 | if (flag != SUBDIR_PARSE) { | 412 | if (flag != SUBDIR_PARSE) { |
450 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH | 413 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH |
451 | free_config_lines(&g_auth); | 414 | free_Htaccess_list(&g_auth); |
452 | #endif | 415 | #endif |
453 | #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES | 416 | #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES |
454 | free_config_lines(&mime_a); | 417 | free_Htaccess_list(&mime_a); |
455 | #endif | 418 | #endif |
456 | #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR | 419 | #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR |
457 | free_config_lines(&script_i); | 420 | free_Htaccess_list(&script_i); |
458 | #endif | 421 | #endif |
459 | } | 422 | } |
460 | #endif | 423 | #endif |
@@ -463,7 +426,7 @@ static void parse_conf(const char *path, int flag) | |||
463 | cf = alloca(strlen(path) + sizeof(httpd_conf) + 2); | 426 | cf = alloca(strlen(path) + sizeof(httpd_conf) + 2); |
464 | if (cf == NULL) { | 427 | if (cf == NULL) { |
465 | if (flag == FIRST_PARSE) | 428 | if (flag == FIRST_PARSE) |
466 | bb_error_msg_and_die(bb_msg_memory_exhausted); | 429 | bb_error_msg_and_die(bb_msg_memory_exhausted); |
467 | return; | 430 | return; |
468 | } | 431 | } |
469 | sprintf((char *)cf, "%s/%s", path, httpd_conf); | 432 | sprintf((char *)cf, "%s/%s", path, httpd_conf); |
@@ -486,21 +449,21 @@ static void parse_conf(const char *path, int flag) | |||
486 | /* This could stand some work */ | 449 | /* This could stand some work */ |
487 | while ((p0 = fgets(buf, sizeof(buf), f)) != NULL) { | 450 | while ((p0 = fgets(buf, sizeof(buf), f)) != NULL) { |
488 | c = NULL; | 451 | c = NULL; |
489 | for (p = p0; *p0 != 0 && *p0 != '#'; p0++) { | 452 | for (p = p0; *p0 != '\0' && *p0 != '#'; p0++) { |
490 | if (!isspace(*p0)) { | 453 | if (!isspace(*p0)) { |
491 | *p++ = *p0; | 454 | *p++ = *p0; |
492 | if (*p0 == ':' && c == NULL) | 455 | if (*p0 == ':' && c == NULL) |
493 | c = p; | 456 | c = p; |
494 | } | 457 | } |
495 | } | 458 | } |
496 | *p = 0; | 459 | *p = '\0'; |
497 | 460 | ||
498 | /* test for empty or strange line */ | 461 | /* test for empty or strange line */ |
499 | if (c == NULL || *c == 0) | 462 | if (c == NULL || *c == '\0') |
500 | continue; | 463 | continue; |
501 | p0 = buf; | 464 | p0 = buf; |
502 | if (*p0 == 'd') | 465 | if (*p0 == 'd') |
503 | *p0 = 'D'; | 466 | *p0 = 'D'; |
504 | if (*c == '*') { | 467 | if (*c == '*') { |
505 | if (*p0 == 'D') { | 468 | if (*p0 == 'D') { |
506 | /* memorize deny all */ | 469 | /* memorize deny all */ |
@@ -535,7 +498,7 @@ static void parse_conf(const char *path, int flag) | |||
535 | } | 498 | } |
536 | pip->allow_deny = *p0; | 499 | pip->allow_deny = *p0; |
537 | if (*p0 == 'D') { | 500 | if (*p0 == 'D') { |
538 | /* Deny:form_IP move top */ | 501 | /* Deny:from_IP move top */ |
539 | pip->next = ip_a_d; | 502 | pip->next = ip_a_d; |
540 | ip_a_d = pip; | 503 | ip_a_d = pip; |
541 | } else { | 504 | } else { |
@@ -555,12 +518,12 @@ static void parse_conf(const char *path, int flag) | |||
555 | } | 518 | } |
556 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH | 519 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH |
557 | if (*p0 == '/') { | 520 | if (*p0 == '/') { |
558 | /* make full path from httpd root / curent_path / config_line_path */ | 521 | /* make full path from httpd root / current_path / config_line_path */ |
559 | cf = flag == SUBDIR_PARSE ? path : ""; | 522 | cf = (flag == SUBDIR_PARSE ? path : ""); |
560 | p0 = malloc(strlen(cf) + (c - buf) + 2 + strlen(c)); | 523 | p0 = malloc(strlen(cf) + (c - buf) + 2 + strlen(c)); |
561 | if (p0 == NULL) | 524 | if (p0 == NULL) |
562 | continue; | 525 | continue; |
563 | c[-1] = 0; | 526 | c[-1] = '\0'; |
564 | sprintf(p0, "/%s%s", cf, buf); | 527 | sprintf(p0, "/%s%s", cf, buf); |
565 | 528 | ||
566 | /* another call bb_simplify_path */ | 529 | /* another call bb_simplify_path */ |
@@ -571,9 +534,9 @@ static void parse_conf(const char *path, int flag) | |||
571 | if (*cf == '/') { /* skip duplicate (or initial) slash */ | 534 | if (*cf == '/') { /* skip duplicate (or initial) slash */ |
572 | continue; | 535 | continue; |
573 | } else if (*cf == '.') { | 536 | } else if (*cf == '.') { |
574 | if (cf[1] == '/' || cf[1] == 0) { /* remove extra '.' */ | 537 | if (cf[1] == '/' || cf[1] == '\0') { /* remove extra '.' */ |
575 | continue; | 538 | continue; |
576 | } else if ((cf[1] == '.') && (cf[2] == '/' || cf[2] == 0)) { | 539 | } else if ((cf[1] == '.') && (cf[2] == '/' || cf[2] == '\0')) { |
577 | ++cf; | 540 | ++cf; |
578 | if (p > p0) { | 541 | if (p > p0) { |
579 | while (*--p != '/') /* omit previous dir */; | 542 | while (*--p != '/') /* omit previous dir */; |
@@ -588,7 +551,7 @@ static void parse_conf(const char *path, int flag) | |||
588 | if ((p == p0) || (*p != '/')) { /* not a trailing slash */ | 551 | if ((p == p0) || (*p != '/')) { /* not a trailing slash */ |
589 | ++p; /* so keep last character */ | 552 | ++p; /* so keep last character */ |
590 | } | 553 | } |
591 | *p = 0; | 554 | *p = '\0'; |
592 | sprintf(p0, "%s:%s", p0, c); | 555 | sprintf(p0, "%s:%s", p0, c); |
593 | } | 556 | } |
594 | #endif | 557 | #endif |
@@ -658,23 +621,14 @@ static void parse_conf(const char *path, int flag) | |||
658 | } | 621 | } |
659 | 622 | ||
660 | #if ENABLE_FEATURE_HTTPD_ENCODE_URL_STR | 623 | #if ENABLE_FEATURE_HTTPD_ENCODE_URL_STR |
661 | /**************************************************************************** | 624 | /* |
662 | * | 625 | * Given a string, html-encode special characters. |
663 | > $Function: encodeString() | 626 | * This is used for the -e command line option to provide an easy way |
664 | * | 627 | * for scripts to encode result data without confusing browsers. The |
665 | * $Description: Given a string, html encode special characters. | 628 | * returned string pointer is memory allocated by malloc(). |
666 | * This is used for the -e command line option to provide an easy way | ||
667 | * for scripts to encode result data without confusing browsers. The | ||
668 | * returned string pointer is memory allocated by malloc(). | ||
669 | * | ||
670 | * $Parameters: | ||
671 | * (const char *) string . . The first string to encode. | ||
672 | * | ||
673 | * $Return: (char *) . . . .. . . A pointer to the encoded string. | ||
674 | * | ||
675 | * $Errors: Returns a null string ("") if memory is not available. | ||
676 | * | 629 | * |
677 | ****************************************************************************/ | 630 | * Returns a pointer to the encoded string (malloced). |
631 | */ | ||
678 | static char *encodeString(const char *string) | 632 | static char *encodeString(const char *string) |
679 | { | 633 | { |
680 | /* take the simple route and encode everything */ | 634 | /* take the simple route and encode everything */ |
@@ -694,25 +648,18 @@ static char *encodeString(const char *string) | |||
694 | } | 648 | } |
695 | #endif /* FEATURE_HTTPD_ENCODE_URL_STR */ | 649 | #endif /* FEATURE_HTTPD_ENCODE_URL_STR */ |
696 | 650 | ||
697 | /**************************************************************************** | 651 | /* |
698 | * | 652 | * Given a URL encoded string, convert it to plain ascii. |
699 | > $Function: decodeString() | 653 | * Since decoding always makes strings smaller, the decode is done in-place. |
700 | * | 654 | * Thus, callers should strdup() the argument if they do not want the |
701 | * $Description: Given a URL encoded string, convert it to plain ascii. | 655 | * argument modified. The return is the original pointer, allowing this |
702 | * Since decoding always makes strings smaller, the decode is done in-place. | 656 | * function to be easily used as arguments to other functions. |
703 | * Thus, callers should strdup() the argument if they do not want the | ||
704 | * argument modified. The return is the original pointer, allowing this | ||
705 | * function to be easily used as arguments to other functions. | ||
706 | * | ||
707 | * $Parameters: | ||
708 | * (char *) string . . . The first string to decode. | ||
709 | * (int) option_d . . 1 if called for httpd -d | ||
710 | * | ||
711 | * $Return: (char *) . . . . A pointer to the decoded string (same as input). | ||
712 | * | 657 | * |
713 | * $Errors: None | 658 | * string The first string to decode. |
659 | * option_d 1 if called for httpd -d | ||
714 | * | 660 | * |
715 | ****************************************************************************/ | 661 | * Returns a pointer to the decoded string (same as input). |
662 | */ | ||
716 | static char *decodeString(char *orig, int option_d) | 663 | static char *decodeString(char *orig, int option_d) |
717 | { | 664 | { |
718 | /* note that decoded string is always shorter than original */ | 665 | /* note that decoded string is always shorter than original */ |
@@ -754,9 +701,9 @@ static char *decodeString(char *orig, int option_d) | |||
754 | 701 | ||
755 | 702 | ||
756 | #if ENABLE_FEATURE_HTTPD_CGI | 703 | #if ENABLE_FEATURE_HTTPD_CGI |
757 | /**************************************************************************** | 704 | /* |
758 | * setenv helpers | 705 | * setenv helpers |
759 | ****************************************************************************/ | 706 | */ |
760 | static void setenv1(const char *name, const char *value) | 707 | static void setenv1(const char *name, const char *value) |
761 | { | 708 | { |
762 | if (!value) | 709 | if (!value) |
@@ -773,10 +720,10 @@ static void setenv_long(const char *name, long value) | |||
773 | 720 | ||
774 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH | 721 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH |
775 | /* | 722 | /* |
776 | * Decode a base 64 data stream as per rfc1521. | 723 | * Decode a base64 data stream as per rfc1521. |
777 | * Note that the rfc states that non base64 chars are to be ignored. | 724 | * Note that the rfc states that non base64 chars are to be ignored. |
778 | * Since the decode always results in a shorter size than the input, it is | 725 | * Since the decode always results in a shorter size than the input, |
779 | * OK to pass the input arg as an output arg. | 726 | * it is OK to pass the input arg as an output arg. |
780 | * Parameter: a pointer to a base64 encoded string. | 727 | * Parameter: a pointer to a base64 encoded string. |
781 | * Decoded data is stored in-place. | 728 | * Decoded data is stored in-place. |
782 | */ | 729 | */ |
@@ -818,18 +765,9 @@ static void decodeBase64(char *Data) | |||
818 | } | 765 | } |
819 | #endif | 766 | #endif |
820 | 767 | ||
821 | 768 | /* | |
822 | /**************************************************************************** | 769 | * Create a listen server socket on the designated port. |
823 | * | 770 | */ |
824 | > $Function: openServer() | ||
825 | * | ||
826 | * $Description: create a listen server socket on the designated port. | ||
827 | * | ||
828 | * $Return: (int) . . . A connection socket. -1 for errors. | ||
829 | * | ||
830 | * $Errors: None | ||
831 | * | ||
832 | ****************************************************************************/ | ||
833 | #if BB_MMU | 771 | #if BB_MMU |
834 | static int openServer(void) | 772 | static int openServer(void) |
835 | { | 773 | { |
@@ -853,6 +791,8 @@ static int openServer(void) | |||
853 | */ | 791 | */ |
854 | static int sendHeaders(HttpResponseNum responseNum) | 792 | static int sendHeaders(HttpResponseNum responseNum) |
855 | { | 793 | { |
794 | static const char RFC1123FMT[] ALIGN1 = "%a, %d %b %Y %H:%M:%S GMT"; | ||
795 | |||
856 | const char *responseString = ""; | 796 | const char *responseString = ""; |
857 | const char *infoString = NULL; | 797 | const char *infoString = NULL; |
858 | const char *mime_type; | 798 | const char *mime_type; |
@@ -1318,6 +1258,28 @@ static void send_cgi_and_exit( | |||
1318 | static void send_file_and_exit(const char *url) ATTRIBUTE_NORETURN; | 1258 | static void send_file_and_exit(const char *url) ATTRIBUTE_NORETURN; |
1319 | static void send_file_and_exit(const char *url) | 1259 | static void send_file_and_exit(const char *url) |
1320 | { | 1260 | { |
1261 | static const char *const suffixTable[] = { | ||
1262 | /* Warning: shorter equivalent suffix in one line must be first */ | ||
1263 | ".htm.html", "text/html", | ||
1264 | ".jpg.jpeg", "image/jpeg", | ||
1265 | ".gif", "image/gif", | ||
1266 | ".png", "image/png", | ||
1267 | ".txt.h.c.cc.cpp", "text/plain", | ||
1268 | ".css", "text/css", | ||
1269 | ".wav", "audio/wav", | ||
1270 | ".avi", "video/x-msvideo", | ||
1271 | ".qt.mov", "video/quicktime", | ||
1272 | ".mpe.mpeg", "video/mpeg", | ||
1273 | ".mid.midi", "audio/midi", | ||
1274 | ".mp3", "audio/mpeg", | ||
1275 | #if 0 /* unpopular */ | ||
1276 | ".au", "audio/basic", | ||
1277 | ".pac", "application/x-ns-proxy-autoconfig", | ||
1278 | ".vrml.wrl", "model/vrml", | ||
1279 | #endif | ||
1280 | NULL | ||
1281 | }; | ||
1282 | |||
1321 | char *suffix; | 1283 | char *suffix; |
1322 | int f; | 1284 | int f; |
1323 | int fd; | 1285 | int fd; |
@@ -1330,25 +1292,31 @@ static void send_file_and_exit(const char *url) | |||
1330 | 1292 | ||
1331 | suffix = strrchr(url, '.'); | 1293 | suffix = strrchr(url, '.'); |
1332 | 1294 | ||
1333 | for (table = suffixTable; *table; table += 2) | 1295 | /* If not found, set default as "application/octet-stream"; */ |
1334 | if (suffix != NULL && (try_suffix = strstr(*table, suffix)) != 0) { | 1296 | found_mime_type = "application/octet-stream"; |
1335 | try_suffix += strlen(suffix); | 1297 | if (suffix) { |
1336 | if (*try_suffix == 0 || *try_suffix == '.') | 1298 | #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES |
1337 | break; | 1299 | Htaccess *cur; |
1300 | #endif | ||
1301 | for (table = suffixTable; *table; table += 2) { | ||
1302 | try_suffix = strstr(table[0], suffix); | ||
1303 | if (try_suffix) { | ||
1304 | try_suffix += strlen(suffix); | ||
1305 | if (*try_suffix == '\0' || *try_suffix == '.') { | ||
1306 | found_mime_type = table[1]; | ||
1307 | break; | ||
1308 | } | ||
1309 | } | ||
1338 | } | 1310 | } |
1339 | /* also, if not found, set default as "application/octet-stream"; */ | ||
1340 | found_mime_type = table[1]; | ||
1341 | #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES | 1311 | #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES |
1342 | if (suffix) { | ||
1343 | Htaccess * cur; | ||
1344 | for (cur = mime_a; cur; cur = cur->next) { | 1312 | for (cur = mime_a; cur; cur = cur->next) { |
1345 | if (strcmp(cur->before_colon, suffix) == 0) { | 1313 | if (strcmp(cur->before_colon, suffix) == 0) { |
1346 | found_mime_type = cur->after_colon; | 1314 | found_mime_type = cur->after_colon; |
1347 | break; | 1315 | break; |
1348 | } | 1316 | } |
1349 | } | 1317 | } |
1318 | #endif | ||
1350 | } | 1319 | } |
1351 | #endif /* FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES */ | ||
1352 | 1320 | ||
1353 | if (DEBUG) | 1321 | if (DEBUG) |
1354 | bb_error_msg("sending file '%s' content-type: %s", | 1322 | bb_error_msg("sending file '%s' content-type: %s", |
@@ -1426,27 +1394,21 @@ static int checkPermIP(void) | |||
1426 | return !flg_deny_all; | 1394 | return !flg_deny_all; |
1427 | } | 1395 | } |
1428 | 1396 | ||
1429 | /**************************************************************************** | 1397 | /* |
1430 | * | 1398 | * Check the permission file for access password protected. |
1431 | > $Function: checkPerm() | ||
1432 | * | ||
1433 | * $Description: Check the permission file for access password protected. | ||
1434 | * | ||
1435 | * If config file isn't present, everything is allowed. | ||
1436 | * Entries are of the form you can see example from header source | ||
1437 | * | 1399 | * |
1438 | * $Parameters: | 1400 | * If config file isn't present, everything is allowed. |
1439 | * (const char *) path . . . . The file path. | 1401 | * Entries are of the form you can see example from header source |
1440 | * (const char *) request . . . User information to validate. | ||
1441 | * | 1402 | * |
1442 | * $Return: (int) . . . . . . . . . 1 if request OK, 0 otherwise. | 1403 | * path The file path. |
1404 | * request User information to validate. | ||
1443 | * | 1405 | * |
1444 | ****************************************************************************/ | 1406 | * Returns 1 if request is OK. |
1445 | 1407 | */ | |
1446 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH | 1408 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH |
1447 | static int checkPerm(const char *path, const char *request) | 1409 | static int checkPerm(const char *path, const char *request) |
1448 | { | 1410 | { |
1449 | Htaccess * cur; | 1411 | Htaccess *cur; |
1450 | const char *p; | 1412 | const char *p; |
1451 | const char *p0; | 1413 | const char *p0; |
1452 | 1414 | ||
@@ -1481,7 +1443,7 @@ static int checkPerm(const char *path, const char *request) | |||
1481 | char *cipher; | 1443 | char *cipher; |
1482 | char *pp; | 1444 | char *pp; |
1483 | 1445 | ||
1484 | if (strncmp(p, request, u-request) != 0) { | 1446 | if (strncmp(p, request, u - request) != 0) { |
1485 | /* user uncompared */ | 1447 | /* user uncompared */ |
1486 | continue; | 1448 | continue; |
1487 | } | 1449 | } |
@@ -1528,15 +1490,17 @@ static void exit_on_signal(int sig) | |||
1528 | static void handle_incoming_and_exit(void) ATTRIBUTE_NORETURN; | 1490 | static void handle_incoming_and_exit(void) ATTRIBUTE_NORETURN; |
1529 | static void handle_incoming_and_exit(void) | 1491 | static void handle_incoming_and_exit(void) |
1530 | { | 1492 | { |
1493 | static const char request_GET[] ALIGN1 = "GET"; | ||
1494 | |||
1531 | char *url; | 1495 | char *url; |
1532 | char *purl; | 1496 | char *purl; |
1533 | int count; | 1497 | int count; |
1534 | int blank = -1; | 1498 | int http_major_version; |
1535 | char *test; | 1499 | char *test; |
1536 | struct stat sb; | 1500 | struct stat sb; |
1537 | int ip_allowed; | 1501 | int ip_allowed; |
1538 | #if ENABLE_FEATURE_HTTPD_CGI | 1502 | #if ENABLE_FEATURE_HTTPD_CGI |
1539 | const char *prequest = request_GET; | 1503 | const char *prequest; |
1540 | unsigned long length = 0; | 1504 | unsigned long length = 0; |
1541 | char *cookie = 0; | 1505 | char *cookie = 0; |
1542 | char *content_type = 0; | 1506 | char *content_type = 0; |
@@ -1546,21 +1510,24 @@ static void handle_incoming_and_exit(void) | |||
1546 | int credentials = -1; /* if not required this is Ok */ | 1510 | int credentials = -1; /* if not required this is Ok */ |
1547 | #endif | 1511 | #endif |
1548 | 1512 | ||
1513 | /* Install timeout handler */ | ||
1549 | sa.sa_handler = exit_on_signal; | 1514 | sa.sa_handler = exit_on_signal; |
1550 | sigemptyset(&sa.sa_mask); | 1515 | sigemptyset(&sa.sa_mask); |
1551 | sa.sa_flags = 0; /* no SA_RESTART */ | 1516 | sa.sa_flags = 0; /* no SA_RESTART */ |
1552 | sigaction(SIGALRM, &sa, NULL); | 1517 | sigaction(SIGALRM, &sa, NULL); |
1518 | alarm(HEADER_READ_TIMEOUT); | ||
1553 | 1519 | ||
1554 | alarm(TIMEOUT); | ||
1555 | if (!get_line()) | 1520 | if (!get_line()) |
1556 | _exit(0); /* EOF or error or empty line */ | 1521 | _exit(0); /* EOF or error or empty line */ |
1557 | 1522 | ||
1523 | /* Determine type of request (GET/POST) */ | ||
1558 | purl = strpbrk(iobuf, " \t"); | 1524 | purl = strpbrk(iobuf, " \t"); |
1559 | if (purl == NULL) { | 1525 | if (purl == NULL) { |
1560 | send_headers_and_exit(HTTP_BAD_REQUEST); | 1526 | send_headers_and_exit(HTTP_BAD_REQUEST); |
1561 | } | 1527 | } |
1562 | *purl = '\0'; | 1528 | *purl = '\0'; |
1563 | #if ENABLE_FEATURE_HTTPD_CGI | 1529 | #if ENABLE_FEATURE_HTTPD_CGI |
1530 | prequest = request_GET; | ||
1564 | if (strcasecmp(iobuf, prequest) != 0) { | 1531 | if (strcasecmp(iobuf, prequest) != 0) { |
1565 | prequest = "POST"; | 1532 | prequest = "POST"; |
1566 | if (strcasecmp(iobuf, prequest) != 0) { | 1533 | if (strcasecmp(iobuf, prequest) != 0) { |
@@ -1573,8 +1540,10 @@ static void handle_incoming_and_exit(void) | |||
1573 | } | 1540 | } |
1574 | #endif | 1541 | #endif |
1575 | *purl = ' '; | 1542 | *purl = ' '; |
1576 | count = sscanf(purl, " %[^ ] HTTP/%d.%*d", iobuf, &blank); | ||
1577 | 1543 | ||
1544 | /* Copy URL from after "GET "/"POST " to stack-allocated char[] */ | ||
1545 | http_major_version = -1; | ||
1546 | count = sscanf(purl, " %[^ ] HTTP/%d.%*d", iobuf, &http_major_version); | ||
1578 | if (count < 1 || iobuf[0] != '/') { | 1547 | if (count < 1 || iobuf[0] != '/') { |
1579 | /* Garbled request/URL */ | 1548 | /* Garbled request/URL */ |
1580 | send_headers_and_exit(HTTP_BAD_REQUEST); | 1549 | send_headers_and_exit(HTTP_BAD_REQUEST); |
@@ -1584,7 +1553,8 @@ static void handle_incoming_and_exit(void) | |||
1584 | send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR); | 1553 | send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR); |
1585 | } | 1554 | } |
1586 | strcpy(url, iobuf); | 1555 | strcpy(url, iobuf); |
1587 | /* extract url args if present */ | 1556 | |
1557 | /* Extract url args if present */ | ||
1588 | test = strchr(url, '?'); | 1558 | test = strchr(url, '?'); |
1589 | g_query = NULL; | 1559 | g_query = NULL; |
1590 | if (test) { | 1560 | if (test) { |
@@ -1592,6 +1562,7 @@ static void handle_incoming_and_exit(void) | |||
1592 | g_query = test; | 1562 | g_query = test; |
1593 | } | 1563 | } |
1594 | 1564 | ||
1565 | /* Decode URL escape sequences */ | ||
1595 | test = decodeString(url, 0); | 1566 | test = decodeString(url, 0); |
1596 | if (test == NULL) | 1567 | if (test == NULL) |
1597 | send_headers_and_exit(HTTP_BAD_REQUEST); | 1568 | send_headers_and_exit(HTTP_BAD_REQUEST); |
@@ -1600,7 +1571,8 @@ static void handle_incoming_and_exit(void) | |||
1600 | send_headers_and_exit(HTTP_NOT_FOUND); | 1571 | send_headers_and_exit(HTTP_NOT_FOUND); |
1601 | } | 1572 | } |
1602 | 1573 | ||
1603 | /* algorithm stolen from libbb bb_simplify_path(), | 1574 | /* Canonicalize path */ |
1575 | /* Algorithm stolen from libbb bb_simplify_path(), | ||
1604 | * but don't strdup and reducing trailing slash and protect out root */ | 1576 | * but don't strdup and reducing trailing slash and protect out root */ |
1605 | purl = test = url; | 1577 | purl = test = url; |
1606 | do { | 1578 | do { |
@@ -1631,13 +1603,14 @@ static void handle_incoming_and_exit(void) | |||
1631 | *++purl = '\0'; /* so keep last character */ | 1603 | *++purl = '\0'; /* so keep last character */ |
1632 | test = purl; /* end ptr */ | 1604 | test = purl; /* end ptr */ |
1633 | 1605 | ||
1634 | /* If URL is directory, adding '/' */ | 1606 | /* If URL is a directory, add '/' */ |
1635 | if (test[-1] != '/') { | 1607 | if (test[-1] != '/') { |
1636 | if (is_directory(url + 1, 1, &sb)) { | 1608 | if (is_directory(url + 1, 1, &sb)) { |
1637 | found_moved_temporarily = url; | 1609 | found_moved_temporarily = url; |
1638 | } | 1610 | } |
1639 | } | 1611 | } |
1640 | 1612 | ||
1613 | /* Log it */ | ||
1641 | if (verbose > 1) | 1614 | if (verbose > 1) |
1642 | bb_error_msg("url:%s", url); | 1615 | bb_error_msg("url:%s", url); |
1643 | 1616 | ||
@@ -1653,15 +1626,17 @@ static void handle_incoming_and_exit(void) | |||
1653 | } | 1626 | } |
1654 | *test = '/'; | 1627 | *test = '/'; |
1655 | } | 1628 | } |
1656 | if (blank >= 0) { | 1629 | if (http_major_version >= 0) { |
1657 | /* read until blank line for HTTP version specified, else parse immediate */ | 1630 | /* Request was with "... HTTP/n.m", and n >= 0 */ |
1631 | |||
1632 | /* Read until blank line for HTTP version specified, else parse immediate */ | ||
1658 | while (1) { | 1633 | while (1) { |
1659 | alarm(TIMEOUT); | 1634 | alarm(HEADER_READ_TIMEOUT); |
1660 | if (!get_line()) | 1635 | if (!get_line()) |
1661 | break; /* EOF or error or empty line */ | 1636 | break; /* EOF or error or empty line */ |
1662 | |||
1663 | if (DEBUG) | 1637 | if (DEBUG) |
1664 | bb_error_msg("header: '%s'", iobuf); | 1638 | bb_error_msg("header: '%s'", iobuf); |
1639 | |||
1665 | #if ENABLE_FEATURE_HTTPD_CGI | 1640 | #if ENABLE_FEATURE_HTTPD_CGI |
1666 | /* try and do our best to parse more lines */ | 1641 | /* try and do our best to parse more lines */ |
1667 | if ((STRNCASECMP(iobuf, "Content-length:") == 0)) { | 1642 | if ((STRNCASECMP(iobuf, "Content-length:") == 0)) { |
@@ -1707,6 +1682,7 @@ static void handle_incoming_and_exit(void) | |||
1707 | } /* while extra header reading */ | 1682 | } /* while extra header reading */ |
1708 | } | 1683 | } |
1709 | 1684 | ||
1685 | /* We read everything, disable peer timeout */ | ||
1710 | alarm(0); | 1686 | alarm(0); |
1711 | 1687 | ||
1712 | if (strcmp(bb_basename(url), httpd_conf) == 0 || ip_allowed == 0) { | 1688 | if (strcmp(bb_basename(url), httpd_conf) == 0 || ip_allowed == 0) { |
@@ -1727,9 +1703,9 @@ static void handle_incoming_and_exit(void) | |||
1727 | test = url + 1; /* skip first '/' */ | 1703 | test = url + 1; /* skip first '/' */ |
1728 | 1704 | ||
1729 | #if ENABLE_FEATURE_HTTPD_CGI | 1705 | #if ENABLE_FEATURE_HTTPD_CGI |
1730 | if (strncmp(test, "cgi-bin", 7) == 0) { | 1706 | if (strncmp(test, "cgi-bin/", 8) == 0) { |
1731 | if (test[7] == '/' && test[8] == '\0') { | 1707 | if (test[8] == '\0') { |
1732 | /* protect listing cgi-bin/ */ | 1708 | /* protect listing "cgi-bin/" */ |
1733 | send_headers_and_exit(HTTP_FORBIDDEN); | 1709 | send_headers_and_exit(HTTP_FORBIDDEN); |
1734 | } | 1710 | } |
1735 | send_cgi_and_exit(url, prequest, length, cookie, content_type); | 1711 | send_cgi_and_exit(url, prequest, length, cookie, content_type); |
@@ -1768,7 +1744,11 @@ static void handle_incoming_and_exit(void) | |||
1768 | send_cgi_and_exit("/cgi-bin/index.cgi", prequest, length, cookie, content_type); | 1744 | send_cgi_and_exit("/cgi-bin/index.cgi", prequest, length, cookie, content_type); |
1769 | } | 1745 | } |
1770 | } | 1746 | } |
1771 | #endif /* FEATURE_HTTPD_CGI */ | 1747 | #endif |
1748 | /* else { | ||
1749 | * fall through to send_file, it errors out if open fails | ||
1750 | * } | ||
1751 | */ | ||
1772 | 1752 | ||
1773 | send_file_and_exit(test); | 1753 | send_file_and_exit(test); |
1774 | 1754 | ||
@@ -1813,6 +1793,11 @@ static void handle_incoming_and_exit(void) | |||
1813 | static void mini_httpd(int server) ATTRIBUTE_NORETURN; | 1793 | static void mini_httpd(int server) ATTRIBUTE_NORETURN; |
1814 | static void mini_httpd(int server) | 1794 | static void mini_httpd(int server) |
1815 | { | 1795 | { |
1796 | /* NB: it's best to not use xfuncs in this loop before fork(). | ||
1797 | * Otherwise server may die on transient errors (temporary | ||
1798 | * out-of-memory condition, etc), which is Bad(tm). | ||
1799 | * Try to do any dangerous calls after fork. | ||
1800 | */ | ||
1816 | while (1) { | 1801 | while (1) { |
1817 | int n; | 1802 | int n; |
1818 | len_and_sockaddr fromAddr; | 1803 | len_and_sockaddr fromAddr; |
@@ -1825,18 +1810,6 @@ static void mini_httpd(int server) | |||
1825 | continue; | 1810 | continue; |
1826 | /* set the KEEPALIVE option to cull dead connections */ | 1811 | /* set the KEEPALIVE option to cull dead connections */ |
1827 | setsockopt(n, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); | 1812 | setsockopt(n, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); |
1828 | accepted_socket = n; | ||
1829 | |||
1830 | n = get_nport(&fromAddr.sa); | ||
1831 | tcp_port = ntohs(n); | ||
1832 | rmt_ip = 0; | ||
1833 | if (fromAddr.sa.sa_family == AF_INET) { | ||
1834 | rmt_ip = ntohl(fromAddr.sin.sin_addr.s_addr); | ||
1835 | } | ||
1836 | if (ENABLE_FEATURE_HTTPD_CGI || DEBUG || verbose) { | ||
1837 | free(rmt_ip_str); | ||
1838 | rmt_ip_str = xmalloc_sockaddr2dotted(&fromAddr.sa, fromAddr.len); | ||
1839 | } | ||
1840 | 1813 | ||
1841 | if (fork() == 0) { | 1814 | if (fork() == 0) { |
1842 | /* child */ | 1815 | /* child */ |
@@ -1844,6 +1817,16 @@ static void mini_httpd(int server) | |||
1844 | /* Do not reload config on HUP */ | 1817 | /* Do not reload config on HUP */ |
1845 | signal(SIGHUP, SIG_IGN); | 1818 | signal(SIGHUP, SIG_IGN); |
1846 | #endif | 1819 | #endif |
1820 | accepted_socket = n; | ||
1821 | n = get_nport(&fromAddr.sa); | ||
1822 | tcp_port = ntohs(n); | ||
1823 | rmt_ip = 0; | ||
1824 | if (fromAddr.sa.sa_family == AF_INET) { | ||
1825 | rmt_ip = ntohl(fromAddr.sin.sin_addr.s_addr); | ||
1826 | } | ||
1827 | if (ENABLE_FEATURE_HTTPD_CGI || DEBUG || verbose) { | ||
1828 | rmt_ip_str = xmalloc_sockaddr2dotted(&fromAddr.sa, fromAddr.len); | ||
1829 | } | ||
1847 | if (verbose) { | 1830 | if (verbose) { |
1848 | /* this trick makes -v logging much simpler */ | 1831 | /* this trick makes -v logging much simpler */ |
1849 | applet_name = rmt_ip_str; | 1832 | applet_name = rmt_ip_str; |
@@ -1853,7 +1836,7 @@ static void mini_httpd(int server) | |||
1853 | handle_incoming_and_exit(); | 1836 | handle_incoming_and_exit(); |
1854 | } | 1837 | } |
1855 | /* parent, or fork failed */ | 1838 | /* parent, or fork failed */ |
1856 | close(accepted_socket); | 1839 | close(n); |
1857 | } /* while (1) */ | 1840 | } /* while (1) */ |
1858 | /* never reached */ | 1841 | /* never reached */ |
1859 | } | 1842 | } |
@@ -1883,12 +1866,13 @@ static void mini_httpd_inetd(void) | |||
1883 | #if ENABLE_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP | 1866 | #if ENABLE_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP |
1884 | static void sighup_handler(int sig) | 1867 | static void sighup_handler(int sig) |
1885 | { | 1868 | { |
1886 | /* set and reset */ | ||
1887 | struct sigaction sa; | 1869 | struct sigaction sa; |
1888 | 1870 | ||
1889 | parse_conf(default_path_httpd_conf, sig == SIGHUP ? SIGNALED_PARSE : FIRST_PARSE); | 1871 | parse_conf(default_path_httpd_conf, sig == SIGHUP ? SIGNALED_PARSE : FIRST_PARSE); |
1872 | |||
1873 | memset(&sa, 0, sizeof(sa)); | ||
1890 | sa.sa_handler = sighup_handler; | 1874 | sa.sa_handler = sighup_handler; |
1891 | sigemptyset(&sa.sa_mask); | 1875 | /*sigemptyset(&sa.sa_mask); - memset should be enough */ |
1892 | sa.sa_flags = SA_RESTART; | 1876 | sa.sa_flags = SA_RESTART; |
1893 | sigaction(SIGHUP, &sa, NULL); | 1877 | sigaction(SIGHUP, &sa, NULL); |
1894 | } | 1878 | } |
@@ -1930,12 +1914,13 @@ int httpd_main(int argc, char **argv) | |||
1930 | USE_FEATURE_HTTPD_SETUID(struct bb_uidgid_t ugid;) | 1914 | USE_FEATURE_HTTPD_SETUID(struct bb_uidgid_t ugid;) |
1931 | USE_FEATURE_HTTPD_AUTH_MD5(const char *pass;) | 1915 | USE_FEATURE_HTTPD_AUTH_MD5(const char *pass;) |
1932 | 1916 | ||
1917 | INIT_G(); | ||
1918 | |||
1933 | #if ENABLE_LOCALE_SUPPORT | 1919 | #if ENABLE_LOCALE_SUPPORT |
1934 | /* Undo busybox.c: we want to speak English in http (dates etc) */ | 1920 | /* Undo busybox.c: we want to speak English in http (dates etc) */ |
1935 | setlocale(LC_TIME, "C"); | 1921 | setlocale(LC_TIME, "C"); |
1936 | #endif | 1922 | #endif |
1937 | 1923 | ||
1938 | INIT_G(); | ||
1939 | home_httpd = xrealloc_getcwd_or_warn(NULL); | 1924 | home_httpd = xrealloc_getcwd_or_warn(NULL); |
1940 | opt_complementary = "vv"; /* counter */ | 1925 | opt_complementary = "vv"; /* counter */ |
1941 | /* We do not "absolutize" path given by -h (home) opt. | 1926 | /* We do not "absolutize" path given by -h (home) opt. |
@@ -2012,13 +1997,12 @@ int httpd_main(int argc, char **argv) | |||
2012 | } | 1997 | } |
2013 | #endif | 1998 | #endif |
2014 | 1999 | ||
2000 | #if BB_MMU | ||
2015 | #if ENABLE_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP | 2001 | #if ENABLE_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP |
2016 | sighup_handler(0); | 2002 | sighup_handler(0); |
2017 | #else | 2003 | #else |
2018 | parse_conf(default_path_httpd_conf, FIRST_PARSE); | 2004 | parse_conf(default_path_httpd_conf, FIRST_PARSE); |
2019 | #endif | 2005 | #endif |
2020 | |||
2021 | #if BB_MMU | ||
2022 | if (opt & OPT_INETD) | 2006 | if (opt & OPT_INETD) |
2023 | mini_httpd_inetd(); | 2007 | mini_httpd_inetd(); |
2024 | if (!(opt & OPT_FOREGROUND)) | 2008 | if (!(opt & OPT_FOREGROUND)) |