diff -urN thttpd-2.21/Makefile.in thttpd-2.21-mnx/Makefile.in
--- thttpd-2.21/Makefile.in	Thu Mar 29 21:36:21 2001
+++ thttpd-2.21-mnx/Makefile.in	Fri Oct 19 15:13:21 2001
@@ -39,7 +39,7 @@
 # CONFIGURE: The group that the web directory belongs to.  This is so that
 # the makeweb program can be installed set-group-id to that group, and make
 # subdirectories.  If you're not going to use makeweb, ignore this.
-WEBGROUP =	www
+WEBGROUP =	www-data
 
 # CONFIGURE: Directory for CGI executables.
 CGIBINDIR =	$(WEBDIR)/cgi-bin
@@ -51,7 +51,7 @@
 DEFS =		@DEFS@
 INCLS =		-I.
 CFLAGS =	$(CCOPT) $(DEFS) $(INCLS)
-LDFLAGS =	@LDFLAGS@
+LDFLAGS =	@LDFLAGS@ -lmysqlclient
 LIBS =		@LIBS@
 NETLIBS =	@V_NETLIBS@
 INSTALL =	@INSTALL@
@@ -62,7 +62,7 @@
 	@rm -f $@
 	$(CC) $(CFLAGS) -c $*.c
 
-SRC =		thttpd.c libhttpd.c fdwatch.c mmc.c timers.c match.c tdate_parse.c syslog.c
+SRC =		thttpd.c libhttpd.c fdwatch.c mmc.c timers.c match.c tdate_parse.c syslog.c vhost.c
 
 OBJ =		$(SRC:.c=.o) @LIBOBJS@
 
@@ -163,11 +163,12 @@
 	  rm -rf $$name ; \
 	  gzip $$name.tar
 
-thttpd.o:	config.h version.h libhttpd.h fdwatch.h mmc.h timers.h match.h
+thttpd.o:	config.h version.h libhttpd.h fdwatch.h mmc.h timers.h match.h vhostconf.h
 libhttpd.o:	config.h version.h libhttpd.h mime_encodings.h mime_types.h \
-		mmc.h timers.h match.h tdate_parse.h
+		mmc.h timers.h match.h tdate_parse.h vhostconf.h
 fdwatch.o:	fdwatch.h
 mmc.o:		mmc.h
 timers.o:	timers.h
 match.o:	match.h
 tdate_parse.o:	tdate_parse.h
+vhost.o:	vhostconf.h
diff -urN thttpd-2.21/config.h thttpd-2.21-mnx/config.h
--- thttpd-2.21/config.h	Tue Apr 10 00:57:36 2001
+++ thttpd-2.21-mnx/config.h	Mon Oct 22 12:52:27 2001
@@ -183,9 +183,7 @@
 ** having to give the -v command line flag.  You can still disable it at
 ** runtime with the -nov flag.
 */
-#ifdef notdef
 #define ALWAYS_VHOST
-#endif
 
 /* CONFIGURE: If you're using the vhost feature and you have a LOT of
 ** virtual hostnames (like, hundreds or thousands), you will want to
@@ -214,6 +212,18 @@
 #define VHOST_DIRLEVELS 2
 #define VHOST_DIRLEVELS 3
 #endif
+/* CONFIGURE:
+** You can use the mapping between vhost and path from a mysql table, just define
+** it here:
+*/
+
+#define VHOST_MYSQL
+
+/* CONFIGURE:
+** Define special logging of requests through unix domain sockets
+*/
+
+#define ADVCOUNTER
 
 /* CONFIGURE: Define this if you want to always use a global passwd file,
 ** without having to give the -P command line flag.  You can still disable
@@ -227,7 +237,7 @@
 ** initializing.  If this user (or the one specified by the -u flag) does
 ** not exist, the program will refuse to run.
 */
-#define DEFAULT_USER "nobody"
+#define DEFAULT_USER "www-data"
 
 /* CONFIGURE: When started as root, the program can automatically chdir()
 ** to the home directory of the user specified by -u or DEFAULT_USER.
@@ -316,7 +326,7 @@
 /* CONFIGURE: A list of index filenames to check.  The files are searched
 ** for in this order.
 */
-#define INDEX_NAMES "index.html", "index.htm", "Default.htm", "index.cgi"
+#define INDEX_NAMES "index.html", "index.htm"
 
 /* CONFIGURE: If this is defined then thttpd will automatically generate
 ** index pages for directories that don't have an explicit index file.
diff -urN thttpd-2.21/libhttpd.c thttpd-2.21-mnx/libhttpd.c
--- thttpd-2.21/libhttpd.c	Sat Apr 21 03:11:32 2001
+++ thttpd-2.21-mnx/libhttpd.c	Tue Nov  6 17:13:43 2001
@@ -76,6 +76,63 @@
 #  include <ndir.h>
 # endif
 #endif
+#ifdef VHOST_MYSQL
+#include "vhostconf.h"
+extern struct node *vh_list;
+extern struct banner *bn_list;
+extern int vh_list_len, bn_list_len;
+int numreq=0;
+
+// KURRR!!!! GOLQM PRI TOVA
+static char* tempfilename;
+static int maxtempfilename = 0;
+     static char* header;
+    static int maxheader = 0;
+    static char* authpath;
+    static int maxauthpath = 0;
+    static char* prevauthpath;
+    static int maxprevauthpath = 0;
+    static char* prevuser;
+    static int maxprevuser = 0;
+    static char* prevcryp;
+    static int maxprevcryp = 0;
+    static char* location;
+    static char* header; 
+    static int maxlocation = 0;
+    static char* temp;
+    static int maxtemp = 0;
+    static char* checked;
+    static char* rest;
+    static int maxchecked = 0, maxrest = 0;
+    static int maxnames = 0;
+
+    static char* names;
+    static char** nameptrs;
+    static char* name;
+    static int maxname = 0;
+    static char* rname;
+    static int maxrname = 0;
+    static char* encrname;
+    static int maxencrname = 0; 
+    static char* buf;
+    static int maxbuf = 0;
+    static char* indexname;
+    static int maxindexname = 0;
+
+#ifdef AUTH_FILE
+    static char* dirname;
+    static int maxdirname = 0;
+#endif /* AUTH_FILE */   
+    static char* refhost = (char*) 0;
+    static int refhost_size = 0;
+
+#endif
+#ifdef ADVCOUNTER
+#include <sys/un.h>
+extern int UDSfd;
+long log_errors;
+extern struct sockaddr_un UDSaddr;
+#endif
 
 extern char* crypt( const char* key, const char* setting );
 
@@ -169,8 +226,20 @@
 static int my_snprintf( char* str, size_t size, const char* format, ... );
 
 
+
 static int reap_time;
 
+void *rllc(void *ptr, size_t size)
+{
+	void *t;
+	t=(void *) malloc(size);
+	memcpy(t, ptr,sizeof(ptr));
+	free(ptr);
+        return t;
+
+}
+
+
 static void
 child_reaper( ClientData client_data, struct timeval* nowP )
     {
@@ -591,8 +660,13 @@
 static void
 clear_ndelay( httpd_conn* hc )
     {
-    int flags, newflags;
-
+	int flags, newflags;
+	/*
+	 XXX: wtf to turn off nonblocking???
+	 there is a bug somewhere, it tries to read from nonblocking socket...
+         so as a temporary measure, I disable it here - maniax
+         */
+    return;
     flags = fcntl( hc->conn_fd, F_GETFL, 0 );
     if ( flags != -1 )
 	{
@@ -842,8 +916,6 @@
 static void
 send_authenticate( httpd_conn* hc, char* realm )
     {
-    static char* header;
-    static int maxheader = 0;
     static char headstr[] = "WWW-Authenticate: Basic realm=\"";
 
     httpd_realloc_str(
@@ -966,8 +1038,6 @@
 static int
 auth_check2( httpd_conn* hc, char* dirname  )
     {
-    static char* authpath;
-    static int maxauthpath = 0;
     struct stat sb;
     char authinfo[500];
     char* authpass;
@@ -975,14 +1045,7 @@
     FILE* fp;
     char line[500];
     char* cryp;
-    static char* prevauthpath;
-    static int maxprevauthpath = 0;
     static time_t prevmtime;
-    static char* prevuser;
-    static int maxprevuser = 0;
-    static char* prevcryp;
-    static int maxprevcryp = 0;
-
     /* Construct auth filename. */
     httpd_realloc_str(
 	&authpath, &maxauthpath, strlen( dirname ) + 1 + sizeof(AUTH_FILE) );
@@ -1111,9 +1174,6 @@
 static void
 send_dirredirect( httpd_conn* hc )
     {
-    static char* location;
-    static char* header;
-    static int maxlocation = 0, maxheader = 0;
     static char headstr[] = "Location: ";
 
     httpd_realloc_str( &location, &maxlocation, strlen( hc->encodedurl ) + 1 );
@@ -1205,8 +1265,6 @@
 static int
 tilde_map_1( httpd_conn* hc )
     {
-    static char* temp;
-    static int maxtemp = 0;
     int len;
     static char* prefix = TILDE_MAP_1;
 
@@ -1228,8 +1286,10 @@
 static int
 tilde_map_2( httpd_conn* hc )
     {
+#ifndef VHOST_MYSQL
     static char* temp;
     static int maxtemp = 0;
+#endif
     static char* postfix = TILDE_MAP_2;
     char* cp;
     struct passwd* pw;
@@ -1287,14 +1347,28 @@
     {
     httpd_sockaddr sa;
     int sz;
+    /*
+     XXX this does not work as planned
+     make them global or sth like that, so they don't get fscked
+     up and allocated every time
+     shit
+     */
+#ifndef VHOST_MYSQL
     static char* tempfilename;
     static int maxtempfilename = 0;
+#endif
     char* cp1;
     int len;
 #ifdef VHOST_DIRLEVELS
     int i;
     char* cp2;
 #endif /* VHOST_DIRLEVELS */
+#ifdef VHOST_MYSQL
+    int tmp,j,j0,day;
+    time_t tm0;
+    struct tm *stt0;
+    char *ext;
+#endif
 
     /* Figure out the virtual hostname. */
     if ( hc->reqhost[0] != '\0' )
@@ -1347,9 +1421,73 @@
 	*cp2++ = '/';
 	}
     (void) strcpy( cp2, hc->hostname );
-#else /* VHOST_DIRLEVELS */
+#endif
+#ifdef VHOST_MYSQL
+    tmp=bin_search(vh_list,vh_list_len,hc->hostname);
+    if (tmp==-1)
+    {
+	    /* not found , fall back to default method*/
+	    httpd_realloc_str( &hc->hostdir, &hc->maxhostdir, strlen( hc->hostname ) );
+	    (void) strcpy( hc->hostdir, hc->hostname );
+
+    }
+    else
+    {
+	    httpd_realloc_str(&hc->hostdir,&hc->maxhostdir,strlen(vh_list[tmp].path));
+	    (void) strcpy (hc->hostdir,vh_list[tmp].path);
+	    // shit, check if file is html!!!
+	    ext=rindex(hc->origfilename,'.');
+	    if ( ext==NULL) ext=hc->origfilename;
+	    else ext++;
+	    // check if the extension is valid
+	    if  (! ((strcasecmp(ext,"html")==0) ||
+		   (strcasecmp(ext,"htm")==0) ||
+		   (strcasecmp(ext,"js")==0) ||
+		   (strcasecmp(ext,"jpg")==0) ||
+		   (strcasecmp(ext,"jpeg")==0) ||
+		   (strcasecmp(ext,"gif")==0) ||
+                   (strcasecmp(ext,"css")==0) ||
+		   (strcasecmp(ext,"png")==0) ||
+		   (strcasecmp(ext,"txt")==0) ||
+		   (strcasecmp(ext,"ico")==0) ||
+		   (strcasecmp(ext,"xml")==0) ||
+		   (strcasecmp(ext,"bmp")==0) ))
+	    {
+		//deny the request
+
+                    return 0;
+	    }
+
+	    if ( ( hc->origfilename[strlen(hc->origfilename)-1]=='/') || (strcasecmp(ext,"htm")==0)
+		 || (strcasecmp(ext,"html")==0) )
+	    {
+		    for (j=0;j<bn_list_len;j++)
+		    {
+			    if (strcmp(vh_list[tmp].adv, bn_list[j].name)==0)
+			    {
+				    time(&tm0);
+				    stt0=localtime(&tm0);
+				    numreq++;
+				    j0=numreq%bn_list[j].num;
+				    hc->banner=bn_list[j].days[stt0->tm_wday].banner[j0];
+				    hc->banner_under=bn_list[j].days[stt0->tm_wday].banner_under[j0];
+				    hc->ban=bn_list[j].days[stt0->tm_wday].fsizes[j0];
+				    hc->ban_u=bn_list[j].days[stt0->tm_wday].fsizes_und[j0];
+				    break;
+			    }
+		    }
+	    }
+
+    }
+    /*
+     XXX FIX!!! stupid ifdefs, etc
+     */
+#endif
+#ifndef VHOST_MYSQL
+#ifndef VHOST_DIRLEVELS
     httpd_realloc_str( &hc->hostdir, &hc->maxhostdir, strlen( hc->hostname ) );
     (void) strcpy( hc->hostdir, hc->hostname );
+#endif
 #endif /* VHOST_DIRLEVELS */
 
     /* Prepend hostdir to the filename. */
@@ -1377,10 +1515,7 @@
 static char*
 expand_symlinks( char* path, char** restP, int no_symlink, int tildemapped )
     {
-    static char* checked;
-    static char* rest;
     char link[5000];
-    static int maxchecked = 0, maxrest = 0;
     int checkedlen, restlen, linklen, prevcheckedlen, prevrestlen, nlinks, i;
     char* r;
     char* cp1;
@@ -1686,6 +1821,15 @@
     hc->keep_alive = 0;
     hc->should_linger = 0;
     hc->file_address = (char*) 0;
+#ifdef VHOST_MYSQL
+    hc->banner=(char *) (1) ;
+    hc->banner_under=(char *) (1);
+    hc->ban=0;
+    hc->ban_u=0;
+    hc->fpos=0;
+    hc->bpos=0;
+    hc->bpos_u=0;
+#endif
     return GC_OK;
     }
 
@@ -2508,8 +2652,10 @@
     DIR* dirp;
     struct dirent* de;
     int namlen;
-    static int maxnames = 0;
     int nnames;
+#ifndef VHOST_MYSQL   
+    static int maxnames = 0;
+
     static char* names;
     static char** nameptrs;
     static char* name;
@@ -2518,6 +2664,7 @@
     static int maxrname = 0;
     static char* encrname;
     static int maxencrname = 0;
+#endif
     FILE* fp;
     int i, r;
     struct stat sb;
@@ -2776,9 +2923,10 @@
     {
     char* cp;
     int size;
+#ifndef VHOST_MYSQL
     static char* buf;
     static int maxbuf = 0;
-
+#endif
     size = strlen( fmt ) + strlen( arg );
     if ( size > maxbuf )
 	httpd_realloc_str( &buf, &maxbuf, size );
@@ -3341,14 +3489,17 @@
 static int
 really_start_request( httpd_conn* hc, struct timeval* nowP )
     {
+    static const char* index_names[] = { INDEX_NAMES };
+    int i;    
+#ifndef VHOST_MYSQL
     static char* indexname;
     static int maxindexname = 0;
-    static const char* index_names[] = { INDEX_NAMES };
-    int i;
+
 #ifdef AUTH_FILE
     static char* dirname;
     static int maxdirname = 0;
 #endif /* AUTH_FILE */
+#endif
     int expnlen, indxlen;
     char* cp;
     char* pi;
@@ -3625,10 +3776,10 @@
 static void
 make_log_entry( httpd_conn* hc, struct timeval* nowP )
     {
+#ifndef ADVCOUNTER
     char* ru;
     char url[305];
     char bytes[40];
-
     if ( hc->hs->no_log )
 	return;
 
@@ -3712,7 +3863,31 @@
 	    "%.80s - %.80s \"%.80s %.200s %.80s\" %d %s \"%.200s\" \"%.80s\"",
 	    httpd_ntoa( &hc->client_addr ), ru,
 	    httpd_method_str( hc->method ), url, hc->protocol,
-	    hc->status, bytes, hc->referer, hc->useragent );
+		hc->status, bytes, hc->referer, hc->useragent );
+#else
+
+    char log_outp[512];
+
+    /*
+     generate packet to be sent to the counter
+     */
+    memset(log_outp,0,512);
+    snprintf(log_outp,512,"%s|%s|%s|%s|",hc->hostname,httpd_ntoa( &hc->client_addr ),hc->origfilename,hc->referer);
+    if ((write(UDSfd, log_outp,strlen(log_outp)) < 0) && (errno != EAGAIN))
+    {
+	if (connect(UDSfd, (struct sockaddr *) &UDSaddr, sizeof(UDSaddr)) < 0)
+	{
+	    log_errors++;
+	    if(log_errors==50000)
+	    {
+		syslog(LOG_ERR,"Reconnection to counter failed, %s",strerror(errno));
+		log_errors=0;
+	    }
+	}
+    }
+
+
+#endif
     }
 
 
@@ -3751,8 +3926,10 @@
     char* cp1;
     char* cp2;
     char* cp3;
+#ifndef VHOST_MYSQL
     static char* refhost = (char*) 0;
     static int refhost_size = 0;
+#endif
     char *lp;
 
     hs = hc->hs;
diff -urN thttpd-2.21/libhttpd.h thttpd-2.21-mnx/libhttpd.h
--- thttpd-2.21/libhttpd.h	Fri Apr 13 08:37:17 2001
+++ thttpd-2.21-mnx/libhttpd.h	Tue Nov  6 17:11:58 2001
@@ -46,7 +46,9 @@
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 #endif
 #define NEW(t,n) ((t*) malloc( sizeof(t) * (n) ))
-#define RENEW(o,t,n) ((t*) realloc( (void*) o, sizeof(t) * (n) ))
+//#define RENEW(o,t,n) ((t*) realloc( (void*) o, sizeof(t) * (n) ))
+#define RENEW(o,t,n) ((t*) rllc( (void*) o, sizeof(t) * (n) ))
+
 
 
 /* The httpd structs. */
@@ -137,6 +139,10 @@
     struct stat sb;
     int conn_fd;
     char* file_address;
+    char* banner, *banner_under; /* MYSQL_VHOST banners */
+    off_t ban,ban_u; /* banner sizes... shit... */
+    off_t fsize;
+    off_t fpos,bpos,bpos_u;
     } httpd_conn;
 
 /* Methods. */
@@ -175,6 +181,7 @@
 
 /* Call to shut down. */
 extern void httpd_terminate( httpd_server* hs );
+void *rllc(void *ptr, size_t sz);
 
 
 /* When a listen fd is ready to read, call this.  It does the accept() and
@@ -261,3 +268,4 @@
 extern void httpd_logstats( long secs );
 
 #endif /* _LIBHTTPD_H_ */
+
diff -urN thttpd-2.21/sample.cfg thttpd-2.21-mnx/sample.cfg
--- thttpd-2.21/sample.cfg	Thu Jan  1 02:00:00 1970
+++ thttpd-2.21-mnx/sample.cfg	Wed Oct 24 13:30:36 2001
@@ -0,0 +1 @@
+urlpat=**.jpg|**.gif|**.jpeg|**.bmp|**.png|**.js
diff -urN thttpd-2.21/thttpd.c thttpd-2.21-mnx/thttpd.c
--- thttpd-2.21/thttpd.c	Sun Apr 15 19:09:20 2001
+++ thttpd-2.21-mnx/thttpd.c	Wed Oct 31 16:17:14 2001
@@ -58,7 +58,17 @@
 #include "mmc.h"
 #include "timers.h"
 #include "match.h"
-
+#ifdef VHOST_MYSQL
+#include "vhostconf.h"
+extern struct node *vh_list;
+extern struct banner *bn_list;
+extern int vh_list_len,bn_list_len;
+#endif
+#ifdef ADVCOUNTER
+#include <sys/un.h>
+int UDSfd;
+struct sockaddr_un UDSaddr;
+#endif
 
 static char* argv0;
 static int debug;
@@ -172,7 +182,7 @@
 handle_hup( int sig )
     {
     FILE* logfp;
-
+#ifndef ADVCOUNTER
     if ( no_log )
 	return;
 
@@ -188,6 +198,7 @@
 	(void) fcntl( fileno( logfp ), F_SETFD, 1 );
 	httpd_set_logfp( hs, logfp );
 	}
+#endif
     }
 
 
@@ -223,6 +234,10 @@
     int gotv4, gotv6;
     struct timeval tv;
 
+#ifdef ADVCOUNTER
+    long int flg;
+#endif
+
     argv0 = argv[0];
 
     cp = strrchr( argv0, '/' );
@@ -262,6 +277,7 @@
     if ( throttlefile != (char*) 0 )
 	read_throttlefile( throttlefile );
 
+#ifndef ADVCOUNTER
     /* Log file. */
     if ( logfile != (char*) 0 )
 	{
@@ -284,6 +300,7 @@
 	}
     else
 	logfp = (FILE*) 0;
+#endif
 
     /* Figure out uid/gid from user. */
     pwd = getpwnam( user );
@@ -401,6 +418,36 @@
 	    }
 	}
 
+#ifdef VHOST_MYSQL
+    vh_list=vh_init_struct(&vh_list_len);
+    if (vh_list==NULL) exit(1);
+    bn_list=init_banners_list(&bn_list_len);
+    if (bn_list==NULL) exit(1);
+
+#endif
+#ifdef ADVCOUNTER
+    UDSfd = socket(AF_UNIX,SOCK_DGRAM,0);
+    if (UDSfd == -1 )
+    {
+	(void) fprintf( stderr, "error creating unix domain socket %s \n",strerror(errno));
+	exit( 1 );
+    }
+    bzero( (char *) &UDSaddr, sizeof(UDSaddr));
+    strcpy(UDSaddr.sun_path, UDSPATH);
+    UDSaddr.sun_family=AF_UNIX;
+    fcntl(UDSfd, F_GETFL, flg);
+    flg |= O_NONBLOCK;
+    fcntl(UDSfd, F_SETFL, flg);
+
+    if (connect(UDSfd, (struct sockaddr *) &UDSaddr, sizeof(UDSaddr)) < 0)
+    {
+	(void) fprintf( stderr, "error connecting to %s, %s\n",UDSPATH,strerror(errno));
+//	exit( 1 );
+    }
+
+
+#endif
+
     /* Set up to catch signals. */
     (void) signal( SIGTERM, handle_term );
     (void) signal( SIGINT, handle_term );
@@ -1382,7 +1429,12 @@
 	c->bytes_to_send = hc->end_byte_loc + 1;
 	}
     else
-	c->bytes_to_send = hc->bytes_to_send;
+        c->bytes_to_send = hc->bytes_to_send;
+
+#ifdef VHOST_MYSQL
+        hc->fsize=c->bytes_to_send;
+        c->bytes_to_send+= hc->ban+hc->ban_u;
+#endif
 
     /* Check if it's already handled. */
     if ( hc->file_address == (char*) 0 )
@@ -1420,6 +1472,12 @@
     }
 
 
+/*
+ fucked a lot by maniax
+ this really sucks ass, should be a bit rewriten and beautyfied
+ what bit... damn
+ */
+
 static void
 handle_send( connecttab* c, struct timeval* tvP )
     {
@@ -1429,6 +1487,7 @@
     httpd_conn* hc = c->hc;
 
     /* Do we need to write the headers first? */
+#ifndef VHOST_MYSQL
     if ( hc->responselen == 0 )
 	{
 	/* No, just write the file. */
@@ -1437,10 +1496,19 @@
 	    MIN( c->bytes_to_send - c->bytes_sent, c->limit ) );
 	}
     else
-	{
+    {
+#endif
 	/* Yes.  We'll combine headers and file into a single writev(),
 	** hoping that this generates a single packet.
 	*/
+
+	    /*
+             XXX
+	     kur
+	     po nqkkakuv nachin tuk trqbva da vkaram server-vaneto na bannerite
+             majko mila.....
+	     */
+#ifndef VHOST_MYSQL
 	struct iovec iv[2];
 
 	iv[0].iov_base = hc->response;
@@ -1448,8 +1516,28 @@
 	iv[1].iov_base = &(hc->file_address[c->bytes_sent]);
 	iv[1].iov_len = MIN( c->bytes_to_send - c->bytes_sent, c->limit );
 	sz = writev( hc->conn_fd, iv, 2 );
-	}
+#else
+	struct iovec iv[4];
 
+	iv[0].iov_base = hc->response;
+	iv[0].iov_len = hc->responselen;
+
+	iv[1].iov_base = &(hc->banner[hc->bpos]);
+	iv[1].iov_len = hc->ban-hc->bpos;
+
+	iv[2].iov_base = &(hc->file_address[hc->fpos]);
+	//	iv[2].iov_len = MIN( hc->fsize  , c->limit );
+        iv[2].iov_len = hc->fsize-hc->fpos;
+
+	iv[3].iov_base = &(hc->banner_under[hc->bpos_u]);
+	iv[3].iov_len = hc->ban_u-hc->bpos_u;
+
+	sz = writev( hc->conn_fd, iv, 4 );
+
+#endif
+#ifndef VHOST_MYSQL
+	}
+#endif
     if ( sz == 0 ||
 	 ( sz < 0 && ( errno == EWOULDBLOCK || errno == EAGAIN ) ) )
 	{
@@ -1519,6 +1607,42 @@
     /* And update how much of the file we wrote. */
     c->bytes_sent += sz;
     c->hc->bytes_sent += sz;
+#ifdef VHOST_MYSQL
+
+    if  ( (sz>=(hc->ban-hc->bpos)) || (hc->bpos==hc->ban))
+    {
+            // first banner served, no fscking with the pos
+            sz -= (hc->ban-hc->bpos);
+	    hc->bpos=hc->ban;
+
+    } else
+    {
+	    hc->bpos+=sz;
+            sz=0;
+    }
+    if  ( (sz>=(hc->fsize-hc->fpos)) || (hc->fsize==hc->fpos)) // file is served already
+    {
+            sz-=(hc->fsize-hc->fpos);
+            hc->fpos=hc->fsize;
+    }
+    else
+    {
+	    hc->fpos+=sz;
+            sz=0;
+    }
+    if  ( (sz>=(hc->ban_u-hc->bpos_u)) || (hc->ban_u==hc->bpos_u)) // file is served already
+    {
+            sz-=(hc->ban_u-hc->bpos_u);
+            hc->bpos_u=hc->ban_u;
+    }
+    else
+    {
+	    hc->ban_u+=sz;
+    }
+
+
+
+#endif
 
     /* Are we done? */
     if ( c->bytes_sent >= c->bytes_to_send )
diff -urN thttpd-2.21/vhost.c thttpd-2.21-mnx/vhost.c
--- thttpd-2.21/vhost.c	Thu Jan  1 02:00:00 1970
+++ thttpd-2.21-mnx/vhost.c	Wed Oct 24 16:20:56 2001
@@ -0,0 +1,215 @@
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <mysql/mysql.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
+#include "vhostconf.h"
+
+struct node *vh_list;
+struct banner *bn_list;
+int vh_list_len,bn_list_len;
+
+/*
+ Allocates memory for *tmp, and loads the vhost map in it. Sets n accordingly.
+ */
+
+struct node *vh_init_struct(int *n)
+{
+
+	MYSQL *conn;
+	MYSQL_RES * result;
+	MYSQL_ROW row;
+        struct node *tmp;
+
+
+	conn=mysql_init(NULL);
+	if (conn==NULL)
+	{
+		syslog(LOG_ERR,"Error initalizing mysql handle");
+                return NULL;
+	}
+	if (mysql_real_connect(conn,DBHOST,DBUSER,DBPASS,DBNAME,0,NULL,0)==NULL)
+	{
+		syslog(LOG_ERR,"Error connecting to the database");
+                return NULL;
+	}
+
+	/*
+	 I use string constant for the query, because I haven't thought of a way to
+         make it more flexible for the moment.
+	 */
+
+
+	if(mysql_real_query(conn,QUERY,strlen(QUERY)+1)!=0)
+	{
+		syslog(LOG_ERR,"Error querying the database");
+		return NULL;
+	}
+	result=mysql_store_result(conn);
+	/*
+	 Okay, we have the results , let's allocate some memory and parse them
+	 */
+
+	tmp=(struct node *) malloc(sizeof(struct node) * mysql_num_rows(result));
+
+	row=mysql_fetch_row(result);
+        (*n)=0;
+	while (row!=NULL)
+	{
+                tmp[*n].vhost=strdup(row[0]);
+		tmp[*n].path=strdup(row[1]);
+                tmp[*n].adv=strdup(row[2]);
+		(*n)++;
+		row=mysql_fetch_row(result);
+	}
+	(*n)--;
+        mysql_close(conn);
+        return tmp;
+}
+
+struct banner *init_banners_list(int *n)
+{
+	MYSQL *conn;
+	MYSQL_RES * result;
+	MYSQL_ROW row;
+	struct banner *tmp;
+	int i,j,fd;
+        struct stat st0;
+        char fname[255];
+
+	conn=mysql_init(NULL);
+	if (conn==NULL)
+	{
+		syslog(LOG_ERR,"Error initalizing mysql handle");
+                return NULL;
+	}
+	if (mysql_real_connect(conn,DBHOST,DBUSER,DBPASS,DBNAME,0,NULL,0)==NULL)
+	{
+		syslog(LOG_ERR,"Error connecting to the database");
+                return NULL;
+	}
+
+	/*
+	 I use string constant for the query, because I haven't thought of a way to
+         make it more flexible for the moment.
+	 */
+
+	if(mysql_real_query(conn,QUERY_BAN,strlen(QUERY_BAN)+1)!=0)
+	{
+		syslog(LOG_ERR,"Error querying the database %s",QUERY_BAN);
+		return NULL;
+	}
+	result=mysql_store_result(conn);
+	/*
+	 Okay, we have the results , let's allocate some memory and parse them
+	 */
+
+	tmp=(struct banner *) malloc(sizeof(struct banner) * mysql_num_rows(result));
+
+	row=mysql_fetch_row(result);
+	(*n)=0;
+
+	while (row!=NULL)
+	{
+                tmp[*n].name=strdup(row[0]);
+		tmp[*n].num=atoi(row[1]);
+
+		row=mysql_fetch_row(result);
+		/*
+                 mmaping the files....
+		 */
+		for (i=0;i<tmp[*n].num;i++)
+		{
+			for(j=0;j<7;j++)
+			{
+
+				/*
+				 XXX:
+                                 Repeating code twice sux, fix this
+                                 */
+                                                 /*adv 7  1banner*/
+				snprintf(fname,255,"%s/%s/%d/%dbanner.html", BANNER_BASE, tmp[*n].name,j,i+1);
+				fd=open(fname,O_RDONLY);
+				if (fd>0)
+				{
+					fstat(fd,&st0);
+					if (st0.st_size!=0)
+					{
+						tmp[*n].days[j].banner[i]=(char *) mmap(NULL,st0.st_size,PROT_READ,MAP_PRIVATE,fd,0);
+                                                tmp[*n].days[j].fsizes[i]=st0.st_size;
+					}
+					else
+					{
+						/* lets' follow the thttpd ideas here - never mmap zero length file */
+						tmp[*n].days[j].banner[i]=(char *) (1);
+                                                tmp[*n].days[j].fsizes[i]=0;
+					}
+                                        close(fd);
+				}
+				snprintf(fname,255,"%s/%s/%d/%dbanner_under.html", BANNER_BASE, tmp[*n].name,j,i+1);
+				fd=open(fname,O_RDONLY);
+				if (fd>0)
+				{
+					fstat(fd,&st0);
+					if (st0.st_size!=0)
+					{
+						tmp[*n].days[j].banner_under[i]=(char *) mmap(NULL,st0.st_size,PROT_READ,MAP_PRIVATE,fd,0);
+                                                tmp[*n].days[j].fsizes_und[i]=st0.st_size;
+					}
+					else
+					{
+						/* lets' follow the thttpd ideas here - never mmap zero length file */
+						tmp[*n].days[j].banner_under[i]=(char *) (1);
+                                                tmp[*n].days[j].fsizes_und[i]=0;
+					}
+                                        close(fd);
+				}
+
+			}
+
+		}
+		(*n)++;
+
+	}
+	(*n)--;
+        mysql_close(conn);
+        return tmp;
+
+}
+
+/*
+ Searches for vhost position in *table
+ Uses simple binary search in sorted array, tests proved that it's fast enough
+ (30 000 searches in 30 000 elements array took about 100 ms , not like the
+ linear search,that took about 100 s )
+ */
+
+int bin_search(struct node *tbl, int n, char *tosrch)
+{
+	int k,i,left,right;
+
+	left=0;
+	right=n;
+	while (left!=right)
+	{
+		i=(left+right)/2;
+		k=strcmp(tosrch,tbl[i].vhost);
+		if (k==0) return i;
+		if (k<0) right=i;
+		else
+			if (left==i) return -1 ;
+			else left=i;
+
+	}
+        return -1;
+}
+
diff -urN thttpd-2.21/vhostconf.h thttpd-2.21-mnx/vhostconf.h
--- thttpd-2.21/vhostconf.h	Thu Jan  1 02:00:00 1970
+++ thttpd-2.21-mnx/vhostconf.h	Wed Oct 24 16:29:04 2001
@@ -0,0 +1,54 @@
+#define DBHOST "localhost"
+#define DBNAME "test0"
+#define DBUSER "root"
+#define DBPASS ""
+#define UDSPATH "/tmp/testsock"
+#define QUERY "select hostname,path,advtype from vhost order by hostname"
+#define QUERY_BAN "select advtype,num from numban"
+#define BANNER_BASE "/home/banners"
+#include <syslog.h>
+
+
+
+struct node
+{
+
+    char *vhost;
+    char *path;
+    char *adv;
+
+};
+struct day
+{
+	char *banner[10];
+        int fsizes[10];
+	char *banner_under[10];
+        int fsizes_und[10];
+
+};
+struct banner
+{
+	char *name;
+	int num;
+        struct day days[7];
+};
+
+
+/*
+
+
+
+ */
+
+/* forward declarations */
+
+struct node *vh_init_struct(int *n);
+struct banner *init_banners_list(int *n);
+int bin_search(struct node *tbl, int n,char *tosrch);
+
+
+
+
+
+
+
