Mail Archives: cygwin/2001/04/30/13:14:36
------=_NextPart_000_0075_01C0D165.726C34D0
Content-Type: text/plain;
charset="utf-8"
Content-Transfer-Encoding: 7bit
I hate this mailer! I think I should better use another one.
Again, this is the failing source code. Whenever realloc() is used in
sendfile(), the MicroHTTPD segfaults.
Thunder
System:
AMD K6-II 400
Windows NT 4.0 with latest cygwin --> uhttpd problem
Self-compiled Linux with self-compiled programs --> uhttpd seems to work
when running as root, else chroot() fails with ENOPERM. (sure, since only
root may chroot().)
VIIB graphic card
SB Live!
------=_NextPart_000_0075_01C0D165.726C34D0
Content-Type: application/octet-stream;
name="uhttpd-segfault.c"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="uhttpd-segfault.c"
/*
* MicroHTTPD - A minimalistic HTTP daemon.
*
* Written 2001 by Thunder from the hill
*/
/*
* Include files
*/
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
/*
* Functions
*/
int sendfile(int Socket, char *filename); /* Send file */
int http_request(int Socket, char *req); /* Respond to HTTP request */
void clear(char *set, size_t len); /* Emtpy array of size len */
/*
* Variables
*/
int MySock; /* Socket */
int NewSock; /* Socket for accept. */
int peer_size =3D 0; /* Name stack size for the peer */
struct sockaddr_in addr; /* Our address */
struct sockaddr_in peer; /* The peer's address */
struct hostent *hostentry; /* Hostentry - for anything we need */
char *request; /* Our HTTP request */
char *BufIn, *BufOut; /* Input/Output-Buffer */
int BufInLen =3D 2048, BufOutLen =3D 2048;
struct arx {
short port;
char *basedir;
} args;
void clear(char *set, size_t len) {
char *sptr;
realloc(set, len + 1);
sptr =3D set;
for (sptr =3D set; sptr < set + len; sptr++) {
*sptr =3D '\0';
}
return;
}
int http_request(int Socket, char *req) {
char *req_substr;
req_substr =3D strtok(req, " ");
printf("HTTP Request: %s", req_substr);
if (strlen(req_substr) > 0 && strcmp(req_substr, "GET") =3D=3D 0) {
req_substr =3D strtok(NULL, " ");
printf(" %s\n", req_substr);
if (strstr(req_substr, "/internal/") !=3D NULL) {
if (strcmp(req_substr, "/internal/uhttpd-logo") =3D=3D 0) {
char uhttpd_logo[] =3D {71, 73, 70, 56, 57, 97, 100, 0, 25, 0, -9, 0, =
0,
0, 0, -128, 124, 124, -67, -102, -102, -51, -31, -31, -16, -23, -23,
-12, -16, -16, -9, -8, -8, -5, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44,
0, 0, 0, 0, 100, 0, 25, 0, 71, 8, -4, 0, 1, 8, 28, 72, -80, -96, -63,
-125, 8, 19, 42, 92, -56, -80, -95, -61, -127, 5, 34, 70, 76, 56, 96,
34, -128, -118, 22, 21, 22, 104, -72, -15, 96, 71, -126, 31, 25,
-122, 124, 88, 48, 35, -56, -111, 26, 81, -110, 116, -88, 114, -91,
-53, -105, 48, 99, -54, 76, 104, 114, 102, -53, -103, 56, 89, 74,
-108, 88, 50, 100, 77, -113, 39, 81, 126, -12, 105, -112, -88, -64,
-114, 67, 115, -98, 124, -8, 83, -87, 83, -105, 60, 87, -18, 124, 74,
-107, 41, -43, -90, 85, -77, 70, 45, -22, -13, 38, -60, -98, 38, 45,
26, 5, 73, -10, -88, -39, -77, 76, -57, 114, -35, -71, -43, -93, -41,
-81, 104, -113, -114, 20, -37, 118, 106, -50, -102, 88, -117, 102,
-35, -5, -78, 109, 79, -66, -128, 117, -78, 29, 60, 56, -80, 97, -82,
56, -13, 30, -66, 123, 117, -79, 86, -118, 22, 49, -66, 5, 48, -103,
50, 66, -95, 86, 97, 42, 14, -5, -106, -16, 101, -54, 93, 51, -38,
-75, 43, 87, 113, 80, -62, 126, 65, 47, 93, -117, -70, -80, -27, -72,
-104, -31, -66, 78, 42, -107, -76, -37, 0, 0, 4, 96, 92, -24, 26, 40,
108, -67, -78, -111, -54, -42, -36, -110, 109, -128, -120, 3, 104,
86, -106, -71, -100, -71, -48, -26, -51, 29, 59, -1, 88, 81, 100,
116, -23, 119, 77, -85, -58, -50, 29, 98, -21, -21, 4, -35, 11, 6, 4,
0, 33, -2, -45, 84, 104, 105, 115, 32, 102, 105, 108, 101, 32, 119,
97, 115, 32, 99, 114, 101, 97, 116, 101, 100, 32, 98, 121, 13, 13,
71, 114, 97, 112, 104, 105, 99, 32, 87, 111, 114, 107, 115, 104, 111,
112, -103, 32, 80, 114, 111, 102, 101, 115, 115, 105, 111, 110, 97,
108, 32, 50, 46, 48, 97, 13, 13, 102, 114, 111, 109, 32, 65, 108, 99,
104, 101, 109, 121, 32, 77, 105, 110, 100, 119, 111, 114, 107, 115,
32, 73, 110, 99, 46, 13, 104, 116, 116, 112, 58, 47, 47, 119, 119,
119, 46, 109, 105, 110, 100, 119, 111, 114, 107, 115, 104, 111, 112,
46, 99, 111, 109, 13, 13, 84, 104, 105, 115, 32, 105, 109, 97, 103,
101, 32, 109, 97, 121, 32, 104, 97, 118, 101, 32, 98, 101, 101, 110,
32, 99, 114, 101, 97, 116, 101, 100, 32, 98, 121, 13, 97, 32, 112,
97, 114, 116, 121, 32, 111, 116, 104, 101, 114, 32, 116, 104, 97,
110, 32, 65, 108, 99, 104, 101, 109, 121, 32, 77, 105, 110, 100, 119,
111, 114, 107, 115, 32, 73, 110, 99, 46, 13, 13, 85, 115, 101, 32,
110, 111, 32, 104, 111, 111, 107, 115, 0, 59, -1, '\0'};
clear(BufOut, BufOutLen);
if (BufOutLen < 1536 || BufOutLen > 2560) {
realloc(BufOut, 1536);
BufOutLen =3D 1536;
}
strcpy(BufOut, uhttpd_logo);
} else if (strcmp(req_substr, "/internal/uhttpd-version") =3D=3D =
0) {
clear(BufOut, BufOutLen);
if (BufOutLen < 2304 || BufOutLen > 2560) {
realloc(BufOut, 2304);
BufOutLen =3D 2304;
}
strcpy(BufOut, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 =
Transitional//EN\">\n<html>\n <head>\n <title>The MicroHTTPD</title>\n =
<meta name=3D\"AUTHOR\" content=3D\"Thunder from the hill\">\n <meta =
name=3D\"GENERATOR\" content=3D\"MicroHTTPD internal data\">\n </head>\n =
<body bgcolor=3D\"#040050\" text=3D\"#FFFFE0\" link=3D\"#F0F040\" =
vlink=3D\"#F0F040\" alink=3D\"#F0F040\">\n <table =
width=3D\"100%%\"><tr><td align=3D\"left\"><img =
src=3D\"/internal/uhttpd-logo\" alt=3D\"uhttpd logo\"></td><td =
align=3D\"right\">Want something tiny at home instead of huge HTTP =
servers? We have it: <big>MicroHTTPD</big></td></tr></table>\n <h1 =
align=3D\"center\">MicroHTTPD</h1>\n <p align=3D\"justify\">The =
MicroHTTPD (or evern more short, uhttpd) is a very small OpenSource HTTP =
daemon. CGIs are not yet supported, but may come later. If you like it, =
please tell <a href=3D\"mailto:thunder AT ngforever DOT de\" =
onMouseover=3D\"status=3D\'Click here to send a mail to Thunder from the =
hill!'; return true;\" onMouseout=3D\"status=3D\'\'; return true;\">the =
author</a>!\n <h1 align=3D\"center\">License</h1>\n <p =
align=3D\"justify\">MicroHTTPD v1.0 - a minimalistic HTTP daemon.<br>\n =
Copyright (c) 2001, Thunder from the hill.<br><br>\n This server is =
free software; you can redistribute and/or modify it under the terms of =
the GNU General Public License as published by the Free Software =
Foundation; either version 2 of the License or (at your option) any =
later version.<br><br>\n This server is distributed in hope that it =
will be useful, but <b>WITHOUT ANY WARRANTY</b>; without even the =
implied warranty of <b>MERCHANTABILITY</b> or <b>FITNESS FOR A =
PARTICULAR PURPOSE</b>. See the GNU General Public License for more =
details.<br><br>\n For the license, visit <a =
href=3D\"http://www.gnu.org/\">the GNU website</a>!<br><br><br>\n =
Thunder from the hill hereby disclaims any copyright interest in the =
server »MicroHTTPD« (a minimalistic web server), written by =
Thunder from the hill.<br>thunder, April 28, 2001<br>Thunder from the =
hill, OpenSource Author\n <p align=3D\"center\">Visit <a =
href=3D\"http://members.tripod.de/fromthehill/uhttpd/\" =
onMouseover=3D\"status=3D\'Click here to visit the MicroHTTPD site!\'; =
return true;\" onMouseout=3D\"status=3D\'\'; return true;\">this =
site</a> for updates and news!</p>\n </body>\n</html>\n");
} else if (strcmp(req_substr, "/internal/getuhttpdversion") =3D=3D =
0) {
clear(BufOut, BufOutLen);
if (BufOutLen < 16 || BufOutLen > 128) {
realloc(BufOut, 16);
BufOutLen =3D 16;
}
strcpy(BufOut, "1.0\n");
} else {
clear(BufOut, BufOutLen);
if (BufOutLen < 16 || BufOutLen > 128) {
realloc(BufOut, 16);
BufOutLen =3D 16;
}
strcpy(BufOut, "HTTP/1.0 404\n");
printf("Answered 404\n");
}
if (send(Socket, BufOut, BufOutLen, 0) < strlen(BufOut)) {
printf("Error while sending %i bytes in line %i!\n", strlen(BufOut), =
__LINE__ - 1);
return -1;
}
} else {
/* req_substr =3D strtok(NULL, " "); */
if (sendfile(Socket, req_substr) < 0) {
printf("Error while sending %s in line %i!\n", req_substr, __LINE__ - =
1);
return -1;
}
}
} else {
printf("Invalid request method %s.\n", req_substr);
strcpy(BufOut, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 =
Transitional//EN\">\n<html>\n <head>\n <title>Invalid request =
method</title>\n </head>\n <body>\n <h1>Invalid request method</h1>\n =
<p align=3D\"justify\">The desired request method was not supported by =
the server.</p>\n </body>\n</html>\n");
if (send(Socket, BufOut, 1024, 0) < 0) {
printf("Error while sending 318 bytes in line %i.\n", __LINE__ - =
1);
return -1;
}
}
return 0;
}
int sendfile(int Socket, char *filename) {
int fd; /* File descriptor */
char *NoQuestPtr; /* Question marks removed */
char *fn_afterall =3D malloc(strlen(filename));
/* What will be left from filename */
char *sbuf =3D malloc(1024);
int i =3D 0;
struct stat _thisfile; /* Stat structure */
struct stat *thisfile =3D &_thisfile; /* Stat structure pointer */
NoQuestPtr =3D strtok(filename, "?");
if (stat(NoQuestPtr, thisfile) < 0) {
if (send(Socket, "HTTP/1.0 404\n", 14, 0) < 0) {
return -1;
}
return 0;
}
strcpy(fn_afterall, NoQuestPtr);
if (S_ISDIR(thisfile->st_mode) !=3D 0) {
char *fn_last =3D NoQuestPtr + strlen(NoQuestPtr) - 1;
printf("%s considered to be a directory (%i)\n", NoQuestPtr, =
S_ISDIR(thisfile->st_mode));
printf("STUB: realloc() segfaults in sendfile(Socket, \"%s\");\n", =
NoQuestPtr);
realloc(fn_afterall, strlen(filename) + 20);
printf("fn_afterall has address %p and contains string %s.\n", =
fn_afterall, fn_afterall);
if (*fn_last !=3D '/')
strcat(fn_afterall, "/");
strcat(fn_afterall, "index.html");
}
if ((fd =3D open(fn_afterall, O_RDONLY)) < 0) {
printf("Access to %s seems denied, or such.\n", fn_afterall);
if (send(Socket, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 =
Transitional//EN\">\n<html>\n <head>\n <title>Access to file =
denied.</title>\n </head>\n <body>\n <h1>File access error</h1>\n <p =
align=3D\"justify\">File access seems denied: chdir() worked, stat() =
returned OK, but file access seems denied.</p>\n </body>\n</html>\n", =
347, 0) < 0) {
return -1;
}
return 0;
}
printf("sbuf has address %p and contains %s. Clearing.\n", sbuf, =
sbuf);
clear(sbuf, 1024);
printf("Survived clearing.\n");
while (read(fd, sbuf, 1024) > 0) {
if (send(Socket, sbuf, strlen(sbuf), 0) < 0) {
return -1;
}
}
if (close(fd) < 0) {
printf("Error while closing file descriptor!\n");
}
if (chdir("/") < 0) {
printf("Error when changing back to base dir (/).\n");
}
return 0;
}
void usage(void) {
printf("%s [-d directory] port\n\t-d directory\n\t\tThe web directory =
(target for chroot).\n\tport\n\t\tThe port to bind the server to.\n", =
__FILE__);
return;
}
int main (int argc, char **argv) {
int argp =3D 1;
BufOut =3D malloc(2048);
BufIn =3D malloc(2048);
args.basedir =3D malloc(24);
strcpy(args.basedir, "/usr/local/httpd");
if (argc < 2 || argc > 4) {
usage();
exit (1);
}
while (argp < argc) {
if (strcmp(argv[argp], "-d") =3D=3D 0) {
if (argv[argp + 1] !=3D NULL) {
clear(args.basedir, strlen(args.basedir));
realloc(args.basedir, strlen(argv[argp + 1]) + 1);
strcpy(args.basedir, argv[argp + 1]);
argp++; argp++;
} else {
printf("Parameter -d requires a directory to be set.\n");
usage();
exit(1);
}
} else {
args.port =3D (short) atol(argv[argp]);
argp++;
}
}
printf("\033[2J\t\t\t --- MicroHTTPD ---\n");
printf("Creating socket: AF_INET, SOCK_STREAM, IPPROTO_TCP.\n");
MySock =3D socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (MySock =3D=3D (~0)) {
printf("%s: Error creating server socket.\nErrno was: %i\n", =
__FILE__,
errno);
exit(1);
}
printf("Setting up server socket: ");
addr.sin_family =3D AF_INET;
printf("AF_INET");
addr.sin_port =3D htons(args.port);
printf(", Port=3D%i", args.port);
addr.sin_addr.s_addr =3D htonl(INADDR_ANY);
printf(", any IP.\n");
if (bind(MySock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
printf("%s: Error when using bind.\n", __FILE__);
if (errno =3D=3D EADDRNOTAVAIL) {
printf("Address not available.\n");
} else if (errno =3D=3D EADDRINUSE) {
printf("Some other socket is already using the address.\n");
} else if (errno =3D=3D EINVAL) {
printf("The socket already has an address.\n");
} else if (errno =3D=3D EACCES) {
printf("Access to socket denied. (Maybe choose a port > =
1024?)\n");
} else if (errno =3D=3D EBADF) {
printf("Bad file descriptor. (???)\n");
} else {
printf("Unknown error (errno =3D %i)\n", errno);
}
exit(1);
}
printf("\n\t =3D=3D=3D Server socket started up and bound to port %i =
=3D=3D=3D\n\n", args.port);
printf("Listening for connections.\n");
if (listen(MySock, 10) < 0) {
printf("%s: Listening error. Errno is %i.\n", __FILE__, errno);
exit(1);
}
peer_size =3D sizeof(peer);
if (chroot(args.basedir) < 0) {
printf("chroot() failed!\n");
exit(1);
}
BufIn =3D malloc(1025);
while ((NewSock =3D accept(MySock, (struct sockaddr *)&peer, =
&peer_size)) !=3D
-1) {
char host_addr[16];
clear(BufIn, BufInLen);
clear(BufOut, BufOutLen);
strcpy(host_addr, inet_ntoa(peer.sin_addr));
hostentry =3D gethostbyname(host_addr);
if (hostentry =3D=3D NULL) {
printf("Connection from %s, port %i.\n", host_addr,
ntohs(peer.sin_port));
} else {
printf("Connection from %s (%s), port %i.\n", hostentry->h_name,
inet_ntoa(peer.sin_addr), ntohs(peer.sin_port));
}
errno =3D 0;
if (recv(NewSock, BufIn, 1024, 0) < 0) {
printf("%s: recv() failed. ", __FILE__);
if (errno =3D=3D EBADF) {
printf("Bad file descriptor. (???)\n");
} else if (errno =3D=3D ENOTSOCK) {
printf("Not a socket. (???)\n");
} else if (errno =3D=3D EWOULDBLOCK) {
printf("Would block nonblocking mode socket.\n");
} else if (errno =3D=3D EINTR) {
printf("Interrupted by a signal.\n");
} else if (errno =3D=3D ENOTCONN) {
printf("Socket disconnected.\n");
} else {
printf("Unknown error (errno =3D %i)\n", errno);
}
errno =3D 0;
}
if (BufIn =3D=3D NULL) {
printf("Error: HTTP request was NULL!\n");
send(NewSock, "HTTP/1.0 505\n", 1024, 0);
} else if (http_request(NewSock, BufIn) < 0) {
printf("Socket error %i.\n", errno);
errno =3D 0;
}
printf("Host disconnected.\n");
shutdown(NewSock, 2);
close (NewSock);
}
if (NewSock =3D=3D -1) {
printf("Exit from bad accept() run (whatever might have =
happened).\n");
}
printf("%s: Cleaning up. Closing socket: ", __FILE__);
close (MySock);
printf("OK.\n");
printf("Server: exit.\n");
exit(0);
}
------=_NextPart_000_0075_01C0D165.726C34D0
Content-Type: text/plain; charset=us-ascii
--
Want to unsubscribe from this list?
Check out: http://cygwin.com/ml/#unsubscribe-simple
------=_NextPart_000_0075_01C0D165.726C34D0--
- Raw text -