diff options
Diffstat (limited to 'networking')
-rw-r--r-- | networking/ftpgetput.c | 6 | ||||
-rw-r--r-- | networking/httpd.c | 297 | ||||
-rw-r--r-- | networking/nc.c | 12 | ||||
-rw-r--r-- | networking/ssl_client.c | 21 | ||||
-rw-r--r-- | networking/tls.c | 2 | ||||
-rw-r--r-- | networking/wget.c | 53 |
6 files changed, 383 insertions, 8 deletions
diff --git a/networking/ftpgetput.c b/networking/ftpgetput.c index 1172850ce..86342769b 100644 --- a/networking/ftpgetput.c +++ b/networking/ftpgetput.c | |||
@@ -106,6 +106,9 @@ static int ftpcmd(const char *s1, const char *s2) | |||
106 | fprintf(control_stream, (s2 ? "%s %s\r\n" : "%s %s\r\n"+3), | 106 | fprintf(control_stream, (s2 ? "%s %s\r\n" : "%s %s\r\n"+3), |
107 | s1, s2); | 107 | s1, s2); |
108 | fflush(control_stream); | 108 | fflush(control_stream); |
109 | #if ENABLE_PLATFORM_MINGW32 | ||
110 | fseek(control_stream, 0L, SEEK_CUR); | ||
111 | #endif | ||
109 | } | 112 | } |
110 | 113 | ||
111 | do { | 114 | do { |
@@ -114,6 +117,9 @@ static int ftpcmd(const char *s1, const char *s2) | |||
114 | ftp_die(NULL); | 117 | ftp_die(NULL); |
115 | } | 118 | } |
116 | } while (!isdigit(buf[0]) || buf[3] != ' '); | 119 | } while (!isdigit(buf[0]) || buf[3] != ' '); |
120 | #if ENABLE_PLATFORM_MINGW32 | ||
121 | fseek(control_stream, 0L, SEEK_CUR); | ||
122 | #endif | ||
117 | 123 | ||
118 | buf[3] = '\0'; | 124 | buf[3] = '\0'; |
119 | n = xatou(buf); | 125 | n = xatou(buf); |
diff --git a/networking/httpd.c b/networking/httpd.c index ddcb03bca..1dae602ee 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
@@ -264,7 +264,12 @@ | |||
264 | //kbuild:lib-$(CONFIG_HTTPD) += httpd.o | 264 | //kbuild:lib-$(CONFIG_HTTPD) += httpd.o |
265 | 265 | ||
266 | //usage:#define httpd_trivial_usage | 266 | //usage:#define httpd_trivial_usage |
267 | //usage: IF_NOT_PLATFORM_MINGW32( | ||
267 | //usage: "[-ifv[v]]" | 268 | //usage: "[-ifv[v]]" |
269 | //usage: ) | ||
270 | //usage: IF_PLATFORM_MINGW32( | ||
271 | //usage: "[-fv[v]]" | ||
272 | //usage: ) | ||
268 | //usage: " [-c CONFFILE]" | 273 | //usage: " [-c CONFFILE]" |
269 | //usage: " [-p [IP:]PORT]" | 274 | //usage: " [-p [IP:]PORT]" |
270 | //usage: IF_FEATURE_HTTPD_SETUID(" [-u USER[:GRP]]") | 275 | //usage: IF_FEATURE_HTTPD_SETUID(" [-u USER[:GRP]]") |
@@ -273,7 +278,9 @@ | |||
273 | //usage: "or httpd -d/-e" IF_FEATURE_HTTPD_AUTH_MD5("/-m") " STRING" | 278 | //usage: "or httpd -d/-e" IF_FEATURE_HTTPD_AUTH_MD5("/-m") " STRING" |
274 | //usage:#define httpd_full_usage "\n\n" | 279 | //usage:#define httpd_full_usage "\n\n" |
275 | //usage: "Listen for incoming HTTP requests\n" | 280 | //usage: "Listen for incoming HTTP requests\n" |
281 | //usage: IF_NOT_PLATFORM_MINGW32( | ||
276 | //usage: "\n -i Inetd mode" | 282 | //usage: "\n -i Inetd mode" |
283 | //usage: ) | ||
277 | //usage: "\n -f Run in foreground" | 284 | //usage: "\n -f Run in foreground" |
278 | //usage: "\n -v[v] Verbose" | 285 | //usage: "\n -v[v] Verbose" |
279 | //usage: "\n -p [IP:]PORT Bind to IP:PORT (default *:"STR(CONFIG_FEATURE_HTTPD_PORT_DEFAULT)")" | 286 | //usage: "\n -p [IP:]PORT Bind to IP:PORT (default *:"STR(CONFIG_FEATURE_HTTPD_PORT_DEFAULT)")" |
@@ -292,6 +299,9 @@ | |||
292 | 299 | ||
293 | #include "libbb.h" | 300 | #include "libbb.h" |
294 | #include "common_bufsiz.h" | 301 | #include "common_bufsiz.h" |
302 | #if ENABLE_PLATFORM_MINGW32 | ||
303 | # include "BB_VER.h" | ||
304 | #endif | ||
295 | #if ENABLE_PAM | 305 | #if ENABLE_PAM |
296 | /* PAM may include <locale.h>. We may need to undefine bbox's stub define: */ | 306 | /* PAM may include <locale.h>. We may need to undefine bbox's stub define: */ |
297 | # undef setlocale | 307 | # undef setlocale |
@@ -322,6 +332,8 @@ | |||
322 | 332 | ||
323 | #define HEADER_READ_TIMEOUT 60 | 333 | #define HEADER_READ_TIMEOUT 60 |
324 | 334 | ||
335 | static void send_REQUEST_TIMEOUT_and_exit(int sig) NORETURN; | ||
336 | |||
325 | #define STR1(s) #s | 337 | #define STR1(s) #s |
326 | #define STR(s) STR1(s) | 338 | #define STR(s) STR1(s) |
327 | 339 | ||
@@ -452,6 +464,13 @@ static const struct { | |||
452 | 464 | ||
453 | struct globals { | 465 | struct globals { |
454 | int verbose; /* must be int (used by getopt32) */ | 466 | int verbose; /* must be int (used by getopt32) */ |
467 | #if ENABLE_PLATFORM_MINGW32 | ||
468 | smallint foreground; | ||
469 | # if ENABLE_FEATURE_HTTPD_CGI | ||
470 | int server_argc; | ||
471 | char **server_argv; | ||
472 | # endif | ||
473 | #endif | ||
455 | smallint flg_deny_all; | 474 | smallint flg_deny_all; |
456 | #if ENABLE_FEATURE_HTTPD_GZIP | 475 | #if ENABLE_FEATURE_HTTPD_GZIP |
457 | /* client can handle gzip / we are going to send gzip */ | 476 | /* client can handle gzip / we are going to send gzip */ |
@@ -509,6 +528,11 @@ struct globals { | |||
509 | }; | 528 | }; |
510 | #define G (*ptr_to_globals) | 529 | #define G (*ptr_to_globals) |
511 | #define verbose (G.verbose ) | 530 | #define verbose (G.verbose ) |
531 | #if ENABLE_PLATFORM_MINGW32 | ||
532 | #define foreground (G.foreground ) | ||
533 | #define server_argc (G.server_argc ) | ||
534 | #define server_argv (G.server_argv ) | ||
535 | #endif | ||
512 | #define flg_deny_all (G.flg_deny_all ) | 536 | #define flg_deny_all (G.flg_deny_all ) |
513 | #if ENABLE_FEATURE_HTTPD_GZIP | 537 | #if ENABLE_FEATURE_HTTPD_GZIP |
514 | # define content_gzip (G.content_gzip ) | 538 | # define content_gzip (G.content_gzip ) |
@@ -557,7 +581,12 @@ enum { | |||
557 | } while (0) | 581 | } while (0) |
558 | 582 | ||
559 | 583 | ||
584 | #if !ENABLE_PLATFORM_MINGW32 | ||
560 | #define STRNCASECMP(a, str) strncasecmp((a), (str), sizeof(str)-1) | 585 | #define STRNCASECMP(a, str) strncasecmp((a), (str), sizeof(str)-1) |
586 | #else | ||
587 | /* Not exactly equivalent to strncasecmp(), but OK for its use here */ | ||
588 | #define STRNCASECMP(a, str) (!is_prefixed_with_case((a), (str))) | ||
589 | #endif | ||
561 | 590 | ||
562 | /* Prototypes */ | 591 | /* Prototypes */ |
563 | enum { | 592 | enum { |
@@ -721,8 +750,16 @@ static int parse_conf(const char *path, int flag) | |||
721 | 750 | ||
722 | filename = opt_c_configFile; | 751 | filename = opt_c_configFile; |
723 | if (flag == SUBDIR_PARSE || filename == NULL) { | 752 | if (flag == SUBDIR_PARSE || filename == NULL) { |
753 | #if !ENABLE_PLATFORM_MINGW32 | ||
724 | filename = alloca(strlen(path) + sizeof(HTTPD_CONF) + 2); | 754 | filename = alloca(strlen(path) + sizeof(HTTPD_CONF) + 2); |
725 | sprintf((char *)filename, "%s/%s", path, HTTPD_CONF); | 755 | sprintf((char *)filename, "%s/%s", path, HTTPD_CONF); |
756 | #else | ||
757 | const char *sd = ""; | ||
758 | if (root_len(path) == 0 && (path[0] == '/' || path[0] == '\\')) | ||
759 | sd = get_system_drive(); | ||
760 | |||
761 | filename = auto_string(xasprintf("%s%s/%s", sd, path, HTTPD_CONF)); | ||
762 | #endif | ||
726 | } | 763 | } |
727 | 764 | ||
728 | while ((f = fopen_for_read(filename)) == NULL) { | 765 | while ((f = fopen_for_read(filename)) == NULL) { |
@@ -771,6 +808,7 @@ static int parse_conf(const char *path, int flag) | |||
771 | * without needless copying, therefore we don't merge | 808 | * without needless copying, therefore we don't merge |
772 | * this operation into next while loop. */ | 809 | * this operation into next while loop. */ |
773 | while ((ch = *p0) != '\0' && ch != '\n' && ch != '#' | 810 | while ((ch = *p0) != '\0' && ch != '\n' && ch != '#' |
811 | IF_PLATFORM_MINGW32(&& ch != '\r') | ||
774 | && ch != ' ' && ch != '\t' | 812 | && ch != ' ' && ch != '\t' |
775 | ) { | 813 | ) { |
776 | p0++; | 814 | p0++; |
@@ -778,7 +816,11 @@ static int parse_conf(const char *path, int flag) | |||
778 | p = p0; | 816 | p = p0; |
779 | /* if we enter this loop, we have some whitespace. | 817 | /* if we enter this loop, we have some whitespace. |
780 | * discard it */ | 818 | * discard it */ |
819 | #if !ENABLE_PLATFORM_MINGW32 | ||
781 | while (ch != '\0' && ch != '\n' && ch != '#') { | 820 | while (ch != '\0' && ch != '\n' && ch != '#') { |
821 | #else | ||
822 | while (ch != '\0' && ch != '\n' && ch != '\r' && ch != '#') { | ||
823 | #endif | ||
782 | if (ch != ' ' && ch != '\t') { | 824 | if (ch != ' ' && ch != '\t') { |
783 | *p++ = ch; | 825 | *p++ = ch; |
784 | } | 826 | } |
@@ -1311,7 +1353,21 @@ static unsigned get_line(void) | |||
1311 | count = 0; | 1353 | count = 0; |
1312 | while (1) { | 1354 | while (1) { |
1313 | if (hdr_cnt <= 0) { | 1355 | if (hdr_cnt <= 0) { |
1356 | #if ENABLE_PLATFORM_MINGW32 | ||
1357 | int nfds = 1; | ||
1358 | struct pollfd fds = {STDIN_FILENO, POLLIN, 0}; | ||
1359 | |||
1360 | switch (poll(&fds, nfds, HEADER_READ_TIMEOUT*1000)) { | ||
1361 | case 0: | ||
1362 | send_REQUEST_TIMEOUT_and_exit(0); | ||
1363 | break; | ||
1364 | case -1: | ||
1365 | bb_simple_perror_msg_and_die("poll"); | ||
1366 | break; | ||
1367 | } | ||
1368 | #else | ||
1314 | alarm(HEADER_READ_TIMEOUT); | 1369 | alarm(HEADER_READ_TIMEOUT); |
1370 | #endif | ||
1315 | hdr_cnt = safe_read(STDIN_FILENO, hdr_buf, sizeof_hdr_buf); | 1371 | hdr_cnt = safe_read(STDIN_FILENO, hdr_buf, sizeof_hdr_buf); |
1316 | if (hdr_cnt <= 0) | 1372 | if (hdr_cnt <= 0) |
1317 | goto ret; | 1373 | goto ret; |
@@ -1523,6 +1579,47 @@ static NOINLINE void cgi_io_loop_and_exit(int fromCgi_rd, int toCgi_wr, int post | |||
1523 | #endif | 1579 | #endif |
1524 | 1580 | ||
1525 | #if ENABLE_FEATURE_HTTPD_CGI | 1581 | #if ENABLE_FEATURE_HTTPD_CGI |
1582 | # if ENABLE_PLATFORM_MINGW32 | ||
1583 | static void cgi_handler(char **argv) | ||
1584 | { | ||
1585 | struct fd_pair fromCgi; /* CGI -> httpd pipe */ | ||
1586 | struct fd_pair toCgi; /* httpd -> CGI pipe */ | ||
1587 | |||
1588 | xfunc_error_retval = 242; | ||
1589 | |||
1590 | if (sscanf(argv[0], "%d:%d:%d:%d", &toCgi.wr, &toCgi.rd, | ||
1591 | &fromCgi.wr, &fromCgi.rd) != 4) { | ||
1592 | exit(242); | ||
1593 | } | ||
1594 | |||
1595 | /* NB: close _first_, then move fds! */ | ||
1596 | close(toCgi.wr); | ||
1597 | close(fromCgi.rd); | ||
1598 | xmove_fd(toCgi.rd, 0); /* replace stdin with the pipe */ | ||
1599 | xmove_fd(fromCgi.wr, 1); /* replace stdout with the pipe */ | ||
1600 | |||
1601 | if (argv[1][0] && chdir_or_warn(argv[1]) != 0) { | ||
1602 | goto error_execing_cgi; | ||
1603 | } | ||
1604 | |||
1605 | /* set argv[0] to name without path */ | ||
1606 | argv += 2; | ||
1607 | |||
1608 | /* _NOT_ execvp. We do not search PATH. argv[0] is a filename | ||
1609 | * without any dir components and will only match a file | ||
1610 | * in the current directory */ | ||
1611 | if (foreground) | ||
1612 | execv(argv[0], argv); | ||
1613 | else | ||
1614 | httpd_execv_detach(argv[0], argv); | ||
1615 | if (verbose) | ||
1616 | bb_perror_msg("can't execute '%s'", argv[0]); | ||
1617 | error_execing_cgi: | ||
1618 | /* send to stdout */ | ||
1619 | iobuf = xmalloc(IOBUF_SIZE); | ||
1620 | send_headers_and_exit(HTTP_NOT_FOUND); | ||
1621 | } | ||
1622 | # endif | ||
1526 | 1623 | ||
1527 | static void setenv1(const char *name, const char *value) | 1624 | static void setenv1(const char *name, const char *value) |
1528 | { | 1625 | { |
@@ -1556,6 +1653,10 @@ static void send_cgi_and_exit( | |||
1556 | struct fd_pair toCgi; /* httpd -> CGI pipe */ | 1653 | struct fd_pair toCgi; /* httpd -> CGI pipe */ |
1557 | char *script, *last_slash; | 1654 | char *script, *last_slash; |
1558 | int pid; | 1655 | int pid; |
1656 | #if ENABLE_PLATFORM_MINGW32 | ||
1657 | const char *script_dir; | ||
1658 | char **argv; | ||
1659 | #endif | ||
1559 | 1660 | ||
1560 | /* Make a copy. NB: caller guarantees: | 1661 | /* Make a copy. NB: caller guarantees: |
1561 | * url[0] == '/', url[1] != '/' */ | 1662 | * url[0] == '/', url[1] != '/' */ |
@@ -1592,7 +1693,11 @@ static void send_cgi_and_exit( | |||
1592 | *script = '\0'; /* cut off /PATH_INFO */ | 1693 | *script = '\0'; /* cut off /PATH_INFO */ |
1593 | 1694 | ||
1594 | /* SCRIPT_FILENAME is required by PHP in CGI mode */ | 1695 | /* SCRIPT_FILENAME is required by PHP in CGI mode */ |
1696 | #if ENABLE_PLATFORM_MINGW32 | ||
1697 | if (!is_relative_path(home_httpd)) { | ||
1698 | #else | ||
1595 | if (home_httpd[0] == '/') { | 1699 | if (home_httpd[0] == '/') { |
1700 | #endif | ||
1596 | char *fullpath = concat_path_file(home_httpd, url); | 1701 | char *fullpath = concat_path_file(home_httpd, url); |
1597 | setenv1("SCRIPT_FILENAME", fullpath); | 1702 | setenv1("SCRIPT_FILENAME", fullpath); |
1598 | } | 1703 | } |
@@ -1642,6 +1747,50 @@ static void send_cgi_and_exit( | |||
1642 | xpiped_pair(fromCgi); | 1747 | xpiped_pair(fromCgi); |
1643 | xpiped_pair(toCgi); | 1748 | xpiped_pair(toCgi); |
1644 | 1749 | ||
1750 | #if ENABLE_PLATFORM_MINGW32 | ||
1751 | /* Find script's dir */ | ||
1752 | script_dir = ""; | ||
1753 | script = last_slash; | ||
1754 | if (script != url) { /* paranoia */ | ||
1755 | *script = '\0'; | ||
1756 | script_dir = url + 1; | ||
1757 | } | ||
1758 | script++; | ||
1759 | |||
1760 | argv = xzalloc((server_argc + 9) * sizeof(char *)); | ||
1761 | argv[0] = (char *)bb_busybox_exec_path; | ||
1762 | argv[1] = (char *)"--busybox"; | ||
1763 | argv[2] = (char *)"-httpd"; // don't daemonise in main() | ||
1764 | argv[3] = (char *)"-I0"; | ||
1765 | memcpy(argv + 4, server_argv, sizeof(*argv) * server_argc); | ||
1766 | argv[server_argc + 4] = xasprintf("%d:%d:%d:%d", toCgi.wr, toCgi.rd, | ||
1767 | fromCgi.wr, fromCgi.rd); | ||
1768 | argv[server_argc + 5] = (char *)script_dir; // script directory | ||
1769 | argv[server_argc + 6] = (char *)script; // script name | ||
1770 | |||
1771 | #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR | ||
1772 | { | ||
1773 | char *suffix = strrchr(script, '.'); | ||
1774 | |||
1775 | if (suffix) { | ||
1776 | Htaccess *cur; | ||
1777 | for (cur = script_i; cur; cur = cur->next) { | ||
1778 | if (strcmp(cur->before_colon + 1, suffix) == 0) { | ||
1779 | /* found interpreter name */ | ||
1780 | argv[server_argc + 6] = (char *)cur->after_colon; | ||
1781 | argv[server_argc + 7] = (char *)script; | ||
1782 | break; | ||
1783 | } | ||
1784 | } | ||
1785 | } | ||
1786 | } | ||
1787 | #endif | ||
1788 | /* argv[server_argc + N] = NULL; - xzalloc did it */ | ||
1789 | |||
1790 | pid = foreground ? mingw_spawn(argv) : mingw_spawn_detach(argv); | ||
1791 | if (pid == -1) | ||
1792 | log_and_exit(); | ||
1793 | #else | ||
1645 | pid = vfork(); | 1794 | pid = vfork(); |
1646 | if (pid < 0) { | 1795 | if (pid < 0) { |
1647 | /* TODO: log perror? */ | 1796 | /* TODO: log perror? */ |
@@ -1719,6 +1868,7 @@ static void send_cgi_and_exit( | |||
1719 | 1868 | ||
1720 | /* Restore variables possibly changed by child */ | 1869 | /* Restore variables possibly changed by child */ |
1721 | xfunc_error_retval = 0; | 1870 | xfunc_error_retval = 0; |
1871 | #endif | ||
1722 | 1872 | ||
1723 | /* Pump data */ | 1873 | /* Pump data */ |
1724 | close(fromCgi.wr); | 1874 | close(fromCgi.wr); |
@@ -1770,7 +1920,7 @@ static NOINLINE void send_file_and_exit(const char *url, int what) | |||
1770 | } | 1920 | } |
1771 | #if ENABLE_FEATURE_HTTPD_ETAG | 1921 | #if ENABLE_FEATURE_HTTPD_ETAG |
1772 | /* ETag is "hex(last_mod)-hex(file_size)" e.g. "5e132e20-417" */ | 1922 | /* ETag is "hex(last_mod)-hex(file_size)" e.g. "5e132e20-417" */ |
1773 | sprintf(G.etag, "\"%llx-%llx\"", (unsigned long long)last_mod, (unsigned long long)file_size); | 1923 | sprintf(G.etag, "\"%"LL_FMT"x-%"LL_FMT"x\"", (unsigned long long)last_mod, (unsigned long long)file_size); |
1774 | 1924 | ||
1775 | if (G.if_none_match) { | 1925 | if (G.if_none_match) { |
1776 | dbg("If-None-Match:'%s' file's ETag:'%s'\n", G.if_none_match, G.etag); | 1926 | dbg("If-None-Match:'%s' file's ETag:'%s'\n", G.if_none_match, G.etag); |
@@ -2025,7 +2175,11 @@ static int check_user_passwd(const char *path, char *user_and_passwd) | |||
2025 | 2175 | ||
2026 | /* WHY? */ | 2176 | /* WHY? */ |
2027 | /* If already saw a match, don't accept other different matches */ | 2177 | /* If already saw a match, don't accept other different matches */ |
2178 | #if !ENABLE_PLATFORM_MINGW32 | ||
2028 | if (prev && strcmp(prev, dir_prefix) != 0) | 2179 | if (prev && strcmp(prev, dir_prefix) != 0) |
2180 | #else | ||
2181 | if (prev && strcasecmp(prev, dir_prefix) != 0) | ||
2182 | #endif | ||
2029 | continue; | 2183 | continue; |
2030 | 2184 | ||
2031 | dbg("checkPerm: '%s' ? '%s'\n", dir_prefix, user_and_passwd); | 2185 | dbg("checkPerm: '%s' ? '%s'\n", dir_prefix, user_and_passwd); |
@@ -2033,7 +2187,11 @@ static int check_user_passwd(const char *path, char *user_and_passwd) | |||
2033 | /* If it's not a prefix match, continue searching */ | 2187 | /* If it's not a prefix match, continue searching */ |
2034 | len = strlen(dir_prefix); | 2188 | len = strlen(dir_prefix); |
2035 | if (len != 1 /* dir_prefix "/" matches all, don't need to check */ | 2189 | if (len != 1 /* dir_prefix "/" matches all, don't need to check */ |
2190 | #if !ENABLE_PLATFORM_MINGW32 | ||
2036 | && (strncmp(dir_prefix, path, len) != 0 | 2191 | && (strncmp(dir_prefix, path, len) != 0 |
2192 | #else | ||
2193 | && (strncasecmp(dir_prefix, path, len) != 0 | ||
2194 | #endif | ||
2037 | || (path[len] != '/' && path[len] != '\0') | 2195 | || (path[len] != '/' && path[len] != '\0') |
2038 | ) | 2196 | ) |
2039 | ) { | 2197 | ) { |
@@ -2055,6 +2213,7 @@ static int check_user_passwd(const char *path, char *user_and_passwd) | |||
2055 | goto bad_input; | 2213 | goto bad_input; |
2056 | 2214 | ||
2057 | /* compare "user:" */ | 2215 | /* compare "user:" */ |
2216 | # if !ENABLE_PLATFORM_MINGW32 | ||
2058 | if (cur->after_colon[0] != '*' | 2217 | if (cur->after_colon[0] != '*' |
2059 | && strncmp(cur->after_colon, user_and_passwd, | 2218 | && strncmp(cur->after_colon, user_and_passwd, |
2060 | colon_after_user - user_and_passwd + 1) != 0 | 2219 | colon_after_user - user_and_passwd + 1) != 0 |
@@ -2062,11 +2221,20 @@ static int check_user_passwd(const char *path, char *user_and_passwd) | |||
2062 | continue; | 2221 | continue; |
2063 | } | 2222 | } |
2064 | /* this cfg entry is '*' or matches username from peer */ | 2223 | /* this cfg entry is '*' or matches username from peer */ |
2224 | # else | ||
2225 | if (strncmp(cur->after_colon, user_and_passwd, | ||
2226 | colon_after_user - user_and_passwd + 1) != 0 | ||
2227 | ) { | ||
2228 | continue; | ||
2229 | } | ||
2230 | /* this cfg entry matches username from peer */ | ||
2231 | # endif | ||
2065 | 2232 | ||
2066 | passwd = strchr(cur->after_colon, ':'); | 2233 | passwd = strchr(cur->after_colon, ':'); |
2067 | if (!passwd) | 2234 | if (!passwd) |
2068 | goto bad_input; | 2235 | goto bad_input; |
2069 | passwd++; | 2236 | passwd++; |
2237 | # if !ENABLE_PLATFORM_MINGW32 | ||
2070 | if (passwd[0] == '*') { | 2238 | if (passwd[0] == '*') { |
2071 | # if ENABLE_PAM | 2239 | # if ENABLE_PAM |
2072 | struct pam_userinfo userinfo; | 2240 | struct pam_userinfo userinfo; |
@@ -2114,11 +2282,12 @@ static int check_user_passwd(const char *path, char *user_and_passwd) | |||
2114 | goto check_encrypted; | 2282 | goto check_encrypted; |
2115 | # endif /* ENABLE_PAM */ | 2283 | # endif /* ENABLE_PAM */ |
2116 | } | 2284 | } |
2285 | # endif /* !ENABLE_PLATFORM_MINGW32 */ | ||
2117 | /* Else: passwd is from httpd.conf, it is either plaintext or encrypted */ | 2286 | /* Else: passwd is from httpd.conf, it is either plaintext or encrypted */ |
2118 | 2287 | ||
2119 | if (passwd[0] == '$' && isdigit(passwd[1])) { | 2288 | if (passwd[0] == '$' && isdigit(passwd[1])) { |
2120 | char *encrypted; | 2289 | char *encrypted; |
2121 | # if !ENABLE_PAM | 2290 | # if !ENABLE_PAM && !ENABLE_PLATFORM_MINGW32 |
2122 | check_encrypted: | 2291 | check_encrypted: |
2123 | # endif | 2292 | # endif |
2124 | /* encrypt pwd from peer and check match with local one */ | 2293 | /* encrypt pwd from peer and check match with local one */ |
@@ -2167,7 +2336,6 @@ static Htaccess_Proxy *find_proxy_entry(const char *url) | |||
2167 | /* | 2336 | /* |
2168 | * Handle timeouts | 2337 | * Handle timeouts |
2169 | */ | 2338 | */ |
2170 | static void send_REQUEST_TIMEOUT_and_exit(int sig) NORETURN; | ||
2171 | static void send_REQUEST_TIMEOUT_and_exit(int sig UNUSED_PARAM) | 2339 | static void send_REQUEST_TIMEOUT_and_exit(int sig UNUSED_PARAM) |
2172 | { | 2340 | { |
2173 | send_headers_and_exit(HTTP_REQUEST_TIMEOUT); | 2341 | send_headers_and_exit(HTTP_REQUEST_TIMEOUT); |
@@ -2231,17 +2399,29 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
2231 | remote_ip = ntohl(fromAddr->u.sin.sin_addr.s_addr); | 2399 | remote_ip = ntohl(fromAddr->u.sin.sin_addr.s_addr); |
2232 | } | 2400 | } |
2233 | # if ENABLE_FEATURE_IPV6 | 2401 | # if ENABLE_FEATURE_IPV6 |
2402 | # if !ENABLE_PLATFORM_MINGW32 | ||
2234 | if (fromAddr->u.sa.sa_family == AF_INET6 | 2403 | if (fromAddr->u.sa.sa_family == AF_INET6 |
2235 | && fromAddr->u.sin6.sin6_addr.s6_addr32[0] == 0 | 2404 | && fromAddr->u.sin6.sin6_addr.s6_addr32[0] == 0 |
2236 | && fromAddr->u.sin6.sin6_addr.s6_addr32[1] == 0 | 2405 | && fromAddr->u.sin6.sin6_addr.s6_addr32[1] == 0 |
2237 | && ntohl(fromAddr->u.sin6.sin6_addr.s6_addr32[2]) == 0xffff) | 2406 | && ntohl(fromAddr->u.sin6.sin6_addr.s6_addr32[2]) == 0xffff) |
2238 | remote_ip = ntohl(fromAddr->u.sin6.sin6_addr.s6_addr32[3]); | 2407 | remote_ip = ntohl(fromAddr->u.sin6.sin6_addr.s6_addr32[3]); |
2408 | # else | ||
2409 | if (fromAddr->u.sa.sa_family == AF_INET6 | ||
2410 | && fromAddr->u.sin6.sin6_addr.s6_words[0] == 0 | ||
2411 | && fromAddr->u.sin6.sin6_addr.s6_words[1] == 0 | ||
2412 | && fromAddr->u.sin6.sin6_addr.s6_words[2] == 0 | ||
2413 | && fromAddr->u.sin6.sin6_addr.s6_words[3] == 0 | ||
2414 | && ntohl(*(uint32_t *)(fromAddr->u.sin6.sin6_addr.s6_words+4)) == 0xffff) | ||
2415 | remote_ip = ntohl(*(uint32_t *)(fromAddr->u.sin6.sin6_addr.s6_words+6)); | ||
2416 | # endif | ||
2239 | # endif | 2417 | # endif |
2240 | if_ip_denied_send_HTTP_FORBIDDEN_and_exit(remote_ip); | 2418 | if_ip_denied_send_HTTP_FORBIDDEN_and_exit(remote_ip); |
2241 | #endif | 2419 | #endif |
2242 | 2420 | ||
2421 | #ifdef SIGALRM | ||
2243 | /* Install timeout handler. get_line() needs it. */ | 2422 | /* Install timeout handler. get_line() needs it. */ |
2244 | signal(SIGALRM, send_REQUEST_TIMEOUT_and_exit); | 2423 | signal(SIGALRM, send_REQUEST_TIMEOUT_and_exit); |
2424 | #endif | ||
2245 | 2425 | ||
2246 | if (!get_line()) { /* EOF or error or empty line */ | 2426 | if (!get_line()) { /* EOF or error or empty line */ |
2247 | /* Observed Firefox to "speculatively" open | 2427 | /* Observed Firefox to "speculatively" open |
@@ -2580,7 +2760,11 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
2580 | /* We are done reading headers, disable peer timeout */ | 2760 | /* We are done reading headers, disable peer timeout */ |
2581 | alarm(0); | 2761 | alarm(0); |
2582 | 2762 | ||
2763 | #if !ENABLE_PLATFORM_MINGW32 | ||
2583 | if (strcmp(bb_basename(urlcopy), HTTPD_CONF) == 0) { | 2764 | if (strcmp(bb_basename(urlcopy), HTTPD_CONF) == 0) { |
2765 | #else | ||
2766 | if (strcasecmp(bb_basename(urlcopy), HTTPD_CONF) == 0) { | ||
2767 | #endif | ||
2584 | /* protect listing [/path]/httpd.conf or IP deny */ | 2768 | /* protect listing [/path]/httpd.conf or IP deny */ |
2585 | send_headers_and_exit(HTTP_FORBIDDEN); | 2769 | send_headers_and_exit(HTTP_FORBIDDEN); |
2586 | } | 2770 | } |
@@ -2626,12 +2810,14 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
2626 | ); | 2810 | ); |
2627 | } | 2811 | } |
2628 | 2812 | ||
2813 | |||
2629 | /* | 2814 | /* |
2630 | * The main http server function. | 2815 | * The main http server function. |
2631 | * Given a socket, listen for new connections and farm out | 2816 | * Given a socket, listen for new connections and farm out |
2632 | * the processing as a [v]forked process. | 2817 | * the processing as a [v]forked process. |
2633 | * Never returns. | 2818 | * Never returns. |
2634 | */ | 2819 | */ |
2820 | # if !ENABLE_PLATFORM_MINGW32 | ||
2635 | #if BB_MMU | 2821 | #if BB_MMU |
2636 | static void mini_httpd(int server_socket) NORETURN; | 2822 | static void mini_httpd(int server_socket) NORETURN; |
2637 | static void mini_httpd(int server_socket) | 2823 | static void mini_httpd(int server_socket) |
@@ -2720,6 +2906,40 @@ static void mini_httpd_nommu(int server_socket, int argc, char **argv) | |||
2720 | /* never reached */ | 2906 | /* never reached */ |
2721 | } | 2907 | } |
2722 | #endif | 2908 | #endif |
2909 | #else /* ENABLE_PLATFORM_MINGW32 */ | ||
2910 | static void mini_httpd_win32(int sock, int argc, char **argv) NORETURN; | ||
2911 | static void mini_httpd_win32(int sock, int argc, char **argv) | ||
2912 | { | ||
2913 | char *argv_copy[argc + 5]; | ||
2914 | |||
2915 | argv_copy[0] = (char *)bb_busybox_exec_path; | ||
2916 | argv_copy[1] = (char *)"--busybox"; | ||
2917 | argv_copy[2] = (char *)"-httpd"; // don't daemonise in main() | ||
2918 | argv_copy[3] = (char *)"-I"; | ||
2919 | memcpy(&argv_copy[5], &argv[1], argc * sizeof(argv[0])); | ||
2920 | |||
2921 | while (1) { | ||
2922 | int n; | ||
2923 | |||
2924 | /* Wait for connections... */ | ||
2925 | n = accept(sock, NULL, NULL); | ||
2926 | if (n < 0) | ||
2927 | continue; | ||
2928 | |||
2929 | /* set the KEEPALIVE option to cull dead connections */ | ||
2930 | setsockopt_keepalive(n); | ||
2931 | |||
2932 | argv_copy[4] = itoa(n); | ||
2933 | if ((foreground ? | ||
2934 | spawn(argv_copy) : mingw_spawn_detach(argv_copy)) == -1) | ||
2935 | bb_perror_msg_and_die("can't execute 'httpd'"); | ||
2936 | |||
2937 | /* parent, or spawn failed */ | ||
2938 | close(n); | ||
2939 | } /* while (1) */ | ||
2940 | /* never reached */ | ||
2941 | } | ||
2942 | #endif | ||
2723 | 2943 | ||
2724 | /* | 2944 | /* |
2725 | * Process a HTTP connection on stdin/out. | 2945 | * Process a HTTP connection on stdin/out. |
@@ -2737,12 +2957,36 @@ static void mini_httpd_inetd(void) | |||
2737 | handle_incoming_and_exit(&fromAddr); | 2957 | handle_incoming_and_exit(&fromAddr); |
2738 | } | 2958 | } |
2739 | 2959 | ||
2960 | #if ENABLE_PLATFORM_MINGW32 | ||
2961 | static void mingw_daemonize(char **argv) | ||
2962 | { | ||
2963 | char **new_argv; | ||
2964 | int fd; | ||
2965 | |||
2966 | new_argv = grow_argv(argv + 1, 3); | ||
2967 | new_argv[0] = (char *)bb_busybox_exec_path; | ||
2968 | new_argv[1] = (char *)"--busybox"; | ||
2969 | // don't daemonise in main(), we explicitly detach below | ||
2970 | new_argv[2] = (char *)"-httpd"; | ||
2971 | |||
2972 | fd = xopen(bb_dev_null, O_RDWR); | ||
2973 | xdup2(fd, 0); | ||
2974 | xdup2(fd, 1); | ||
2975 | xdup2(fd, 2); | ||
2976 | close(fd); | ||
2977 | |||
2978 | exit(mingw_spawn_detach(new_argv) == -1 ? EXIT_FAILURE : EXIT_SUCCESS); | ||
2979 | } | ||
2980 | #endif | ||
2981 | |||
2982 | #if !ENABLE_PLATFORM_MINGW32 | ||
2740 | static void sighup_handler(int sig UNUSED_PARAM) | 2983 | static void sighup_handler(int sig UNUSED_PARAM) |
2741 | { | 2984 | { |
2742 | int sv = errno; | 2985 | int sv = errno; |
2743 | parse_conf(DEFAULT_PATH_HTTPD_CONF, SIGNALED_PARSE); | 2986 | parse_conf(DEFAULT_PATH_HTTPD_CONF, SIGNALED_PARSE); |
2744 | errno = sv; | 2987 | errno = sv; |
2745 | } | 2988 | } |
2989 | #endif | ||
2746 | 2990 | ||
2747 | enum { | 2991 | enum { |
2748 | c_opt_config_file = 0, | 2992 | c_opt_config_file = 0, |
@@ -2780,6 +3024,7 @@ int httpd_main(int argc UNUSED_PARAM, char **argv) | |||
2780 | IF_FEATURE_HTTPD_SETUID(const char *s_ugid = NULL;) | 3024 | IF_FEATURE_HTTPD_SETUID(const char *s_ugid = NULL;) |
2781 | IF_FEATURE_HTTPD_SETUID(struct bb_uidgid_t ugid;) | 3025 | IF_FEATURE_HTTPD_SETUID(struct bb_uidgid_t ugid;) |
2782 | IF_FEATURE_HTTPD_AUTH_MD5(const char *pass;) | 3026 | IF_FEATURE_HTTPD_AUTH_MD5(const char *pass;) |
3027 | IF_PLATFORM_MINGW32(int fd;) | ||
2783 | 3028 | ||
2784 | INIT_G(); | 3029 | INIT_G(); |
2785 | 3030 | ||
@@ -2798,16 +3043,19 @@ int httpd_main(int argc UNUSED_PARAM, char **argv) | |||
2798 | IF_FEATURE_HTTPD_BASIC_AUTH("r:") | 3043 | IF_FEATURE_HTTPD_BASIC_AUTH("r:") |
2799 | IF_FEATURE_HTTPD_AUTH_MD5("m:") | 3044 | IF_FEATURE_HTTPD_AUTH_MD5("m:") |
2800 | IF_FEATURE_HTTPD_SETUID("u:") | 3045 | IF_FEATURE_HTTPD_SETUID("u:") |
2801 | "p:ifv" | 3046 | IF_NOT_PLATFORM_MINGW32("p:ifv") |
3047 | IF_PLATFORM_MINGW32("p:I:+fv") | ||
2802 | "\0" | 3048 | "\0" |
2803 | /* -v counts, -i implies -f */ | 3049 | /* -v counts, -i implies -f */ |
2804 | "vv:if", | 3050 | IF_NOT_PLATFORM_MINGW32("vv:if",) |
3051 | IF_PLATFORM_MINGW32("vv:",) | ||
2805 | &opt_c_configFile, &url_for_decode, &home_httpd | 3052 | &opt_c_configFile, &url_for_decode, &home_httpd |
2806 | IF_FEATURE_HTTPD_ENCODE_URL_STR(, &url_for_encode) | 3053 | IF_FEATURE_HTTPD_ENCODE_URL_STR(, &url_for_encode) |
2807 | IF_FEATURE_HTTPD_BASIC_AUTH(, &g_realm) | 3054 | IF_FEATURE_HTTPD_BASIC_AUTH(, &g_realm) |
2808 | IF_FEATURE_HTTPD_AUTH_MD5(, &pass) | 3055 | IF_FEATURE_HTTPD_AUTH_MD5(, &pass) |
2809 | IF_FEATURE_HTTPD_SETUID(, &s_ugid) | 3056 | IF_FEATURE_HTTPD_SETUID(, &s_ugid) |
2810 | , &bind_addr_or_port | 3057 | , &bind_addr_or_port |
3058 | IF_PLATFORM_MINGW32(, &fd) | ||
2811 | , &verbose | 3059 | , &verbose |
2812 | ); | 3060 | ); |
2813 | if (opt & OPT_DECODE_URL) { | 3061 | if (opt & OPT_DECODE_URL) { |
@@ -2837,20 +3085,33 @@ int httpd_main(int argc UNUSED_PARAM, char **argv) | |||
2837 | } | 3085 | } |
2838 | #endif | 3086 | #endif |
2839 | 3087 | ||
3088 | #if !ENABLE_PLATFORM_MINGW32 | ||
2840 | #if !BB_MMU | 3089 | #if !BB_MMU |
2841 | if (!(opt & OPT_FOREGROUND)) { | 3090 | if (!(opt & OPT_FOREGROUND)) { |
2842 | bb_daemonize_or_rexec(0, argv); /* don't change current directory */ | 3091 | bb_daemonize_or_rexec(0, argv); /* don't change current directory */ |
2843 | re_execed = 0; /* for the following chdir to work */ | 3092 | re_execed = 0; /* for the following chdir to work */ |
2844 | } | 3093 | } |
2845 | #endif | 3094 | #endif |
3095 | #else /* ENABLE_PLATFORM_MINGW32 */ | ||
3096 | foreground = (opt & OPT_FOREGROUND) == OPT_FOREGROUND; | ||
3097 | if (!foreground && argv[0][0] != '-') | ||
3098 | mingw_daemonize(argv); | ||
3099 | #endif | ||
3100 | |||
2846 | /* Chdir to home (unless we were re_exec()ed for NOMMU case | 3101 | /* Chdir to home (unless we were re_exec()ed for NOMMU case |
2847 | * in mini_httpd_nommu(): we are already in the home dir then). | 3102 | * in mini_httpd_nommu(): we are already in the home dir then). |
2848 | */ | 3103 | */ |
3104 | #if ENABLE_PLATFORM_MINGW32 | ||
3105 | if (!(opt & OPT_INETD)) | ||
3106 | #else | ||
2849 | if (!re_execed) | 3107 | if (!re_execed) |
3108 | #endif | ||
2850 | xchdir(home_httpd); | 3109 | xchdir(home_httpd); |
2851 | 3110 | ||
2852 | if (!(opt & OPT_INETD)) { | 3111 | if (!(opt & OPT_INETD)) { |
3112 | #ifdef SIGCHLD | ||
2853 | signal(SIGCHLD, SIG_IGN); | 3113 | signal(SIGCHLD, SIG_IGN); |
3114 | #endif | ||
2854 | server_socket = openServer(); | 3115 | server_socket = openServer(); |
2855 | #if ENABLE_FEATURE_HTTPD_SETUID | 3116 | #if ENABLE_FEATURE_HTTPD_SETUID |
2856 | /* drop privileges */ | 3117 | /* drop privileges */ |
@@ -2884,12 +3145,35 @@ int httpd_main(int argc UNUSED_PARAM, char **argv) | |||
2884 | #endif | 3145 | #endif |
2885 | 3146 | ||
2886 | parse_conf(DEFAULT_PATH_HTTPD_CONF, FIRST_PARSE); | 3147 | parse_conf(DEFAULT_PATH_HTTPD_CONF, FIRST_PARSE); |
3148 | #if ENABLE_PLATFORM_MINGW32 | ||
3149 | # if ENABLE_FEATURE_HTTPD_CGI | ||
3150 | if ((opt & OPT_INETD) && fd == 0) { | ||
3151 | cgi_handler(argv + optind); | ||
3152 | return 0; | ||
3153 | } | ||
3154 | # endif | ||
3155 | #else | ||
2887 | if (!(opt & OPT_INETD)) | 3156 | if (!(opt & OPT_INETD)) |
2888 | signal(SIGHUP, sighup_handler); | 3157 | signal(SIGHUP, sighup_handler); |
3158 | #endif | ||
2889 | 3159 | ||
2890 | xfunc_error_retval = 0; | 3160 | xfunc_error_retval = 0; |
3161 | #if ENABLE_PLATFORM_MINGW32 | ||
3162 | if (opt & OPT_INETD) { | ||
3163 | xmove_fd(fd, 0); | ||
3164 | xdup2(0, 1); | ||
3165 | while (--fd > 2) | ||
3166 | close(fd); | ||
3167 | # if ENABLE_FEATURE_HTTPD_CGI | ||
3168 | /* Skip 'httpd -I N' and omit any non-option arguments */ | ||
3169 | server_argc = optind - 3; | ||
3170 | server_argv = argv + 3; | ||
3171 | # endif | ||
3172 | } | ||
3173 | #endif | ||
2891 | if (opt & OPT_INETD) | 3174 | if (opt & OPT_INETD) |
2892 | mini_httpd_inetd(); /* never returns */ | 3175 | mini_httpd_inetd(); /* never returns */ |
3176 | #if !ENABLE_PLATFORM_MINGW32 | ||
2893 | #if BB_MMU | 3177 | #if BB_MMU |
2894 | if (!(opt & OPT_FOREGROUND)) | 3178 | if (!(opt & OPT_FOREGROUND)) |
2895 | bb_daemonize(0); /* don't change current directory */ | 3179 | bb_daemonize(0); /* don't change current directory */ |
@@ -2897,5 +3181,8 @@ int httpd_main(int argc UNUSED_PARAM, char **argv) | |||
2897 | #else | 3181 | #else |
2898 | mini_httpd_nommu(server_socket, argc, argv); /* never returns */ | 3182 | mini_httpd_nommu(server_socket, argc, argv); /* never returns */ |
2899 | #endif | 3183 | #endif |
3184 | #else /* ENABLE_PLATFORM_MINGW32 */ | ||
3185 | mini_httpd_win32(server_socket, argc, argv); | ||
3186 | #endif | ||
2900 | /* return 0; */ | 3187 | /* return 0; */ |
2901 | } | 3188 | } |
diff --git a/networking/nc.c b/networking/nc.c index ab1316339..ee008595d 100644 --- a/networking/nc.c +++ b/networking/nc.c | |||
@@ -30,7 +30,7 @@ | |||
30 | //config:config NC_EXTRA | 30 | //config:config NC_EXTRA |
31 | //config: bool "Netcat extensions (-eiw and -f FILE)" | 31 | //config: bool "Netcat extensions (-eiw and -f FILE)" |
32 | //config: default y | 32 | //config: default y |
33 | //config: depends on NC || NETCAT | 33 | //config: depends on (NC || NETCAT) && PLATFORM_POSIX |
34 | //config: help | 34 | //config: help |
35 | //config: Add -e (support for executing the rest of the command line after | 35 | //config: Add -e (support for executing the rest of the command line after |
36 | //config: making or receiving a successful connection), -i (delay interval for | 36 | //config: making or receiving a successful connection), -i (delay interval for |
@@ -110,10 +110,12 @@ | |||
110 | * when compared to "standard" nc | 110 | * when compared to "standard" nc |
111 | */ | 111 | */ |
112 | 112 | ||
113 | #if !ENABLE_PLATFORM_MINGW32 | ||
113 | static void timeout(int signum UNUSED_PARAM) | 114 | static void timeout(int signum UNUSED_PARAM) |
114 | { | 115 | { |
115 | bb_simple_error_msg_and_die("timed out"); | 116 | bb_simple_error_msg_and_die("timed out"); |
116 | } | 117 | } |
118 | #endif | ||
117 | 119 | ||
118 | int nc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 120 | int nc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
119 | int nc_main(int argc, char **argv) | 121 | int nc_main(int argc, char **argv) |
@@ -123,7 +125,9 @@ int nc_main(int argc, char **argv) | |||
123 | int cfd = 0; | 125 | int cfd = 0; |
124 | unsigned lport = 0; | 126 | unsigned lport = 0; |
125 | IF_NOT_NC_SERVER(const) unsigned do_listen = 0; | 127 | IF_NOT_NC_SERVER(const) unsigned do_listen = 0; |
128 | #if !ENABLE_PLATFORM_MINGW32 | ||
126 | IF_NOT_NC_EXTRA (const) unsigned wsecs = 0; | 129 | IF_NOT_NC_EXTRA (const) unsigned wsecs = 0; |
130 | #endif | ||
127 | IF_NOT_NC_EXTRA (const) unsigned delay = 0; | 131 | IF_NOT_NC_EXTRA (const) unsigned delay = 0; |
128 | IF_NOT_NC_EXTRA (const int execparam = 0;) | 132 | IF_NOT_NC_EXTRA (const int execparam = 0;) |
129 | IF_NC_EXTRA (char **execparam = NULL;) | 133 | IF_NC_EXTRA (char **execparam = NULL;) |
@@ -187,10 +191,12 @@ int nc_main(int argc, char **argv) | |||
187 | argv++; | 191 | argv++; |
188 | } | 192 | } |
189 | 193 | ||
194 | #if !ENABLE_PLATFORM_MINGW32 | ||
190 | if (wsecs) { | 195 | if (wsecs) { |
191 | signal(SIGALRM, timeout); | 196 | signal(SIGALRM, timeout); |
192 | alarm(wsecs); | 197 | alarm(wsecs); |
193 | } | 198 | } |
199 | #endif | ||
194 | 200 | ||
195 | if (!cfd) { | 201 | if (!cfd) { |
196 | if (do_listen) { | 202 | if (do_listen) { |
@@ -208,7 +214,7 @@ int nc_main(int argc, char **argv) | |||
208 | } | 214 | } |
209 | #endif | 215 | #endif |
210 | close_on_exec_on(sfd); | 216 | close_on_exec_on(sfd); |
211 | accept_again: | 217 | IF_NOT_PLATFORM_MINGW32(accept_again:) |
212 | cfd = accept(sfd, NULL, 0); | 218 | cfd = accept(sfd, NULL, 0); |
213 | if (cfd < 0) | 219 | if (cfd < 0) |
214 | bb_simple_perror_msg_and_die("accept"); | 220 | bb_simple_perror_msg_and_die("accept"); |
@@ -220,6 +226,7 @@ int nc_main(int argc, char **argv) | |||
220 | } | 226 | } |
221 | } | 227 | } |
222 | 228 | ||
229 | #if !ENABLE_PLATFORM_MINGW32 | ||
223 | if (wsecs) { | 230 | if (wsecs) { |
224 | alarm(0); | 231 | alarm(0); |
225 | /* Non-ignored signals revert to SIG_DFL on exec anyway */ | 232 | /* Non-ignored signals revert to SIG_DFL on exec anyway */ |
@@ -244,6 +251,7 @@ int nc_main(int argc, char **argv) | |||
244 | IF_NC_EXTRA(BB_EXECVP(execparam[0], execparam);) | 251 | IF_NC_EXTRA(BB_EXECVP(execparam[0], execparam);) |
245 | IF_NC_EXTRA(bb_perror_msg_and_die("can't execute '%s'", execparam[0]);) | 252 | IF_NC_EXTRA(bb_perror_msg_and_die("can't execute '%s'", execparam[0]);) |
246 | } | 253 | } |
254 | #endif | ||
247 | 255 | ||
248 | /* loop copying stdin to cfd, and cfd to stdout */ | 256 | /* loop copying stdin to cfd, and cfd to stdout */ |
249 | 257 | ||
diff --git a/networking/ssl_client.c b/networking/ssl_client.c index 582fb0e71..757745896 100644 --- a/networking/ssl_client.c +++ b/networking/ssl_client.c | |||
@@ -15,7 +15,12 @@ | |||
15 | //kbuild:lib-$(CONFIG_SSL_CLIENT) += ssl_client.o | 15 | //kbuild:lib-$(CONFIG_SSL_CLIENT) += ssl_client.o |
16 | 16 | ||
17 | //usage:#define ssl_client_trivial_usage | 17 | //usage:#define ssl_client_trivial_usage |
18 | //usage: IF_NOT_PLATFORM_MINGW32( | ||
18 | //usage: "[-e] -s FD [-r FD] [-n SNI]" | 19 | //usage: "[-e] -s FD [-r FD] [-n SNI]" |
20 | //usage: ) | ||
21 | //usage: IF_PLATFORM_MINGW32( | ||
22 | //usage: "[-e] -h handle [-n SNI]" | ||
23 | //usage: ) | ||
19 | //usage:#define ssl_client_full_usage "" | 24 | //usage:#define ssl_client_full_usage "" |
20 | 25 | ||
21 | #include "libbb.h" | 26 | #include "libbb.h" |
@@ -26,15 +31,23 @@ int ssl_client_main(int argc UNUSED_PARAM, char **argv) | |||
26 | tls_state_t *tls; | 31 | tls_state_t *tls; |
27 | const char *sni = NULL; | 32 | const char *sni = NULL; |
28 | int opt; | 33 | int opt; |
34 | #if ENABLE_PLATFORM_MINGW32 | ||
35 | char *hstr = NULL; | ||
36 | HANDLE h; | ||
37 | #endif | ||
29 | 38 | ||
30 | // INIT_G(); | 39 | // INIT_G(); |
31 | 40 | ||
32 | tls = new_tls_state(); | 41 | tls = new_tls_state(); |
42 | #if !ENABLE_PLATFORM_MINGW32 | ||
33 | opt = getopt32(argv, "es:+r:+n:", &tls->ofd, &tls->ifd, &sni); | 43 | opt = getopt32(argv, "es:+r:+n:", &tls->ofd, &tls->ifd, &sni); |
34 | if (!(opt & (1<<2))) { | 44 | if (!(opt & (1<<2))) { |
35 | /* -r N defaults to -s N */ | 45 | /* -r N defaults to -s N */ |
36 | tls->ifd = tls->ofd; | 46 | tls->ifd = tls->ofd; |
37 | } | 47 | } |
48 | #else | ||
49 | opt = getopt32(argv, "eh:n:", &hstr, &sni); | ||
50 | #endif | ||
38 | 51 | ||
39 | if (!(opt & (3<<1))) { | 52 | if (!(opt & (3<<1))) { |
40 | if (!argv[1]) | 53 | if (!argv[1]) |
@@ -47,6 +60,14 @@ int ssl_client_main(int argc UNUSED_PARAM, char **argv) | |||
47 | sni = argv[1]; | 60 | sni = argv[1]; |
48 | tls->ifd = tls->ofd = create_and_connect_stream_or_die(argv[1], 443); | 61 | tls->ifd = tls->ofd = create_and_connect_stream_or_die(argv[1], 443); |
49 | } | 62 | } |
63 | #if ENABLE_PLATFORM_MINGW32 | ||
64 | else { | ||
65 | if (!hstr || sscanf(hstr, "%p", &h) != 1) | ||
66 | bb_error_msg_and_die("invalid handle"); | ||
67 | init_winsock(); | ||
68 | tls->ifd = tls->ofd = _open_osfhandle((intptr_t)h, _O_RDWR|_O_BINARY); | ||
69 | } | ||
70 | #endif | ||
50 | 71 | ||
51 | tls_handshake(tls, sni); | 72 | tls_handshake(tls, sni); |
52 | 73 | ||
diff --git a/networking/tls.c b/networking/tls.c index 8d074c058..9f1dd67ec 100644 --- a/networking/tls.c +++ b/networking/tls.c | |||
@@ -331,7 +331,7 @@ static void dump_tls_record(const void *vp, int len) | |||
331 | 331 | ||
332 | void FAST_FUNC tls_get_random(void *buf, unsigned len) | 332 | void FAST_FUNC tls_get_random(void *buf, unsigned len) |
333 | { | 333 | { |
334 | if (len != open_read_close("/dev/urandom", buf, len)) | 334 | if (len != MINGW_SPECIAL(open_read_close)("/dev/urandom", buf, len)) |
335 | xfunc_die(); | 335 | xfunc_die(); |
336 | } | 336 | } |
337 | 337 | ||
diff --git a/networking/wget.c b/networking/wget.c index ec3767793..6a64836fb 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -214,6 +214,9 @@ enum { | |||
214 | HDR_CONTENT_TYPE = (1<<3), | 214 | HDR_CONTENT_TYPE = (1<<3), |
215 | HDR_AUTH = (1<<4) * ENABLE_FEATURE_WGET_AUTHENTICATION, | 215 | HDR_AUTH = (1<<4) * ENABLE_FEATURE_WGET_AUTHENTICATION, |
216 | HDR_PROXY_AUTH = (1<<5) * ENABLE_FEATURE_WGET_AUTHENTICATION, | 216 | HDR_PROXY_AUTH = (1<<5) * ENABLE_FEATURE_WGET_AUTHENTICATION, |
217 | # if ENABLE_PLATFORM_MINGW32 | ||
218 | HDR_CONTENT_LENGTH = (1<<(4 + 2 * ENABLE_FEATURE_WGET_AUTHENTICATION)), | ||
219 | # endif | ||
217 | }; | 220 | }; |
218 | static const char wget_user_headers[] ALIGN1 = | 221 | static const char wget_user_headers[] ALIGN1 = |
219 | "Host:\0" | 222 | "Host:\0" |
@@ -224,6 +227,9 @@ static const char wget_user_headers[] ALIGN1 = | |||
224 | "Authorization:\0" | 227 | "Authorization:\0" |
225 | "Proxy-Authorization:\0" | 228 | "Proxy-Authorization:\0" |
226 | # endif | 229 | # endif |
230 | # if ENABLE_PLATFORM_MINGW32 | ||
231 | "Content-Length:\0" | ||
232 | # endif | ||
227 | ; | 233 | ; |
228 | # define USR_HEADER_HOST (G.user_headers & HDR_HOST) | 234 | # define USR_HEADER_HOST (G.user_headers & HDR_HOST) |
229 | # define USR_HEADER_USER_AGENT (G.user_headers & HDR_USER_AGENT) | 235 | # define USR_HEADER_USER_AGENT (G.user_headers & HDR_USER_AGENT) |
@@ -231,6 +237,7 @@ static const char wget_user_headers[] ALIGN1 = | |||
231 | # define USR_HEADER_CONTENT_TYPE (G.user_headers & HDR_CONTENT_TYPE) | 237 | # define USR_HEADER_CONTENT_TYPE (G.user_headers & HDR_CONTENT_TYPE) |
232 | # define USR_HEADER_AUTH (G.user_headers & HDR_AUTH) | 238 | # define USR_HEADER_AUTH (G.user_headers & HDR_AUTH) |
233 | # define USR_HEADER_PROXY_AUTH (G.user_headers & HDR_PROXY_AUTH) | 239 | # define USR_HEADER_PROXY_AUTH (G.user_headers & HDR_PROXY_AUTH) |
240 | # define USR_HEADER_CONTENT_LENGTH (G.user_headers & HDR_CONTENT_LENGTH) | ||
234 | #else /* No long options, no user-headers :( */ | 241 | #else /* No long options, no user-headers :( */ |
235 | # define USR_HEADER_HOST 0 | 242 | # define USR_HEADER_HOST 0 |
236 | # define USR_HEADER_USER_AGENT 0 | 243 | # define USR_HEADER_USER_AGENT 0 |
@@ -238,6 +245,7 @@ static const char wget_user_headers[] ALIGN1 = | |||
238 | # define USR_HEADER_CONTENT_TYPE 0 | 245 | # define USR_HEADER_CONTENT_TYPE 0 |
239 | # define USR_HEADER_AUTH 0 | 246 | # define USR_HEADER_AUTH 0 |
240 | # define USR_HEADER_PROXY_AUTH 0 | 247 | # define USR_HEADER_PROXY_AUTH 0 |
248 | # define USR_HEADER_CONTENT_LENGTH 0 | ||
241 | #endif | 249 | #endif |
242 | 250 | ||
243 | /* Globals */ | 251 | /* Globals */ |
@@ -517,6 +525,9 @@ static int ftpcmd(const char *s1, const char *s2, FILE *fp) | |||
517 | fprintf(stderr, "--> %s%s\n\n", s1, s2); | 525 | fprintf(stderr, "--> %s%s\n\n", s1, s2); |
518 | fflush(fp); | 526 | fflush(fp); |
519 | log_io("> %s%s", s1, s2); | 527 | log_io("> %s%s", s1, s2); |
528 | #if ENABLE_PLATFORM_MINGW32 | ||
529 | fseek(fp, 0L, SEEK_CUR); | ||
530 | #endif | ||
520 | } | 531 | } |
521 | 532 | ||
522 | /* Read until "Nxx something" is received */ | 533 | /* Read until "Nxx something" is received */ |
@@ -524,6 +535,9 @@ static int ftpcmd(const char *s1, const char *s2, FILE *fp) | |||
524 | do { | 535 | do { |
525 | fgets_trim_sanitize(fp, "%s\n"); | 536 | fgets_trim_sanitize(fp, "%s\n"); |
526 | } while (!isdigit(G.wget_buf[0]) || G.wget_buf[3] != ' '); | 537 | } while (!isdigit(G.wget_buf[0]) || G.wget_buf[3] != ' '); |
538 | #if ENABLE_PLATFORM_MINGW32 | ||
539 | fseek(fp, 0L, SEEK_CUR); | ||
540 | #endif | ||
527 | 541 | ||
528 | G.wget_buf[3] = '\0'; | 542 | G.wget_buf[3] = '\0'; |
529 | result = xatoi_positive(G.wget_buf); | 543 | result = xatoi_positive(G.wget_buf); |
@@ -766,6 +780,7 @@ static int spawn_https_helper_openssl(const char *host, unsigned port) | |||
766 | #endif | 780 | #endif |
767 | 781 | ||
768 | #if ENABLE_FEATURE_WGET_HTTPS | 782 | #if ENABLE_FEATURE_WGET_HTTPS |
783 | # if !ENABLE_PLATFORM_MINGW32 | ||
769 | static void spawn_ssl_client(const char *host, int network_fd, int flags) | 784 | static void spawn_ssl_client(const char *host, int network_fd, int flags) |
770 | { | 785 | { |
771 | int sp[2]; | 786 | int sp[2]; |
@@ -820,6 +835,31 @@ static void spawn_ssl_client(const char *host, int network_fd, int flags) | |||
820 | close(sp[1]); | 835 | close(sp[1]); |
821 | xmove_fd(sp[0], network_fd); | 836 | xmove_fd(sp[0], network_fd); |
822 | } | 837 | } |
838 | # else | ||
839 | static void spawn_ssl_client(const char *host, int network_fd, int flags) | ||
840 | { | ||
841 | int fd1; | ||
842 | char *servername, *p, *cmd; | ||
843 | |||
844 | servername = xstrdup(host); | ||
845 | p = strrchr(servername, ':'); | ||
846 | if (p) *p = '\0'; | ||
847 | |||
848 | fflush_all(); | ||
849 | |||
850 | cmd = xasprintf("ssl_client -h %p -n %s%s", | ||
851 | (void *)_get_osfhandle(network_fd), servername, | ||
852 | flags & TLSLOOP_EXIT_ON_LOCAL_EOF ? " -e" : ""); | ||
853 | |||
854 | if ((fd1=mingw_popen_fd("ssl_client", cmd, "b", -1, NULL)) == -1) { | ||
855 | bb_perror_msg_and_die("can't execute ssl_client"); | ||
856 | } | ||
857 | |||
858 | free(cmd); | ||
859 | free(servername); | ||
860 | xmove_fd(fd1, network_fd); | ||
861 | } | ||
862 | # endif | ||
823 | #endif | 863 | #endif |
824 | 864 | ||
825 | #if ENABLE_FEATURE_WGET_FTP | 865 | #if ENABLE_FEATURE_WGET_FTP |
@@ -1273,6 +1313,18 @@ static void download_one_url(const char *url) | |||
1273 | "Content-Type: application/x-www-form-urlencoded\r\n" | 1313 | "Content-Type: application/x-www-form-urlencoded\r\n" |
1274 | ); | 1314 | ); |
1275 | } | 1315 | } |
1316 | # if ENABLE_PLATFORM_MINGW32 | ||
1317 | if (!USR_HEADER_CONTENT_LENGTH) | ||
1318 | SENDFMT(sfp, "Content-Length: %u\r\n", | ||
1319 | (int)strlen(G.post_data) | ||
1320 | ); | ||
1321 | SENDFMT(sfp, | ||
1322 | "\r\n" | ||
1323 | "%s", | ||
1324 | G.post_data | ||
1325 | ); | ||
1326 | } else | ||
1327 | # else | ||
1276 | SENDFMT(sfp, | 1328 | SENDFMT(sfp, |
1277 | "Content-Length: %u\r\n" | 1329 | "Content-Length: %u\r\n" |
1278 | "\r\n" | 1330 | "\r\n" |
@@ -1280,6 +1332,7 @@ static void download_one_url(const char *url) | |||
1280 | (int) strlen(G.post_data), G.post_data | 1332 | (int) strlen(G.post_data), G.post_data |
1281 | ); | 1333 | ); |
1282 | } else | 1334 | } else |
1335 | # endif | ||
1283 | #endif | 1336 | #endif |
1284 | { | 1337 | { |
1285 | SENDFMT(sfp, "\r\n"); | 1338 | SENDFMT(sfp, "\r\n"); |