diff -c -r -P thttpd-2.22beta5cg/Makefile thttpd-2.22beta5cg-dbm/Makefile
*** thttpd-2.22beta5cg/Makefile	Wed Apr  3 01:32:26 2002
--- thttpd-2.22beta5cg-dbm/Makefile	Wed Apr 24 14:22:01 2002
***************
*** 50,59 ****
  CC =		gcc
  CCOPT =		-O2
  DEFS =		 -DHAVE__PROGNAME=1 -DHAVE_FCNTL_H=1 -DHAVE_GRP_H=1 -DHAVE_MEMORY_H=1 -DHAVE_PATHS_H=1 -DHAVE_POLL_H=1 -DHAVE_SYS_POLL_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_DIRENT_H=1 -DHAVE_LIBCRYPT=1 -DHAVE_STRERROR=1 -DHAVE_WAITPID=1 -DHAVE_VSNPRINTF=1 -DHAVE_DAEMON=1 -DHAVE_SETSID=1 -DHAVE_GETADDRINFO=1 -DHAVE_GETNAMEINFO=1 -DHAVE_GAI_STRERROR=1 -DHAVE_SIGSET=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_SELECT=1 -DHAVE_POLL=1 -DHAVE_TM_GMTOFF=1 -DHAVE_INT64T=1 
! INCLS =		-I.
  CFLAGS =	$(CCOPT) $(DEFS) $(INCLS)
  LDFLAGS =	
! LIBS =		-lcrypt 
  NETLIBS =	
  INSTALL =	/usr/bin/install -c
  
--- 50,59 ----
  CC =		gcc
  CCOPT =		-O2
  DEFS =		 -DHAVE__PROGNAME=1 -DHAVE_FCNTL_H=1 -DHAVE_GRP_H=1 -DHAVE_MEMORY_H=1 -DHAVE_PATHS_H=1 -DHAVE_POLL_H=1 -DHAVE_SYS_POLL_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_DIRENT_H=1 -DHAVE_LIBCRYPT=1 -DHAVE_STRERROR=1 -DHAVE_WAITPID=1 -DHAVE_VSNPRINTF=1 -DHAVE_DAEMON=1 -DHAVE_SETSID=1 -DHAVE_GETADDRINFO=1 -DHAVE_GETNAMEINFO=1 -DHAVE_GAI_STRERROR=1 -DHAVE_SIGSET=1 -DHAVE_UNISTD_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MMAP=1 -DHAVE_SELECT=1 -DHAVE_POLL=1 -DHAVE_TM_GMTOFF=1 -DHAVE_INT64T=1 
! INCLS =		-I. -I/usr/include/gdbm
  CFLAGS =	$(CCOPT) $(DEFS) $(INCLS)
  LDFLAGS =	
! LIBS =		-lcrypt -lgdbm
  NETLIBS =	
  INSTALL =	/usr/bin/install -c
  
diff -c -r -P thttpd-2.22beta5cg/config.h thttpd-2.22beta5cg-dbm/config.h
*** thttpd-2.22beta5cg/config.h	Tue Mar 19 09:07:29 2002
--- thttpd-2.22beta5cg-dbm/config.h	Wed Apr 24 13:37:09 2002
***************
*** 118,123 ****
--- 118,129 ----
  #define TILDE_MAP_2 "public_html"
  #endif
  
+ /* CONFIGURE: Set AUTH_DBM to be defined if you would like to use
+ ** dbm.  You should still have the original text file.  ie .htpasswd
+ ** and then run pass2dbm .htpasswd to get the .dir and .pag files.
+ */
+ #define AUTH_DBM
+ 
  /* CONFIGURE: The file to use for authentication.  If this is defined then
  ** thttpd checks for this file in the local directory before every fetch.
  ** If the file exists then authentication is done, otherwise the fetch
diff -c -r -P thttpd-2.22beta5cg/contrib/dbm/.htpasswd thttpd-2.22beta5cg-dbm/contrib/dbm/.htpasswd
*** thttpd-2.22beta5cg/contrib/dbm/.htpasswd	Thu Jan  1 10:00:00 1970
--- thttpd-2.22beta5cg-dbm/contrib/dbm/.htpasswd	Wed Apr 24 13:43:15 2002
***************
*** 0 ****
--- 1 ----
+ guest:MQazUCEZR3gds
Binary files thttpd-2.22beta5cg/contrib/dbm/.htpasswd.dir and thttpd-2.22beta5cg-dbm/contrib/dbm/.htpasswd.dir differ
Binary files thttpd-2.22beta5cg/contrib/dbm/.htpasswd.pag and thttpd-2.22beta5cg-dbm/contrib/dbm/.htpasswd.pag differ
diff -c -r -P thttpd-2.22beta5cg/contrib/dbm/makefile thttpd-2.22beta5cg-dbm/contrib/dbm/makefile
*** thttpd-2.22beta5cg/contrib/dbm/makefile	Thu Jan  1 10:00:00 1970
--- thttpd-2.22beta5cg-dbm/contrib/dbm/makefile	Wed Apr 24 12:49:09 2002
***************
*** 0 ****
--- 1,11 ----
+ all: pass2dbm
+ CC=gcc
+ CINC=-I/usr/include/gdbm
+ CFLAGS=${CINC} -O2
+ CFLAGS=${CINC} -g
+ LIBS=-lgdbm
+ pass2dbm: pass2dbm.o
+ 	${CC} -o pass2dbm pass2dbm.o ${LIBS}
+ clean: force
+ 	/bin/rm -f pass2dbm *.o
+ force:
Binary files thttpd-2.22beta5cg/contrib/dbm/pass2dbm and thttpd-2.22beta5cg-dbm/contrib/dbm/pass2dbm differ
diff -c -r -P thttpd-2.22beta5cg/contrib/dbm/pass2dbm.c thttpd-2.22beta5cg-dbm/contrib/dbm/pass2dbm.c
*** thttpd-2.22beta5cg/contrib/dbm/pass2dbm.c	Thu Jan  1 10:00:00 1970
--- thttpd-2.22beta5cg-dbm/contrib/dbm/pass2dbm.c	Wed Apr 24 13:43:53 2002
***************
*** 0 ****
--- 1,86 ----
+ #include <ndbm.h>
+ #include <stdio.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <string.h>
+ #include <errno.h>
+ 
+ /**
+  * 
+  * This and the patch,
+  * only took two hours to write including testing, so I wouldn't use it :-)
+  *
+  * .htpasswd contains user: guest pass: guest
+  *
+  * @author Cameron Gregory, http://www.flamingtext.com/
+  * Wed Apr 24 13:41:22 EST 2002
+  */
+ int main (int argc, char **argv)
+ {
+    char *authpath;
+    char *dbfile;
+    char line[500];
+    char *cryp;
+    FILE *fp;
+    int ret;
+    DBM *dbm;
+    datum key,value;
+    if (argc < 1 || argc > 3) {
+ 	fprintf(stderr,"Usage: %s [ htpassfile [ dbmoutfile ] ] \n", argv[0]);
+ 	exit(1);
+ 	}
+    if (argc<2)
+      authpath=".htpasswd";
+    else
+      authpath=argv[1];
+    if (argc<3)
+      dbfile=authpath;
+    else
+      dbfile=argv[2];
+ 
+     /* Open the password file. */
+     fp = fopen( authpath, "r" );
+     if ( fp == (FILE*) 0 )
+ 	{
+ 	fprintf(stderr,"Can't open file %s\n",authpath);
+ 	exit(1);
+ 	}
+ 
+     dbm = dbm_open(dbfile,3,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); // 3 == writer|createnew, rw-r--r--
+     //dbm = dbm_open(dbfile,3,0644); // 3 == writer|createnew, rw-r--r--
+     if ( dbm == (DBM*) 0 )
+ 	{
+ 	fprintf(stderr,"Can't open dbm file for writing: %s %s\n",dbfile,strerror(errno));
+ 	(void)fclose(fp);
+ 	exit(1);
+ 	}
+ 
+     /* Read it. */
+     while ( fgets( line, sizeof(line), fp ) != (char*) 0 )
+ 	{
+ 	/* Nuke newline. */
+ 	int l = strlen( line );
+ 	if ( line[l - 1] == '\n' )
+ 	    line[l - 1] = '\0';
+ 	/* Split into user and encrypted password. */
+ 	cryp = strchr( line, ':' );
+ 	if ( cryp == (char*) 0 )
+ 	    continue;
+ 	*cryp++ = '\0';
+ 	/* Is this the right user? */
+ 	key.dptr=line;
+ 	key.dsize=strlen(line)+1;
+ 	value.dptr=cryp;
+ 	value.dsize=strlen(cryp)+1;
+ 	ret = dbm_store(dbm, key,value, DBM_REPLACE);
+ 	if (ret == -1) {
+ 		fprintf(stderr,"Failed to store user %s. Blindly continuing",line);
+ 		continue;
+ 		}
+ 	}
+ 
+     (void) fclose( fp );
+     (void) dbm_close( dbm );
+     return 0;
+ }
Binary files thttpd-2.22beta5cg/contrib/dbm/pass2dbm.o and thttpd-2.22beta5cg-dbm/contrib/dbm/pass2dbm.o differ
diff -c -r -P thttpd-2.22beta5cg/libhttpd.c thttpd-2.22beta5cg-dbm/libhttpd.c
*** thttpd-2.22beta5cg/libhttpd.c	Wed Apr  3 01:35:05 2002
--- thttpd-2.22beta5cg-dbm/libhttpd.c	Wed Apr 24 13:22:45 2002
***************
*** 55,60 ****
--- 55,63 ----
  #include <syslog.h>
  #include <unistd.h>
  #include <stdarg.h>
+ #ifdef AUTH_DBM
+ #include <ndbm.h>
+ #endif
  
  #ifdef HAVE_OSRELDATE_H
  #include <osreldate.h>
***************
*** 1038,1043 ****
--- 1041,1052 ----
      char* authpass;
      char* colon;
      int l;
+ #ifdef AUTH_DBM
+     DBM *dbm;
+     datum key;
+     datum value;
+     char *cryp;
+ #else /* AUTH_DBM */
      FILE* fp;
      char line[500];
      char* cryp;
***************
*** 1048,1053 ****
--- 1057,1063 ----
      static size_t maxprevuser = 0;
      static char* prevcryp;
      static size_t maxprevcryp = 0;
+ #endif /* AUTH_DBM */
  
      /* Construct auth filename. */
      httpd_realloc_str(
***************
*** 1087,1092 ****
--- 1097,1138 ----
      if ( colon != (char*) 0 )
  	*colon = '\0';
  
+ #ifdef AUTH_DBM
+     dbm = dbm_open( authpath, 0, 0 ); /* 0 == READER, 0 = mode */
+ 
+     if ( dbm == (DBM*) 0 )
+ 	{
+ 	/* The file exists but we can't open it?  Disallow access. */
+ 	syslog(
+ 	    LOG_ERR, "%.80s auth file %.80s could not be opened - %m",
+ 	    httpd_ntoa( &hc->client_addr ), authpath );
+ 	httpd_send_err(
+ 	    hc, 403, err403title, "",
+ 	    ERROR_FORM( err403form, "The requested URL '%.80s' is protected by an authentication file, but the authentication file cannot be opened.\n" ),
+ 	    hc->encodedurl );
+ 	return -1;
+ 	}
+     key.dptr=authinfo;
+     key.dsize=strlen(authinfo)+1;
+     value = dbm_fetch( dbm, key );
+     cryp = value.dptr;
+     if (cryp != (char *) 0)
+ 	{
+ 	/* Yes, So is the password right? */
+ 	if ( strcmp( crypt( authpass, cryp ), cryp ) == 0 )
+ 	    {
+ 	    /* Ok! */
+ 	    (void) dbm_close( dbm ); // should cache this...
+ 	    httpd_realloc_str(
+ 	        &hc->remoteuser, &hc->maxremoteuser, strlen( authinfo ) );
+ 	    (void) strcpy( hc->remoteuser, authinfo );
+ 	    return 1;
+ 	    }
+ 	}
+     (void) dbm_close( dbm ); // should cache this...
+ 
+ #else /* AUTH_DBM */
+ 
      /* See if we have a cached entry and can use it. */
      if ( maxprevauthpath != 0 &&
  	 strcmp( authpath, prevauthpath ) == 0 &&
***************
*** 1170,1177 ****
  	    }
  	}
  
-     /* Didn't find that user.  Access denied. */
      (void) fclose( fp );
      send_authenticate( hc, dirname );
      return -1;
      }
--- 1216,1225 ----
  	    }
  	}
  
      (void) fclose( fp );
+ #endif /* else AUTH_DBM */
+ 
+     /* Didn't find that user.  Access denied. */
      send_authenticate( hc, dirname );
      return -1;
      }
