#include #include #include #include #include #include #define VHOST_ROOT "/var/www/vhosts" #define SITES_ROOT "/var/www/sites" #define CGI "cgi-bin" #define SERVER "epochttpd/2.0 (Unix)" void standard_headers() { printf("Server: %s\r\n",SERVER); printf("Connection: close\r\n"); } int main(int argc,char *argv[]) { int fd; char *name[10]; int s,n; short in; char *method; char *page; char *version; char *get_param; char line[getpagesize()]; fgets(line,sizeof(line)-1,stdin); // syslog(LOG_INFO,"ADDRESS did a LINE"); // syslog(LOG_WARNING,"httpd syslog test\n"); if(!strchr(line,'\n')) { printf("HTTP/1.1 413 Entity Too Large\r\n"); standard_headers(); printf("Content-type: text/plain\r\n\r\n"); printf("use smaller (<%d bytes) headers.\n",getpagesize()); return 0; } if(strchr(line,'\r')) *strchr(line,'\r')=0; method=strdup(line); if((page=strchr(method,' '))) { *page=0; page++; if((version=strchr(page,' '))) { *version=0; version++; } if((get_param=strchr(page,'?'))) { *get_param=0; get_param++; setenv("QUERY_STRING",get_param,1); } } while(fgets(line,sizeof(line)-1,stdin)) { if(!strchr(line,'\n')) { printf("HTTP/1.1 413 Entity Too Large\r\n"); standard_headers(); printf("Content-type: text/plain\r\n\r\n"); printf("use smaller (<%d bytes) headers.\n",getpagesize()); return 0; } if(strchr(line,'\r')) *strchr(line,'\r')=0; if(!strncasecmp(line,"Host: ",6)) { setenv("HTTP_HOST",line+6,1); } if(!strcmp(line,"")) { break; } } //TODO: sanitize this. if(chdir(VHOST_ROOT) == -1) { printf("HTTP/1.1 500 Internal Server Error\r\n"); standard_headers(); printf("Content-type: text/html\r\n\r\ncouldn't chdir(\"%s\");",VHOST_ROOT); exit(3); } if(chdir((char*)getenv("HTTP_HOST")) == -1) { if(chdir(SITES_ROOT) != -1) { if(chdir("default") == -1) { //no backup site to show people. fuck. shit happens. printf("HTTP/1.1 500 Internal Server Error\r\n"); standard_headers(); printf("Content-type: text/html\r\n\r\nfuck"); exit(1); } //we're good. } else { printf("HTTP/1.1 500 Internal Server Error\r\n"); standard_headers(); printf("Content-type: text/html\r\n\r\ncouldn't chdir(\"%s\");",SITES_ROOT); //wtf? no sites dir??? exit(2); } } if(strncmp(page,"/cgi-bin/",9)) { for(;*page == '/';page++); if(page[strlen(page)-1] == '/') { printf("HTTP/1.1 302 Moved Permanently\r\n"); standard_headers(); printf("Location: /%sindex.html\r\n\r\n",page); return 0; } if((fd=open(page,O_RDONLY)) != -1) {//need to check that the file isn't a directory. :P printf("HTTP/1.1 200 OK\r\n"); standard_headers(); name[0]="/usr/local/bin/mime-type"; name[1]=page; name[2]=0; printf("Content-type: "); fflush(stdout); switch(fork()) { case 0://child execv(name[0],name); break; case -1://error printf("fork failed.\n"); break; default://parent break; } wait(&s); fflush(stdout); printf("\r\n"); fflush(stdout); while((n=read(fd,line,sizeof(line)-1)) > 0) { write(STDOUT_FILENO,line,n); } } else { printf("HTTP/1.1 404 Not Found\r\n"); standard_headers(); printf("Content-type: text/plain\r\n\r\n"); printf("Can't open that page.\n"); } } else { //attempt to run this bastard! chdir(CGI); page+=strlen("/cgi-bin/"); for(;*page == '/';page++); name[0]=page; name[1]=0; printf("HTTP/1.1 200 OK\r\n"); standard_headers(); fflush(stdout); execv(name[0],name); } return 0; }