Hello all,

This patch provides support for virutal \user stored in Postgres database. 
Its structure is identical to MySQL support already in place.

What files have to be changed:

configure.in
Makefile.in

And four new files have to be added:

mdpgsql.c
mdpgsql.h
mdpgsqlconfig.c
mdpgsqlconfig.h

In configure script two new options were added:

--enable-maildroppgsql       enable experimental virutal \user PgSQL support
--with-pgsqlconfig=path      complete path to PgSQL config file

that are the same as options for MySQL support. 
This patch was applied to courier-0.40.1 and works successfully for two months 
already.

You can find the patch source in the attachement.

Note to Sam Varshavchik: please consider this patch for inclusion into main
distribution of maildrop.

Best regards,

Witaly Kurakolov
diff -r -c -P maildrop/Makefile.in maildrop.pgs/Makefile.in
*** maildrop/Makefile.in        Sun Dec 29 23:16:14 2002
--- maildrop.pgs/Makefile.in    Thu Jan 16 17:04:24 2003
***************
*** 84,89 ****
--- 84,90 ----
  
  LIBLDAP = @LIBLDAP@
  LIBMYSQL = @LIBMYSQL@
+ LIBPGSQL = @LIBPGSQL@
  LN_S = @LN_S@
  LOCKEXT_DEF = @LOCKEXT_DEF@
  LOCKREFRESH_DEF = @LOCKREFRESH_DEF@
***************
*** 92,97 ****
--- 93,99 ----
  MAILDROPGID = @MAILDROPGID@
  MAILDROPLDAPCONFIG = @MAILDROPLDAPCONFIG@
  MAILDROPMYSQLCONFIG = @MAILDROPMYSQLCONFIG@
+ MAILDROPPGSQLCONFIG = @MAILDROPPGSQLCONFIG@
  MAILDROPUID = @MAILDROPUID@
  PACKAGE = @PACKAGE@
  PERL = @PERL@
***************
*** 130,147 ****
  
  LDAPSOURCES = mdldapconfig.h mdldapconfig.c mdldap.h mdldap.c
  MYSQLSOURCES = mdmysqlconfig.h mdmysqlconfig.c mdmysql.h mdmysql.c
  noinst_LIBRARIES = libmdcommon.a
  
  @USELDAP_TRUE@MDLDAPSOURCES = $(LDAPSOURCES)
  @USELDAP_FALSE@MDLDAPSOURCES = 
  @USEMYSQL_TRUE@MDMYSQLSOURCES = $(MYSQLSOURCES)
  @USEMYSQL_FALSE@MDMYSQLSOURCES = 
  
  libmdcommon_a_SOURCES = alarm.C alarm.h alarmsleep.C alarmsleep.h alarmtimer.C \
        alarmtimer.h buffer.C buffer.h dotlock.C dotlock.h \
        dotlockrefresh.C dotlockrefresh.h exittrap.C exittrap.h funcs.C \
        funcs.h maildrop.C maildrop.h mio.C mio.h setgroupid.c setgroupid.h \
!       tempfile.C tempfile.h $(MDLDAPSOURCES) $(MDMYSQLSOURCES)
  
  
  maildrop_SOURCES = deliver.C deliverdotlock.C deliverdotlock.h \
--- 132,152 ----
  
  LDAPSOURCES = mdldapconfig.h mdldapconfig.c mdldap.h mdldap.c
  MYSQLSOURCES = mdmysqlconfig.h mdmysqlconfig.c mdmysql.h mdmysql.c
+ PGSQLSOURCES = mdpgsqlconfig.h mdpgsqlconfig.c mdpgsql.h mdpgsql.c
  noinst_LIBRARIES = libmdcommon.a
  
  @USELDAP_TRUE@MDLDAPSOURCES = $(LDAPSOURCES)
  @USELDAP_FALSE@MDLDAPSOURCES = 
  @USEMYSQL_TRUE@MDMYSQLSOURCES = $(MYSQLSOURCES)
  @USEMYSQL_FALSE@MDMYSQLSOURCES = 
+ @USEPGSQL_TRUE@MDPGSQLSOURCES = $(PGSQLSOURCES)
+ @USEPGSQL_FALSE@MDPGSQLSOURCES = 
  
  libmdcommon_a_SOURCES = alarm.C alarm.h alarmsleep.C alarmsleep.h alarmtimer.C \
        alarmtimer.h buffer.C buffer.h dotlock.C dotlock.h \
        dotlockrefresh.C dotlockrefresh.h exittrap.C exittrap.h funcs.C \
        funcs.h maildrop.C maildrop.h mio.C mio.h setgroupid.c setgroupid.h \
!       tempfile.C tempfile.h $(MDLDAPSOURCES) $(MDMYSQLSOURCES) $(MDPGSQLSOURCES)
  
  
  maildrop_SOURCES = deliver.C deliverdotlock.C deliverdotlock.h \
***************
*** 161,167 ****
        ../numlib/libnumlib.a ../liblock/liblock.a \
        @USERDBLIB@ $(DBLIB)
  
! maildrop_LDADD = $(maildrop_DEPENDENCIES) $(LIBGDBM) $(LIBLDAP) $(LIBMYSQL)
  
  reformail_SOURCES = reformail.C buffer.C
  reformail_LDADD = ../rfc822/librfc822.a ../liblock/liblock.a
--- 166,172 ----
        ../numlib/libnumlib.a ../liblock/liblock.a \
        @USERDBLIB@ $(DBLIB)
  
! maildrop_LDADD = $(maildrop_DEPENDENCIES) $(LIBGDBM) $(LIBLDAP) $(LIBMYSQL) 
$(LIBPGSQL)
  
  reformail_SOURCES = reformail.C buffer.C
  reformail_LDADD = ../rfc822/librfc822.a ../liblock/liblock.a
***************
*** 178,184 ****
  
  
  EXTRA_DIST = maildroptips.html $(BUILT_SOURCES)\
!       maildrop.lsm testsuite.txt $(LDAPSOURCES) $(MYSQLSOURCES)
  
  
  noinst_DATA = maildrop.html maildrop.1 maildropfilter.html maildropfilter.5 \
--- 183,189 ----
  
  
  EXTRA_DIST = maildroptips.html $(BUILT_SOURCES)\
!       maildrop.lsm testsuite.txt $(LDAPSOURCES) $(MYSQLSOURCES) $(PGSQLSOURCES)
  
  
  noinst_DATA = maildrop.html maildrop.1 maildropfilter.html maildropfilter.5 \
***************
*** 199,209 ****
  am__objects_3 = mdmysqlconfig.$(OBJEXT) mdmysql.$(OBJEXT)
  @USEMYSQL_TRUE@am__objects_4 = $(am__objects_3)
  @USEMYSQL_FALSE@am__objects_4 =
  am_libmdcommon_a_OBJECTS = alarm.$(OBJEXT) alarmsleep.$(OBJEXT) \
        alarmtimer.$(OBJEXT) buffer.$(OBJEXT) dotlock.$(OBJEXT) \
        dotlockrefresh.$(OBJEXT) exittrap.$(OBJEXT) funcs.$(OBJEXT) \
        maildrop.$(OBJEXT) mio.$(OBJEXT) setgroupid.$(OBJEXT) \
!       tempfile.$(OBJEXT) $(am__objects_2) $(am__objects_4)
  libmdcommon_a_OBJECTS = $(am_libmdcommon_a_OBJECTS)
  noinst_PROGRAMS = maildrop$(EXEEXT) reformail$(EXEEXT) mailbot$(EXEEXT)
  PROGRAMS = $(noinst_PROGRAMS)
--- 204,217 ----
  am__objects_3 = mdmysqlconfig.$(OBJEXT) mdmysql.$(OBJEXT)
  @USEMYSQL_TRUE@am__objects_4 = $(am__objects_3)
  @USEMYSQL_FALSE@am__objects_4 =
+ am__objects_5 = mdpgsqlconfig.$(OBJEXT) mdpgsql.$(OBJEXT)
+ @USEPGSQL_TRUE@am__objects_6 = $(am__objects_5)
+ @USEPGSQL_FALSE@am__objects_6 =
  am_libmdcommon_a_OBJECTS = alarm.$(OBJEXT) alarmsleep.$(OBJEXT) \
        alarmtimer.$(OBJEXT) buffer.$(OBJEXT) dotlock.$(OBJEXT) \
        dotlockrefresh.$(OBJEXT) exittrap.$(OBJEXT) funcs.$(OBJEXT) \
        maildrop.$(OBJEXT) mio.$(OBJEXT) setgroupid.$(OBJEXT) \
!       tempfile.$(OBJEXT) $(am__objects_2) $(am__objects_4) $(am__objects_6)
  libmdcommon_a_OBJECTS = $(am_libmdcommon_a_OBJECTS)
  noinst_PROGRAMS = maildrop$(EXEEXT) reformail$(EXEEXT) mailbot$(EXEEXT)
  PROGRAMS = $(noinst_PROGRAMS)
***************
*** 248,253 ****
--- 256,262 ----
  @AMDEP_TRUE@  ./$(DEPDIR)/maildrop.Po ./$(DEPDIR)/main.Po \
  @AMDEP_TRUE@  ./$(DEPDIR)/mdldap.Po ./$(DEPDIR)/mdldapconfig.Po \
  @AMDEP_TRUE@  ./$(DEPDIR)/mdmysql.Po ./$(DEPDIR)/mdmysqlconfig.Po \
+ @AMDEP_TRUE@  ./$(DEPDIR)/mdpgsql.Po ./$(DEPDIR)/mdpgsqlconfig.Po \
  @AMDEP_TRUE@  ./$(DEPDIR)/message.Po ./$(DEPDIR)/messageinfo.Po \
  @AMDEP_TRUE@  ./$(DEPDIR)/mio.Po ./$(DEPDIR)/pipefds.Po \
  @AMDEP_TRUE@  ./$(DEPDIR)/re.Po ./$(DEPDIR)/recipe.Po \
***************
*** 375,380 ****
--- 384,391 ----
  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mdldapconfig.Po@am__quote@
  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mdmysql.Po@am__quote@
  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mdmysqlconfig.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mdpgsql.Po@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mdpgsqlconfig.Po@am__quote@
  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/message.Po@am__quote@
  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/messageinfo.Po@am__quote@
  @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mio.Po@am__quote@
diff -r -c -P maildrop/configure maildrop.pgs/configure
*** maildrop/configure  Sun Dec 29 23:16:16 2002
--- maildrop.pgs/configure      Thu Jan 16 17:13:13 2003
***************
*** 862,867 ****
--- 862,868 ----
    --enable-userdb              enable experimental virtual user db support
    --enable-maildropldap        enable experimental virutal \user ldap support
    --enable-maildropmysql       enable experimental virutal \user MySQL support
+   --enable-maildroppgsql       enable experimental virutal \user PgSQL support
  
  Optional Packages:
    --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
***************
*** 870,875 ****
--- 871,877 ----
    --with-default-maildrop=file   specify DEFAULT mailbox location
    --with-ldapconfig=path       complete path to ldap config file
    --with-mysqlconfig=path       complete path to MySQL config file
+   --with-pgsqlconfig=path       complete path to PgSQL config file
   --with-dirsync           Manually sync queue file directory
    --with-etcdir=dir            Instead of /etc, use this.
  
***************
*** 6538,6543 ****
--- 6540,6570 ----
  USEMYSQL=0
  LIBMYSQL="-lmysqlclient -lz"
  
+ 
+ 
+ # Check whether --with-pgsqlconfig or --without-pgsqlconfig was given.
+ if test "${with_pgsqlconfig+set}" = set; then
+   withval="$with_pgsqlconfig"
+   pgsqlconfig="$withval"
+ else
+   pgsqlconfig="/etc/maildroppgsql.config"
+ fi;
+ 
+ echo "$as_me:$LINENO: checking for maildrop config file" >&5
+ echo $ECHO_N "checking for maildrop config file... $ECHO_C" >&6
+ 
+ cat >>confdefs.h <<_ACEOF
+ #define MAILDROPPGSQLCONFIG "${pgsqlconfig}"
+ _ACEOF
+ 
+ 
+ echo "$as_me:$LINENO: result: \"${pgsqlconfig}\"" >&5
+ echo "${ECHO_T}\"${pgsqlconfig}\"" >&6
+ 
+ 
+ USEPGSQL=0
+ LIBPGSQL="-lpq"
+ 
  USENSL=no
  saveLIBS="$LIBS"
  echo "$as_me:$LINENO: checking for socket in -lsocket" >&5
***************
*** 7075,7080 ****
--- 7102,7197 ----
  LIBS="$LIBMYSQL $LIBS"
  LIBS="$SAVE_LIBS"
  
+ LIBPGSQL="$LIBPGSQL $LIBNSL"
+ 
+ # Check whether --enable-maildroppgsql or --disable-maildroppgsql was given.
+ if test "${enable_maildroppgsql+set}" = set; then
+   enableval="$enable_maildroppgsql"
+   pgsql="$enableval"
+ fi;
+ 
+ case "$pgsql" in
+ 1*|y*|Y*)
+       for ac_prog in pg_config
+ do
+   # Extract the first word of "$ac_prog", so it can be a program name with args.
+ set dummy $ac_prog; ac_word=$2
+ echo "$as_me:$LINENO: checking for $ac_word" >&5
+ echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+ if test "${ac_cv_path_PG_CONFIG+set}" = set; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   case $PG_CONFIG in
+   [\\/]* | ?:[\\/]*)
+   ac_cv_path_PG_CONFIG="$PG_CONFIG" # Let the user override the test with a path.
+   ;;
+   *)
+   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+ for as_dir in $PATH:/usr/local/bin
+ do
+   IFS=$as_save_IFS
+   test -z "$as_dir" && as_dir=.
+   for ac_exec_ext in '' $ac_executable_extensions; do
+   if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+     ac_cv_path_PG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+     break 2
+   fi
+ done
+ done
+ 
+   ;;
+ esac
+ fi
+ PG_CONFIG=$ac_cv_path_PG_CONFIG
+ 
+ if test -n "$PG_CONFIG"; then
+   echo "$as_me:$LINENO: result: $PG_CONFIG" >&5
+ echo "${ECHO_T}$PG_CONFIG" >&6
+ else
+   echo "$as_me:$LINENO: result: no" >&5
+ echo "${ECHO_T}no" >&6
+ fi
+ 
+   test -n "$PG_CONFIG" && break
+ done
+ test -n "$PG_CONFIG" || PG_CONFIG="pg_config"
+ 
+ 
+ cat >>confdefs.h <<_ACEOF
+ #define USEPGSQL 1
+ _ACEOF
+ 
+       use_pgsql=1
+       if test -x $PG_CONFIG
+       then
+               LIBPGSQL="-L`$PG_CONFIG --libdir` $LIBPGSQL"
+               INCPGSQL="-I`$PG_CONFIG --includedir`"
+       fi
+         ;;
+ *)
+       use_pgsql=0
+         LIBPGSQL=""
+       INCPGSQL=""
+         PGSQLSOURCES=""
+         ;;
+ esac
+ 
+ 
+ 
+ if test x$use_pgsql = x1; then
+   USEPGSQL_TRUE=
+   USEPGSQL_FALSE='#'
+ else
+   USEPGSQL_TRUE='#'
+   USEPGSQL_FALSE=
+ fi
+ 
+ 
+ SAVE_LIBS="$LIBS"
+ LIBS="$LIBPGSQL $LIBS"
+ LIBS="$SAVE_LIBS"
+ 
  
  # Check whether --with-dirsync or --without-dirsync was given.
  if test "${with_dirsync+set}" = set; then
***************
*** 7098,7105 ****
  
  
  
! CFLAGS="$CFLAGS -I$srcdir/../rfc822 -I$srcdir/../rfc2045 -I.. -I$srcdir/.."
! CXXFLAGS="$CXXFLAGS -I$srcdir/../rfc822 -I$srcdir/../rfc2045 -I.. -I$srcdir/.."
  
  
  # Check whether --with-etcdir or --without-etcdir was given.
--- 7215,7222 ----
  
  
  
! CFLAGS="$CFLAGS -I$srcdir/../rfc822 -I$srcdir/../rfc2045 -I.. -I$srcdir/.. $INCPGSQL"
! CXXFLAGS="$CXXFLAGS -I$srcdir/../rfc822 -I$srcdir/../rfc2045 -I.. -I$srcdir/.. 
$INCPGSQL"
  
  
  # Check whether --with-etcdir or --without-etcdir was given.
***************
*** 7285,7290 ****
--- 7402,7414 ----
  Usually this means the macro was only invoked conditionally." >&2;}
     { (exit 1); exit 1; }; }
  fi
+ if test -z "${USEPGSQL_TRUE}" && test -z "${USEPGSQL_FALSE}"; then
+   { { echo "$as_me:$LINENO: error: conditional \"USEPGSQL\" was never defined.
+ Usually this means the macro was only invoked conditionally." >&5
+ echo "$as_me: error: conditional \"USEPGSQL\" was never defined.
+ Usually this means the macro was only invoked conditionally." >&2;}
+    { (exit 1); exit 1; }; }
+ fi
  if test -z "${HAVE_SGML_TRUE}" && test -z "${HAVE_SGML_FALSE}"; then
    { { echo "$as_me:$LINENO: error: conditional \"HAVE_SGML\" was never defined.
  Usually this means the macro was only invoked conditionally." >&5
***************
*** 7858,7869 ****
--- 7982,7998 ----
  s,@USERDB_FALSE@,$USERDB_FALSE,;t t
  s,@MAILDROPLDAPCONFIG@,$MAILDROPLDAPCONFIG,;t t
  s,@MAILDROPMYSQLCONFIG@,$MAILDROPMYSQLCONFIG,;t t
+ s,@MAILDROPPGSQLCONFIG@,$MAILDROPPGSQLCONFIG,;t t
  s,@LIBLDAP@,$LIBLDAP,;t t
  s,@USELDAP_TRUE@,$USELDAP_TRUE,;t t
  s,@USELDAP_FALSE@,$USELDAP_FALSE,;t t
  s,@LIBMYSQL@,$LIBMYSQL,;t t
  s,@USEMYSQL_TRUE@,$USEMYSQL_TRUE,;t t
  s,@USEMYSQL_FALSE@,$USEMYSQL_FALSE,;t t
+ s,@PG_CONFIG@,$PG_CONFIG,;t t
+ s,@LIBPGSQL@,$LIBPGSQL,;t t
+ s,@USEPGSQL_TRUE@,$USEPGSQL_TRUE,;t t
+ s,@USEPGSQL_FALSE@,$USEPGSQL_FALSE,;t t
  s,@withetcdir@,$withetcdir,;t t
  s,@HAVE_SGML_TRUE@,$HAVE_SGML_TRUE,;t t
  s,@HAVE_SGML_FALSE@,$HAVE_SGML_FALSE,;t t
diff -r -c -P maildrop/configure.in maildrop.pgs/configure.in
*** maildrop/configure.in       Sun Dec 29 23:07:56 2002
--- maildrop.pgs/configure.in   Thu Jan 16 17:04:46 2003
***************
*** 742,747 ****
--- 742,760 ----
  USEMYSQL=0
  LIBMYSQL="-lmysqlclient -lz"
  
+ 
+ AC_ARG_WITH(pgsqlconfig,  [  --with-pgsqlconfig=path       complete path to PgSQL 
+config file], pgsqlconfig="$withval", pgsqlconfig="/etc/maildroppgsql.config")
+ 
+ AC_MSG_CHECKING(for maildrop config file)
+ AC_DEFINE_UNQUOTED(MAILDROPPGSQLCONFIG,"${pgsqlconfig}",
+       [ PgSQL extension configuration file ])
+ 
+ AC_MSG_RESULT("${pgsqlconfig}")
+ AC_SUBST(MAILDROPPGSQLCONFIG)
+ 
+ USEPGSQL=0
+ LIBPGSQL="-lpq"
+ 
  USENSL=no
  saveLIBS="$LIBS"
  AC_CHECK_LIB(socket,socket,result=yes,result=no)
***************
*** 830,835 ****
--- 843,878 ----
  LIBS="$LIBMYSQL $LIBS"
  LIBS="$SAVE_LIBS"
  
+ LIBPGSQL="$LIBPGSQL $LIBNSL"
+ 
+ AC_ARG_ENABLE(maildroppgsql,[  --enable-maildroppgsql       enable experimental 
+virutal \user PgSQL support],pgsql="$enableval", )
+ 
+ case "$pgsql" in
+ 1*|y*|Y*)
+       AC_PATH_PROGS(PG_CONFIG, pg_config, pg_config, $PATH:/usr/local/bin)
+         AC_DEFINE_UNQUOTED(USEPGSQL,1,
+               [ Whether PgSQL extensions are enabled ])
+       use_pgsql=1
+       if test -x $PG_CONFIG
+       then
+               LIBPGSQL="-L`$PG_CONFIG --libdir` $LIBPGSQL"
+               INCPGSQL="-I`$PG_CONFIG --includedir`"
+       fi
+         ;;
+ *)
+       use_pgsql=0
+         LIBPGSQL=""
+       INCPGSQL=""
+         PGSQLSOURCES=""
+         ;;
+ esac
+ AC_SUBST(LIBPGSQL)
+ AM_CONDITIONAL(USEPGSQL, test x$use_pgsql = x1)
+ 
+ SAVE_LIBS="$LIBS"
+ LIBS="$LIBPGSQL $LIBS"
+ LIBS="$SAVE_LIBS"
+ 
  AC_ARG_WITH(dirsync, [ --with-dirsync           Manually sync queue file directory],
        dirsync="$withval", dirsync="N")
  
***************
*** 844,851 ****
  
  AC_SUBST(VERSION)
  
! CFLAGS="$CFLAGS -I$srcdir/../rfc822 -I$srcdir/../rfc2045 -I.. -I$srcdir/.."
! CXXFLAGS="$CXXFLAGS -I$srcdir/../rfc822 -I$srcdir/../rfc2045 -I.. -I$srcdir/.."
  
  AC_ARG_WITH(etcdir,    [  --with-etcdir=dir            Instead of /etc, use this. ],
        [ withetcdir=$withval],
--- 887,894 ----
  
  AC_SUBST(VERSION)
  
! CFLAGS="$CFLAGS -I$srcdir/../rfc822 -I$srcdir/../rfc2045 -I.. -I$srcdir/.. $INCPGSQL"
! CXXFLAGS="$CXXFLAGS -I$srcdir/../rfc822 -I$srcdir/../rfc2045 -I.. -I$srcdir/.. 
$INCPGSQL"
  
  AC_ARG_WITH(etcdir,    [  --with-etcdir=dir            Instead of /etc, use this. ],
        [ withetcdir=$withval],
diff -r -c -P maildrop/mdpgsql.c maildrop.pgs/mdpgsql.c
*** maildrop/mdpgsql.c  Thu Jan  1 03:00:00 1970
--- maildrop.pgs/mdpgsql.c      Thu Jan 16 17:12:33 2003
***************
*** 0 ****
--- 1,115 ----
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <sys/time.h>
+ #include <errno.h>
+ 
+ #include "mdpgsqlconfig.h"
+ #include "mdpgsql.h"
+ 
+ #include <libpq-fe.h> 
+ 
+ extern int errno;
+ 
+ mdpgsqlrec *get_user_pgsql(mdpgsqlconfig *cfg,char *username)
+ {
+   PGconn *pgconn=0;
+   PGresult *pgresult=0;
+   mdpgsqlrec *rec = NULL;
+   static const char query[]=
+       "SELECT %s, %s, %s, %s, %s, %s, %s FROM %s WHERE %s = \"%s\" %s";
+   char *querybuf;
+   unsigned int querybuf_len;
+ 
+ 
+   pgconn = PQsetdbLogin(cfg->hostname, cfg->port, NULL, NULL , cfg->database,
+                         cfg->dbuser, cfg->dbpw);
+ 
+   if (PQstatus(pgconn) == CONNECTION_BAD)
+     {
+       PQfinish(pgconn);
+       pgconn=NULL;
+       return NULL;
+     }
+   /* allocate memory for SQL query string */
+   querybuf_len = sizeof(query) + 100 + 2 * strlen(cfg->uid_field)
+       + strlen(cfg->uidnumber_field) + strlen(cfg->gidnumber_field)
+       + strlen(cfg->homedir_field) + strlen(cfg->maildir_field)
+       + strlen(cfg->quota_field) + strlen(cfg->mailstatus_field)
+       + strlen(cfg->dbtable) + strlen(username)
+       + strlen(cfg->where_clause);
+   querybuf = malloc(querybuf_len);
+ 
+   if (!querybuf)
+     {
+       /* malloc error*/
+       PQfinish(pgconn);
+       return NULL;
+     }
+ 
+   /* prepare SQL query string */
+   snprintf(querybuf, querybuf_len, query, cfg->uid_field,
+       cfg->uidnumber_field, cfg->gidnumber_field, cfg->homedir_field,
+       cfg->maildir_field, cfg->quota_field, cfg->mailstatus_field,
+       cfg->dbtable, cfg->uid_field, username, cfg->where_clause);
+ 
+   pgresult = PQexec(pgconn, querybuf);
+   if (!pgresult || PQresultStatus(pgresult) != PGRES_TUPLES_OK) 
+     {
+       PQclear(pgresult);
+       PQfinish(pgconn);
+       free(querybuf);
+       return NULL;
+     }
+   free(querybuf);
+   
+ 
+   if ( PQntuples(pgresult) > 0 )
+     {
+       rec = (mdpgsqlrec*)malloc(sizeof(mdpgsqlrec)+1);
+       rec->uid = strdup(PQgetvalue(pgresult,0,0));
+       rec->uidnumber=atoi(PQgetvalue(pgresult,0,1));
+       if (errno == ERANGE) rec->uidnumber = cfg->default_uidnumber;
+       rec->gidnumber=atoi(PQgetvalue(pgresult,0,2));
+       if (errno == ERANGE) rec->gidnumber = cfg->default_gidnumber;
+       rec->homedir=strdup(PQgetvalue(pgresult,0,3));
+       rec->maildir=strdup(PQgetvalue(pgresult,0,4));
+       rec->quota=strdup(PQgetvalue(pgresult,0,5));
+       rec->mailstatus=strdup(PQgetvalue(pgresult,0,6));
+     } else {
+             PQclear(pgresult);
+             PQfinish(pgconn);
+             return NULL;
+     }
+ 
+   PQclear(pgresult);
+   PQfinish(pgconn);
+ 
+   if (!rec->uid || !rec->homedir || !rec->maildir || !rec->mailstatus)
+     return NULL;
+ 
+   return rec;
+ 
+ }
+ 
+ void free_pgsql_rec(mdpgsqlrec **rec)
+ {
+   if ( rec[0]->uid )
+     free(rec[0]->uid);
+ 
+   if ( rec[0]->homedir )
+     free(rec[0]->homedir);
+   
+   if ( rec[0]->maildir )
+     free(rec[0]->maildir);
+ 
+   if ( rec[0]->quota )
+     free(rec[0]->quota);
+ 
+   if ( rec[0]->mailstatus )
+     free(rec[0]->mailstatus);
+ 
+   free(*rec);
+ 
+   *rec = NULL;
+ }
diff -r -c -P maildrop/mdpgsql.h maildrop.pgs/mdpgsql.h
*** maildrop/mdpgsql.h  Thu Jan  1 03:00:00 1970
--- maildrop.pgs/mdpgsql.h      Thu Jan 16 17:12:33 2003
***************
*** 0 ****
--- 1,30 ----
+ #ifndef __MDPGSQL_H
+ #define __MDPGSQL_H 1
+ 
+ #ifdef __cplusplus
+ extern "C" {
+ #endif 
+ 
+ #include "mdpgsqlconfig.h"
+ 
+   typedef struct {
+     char *uid;
+     int uidnumber;
+     int gidnumber;
+     char *homedir;
+     char *maildir;
+     char *quota;
+     char *mailstatus;
+   } mdpgsqlrec;
+ 
+ 
+   mdpgsqlrec *get_user_pgsql(mdpgsqlconfig *cfg, char *username);
+ 
+   void free_pgsql_rec(mdpgsqlrec **rec);
+ 
+ #ifdef __cplusplus
+ }
+ #endif
+ 
+ #endif
+ 
diff -r -c -P maildrop/mdpgsqlconfig.c maildrop.pgs/mdpgsqlconfig.c
*** maildrop/mdpgsqlconfig.c    Thu Jan  1 03:00:00 1970
--- maildrop.pgs/mdpgsqlconfig.c        Thu Jan 16 17:12:42 2003
***************
*** 0 ****
--- 1,142 ----
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include "mdpgsqlconfig.h"
+ 
+ mdpgsqlconfig *get_pgsql_config(char *configfile)
+ {
+   FILE *fp;
+   char *buf,*var,*val;
+   mdpgsqlconfig *cfg = NULL;
+ 
+   buf = (char*)malloc(1025);
+   var = (char*)malloc(1025);
+   val = (char*)malloc(1025);
+ 
+   fp = fopen(configfile,"r");
+   if ( fp )
+     {
+       cfg = (mdpgsqlconfig*)malloc(sizeof(mdpgsqlconfig)+1);
+       cfg->hostname = NULL;
+       cfg->database = NULL;
+       cfg->dbuser = NULL;
+       cfg->dbpw = NULL;
+       cfg->dbtable = NULL;
+ 
+       cfg->uid_field = NULL;
+       cfg->uidnumber_field = NULL;
+       cfg->gidnumber_field = NULL;
+       cfg->maildir_field = NULL;
+       cfg->homedir_field = NULL;
+       cfg->quota_field = NULL;
+       cfg->mailstatus_field = NULL;
+       cfg->where_clause = NULL;
+ 
+       cfg->port = PGSQL_DEFAULT_PORT;
+       cfg->socket = NULL;
+       
+       cfg->timeout = PGSQL_DEFAULT_TIMEOUT;
+ 
+       while ( fgets(buf,1024,fp) )
+       {
+       sscanf(buf,"%s %s",var,val);
+ 
+       if ( !strcasecmp(var,"hostname") )
+         cfg->hostname = (char*)strdup(val);
+       if ( !strcasecmp(var,"port") )
+         cfg->port = (char*)strdup(val);
+       if ( !strcasecmp(var,"socket") )
+         cfg->socket = (char*)strdup(val);
+       if ( !strcasecmp(var,"database") )
+         cfg->database = (char*)strdup(val);
+       if ( !strcasecmp(var,"dbuser") )
+         cfg->dbuser = (char*)strdup(val);
+       if ( !strcasecmp(var,"dbpw") )
+         cfg->dbpw = (char*)strdup(val);
+       if ( !strcasecmp(var,"dbtable") )
+         cfg->dbtable = (char*)strdup(val);
+ 
+       if ( !strcasecmp(var,"uid_field") )
+         cfg->uid_field = (char*)strdup(val);
+       if ( !strcasecmp(var,"uidnumber_field") )
+         cfg->uidnumber_field = (char*)strdup(val);
+       if ( !strcasecmp(var,"gidnumber_field") )
+         cfg->gidnumber_field = (char*)strdup(val);
+       if ( !strcasecmp(var,"maildir_field") )
+         cfg->maildir_field = (char*)strdup(val);
+       if ( !strcasecmp(var,"homedirectory_field") )
+         cfg->homedir_field = (char*)strdup(val);
+       if ( !strcasecmp(var,"quota_field") )
+         cfg->quota_field = (char*)strdup(val);
+       if ( !strcasecmp(var,"mailstatus_field") )
+         cfg->mailstatus_field = (char*)strdup(val);
+       if ( !strcasecmp(var,"where_clause") ) {
+         if ( !strncasecmp(val,"and", 3) ) {
+           val = buf+=3;
+           cfg->where_clause = (char*)strdup(val);
+         }
+       }
+ 
+       if ( !strcasecmp(var,"timeout") )
+         cfg->timeout = atoi(val);
+ 
+       if ( !strcasecmp(var,"default_uidnumber") )
+         cfg->default_uidnumber = atoi(val);
+ 
+       if ( !strcasecmp(var,"default_gidnumber") )
+         cfg->default_gidnumber = atoi(val);
+       }
+ 
+       fclose(fp);
+ 
+       if ( !cfg->uid_field )
+       cfg->uid_field = (char*)strdup(PGSQL_DEFAULT_UID_FIELD);
+       if ( !cfg->uidnumber_field )
+       cfg->uidnumber_field = (char*)strdup(PGSQL_DEFAULT_UIDNUMBER_FIELD);
+       if ( !cfg->gidnumber_field )
+       cfg->gidnumber_field = (char*)strdup(PGSQL_DEFAULT_GIDNUMBER_FIELD);
+       if ( !cfg->maildir_field )
+       cfg->maildir_field = (char*)strdup(PGSQL_DEFAULT_MAILDIR_FIELD);
+       if ( !cfg->homedir_field )
+       cfg->homedir_field = (char*)strdup(PGSQL_DEFAULT_HOMEDIRECTORY_FIELD);
+       if ( !cfg->quota_field )
+       cfg->quota_field = (char*)strdup(PGSQL_DEFAULT_QUOTA_FIELD);
+       if ( !cfg->mailstatus_field )
+       cfg->mailstatus_field = (char*)strdup(PGSQL_DEFAULT_STATUS_FIELD);
+       if ( !cfg->where_clause )
+       cfg->where_clause = (char*)strdup(PGSQL_DEFAULT_WHERE_CLAUSE);
+     }
+ 
+   free(buf);
+   free(var);
+   free(val);
+ 
+   return cfg;
+ }
+ 
+ void free_pgsql_config(mdpgsqlconfig **cfg)
+ {
+   if ( cfg[0]->hostname )
+     free(cfg[0]->hostname);
+   if ( cfg[0]->database )
+     free(cfg[0]->database);
+   if ( cfg[0]->dbuser )
+     free(cfg[0]->dbuser);
+   if ( cfg[0]->dbpw )
+     free(cfg[0]->dbpw);
+   if ( cfg[0]->dbtable )
+     free(cfg[0]->dbtable);
+ 
+   free(cfg[0]->uid_field);
+   free(cfg[0]->uidnumber_field);
+   free(cfg[0]->gidnumber_field);
+   free(cfg[0]->maildir_field);
+   free(cfg[0]->homedir_field);
+   free(cfg[0]->quota_field);
+   free(cfg[0]->mailstatus_field);
+   free(cfg[0]->where_clause);
+ 
+   free(*cfg);
+ 
+   *cfg = NULL;
+ }
diff -r -c -P maildrop/mdpgsqlconfig.h maildrop.pgs/mdpgsqlconfig.h
*** maildrop/mdpgsqlconfig.h    Thu Jan  1 03:00:00 1970
--- maildrop.pgs/mdpgsqlconfig.h        Thu Jan 16 17:12:42 2003
***************
*** 0 ****
--- 1,51 ----
+ #ifndef __MDPGSQLCONFIG_H
+ #define __MDPGSQLCONFIG_H 1
+ 
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+ 
+ #define PGSQL_DEFAULT_PORT "5432"
+ #define PGSQL_DEFAULT_SOCKET "/tmp/s.PGSQL.5432"
+ 
+ #define PGSQL_DEFAULT_UID_FIELD "uid"
+ #define PGSQL_DEFAULT_UIDNUMBER_FIELD "uidnumber"
+ #define PGSQL_DEFAULT_GIDNUMBER_FIELD "gidnumber"
+ #define PGSQL_DEFAULT_MAILDIR_FIELD "maildir"
+ #define PGSQL_DEFAULT_HOMEDIRECTORY_FIELD "homedir"
+ #define PGSQL_DEFAULT_QUOTA_FIELD "quota"
+ #define PGSQL_DEFAULT_STATUS_FIELD "vmailstatus"
+ #define PGSQL_DEFAULT_WHERE_CLAUSE ""
+ #define PGSQL_DEFAULT_TIMEOUT 5
+ 
+ typedef struct {
+   char *hostname;
+   char *port;
+   char *socket;
+   char *database;
+   char *dbuser;
+   char *dbpw;
+   char *dbtable;
+ 
+   char *uid_field;
+   char *uidnumber_field;
+   char *gidnumber_field;
+   char *homedir_field;
+   char *maildir_field;
+   char *quota_field;
+   char *mailstatus_field;
+   char *where_clause;
+ 
+   int default_uidnumber;
+   int default_gidnumber;
+ 
+   int timeout;
+ } mdpgsqlconfig;
+ 
+ mdpgsqlconfig *get_pgsql_config(char *configfile);
+ 
+ #ifdef __cplusplus
+ }
+ #endif
+ 
+ #endif

Reply via email to