aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-08-19 18:53:43 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-08-19 18:53:43 +0000
commit52e15dc50b0eaa30109564dcdbb6b6f9557cd1d9 (patch)
tree411b894818fcfb539f2cb1805ff4d00439c2f251
parentf9000c51dbf7bb9544a305ae06e91bba7e17e26a (diff)
downloadbusybox-w32-52e15dc50b0eaa30109564dcdbb6b6f9557cd1d9.tar.gz
busybox-w32-52e15dc50b0eaa30109564dcdbb6b6f9557cd1d9.tar.bz2
busybox-w32-52e15dc50b0eaa30109564dcdbb6b6f9557cd1d9.zip
httpd: get rid of sscanf usage. Rename some variables.
-rw-r--r--networking/httpd.c204
1 files changed, 110 insertions, 94 deletions
diff --git a/networking/httpd.c b/networking/httpd.c
index c837d67ad..23d442f17 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -110,6 +110,7 @@
110 110
111static const char default_path_httpd_conf[] ALIGN1 = "/etc"; 111static const char default_path_httpd_conf[] ALIGN1 = "/etc";
112static const char httpd_conf[] ALIGN1 = "httpd.conf"; 112static const char httpd_conf[] ALIGN1 = "httpd.conf";
113static const char HTTP_200[] ALIGN1 = "HTTP/1.0 200 OK\r\n";
113 114
114typedef struct has_next_ptr { 115typedef struct has_next_ptr {
115 struct has_next_ptr *next; 116 struct has_next_ptr *next;
@@ -135,6 +136,7 @@ struct globals {
135 smallint flg_deny_all; 136 smallint flg_deny_all;
136 137
137 unsigned rmt_ip; 138 unsigned rmt_ip;
139// TODO: get rid of rmt_port
138 unsigned rmt_port; /* for set env REMOTE_PORT */ 140 unsigned rmt_port; /* for set env REMOTE_PORT */
139 char *rmt_ip_str; /* for set env REMOTE_ADDR */ 141 char *rmt_ip_str; /* for set env REMOTE_ADDR */
140 const char *bind_addr_or_port; 142 const char *bind_addr_or_port;
@@ -661,6 +663,22 @@ static char *encodeString(const char *string)
661 * 663 *
662 * Returns a pointer to the decoded string (same as input). 664 * Returns a pointer to the decoded string (same as input).
663 */ 665 */
666static unsigned hex_to_bin(unsigned char c)
667{
668 unsigned v = c | 0x20; /* lowercase */
669 v = v - '0';
670 if (v <= 9)
671 return v;
672 v = v + ('0' - 'a');
673 if (v <= 5)
674 return v + 10;
675 return ~0;
676}
677/* For testing:
678void t(char c) { printf("'%c' %u\n", c, hex_to_bin(c)); }
679int main() { t('0'); t('9'); t('A'); t('F'); t('a'); t('f');
680t('0'-1); t('9'+1); t('A'-1); t('F'+1); t('a'-1); t('f'+1); return 0; }
681*/
664static char *decodeString(char *orig, int option_d) 682static char *decodeString(char *orig, int option_d)
665{ 683{
666 /* note that decoded string is always shorter than original */ 684 /* note that decoded string is always shorter than original */
@@ -669,7 +687,7 @@ static char *decodeString(char *orig, int option_d)
669 char c; 687 char c;
670 688
671 while ((c = *ptr++) != '\0') { 689 while ((c = *ptr++) != '\0') {
672 unsigned value1, value2; 690 unsigned v;
673 691
674 if (option_d && c == '+') { 692 if (option_d && c == '+') {
675 *string++ = ' '; 693 *string++ = ' ';
@@ -679,21 +697,23 @@ static char *decodeString(char *orig, int option_d)
679 *string++ = c; 697 *string++ = c;
680 continue; 698 continue;
681 } 699 }
682 if (sscanf(ptr, "%1X", &value1) != 1 700 v = hex_to_bin(ptr[0]);
683 || sscanf(ptr+1, "%1X", &value2) != 1 701 if (v > 15) {
684 ) { 702 bad_hex:
685 if (!option_d) 703 if (!option_d)
686 return NULL; 704 return NULL;
687 *string++ = '%'; 705 *string++ = '%';
688 continue; 706 continue;
689 } 707 }
690 value1 = value1 * 16 + value2; 708 v = (v * 16) | hex_to_bin(ptr[1]);
691 if (!option_d && (value1 == '/' || value1 == '\0')) { 709 if (v > 255)
710 goto bad_hex;
711 if (!option_d && (v == '/' || v == '\0')) {
692 /* caller takes it as indication of invalid 712 /* caller takes it as indication of invalid
693 * (dangerous wrt exploits) chars */ 713 * (dangerous wrt exploits) chars */
694 return orig + 1; 714 return orig + 1;
695 } 715 }
696 *string++ = value1; 716 *string++ = v;
697 ptr += 2; 717 ptr += 2;
698 } 718 }
699 *string = '\0'; 719 *string = '\0';
@@ -1188,13 +1208,13 @@ static void send_cgi_and_exit(
1188 1208
1189 /* Are we still buffering CGI output? */ 1209 /* Are we still buffering CGI output? */
1190 if (buf_count >= 0) { 1210 if (buf_count >= 0) {
1191 /* According to http://hoohoo.ncsa.uiuc.edu/cgi/out.html, 1211 /* HTTP_200[] has single "\r\n" at the end.
1212 * According to http://hoohoo.ncsa.uiuc.edu/cgi/out.html,
1192 * CGI scripts MUST send their own header terminated by 1213 * CGI scripts MUST send their own header terminated by
1193 * empty line, then data. That's why we have only one 1214 * empty line, then data. That's why we have only one
1194 * <cr><lf> pair here. We will output "200 OK" line 1215 * <cr><lf> pair here. We will output "200 OK" line
1195 * if needed, but CGI still has to provide blank line 1216 * if needed, but CGI still has to provide blank line
1196 * between header and body */ 1217 * between header and body */
1197 static const char HTTP_200[] ALIGN1 = "HTTP/1.0 200 OK\r\n";
1198 1218
1199 /* Must use safe_read, not full_read, because 1219 /* Must use safe_read, not full_read, because
1200 * CGI may output a few first bytes and then wait 1220 * CGI may output a few first bytes and then wait
@@ -1489,12 +1509,11 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
1489{ 1509{
1490 static const char request_GET[] ALIGN1 = "GET"; 1510 static const char request_GET[] ALIGN1 = "GET";
1491 1511
1492 char *url;
1493 char *purl;
1494 int count;
1495 int http_major_version;
1496 char *test;
1497 struct stat sb; 1512 struct stat sb;
1513 char *urlcopy;
1514 char *urlp;
1515 char *tptr;
1516 int http_major_version;
1498 int ip_allowed; 1517 int ip_allowed;
1499#if ENABLE_FEATURE_HTTPD_CGI 1518#if ENABLE_FEATURE_HTTPD_CGI
1500 const char *prequest; 1519 const char *prequest;
@@ -1535,58 +1554,57 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
1535 sigaction(SIGALRM, &sa, NULL); 1554 sigaction(SIGALRM, &sa, NULL);
1536 alarm(HEADER_READ_TIMEOUT); 1555 alarm(HEADER_READ_TIMEOUT);
1537 1556
1538 if (!get_line()) { 1557 if (!get_line()) /* EOF or error or empty line */
1539 /* EOF or error or empty line */
1540 send_headers_and_exit(HTTP_BAD_REQUEST); 1558 send_headers_and_exit(HTTP_BAD_REQUEST);
1541 }
1542 1559
1543 /* Determine type of request (GET/POST) */ 1560 /* Determine type of request (GET/POST) */
1544 purl = strpbrk(iobuf, " \t"); 1561 urlp = strpbrk(iobuf, " \t");
1545 if (purl == NULL) { 1562 if (urlp == NULL)
1546 send_headers_and_exit(HTTP_BAD_REQUEST); 1563 send_headers_and_exit(HTTP_BAD_REQUEST);
1547 } 1564 *urlp++ = '\0';
1548 *purl = '\0';
1549#if ENABLE_FEATURE_HTTPD_CGI 1565#if ENABLE_FEATURE_HTTPD_CGI
1550 prequest = request_GET; 1566 prequest = request_GET;
1551 if (strcasecmp(iobuf, prequest) != 0) { 1567 if (strcasecmp(iobuf, prequest) != 0) {
1552 prequest = "POST"; 1568 prequest = "POST";
1553 if (strcasecmp(iobuf, prequest) != 0) { 1569 if (strcasecmp(iobuf, prequest) != 0)
1554 send_headers_and_exit(HTTP_NOT_IMPLEMENTED); 1570 send_headers_and_exit(HTTP_NOT_IMPLEMENTED);
1555 }
1556 } 1571 }
1557#else 1572#else
1558 if (strcasecmp(iobuf, request_GET) != 0) { 1573 if (strcasecmp(iobuf, request_GET) != 0)
1559 send_headers_and_exit(HTTP_NOT_IMPLEMENTED); 1574 send_headers_and_exit(HTTP_NOT_IMPLEMENTED);
1560 }
1561#endif 1575#endif
1562 *purl = ' '; 1576 urlp = skip_whitespace(urlp);
1577 if (urlp[0] != '/')
1578 send_headers_and_exit(HTTP_BAD_REQUEST);
1563 1579
1564 /* Copy URL from after "GET "/"POST " to stack-allocated char[] */ 1580 /* Find end of URL and parse HTTP version, if any */
1565 http_major_version = -1; 1581 http_major_version = -1;
1566 count = sscanf(purl, " %[^ ] HTTP/%d.%*d", iobuf, &http_major_version); 1582 tptr = strchrnul(urlp, ' ');
1567 if (count < 1 || iobuf[0] != '/') { 1583 /* Is it " HTTP/"? */
1568 /* Garbled request/URL */ 1584 if (tptr[0] && strncmp(tptr + 1, HTTP_200, 5) == 0)
1569 send_headers_and_exit(HTTP_BAD_REQUEST); 1585 http_major_version = (tptr[6] - '0');
1570 } 1586 *tptr = '\0';
1571 url = alloca(strlen(iobuf) + sizeof("/index.html")); 1587
1572 if (url == NULL) { 1588 /* Copy URL from after "GET "/"POST " to stack-allocated char[] */
1573 send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR); 1589 urlcopy = alloca((tptr - urlp) + sizeof("/index.html"));
1574 } 1590 /*if (urlcopy == NULL)
1575 strcpy(url, iobuf); 1591 * send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);*/
1592 strcpy(urlcopy, urlp);
1593 /* NB: urlcopy ptr is never changed after this */
1576 1594
1577 /* Extract url args if present */ 1595 /* Extract url args if present */
1578 test = strchr(url, '?'); 1596 tptr = strchr(urlcopy, '?');
1579 g_query = NULL; 1597 g_query = NULL;
1580 if (test) { 1598 if (tptr) {
1581 *test++ = '\0'; 1599 *tptr++ = '\0';
1582 g_query = test; 1600 g_query = tptr;
1583 } 1601 }
1584 1602
1585 /* Decode URL escape sequences */ 1603 /* Decode URL escape sequences */
1586 test = decodeString(url, 0); 1604 tptr = decodeString(urlcopy, 0);
1587 if (test == NULL) 1605 if (tptr == NULL)
1588 send_headers_and_exit(HTTP_BAD_REQUEST); 1606 send_headers_and_exit(HTTP_BAD_REQUEST);
1589 if (test == url + 1) { 1607 if (tptr == urlcopy + 1) {
1590 /* '/' or NUL is encoded */ 1608 /* '/' or NUL is encoded */
1591 send_headers_and_exit(HTTP_NOT_FOUND); 1609 send_headers_and_exit(HTTP_NOT_FOUND);
1592 } 1610 }
@@ -1594,60 +1612,58 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
1594 /* Canonicalize path */ 1612 /* Canonicalize path */
1595 /* Algorithm stolen from libbb bb_simplify_path(), 1613 /* Algorithm stolen from libbb bb_simplify_path(),
1596 * but don't strdup and reducing trailing slash and protect out root */ 1614 * but don't strdup and reducing trailing slash and protect out root */
1597 purl = test = url; 1615 urlp = tptr = urlcopy;
1598 do { 1616 do {
1599 if (*purl == '/') { 1617 if (*urlp == '/') {
1600 /* skip duplicate (or initial) slash */ 1618 /* skip duplicate (or initial) slash */
1601 if (*test == '/') { 1619 if (*tptr == '/') {
1602 continue; 1620 continue;
1603 } 1621 }
1604 if (*test == '.') { 1622 if (*tptr == '.') {
1605 /* skip extra '.' */ 1623 /* skip extra '.' */
1606 if (test[1] == '/' || !test[1]) { 1624 if (tptr[1] == '/' || !tptr[1]) {
1607 continue; 1625 continue;
1608 } 1626 }
1609 /* '..': be careful */ 1627 /* '..': be careful */
1610 if (test[1] == '.' && (test[2] == '/' || !test[2])) { 1628 if (tptr[1] == '.' && (tptr[2] == '/' || !tptr[2])) {
1611 ++test; 1629 ++tptr;
1612 if (purl == url) { 1630 if (urlp == urlcopy) /* protect root */
1613 /* protect root */
1614 send_headers_and_exit(HTTP_BAD_REQUEST); 1631 send_headers_and_exit(HTTP_BAD_REQUEST);
1615 } 1632 while (*--urlp != '/') /* omit previous dir */;
1616 while (*--purl != '/') /* omit previous dir */;
1617 continue; 1633 continue;
1618 } 1634 }
1619 } 1635 }
1620 } 1636 }
1621 *++purl = *test; 1637 *++urlp = *tptr;
1622 } while (*++test); 1638 } while (*++tptr);
1623 *++purl = '\0'; /* so keep last character */ 1639 *++urlp = '\0'; /* so keep last character */
1624 test = purl; /* end ptr */ 1640 tptr = urlp; /* end ptr */
1625 1641
1626 /* If URL is a directory, add '/' */ 1642 /* If URL is a directory, add '/' */
1627 if (test[-1] != '/') { 1643 if (tptr[-1] != '/') {
1628 if (is_directory(url + 1, 1, &sb)) { 1644 if (is_directory(urlcopy + 1, 1, &sb)) {
1629 found_moved_temporarily = url; 1645 found_moved_temporarily = urlcopy;
1630 } 1646 }
1631 } 1647 }
1632 1648
1633 /* Log it */ 1649 /* Log it */
1634 if (verbose > 1) 1650 if (verbose > 1)
1635 bb_error_msg("url:%s", url); 1651 bb_error_msg("url:%s", urlcopy);
1636 1652
1637 test = url; 1653 tptr = urlcopy;
1638 ip_allowed = checkPermIP(); 1654 ip_allowed = checkPermIP();
1639 while (ip_allowed && (test = strchr(test + 1, '/')) != NULL) { 1655 while (ip_allowed && (tptr = strchr(tptr + 1, '/')) != NULL) {
1640 /* have path1/path2 */ 1656 /* have path1/path2 */
1641 *test = '\0'; 1657 *tptr = '\0';
1642 if (is_directory(url + 1, 1, &sb)) { 1658 if (is_directory(urlcopy + 1, 1, &sb)) {
1643 /* may be having subdir config */ 1659 /* may be having subdir config */
1644 parse_conf(url + 1, SUBDIR_PARSE); 1660 parse_conf(urlcopy + 1, SUBDIR_PARSE);
1645 ip_allowed = checkPermIP(); 1661 ip_allowed = checkPermIP();
1646 } 1662 }
1647 *test = '/'; 1663 *tptr = '/';
1648 } 1664 }
1649 if (http_major_version >= 0) { 1665 if (http_major_version >= 0) {
1650 /* Request was with "... HTTP/n.m", and n >= 0 */ 1666 /* Request was with "... HTTP/nXXX", and n >= 0 */
1651 1667
1652 /* Read until blank line for HTTP version specified, else parse immediate */ 1668 /* Read until blank line for HTTP version specified, else parse immediate */
1653 while (1) { 1669 while (1) {
@@ -1662,16 +1678,16 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
1662 if ((STRNCASECMP(iobuf, "Content-length:") == 0)) { 1678 if ((STRNCASECMP(iobuf, "Content-length:") == 0)) {
1663 /* extra read only for POST */ 1679 /* extra read only for POST */
1664 if (prequest != request_GET) { 1680 if (prequest != request_GET) {
1665 test = iobuf + sizeof("Content-length:") - 1; 1681 tptr = iobuf + sizeof("Content-length:") - 1;
1666 if (!test[0]) 1682 if (!tptr[0])
1667 send_headers_and_exit(HTTP_BAD_REQUEST); 1683 send_headers_and_exit(HTTP_BAD_REQUEST);
1668 errno = 0; 1684 errno = 0;
1669 /* not using strtoul: it ignores leading minus! */ 1685 /* not using strtoul: it ignores leading minus! */
1670 length = strtol(test, &test, 10); 1686 length = strtol(tptr, &tptr, 10);
1671 /* length is "ulong", but we need to pass it to int later */ 1687 /* length is "ulong", but we need to pass it to int later */
1672 /* so we check for negative or too large values in one go: */ 1688 /* so we check for negative or too large values in one go: */
1673 /* (long -> ulong conv caused negatives to be seen as > INT_MAX) */ 1689 /* (long -> ulong conv caused negatives to be seen as > INT_MAX) */
1674 if (test[0] || errno || length > INT_MAX) 1690 if (tptr[0] || errno || length > INT_MAX)
1675 send_headers_and_exit(HTTP_BAD_REQUEST); 1691 send_headers_and_exit(HTTP_BAD_REQUEST);
1676 } 1692 }
1677 } else if (STRNCASECMP(iobuf, "Cookie:") == 0) { 1693 } else if (STRNCASECMP(iobuf, "Cookie:") == 0) {
@@ -1690,13 +1706,13 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
1690 * It shows up as "Authorization: Basic <userid:password>" where 1706 * It shows up as "Authorization: Basic <userid:password>" where
1691 * the userid:password is base64 encoded. 1707 * the userid:password is base64 encoded.
1692 */ 1708 */
1693 test = skip_whitespace(iobuf + sizeof("Authorization:")-1); 1709 tptr = skip_whitespace(iobuf + sizeof("Authorization:")-1);
1694 if (STRNCASECMP(test, "Basic") != 0) 1710 if (STRNCASECMP(tptr, "Basic") != 0)
1695 continue; 1711 continue;
1696 test += sizeof("Basic")-1; 1712 tptr += sizeof("Basic")-1;
1697 /* decodeBase64() skips whitespace itself */ 1713 /* decodeBase64() skips whitespace itself */
1698 decodeBase64(test); 1714 decodeBase64(tptr);
1699 credentials = checkPerm(url, test); 1715 credentials = checkPerm(urlcopy, tptr);
1700 } 1716 }
1701#endif /* FEATURE_HTTPD_BASIC_AUTH */ 1717#endif /* FEATURE_HTTPD_BASIC_AUTH */
1702 } /* while extra header reading */ 1718 } /* while extra header reading */
@@ -1705,13 +1721,13 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
1705 /* We read headers, disable peer timeout */ 1721 /* We read headers, disable peer timeout */
1706 alarm(0); 1722 alarm(0);
1707 1723
1708 if (strcmp(bb_basename(url), httpd_conf) == 0 || ip_allowed == 0) { 1724 if (strcmp(bb_basename(urlcopy), httpd_conf) == 0 || ip_allowed == 0) {
1709 /* protect listing [/path]/httpd_conf or IP deny */ 1725 /* protect listing [/path]/httpd_conf or IP deny */
1710 send_headers_and_exit(HTTP_FORBIDDEN); 1726 send_headers_and_exit(HTTP_FORBIDDEN);
1711 } 1727 }
1712 1728
1713#if ENABLE_FEATURE_HTTPD_BASIC_AUTH 1729#if ENABLE_FEATURE_HTTPD_BASIC_AUTH
1714 if (credentials <= 0 && checkPerm(url, ":") == 0) { 1730 if (credentials <= 0 && checkPerm(urlcopy, ":") == 0) {
1715 send_headers_and_exit(HTTP_UNAUTHORIZED); 1731 send_headers_and_exit(HTTP_UNAUTHORIZED);
1716 } 1732 }
1717#endif 1733#endif
@@ -1720,24 +1736,24 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
1720 send_headers_and_exit(HTTP_MOVED_TEMPORARILY); 1736 send_headers_and_exit(HTTP_MOVED_TEMPORARILY);
1721 } 1737 }
1722 1738
1723 test = url + 1; /* skip first '/' */ 1739 tptr = urlcopy + 1; /* skip first '/' */
1724 1740
1725#if ENABLE_FEATURE_HTTPD_CGI 1741#if ENABLE_FEATURE_HTTPD_CGI
1726 if (strncmp(test, "cgi-bin/", 8) == 0) { 1742 if (strncmp(tptr, "cgi-bin/", 8) == 0) {
1727 if (test[8] == '\0') { 1743 if (tptr[8] == '\0') {
1728 /* protect listing "cgi-bin/" */ 1744 /* protect listing "cgi-bin/" */
1729 send_headers_and_exit(HTTP_FORBIDDEN); 1745 send_headers_and_exit(HTTP_FORBIDDEN);
1730 } 1746 }
1731 send_cgi_and_exit(url, prequest, length, cookie, content_type); 1747 send_cgi_and_exit(urlcopy, prequest, length, cookie, content_type);
1732 } 1748 }
1733#if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR 1749#if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR
1734 { 1750 {
1735 char *suffix = strrchr(test, '.'); 1751 char *suffix = strrchr(tptr, '.');
1736 if (suffix) { 1752 if (suffix) {
1737 Htaccess *cur; 1753 Htaccess *cur;
1738 for (cur = script_i; cur; cur = cur->next) { 1754 for (cur = script_i; cur; cur = cur->next) {
1739 if (strcmp(cur->before_colon + 1, suffix) == 0) { 1755 if (strcmp(cur->before_colon + 1, suffix) == 0) {
1740 send_cgi_and_exit(url, prequest, length, cookie, content_type); 1756 send_cgi_and_exit(urlcopy, prequest, length, cookie, content_type);
1741 } 1757 }
1742 } 1758 }
1743 } 1759 }
@@ -1748,20 +1764,20 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
1748 } 1764 }
1749#endif /* FEATURE_HTTPD_CGI */ 1765#endif /* FEATURE_HTTPD_CGI */
1750 1766
1751 if (purl[-1] == '/') 1767 if (urlp[-1] == '/')
1752 strcpy(purl, "index.html"); 1768 strcpy(urlp, "index.html");
1753 if (stat(test, &sb) == 0) { 1769 if (stat(tptr, &sb) == 0) {
1754 /* It's a dir URL and there is index.html */ 1770 /* It's a dir URL and there is index.html */
1755 ContentLength = sb.st_size; 1771 ContentLength = sb.st_size;
1756 last_mod = sb.st_mtime; 1772 last_mod = sb.st_mtime;
1757 } 1773 }
1758#if ENABLE_FEATURE_HTTPD_CGI 1774#if ENABLE_FEATURE_HTTPD_CGI
1759 else if (purl[-1] == '/') { 1775 else if (urlp[-1] == '/') {
1760 /* It's a dir URL and there is no index.html 1776 /* It's a dir URL and there is no index.html
1761 * Try cgi-bin/index.cgi */ 1777 * Try cgi-bin/index.cgi */
1762 if (access("/cgi-bin/index.cgi"+1, X_OK) == 0) { 1778 if (access("/cgi-bin/index.cgi"+1, X_OK) == 0) {
1763 purl[0] = '\0'; 1779 urlp[0] = '\0';
1764 g_query = url; 1780 g_query = urlcopy;
1765 send_cgi_and_exit("/cgi-bin/index.cgi", prequest, length, cookie, content_type); 1781 send_cgi_and_exit("/cgi-bin/index.cgi", prequest, length, cookie, content_type);
1766 } 1782 }
1767 } 1783 }
@@ -1771,7 +1787,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
1771 * } 1787 * }
1772 */ 1788 */
1773 1789
1774 send_file_and_exit(test); 1790 send_file_and_exit(tptr);
1775 1791
1776#if 0 /* Is this needed? Why? */ 1792#if 0 /* Is this needed? Why? */
1777 if (DEBUG) 1793 if (DEBUG)