/* Chee-Z-Serv, posix threaded, chroot()ed, and logged version */
#include <pthread.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdarg.h>
#include <fcntl.h>
#include <resolv.h>
int hits=0;
void loghit(int s)
{
struct sockaddr_in name;
struct hostent *host;
int n=sizeof(struct sockaddr_in);
getpeername(s, (struct sockaddr *)&name, &n);
host=gethostbyaddr((char *)&(name.sin_addr.s_addr), 4, AF_INET);
printf("Hit from %s, total hits so far %i\n", host->h_name, ++hits);
fflush(stdout);
}
void handle_connection(int *skt)
{
char myname[513], *fooz, *barz;
int f, t=*skt, z, r;
z=recv(t, myname, sizeof(myname), 0);
if(myname[z-2]=='\n' || myname[z-2]=='\r') myname[z-2]=0;
else if(myname[z-1]=='\n' || myname[z-1]=='\r') myname[z-1]=0;
if(strncasecmp(myname, "GET", 3)==0)
{
fooz=&myname[4];
barz=fooz;
while(*barz!=' ' && *barz!=0) barz++;
*barz=0;
if(fooz[0]=='/' && fooz[1]==0)
strcpy(fooz, "/index.html");
fooz--;
fooz[0]='.';
if((f=open(fooz, O_RDONLY))==-1)
send(t, "404 / File not found\r\n",22, 0);
else
{
for(;;)
{
if((r=read(f, myname, 500))<1) break;
send(t, myname, r, 0);
}
close(f);
}
loghit(t);
}
else send(t,
"501 / I don't know how to do what you're asking!\r\n",
50, 0);
close(t);
}
void main()
{
char myname[513];
int s, t, z, r;
struct sockaddr_in sa;
struct hostent *hp;
pthread_t thread;
memset(&sa, 0, sizeof(struct sockaddr_in));
gethostname(myname, 255);
hp = gethostbyname(myname);
if (hp == NULL)
return;
sa.sin_family= hp->h_addrtype;
sa.sin_port= htons(80);
if ((s= socket(AF_INET, SOCK_STREAM, 0)) < 0)
return;
if (bind(s,(struct sockaddr*)&sa,sizeof(struct sockaddr_in)) < 0)
{
close(s);
return;
}
listen(s, 5);
getcwd(myname, sizeof(myname));
chroot(myname);
for(;;)
{
t=accept(s, NULL, NULL);
pthread_create(&thread, NULL,
(void *)&handle_connection, (void *)&t);
}
}