diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-08-17 19:19:42 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-08-17 19:19:42 +0000 |
commit | 91adf7d5877ecc7587556b993808b63f6f249080 (patch) | |
tree | 6b3cd51028fcefab504cd8502ffe0e9a03b4f665 | |
parent | e45af73dc233d345a642386431703ad9a1597093 (diff) | |
download | busybox-w32-91adf7d5877ecc7587556b993808b63f6f249080.tar.gz busybox-w32-91adf7d5877ecc7587556b993808b63f6f249080.tar.bz2 busybox-w32-91adf7d5877ecc7587556b993808b63f6f249080.zip |
httpd shrink and logging update, part 4 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 | 367 |
1 files changed, 181 insertions, 186 deletions
diff --git a/networking/httpd.c b/networking/httpd.c index 35aa492d0..69d994a47 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
@@ -1506,7 +1506,7 @@ static int checkPerm(const char *path, const char *request) | |||
1506 | } | 1506 | } |
1507 | /* unauthorized */ | 1507 | /* unauthorized */ |
1508 | } | 1508 | } |
1509 | } /* for */ | 1509 | } /* for */ |
1510 | 1510 | ||
1511 | return prev == NULL; | 1511 | return prev == NULL; |
1512 | } | 1512 | } |
@@ -1542,7 +1542,6 @@ static void handle_incoming_and_exit(void) | |||
1542 | char *content_type = 0; | 1542 | char *content_type = 0; |
1543 | #endif | 1543 | #endif |
1544 | struct sigaction sa; | 1544 | struct sigaction sa; |
1545 | |||
1546 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH | 1545 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH |
1547 | int credentials = -1; /* if not required this is Ok */ | 1546 | int credentials = -1; /* if not required this is Ok */ |
1548 | #endif | 1547 | #endif |
@@ -1552,229 +1551,226 @@ static void handle_incoming_and_exit(void) | |||
1552 | sa.sa_flags = 0; /* no SA_RESTART */ | 1551 | sa.sa_flags = 0; /* no SA_RESTART */ |
1553 | sigaction(SIGALRM, &sa, NULL); | 1552 | sigaction(SIGALRM, &sa, NULL); |
1554 | 1553 | ||
1555 | /* It's not a real loop (it ends with while(0)). | 1554 | alarm(TIMEOUT); |
1556 | * Break from this "loop" jumps to exit(0) */ | 1555 | if (!get_line()) |
1557 | do { | 1556 | _exit(0); /* EOF or error or empty line */ |
1558 | alarm(TIMEOUT); | ||
1559 | if (!get_line()) | ||
1560 | _exit(0); /* EOF or error or empty line */ | ||
1561 | 1557 | ||
1562 | purl = strpbrk(iobuf, " \t"); | 1558 | purl = strpbrk(iobuf, " \t"); |
1563 | if (purl == NULL) { | 1559 | if (purl == NULL) { |
1564 | send_headers_and_exit(HTTP_BAD_REQUEST); | 1560 | send_headers_and_exit(HTTP_BAD_REQUEST); |
1565 | } | 1561 | } |
1566 | *purl = '\0'; | 1562 | *purl = '\0'; |
1567 | #if ENABLE_FEATURE_HTTPD_CGI | 1563 | #if ENABLE_FEATURE_HTTPD_CGI |
1564 | if (strcasecmp(iobuf, prequest) != 0) { | ||
1565 | prequest = "POST"; | ||
1568 | if (strcasecmp(iobuf, prequest) != 0) { | 1566 | if (strcasecmp(iobuf, prequest) != 0) { |
1569 | prequest = "POST"; | ||
1570 | if (strcasecmp(iobuf, prequest) != 0) { | ||
1571 | send_headers_and_exit(HTTP_NOT_IMPLEMENTED); | ||
1572 | } | ||
1573 | } | ||
1574 | #else | ||
1575 | if (strcasecmp(iobuf, request_GET) != 0) { | ||
1576 | send_headers_and_exit(HTTP_NOT_IMPLEMENTED); | 1567 | send_headers_and_exit(HTTP_NOT_IMPLEMENTED); |
1577 | } | 1568 | } |
1569 | } | ||
1570 | #else | ||
1571 | if (strcasecmp(iobuf, request_GET) != 0) { | ||
1572 | send_headers_and_exit(HTTP_NOT_IMPLEMENTED); | ||
1573 | } | ||
1578 | #endif | 1574 | #endif |
1579 | *purl = ' '; | 1575 | *purl = ' '; |
1580 | count = sscanf(purl, " %[^ ] HTTP/%d.%*d", iobuf, &blank); | 1576 | count = sscanf(purl, " %[^ ] HTTP/%d.%*d", iobuf, &blank); |
1581 | 1577 | ||
1582 | if (count < 1 || iobuf[0] != '/') { | 1578 | if (count < 1 || iobuf[0] != '/') { |
1583 | /* Garbled request/URL */ | 1579 | /* Garbled request/URL */ |
1584 | send_headers_and_exit(HTTP_BAD_REQUEST); | 1580 | send_headers_and_exit(HTTP_BAD_REQUEST); |
1585 | } | 1581 | } |
1586 | url = alloca(strlen(iobuf) + sizeof("/index.html")); | 1582 | url = alloca(strlen(iobuf) + sizeof("/index.html")); |
1587 | if (url == NULL) { | 1583 | if (url == NULL) { |
1588 | send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR); | 1584 | send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR); |
1589 | } | 1585 | } |
1590 | strcpy(url, iobuf); | 1586 | strcpy(url, iobuf); |
1591 | /* extract url args if present */ | 1587 | /* extract url args if present */ |
1592 | test = strchr(url, '?'); | 1588 | test = strchr(url, '?'); |
1593 | g_query = NULL; | 1589 | g_query = NULL; |
1594 | if (test) { | 1590 | if (test) { |
1595 | *test++ = '\0'; | 1591 | *test++ = '\0'; |
1596 | g_query = test; | 1592 | g_query = test; |
1597 | } | 1593 | } |
1598 | 1594 | ||
1599 | test = decodeString(url, 0); | 1595 | test = decodeString(url, 0); |
1600 | if (test == NULL) | 1596 | if (test == NULL) |
1601 | send_headers_and_exit(HTTP_BAD_REQUEST); | 1597 | send_headers_and_exit(HTTP_BAD_REQUEST); |
1602 | if (test == url + 1) { | 1598 | if (test == url + 1) { |
1603 | /* '/' or NUL is encoded */ | 1599 | /* '/' or NUL is encoded */ |
1604 | send_headers_and_exit(HTTP_NOT_FOUND); | 1600 | send_headers_and_exit(HTTP_NOT_FOUND); |
1605 | } | 1601 | } |
1606 | 1602 | ||
1607 | /* algorithm stolen from libbb bb_simplify_path(), | 1603 | /* algorithm stolen from libbb bb_simplify_path(), |
1608 | * but don't strdup and reducing trailing slash and protect out root */ | 1604 | * but don't strdup and reducing trailing slash and protect out root */ |
1609 | purl = test = url; | 1605 | purl = test = url; |
1610 | do { | 1606 | do { |
1611 | if (*purl == '/') { | 1607 | if (*purl == '/') { |
1612 | /* skip duplicate (or initial) slash */ | 1608 | /* skip duplicate (or initial) slash */ |
1613 | if (*test == '/') { | 1609 | if (*test == '/') { |
1610 | continue; | ||
1611 | } | ||
1612 | if (*test == '.') { | ||
1613 | /* skip extra '.' */ | ||
1614 | if (test[1] == '/' || !test[1]) { | ||
1614 | continue; | 1615 | continue; |
1615 | } | 1616 | } |
1616 | if (*test == '.') { | 1617 | /* '..': be careful */ |
1617 | /* skip extra '.' */ | 1618 | if (test[1] == '.' && (test[2] == '/' || !test[2])) { |
1618 | if (test[1] == '/' || !test[1]) { | 1619 | ++test; |
1619 | continue; | 1620 | if (purl == url) { |
1620 | } | 1621 | /* protect root */ |
1621 | /* '..': be careful */ | 1622 | send_headers_and_exit(HTTP_BAD_REQUEST); |
1622 | if (test[1] == '.' && (test[2] == '/' || !test[2])) { | ||
1623 | ++test; | ||
1624 | if (purl == url) { | ||
1625 | /* protect root */ | ||
1626 | send_headers_and_exit(HTTP_BAD_REQUEST); | ||
1627 | } | ||
1628 | while (*--purl != '/') /* omit previous dir */; | ||
1629 | continue; | ||
1630 | } | 1623 | } |
1624 | while (*--purl != '/') /* omit previous dir */; | ||
1625 | continue; | ||
1631 | } | 1626 | } |
1632 | } | 1627 | } |
1633 | *++purl = *test; | ||
1634 | } while (*++test); | ||
1635 | *++purl = '\0'; /* so keep last character */ | ||
1636 | test = purl; /* end ptr */ | ||
1637 | |||
1638 | /* If URL is directory, adding '/' */ | ||
1639 | if (test[-1] != '/') { | ||
1640 | if (is_directory(url + 1, 1, &sb)) { | ||
1641 | found_moved_temporarily = url; | ||
1642 | } | ||
1643 | } | 1628 | } |
1644 | if (verbose > 1) | 1629 | *++purl = *test; |
1645 | bb_error_msg("url:%s", url); | 1630 | } while (*++test); |
1646 | 1631 | *++purl = '\0'; /* so keep last character */ | |
1647 | test = url; | 1632 | test = purl; /* end ptr */ |
1648 | ip_allowed = checkPermIP(); | 1633 | |
1649 | while (ip_allowed && (test = strchr(test + 1, '/')) != NULL) { | 1634 | /* If URL is directory, adding '/' */ |
1650 | /* have path1/path2 */ | 1635 | if (test[-1] != '/') { |
1651 | *test = '\0'; | 1636 | if (is_directory(url + 1, 1, &sb)) { |
1652 | if (is_directory(url + 1, 1, &sb)) { | 1637 | found_moved_temporarily = url; |
1653 | /* may be having subdir config */ | 1638 | } |
1654 | parse_conf(url + 1, SUBDIR_PARSE); | 1639 | } |
1655 | ip_allowed = checkPermIP(); | 1640 | |
1656 | } | 1641 | if (verbose > 1) |
1657 | *test = '/'; | 1642 | bb_error_msg("url:%s", url); |
1643 | |||
1644 | test = url; | ||
1645 | ip_allowed = checkPermIP(); | ||
1646 | while (ip_allowed && (test = strchr(test + 1, '/')) != NULL) { | ||
1647 | /* have path1/path2 */ | ||
1648 | *test = '\0'; | ||
1649 | if (is_directory(url + 1, 1, &sb)) { | ||
1650 | /* may be having subdir config */ | ||
1651 | parse_conf(url + 1, SUBDIR_PARSE); | ||
1652 | ip_allowed = checkPermIP(); | ||
1658 | } | 1653 | } |
1659 | if (blank >= 0) { | 1654 | *test = '/'; |
1660 | /* read until blank line for HTTP version specified, else parse immediate */ | 1655 | } |
1661 | while (1) { | 1656 | if (blank >= 0) { |
1662 | alarm(TIMEOUT); | 1657 | /* read until blank line for HTTP version specified, else parse immediate */ |
1663 | if (!get_line()) | 1658 | while (1) { |
1664 | break; /* EOF or error or empty line */ | 1659 | alarm(TIMEOUT); |
1665 | 1660 | if (!get_line()) | |
1666 | if (DEBUG) | 1661 | break; /* EOF or error or empty line */ |
1667 | bb_error_msg("header: '%s'", iobuf); | 1662 | |
1663 | if (DEBUG) | ||
1664 | bb_error_msg("header: '%s'", iobuf); | ||
1668 | #if ENABLE_FEATURE_HTTPD_CGI | 1665 | #if ENABLE_FEATURE_HTTPD_CGI |
1669 | /* try and do our best to parse more lines */ | 1666 | /* try and do our best to parse more lines */ |
1670 | if ((STRNCASECMP(iobuf, "Content-length:") == 0)) { | 1667 | if ((STRNCASECMP(iobuf, "Content-length:") == 0)) { |
1671 | /* extra read only for POST */ | 1668 | /* extra read only for POST */ |
1672 | if (prequest != request_GET) { | 1669 | if (prequest != request_GET) { |
1673 | test = iobuf + sizeof("Content-length:") - 1; | 1670 | test = iobuf + sizeof("Content-length:") - 1; |
1674 | if (!test[0]) | 1671 | if (!test[0]) |
1675 | _exit(0); | 1672 | _exit(0); |
1676 | errno = 0; | 1673 | errno = 0; |
1677 | /* not using strtoul: it ignores leading minus! */ | 1674 | /* not using strtoul: it ignores leading minus! */ |
1678 | length = strtol(test, &test, 10); | 1675 | length = strtol(test, &test, 10); |
1679 | /* length is "ulong", but we need to pass it to int later */ | 1676 | /* length is "ulong", but we need to pass it to int later */ |
1680 | /* so we check for negative or too large values in one go: */ | 1677 | /* so we check for negative or too large values in one go: */ |
1681 | /* (long -> ulong conv caused negatives to be seen as > INT_MAX) */ | 1678 | /* (long -> ulong conv caused negatives to be seen as > INT_MAX) */ |
1682 | if (test[0] || errno || length > INT_MAX) | 1679 | if (test[0] || errno || length > INT_MAX) |
1683 | _exit(0); | 1680 | _exit(0); |
1684 | } | ||
1685 | } else if (STRNCASECMP(iobuf, "Cookie:") == 0) { | ||
1686 | cookie = strdup(skip_whitespace(iobuf + sizeof("Cookie:")-1)); | ||
1687 | } else if (STRNCASECMP(iobuf, "Content-Type:") == 0) { | ||
1688 | content_type = strdup(skip_whitespace(iobuf + sizeof("Content-Type:")-1)); | ||
1689 | } else if (STRNCASECMP(iobuf, "Referer:") == 0) { | ||
1690 | referer = strdup(skip_whitespace(iobuf + sizeof("Referer:")-1)); | ||
1691 | } else if (STRNCASECMP(iobuf, "User-Agent:") == 0) { | ||
1692 | user_agent = strdup(skip_whitespace(iobuf + sizeof("User-Agent:")-1)); | ||
1693 | } | 1681 | } |
1682 | } else if (STRNCASECMP(iobuf, "Cookie:") == 0) { | ||
1683 | cookie = strdup(skip_whitespace(iobuf + sizeof("Cookie:")-1)); | ||
1684 | } else if (STRNCASECMP(iobuf, "Content-Type:") == 0) { | ||
1685 | content_type = strdup(skip_whitespace(iobuf + sizeof("Content-Type:")-1)); | ||
1686 | } else if (STRNCASECMP(iobuf, "Referer:") == 0) { | ||
1687 | referer = strdup(skip_whitespace(iobuf + sizeof("Referer:")-1)); | ||
1688 | } else if (STRNCASECMP(iobuf, "User-Agent:") == 0) { | ||
1689 | user_agent = strdup(skip_whitespace(iobuf + sizeof("User-Agent:")-1)); | ||
1690 | } | ||
1694 | #endif | 1691 | #endif |
1695 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH | 1692 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH |
1696 | if (STRNCASECMP(iobuf, "Authorization:") == 0) { | 1693 | if (STRNCASECMP(iobuf, "Authorization:") == 0) { |
1697 | /* We only allow Basic credentials. | 1694 | /* We only allow Basic credentials. |
1698 | * It shows up as "Authorization: Basic <userid:password>" where | 1695 | * It shows up as "Authorization: Basic <userid:password>" where |
1699 | * the userid:password is base64 encoded. | 1696 | * the userid:password is base64 encoded. |
1700 | */ | 1697 | */ |
1701 | test = skip_whitespace(iobuf + sizeof("Authorization:")-1); | 1698 | test = skip_whitespace(iobuf + sizeof("Authorization:")-1); |
1702 | if (STRNCASECMP(test, "Basic") != 0) | 1699 | if (STRNCASECMP(test, "Basic") != 0) |
1703 | continue; | 1700 | continue; |
1704 | test += sizeof("Basic")-1; | 1701 | test += sizeof("Basic")-1; |
1705 | /* decodeBase64() skips whitespace itself */ | 1702 | /* decodeBase64() skips whitespace itself */ |
1706 | decodeBase64(test); | 1703 | decodeBase64(test); |
1707 | credentials = checkPerm(url, test); | 1704 | credentials = checkPerm(url, test); |
1708 | } | 1705 | } |
1709 | #endif /* FEATURE_HTTPD_BASIC_AUTH */ | 1706 | #endif /* FEATURE_HTTPD_BASIC_AUTH */ |
1710 | } /* while extra header reading */ | 1707 | } /* while extra header reading */ |
1711 | } | 1708 | } |
1712 | alarm(0); | ||
1713 | 1709 | ||
1714 | if (strcmp(bb_basename(url), httpd_conf) == 0 || ip_allowed == 0) { | 1710 | alarm(0); |
1715 | /* protect listing [/path]/httpd_conf or IP deny */ | 1711 | |
1716 | send_headers_and_exit(HTTP_FORBIDDEN); | 1712 | if (strcmp(bb_basename(url), httpd_conf) == 0 || ip_allowed == 0) { |
1717 | } | 1713 | /* protect listing [/path]/httpd_conf or IP deny */ |
1714 | send_headers_and_exit(HTTP_FORBIDDEN); | ||
1715 | } | ||
1718 | 1716 | ||
1719 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH | 1717 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH |
1720 | if (credentials <= 0 && checkPerm(url, ":") == 0) { | 1718 | if (credentials <= 0 && checkPerm(url, ":") == 0) { |
1721 | send_headers_and_exit(HTTP_UNAUTHORIZED); | 1719 | send_headers_and_exit(HTTP_UNAUTHORIZED); |
1722 | } | 1720 | } |
1723 | #endif | 1721 | #endif |
1724 | 1722 | ||
1725 | if (found_moved_temporarily) { | 1723 | if (found_moved_temporarily) { |
1726 | send_headers_and_exit(HTTP_MOVED_TEMPORARILY); | 1724 | send_headers_and_exit(HTTP_MOVED_TEMPORARILY); |
1727 | } | 1725 | } |
1728 | 1726 | ||
1729 | test = url + 1; /* skip first '/' */ | 1727 | test = url + 1; /* skip first '/' */ |
1730 | 1728 | ||
1731 | #if ENABLE_FEATURE_HTTPD_CGI | 1729 | #if ENABLE_FEATURE_HTTPD_CGI |
1732 | if (strncmp(test, "cgi-bin", 7) == 0) { | 1730 | if (strncmp(test, "cgi-bin", 7) == 0) { |
1733 | if (test[7] == '/' && test[8] == '\0') { | 1731 | if (test[7] == '/' && test[8] == '\0') { |
1734 | /* protect listing cgi-bin/ */ | 1732 | /* protect listing cgi-bin/ */ |
1735 | send_headers_and_exit(HTTP_FORBIDDEN); | 1733 | send_headers_and_exit(HTTP_FORBIDDEN); |
1736 | } | ||
1737 | send_cgi_and_exit(url, prequest, length, cookie, content_type); | ||
1738 | } | 1734 | } |
1735 | send_cgi_and_exit(url, prequest, length, cookie, content_type); | ||
1736 | } | ||
1739 | #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR | 1737 | #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR |
1740 | { | 1738 | { |
1741 | char *suffix = strrchr(test, '.'); | 1739 | char *suffix = strrchr(test, '.'); |
1742 | if (suffix) { | 1740 | if (suffix) { |
1743 | Htaccess *cur; | 1741 | Htaccess *cur; |
1744 | for (cur = script_i; cur; cur = cur->next) { | 1742 | for (cur = script_i; cur; cur = cur->next) { |
1745 | if (strcmp(cur->before_colon + 1, suffix) == 0) { | 1743 | if (strcmp(cur->before_colon + 1, suffix) == 0) { |
1746 | send_cgi_and_exit(url, prequest, length, cookie, content_type); | 1744 | send_cgi_and_exit(url, prequest, length, cookie, content_type); |
1747 | } | ||
1748 | } | 1745 | } |
1749 | } | 1746 | } |
1750 | } | 1747 | } |
1748 | } | ||
1751 | #endif | 1749 | #endif |
1752 | if (prequest != request_GET) { | 1750 | if (prequest != request_GET) { |
1753 | send_headers_and_exit(HTTP_NOT_IMPLEMENTED); | 1751 | send_headers_and_exit(HTTP_NOT_IMPLEMENTED); |
1754 | } | 1752 | } |
1755 | #endif /* FEATURE_HTTPD_CGI */ | 1753 | #endif /* FEATURE_HTTPD_CGI */ |
1756 | if (purl[-1] == '/') | 1754 | if (purl[-1] == '/') |
1757 | strcpy(purl, "index.html"); | 1755 | strcpy(purl, "index.html"); |
1758 | if (stat(test, &sb) == 0) { | 1756 | if (stat(test, &sb) == 0) { |
1759 | /* It's a dir URL and there is index.html */ | 1757 | /* It's a dir URL and there is index.html */ |
1760 | ContentLength = sb.st_size; | 1758 | ContentLength = sb.st_size; |
1761 | last_mod = sb.st_mtime; | 1759 | last_mod = sb.st_mtime; |
1762 | } | 1760 | } |
1763 | #if ENABLE_FEATURE_HTTPD_CGI | 1761 | #if ENABLE_FEATURE_HTTPD_CGI |
1764 | else if (purl[-1] == '/') { | 1762 | else if (purl[-1] == '/') { |
1765 | /* It's a dir URL and there is no index.html | 1763 | /* It's a dir URL and there is no index.html |
1766 | * Try cgi-bin/index.cgi */ | 1764 | * Try cgi-bin/index.cgi */ |
1767 | if (access("/cgi-bin/index.cgi"+1, X_OK) == 0) { | 1765 | if (access("/cgi-bin/index.cgi"+1, X_OK) == 0) { |
1768 | purl[0] = '\0'; | 1766 | purl[0] = '\0'; |
1769 | g_query = url; | 1767 | g_query = url; |
1770 | send_cgi_and_exit("/cgi-bin/index.cgi", prequest, length, cookie, content_type); | 1768 | send_cgi_and_exit("/cgi-bin/index.cgi", prequest, length, cookie, content_type); |
1771 | } | ||
1772 | } | 1769 | } |
1770 | } | ||
1773 | #endif /* FEATURE_HTTPD_CGI */ | 1771 | #endif /* FEATURE_HTTPD_CGI */ |
1774 | send_file_and_exit(test); | ||
1775 | } while (0); | ||
1776 | 1772 | ||
1777 | _exit(0); | 1773 | send_file_and_exit(test); |
1778 | 1774 | ||
1779 | #if 0 /* Is this needed? Why? */ | 1775 | #if 0 /* Is this needed? Why? */ |
1780 | if (DEBUG) | 1776 | if (DEBUG) |
@@ -1817,7 +1813,6 @@ static void handle_incoming_and_exit(void) | |||
1817 | static void mini_httpd(int server) ATTRIBUTE_NORETURN; | 1813 | static void mini_httpd(int server) ATTRIBUTE_NORETURN; |
1818 | static void mini_httpd(int server) | 1814 | static void mini_httpd(int server) |
1819 | { | 1815 | { |
1820 | /* copy the ports we are watching to the readfd set */ | ||
1821 | while (1) { | 1816 | while (1) { |
1822 | int n; | 1817 | int n; |
1823 | len_and_sockaddr fromAddr; | 1818 | len_and_sockaddr fromAddr; |