--- postfix-2.0.7/src/util/dict_mysql.c.orig	Tue Jul  3 03:15:45 2001
+++ postfix-2.0.7/src/util/dict_mysql.c	Sun Mar 23 21:34:24 2003
@@ -96,7 +96,7 @@
 
 typedef struct {
     int     len_hosts;			/* number of hosts */
-    HOST   *db_hosts;			/* the hosts on which the databases
+    HOST   **db_hosts;			/* the hosts on which the databases
 					 * reside */
 } PLMYSQL;
 
@@ -124,7 +124,7 @@
 #define RETRY_CONN_INTV 60		/* 1 minute */
 
 /* internal function declarations */
-static PLMYSQL *plmysql_init(char *hostnames[], int);
+static PLMYSQL *plmysql_init(char *hostnames[], int, char *, char *);
 static MYSQL_RES *plmysql_query(PLMYSQL *, const char *, char *, char *, char *);
 static void plmysql_dealloc(PLMYSQL *);
 static void plmysql_down_host(HOST *);
@@ -134,9 +134,15 @@
 DICT   *dict_mysql_open(const char *, int, int);
 static void dict_mysql_close(DICT *);
 static MYSQL_NAME *mysqlname_parse(const char *);
-static HOST host_init(char *);
-
+static HOST *host_init(char *, char *, char *);
 
+struct {
+    HOST  host;
+    char *username;
+    char *dbname;
+    int   count;
+} *cache;
+int len_caches;
 
 /**********************************************************************
  * public interface dict_mysql_lookup
@@ -237,7 +243,7 @@
 
     for (i = 0; i < PLDB->len_hosts; i++) {
 	/* can't deal with typing or reading PLDB->db_hosts[i] over & over */
-	host = &(PLDB->db_hosts[i]);
+	host = PLDB->db_hosts[i];
 	if (msg_verbose > 1)
 	    msg_info("dict_mysql: trying host %s stat %d, last res %p", host->hostname, host->stat, res);
 
@@ -363,7 +369,9 @@
     dict_mysql->dict.flags = dict_flags | DICT_FLAG_FIXED;
     dict_mysql->name = mysqlname_parse(name);
     dict_mysql->pldb = plmysql_init(dict_mysql->name->hostnames,
-				    dict_mysql->name->len_hosts);
+				    dict_mysql->name->len_hosts,
+				    dict_mysql->name->username,
+				    dict_mysql->name->dbname);
     if (dict_mysql->pldb == NULL)
 	msg_fatal("couldn't intialize pldb!\n");
     dict_register(name, (DICT *) dict_mysql);
@@ -480,36 +488,50 @@
  * plmysql_init - initalize a MYSQL database.
  *		    Return NULL on failure, or a PLMYSQL * on success.
  */
-static PLMYSQL *plmysql_init(char *hostnames[], int len_hosts)
+static PLMYSQL *plmysql_init(char *hostnames[], int len_hosts, char *username, char *dbname)
 {
     PLMYSQL *PLDB;
     MYSQL  *dbs;
     int     i;
-    HOST    host;
+    HOST    *host;
 
     if ((PLDB = (PLMYSQL *) mymalloc(sizeof(PLMYSQL))) == NULL) {
 	msg_fatal("mymalloc of pldb failed");
     }
     PLDB->len_hosts = len_hosts;
-    if ((PLDB->db_hosts = (HOST *) mymalloc(sizeof(HOST) * len_hosts)) == NULL)
+    if ((PLDB->db_hosts = (HOST **) mymalloc(sizeof(HOST *) * len_hosts)) == NULL)
 	return NULL;
     for (i = 0; i < len_hosts; i++) {
-	PLDB->db_hosts[i] = host_init(hostnames[i]);
+	PLDB->db_hosts[i] = host_init(hostnames[i], username, dbname);
     }
     return PLDB;
 }
 
 
 /* host_init - initialize HOST structure */
-static HOST host_init(char *hostname)
+static HOST *host_init(char *hostname, char *username, char *dbname)
 {
-    HOST    host;
+    int i;
+
+    for (i = 0; i < len_caches; i++) {
+	if (cache[i].count > 0 &&
+	    strcmp(hostname, cache[i].host.hostname) == 0 &&
+	    strcmp(username, cache[i].username) == 0 &&
+	    strcmp(dbname, cache[i].dbname) == 0) {
+	    cache[i].count++;
+	    return &cache[i].host;
+	}
+    }
 
-    host.stat = STATUNTRIED;
-    host.hostname = mystrdup(hostname);
-    host.db = 0;
-    host.ts = 0;
-    return host;
+    cache = (void *)myrealloc((char *)cache, sizeof(*cache) * (len_caches+1));
+    cache[len_caches].host.stat = STATUNTRIED;
+    cache[len_caches].host.hostname = mystrdup(hostname);
+    cache[len_caches].host.db = 0;
+    cache[len_caches].host.ts = 0;
+    cache[len_caches].username = mystrdup(username);
+    cache[len_caches].dbname = mystrdup(dbname);
+    cache[len_caches].count = 1;
+    return &cache[len_caches++].host;
 }
 
 /**********************************************************************
@@ -541,14 +563,32 @@
 static void plmysql_dealloc(PLMYSQL *PLDB)
 {
     int     i;
+    int	    j;
 
     for (i = 0; i < PLDB->len_hosts; i++) {
-	if (PLDB->db_hosts[i].db)
-	    mysql_close(PLDB->db_hosts[i].db);
-	myfree(PLDB->db_hosts[i].hostname);
+	for (j = 0; j < len_caches; j++) {
+	    if (PLDB->db_hosts[i] == &cache[j].host) {
+		cache[j].count--;
+		if (cache[j].count == 0) {
+		    if (cache[j].host.db)
+			mysql_close(cache[j].host.db);
+		    myfree(cache[j].host.hostname);
+		    myfree(cache[j].username);
+		    myfree(cache[j].dbname);
+		}
+	    }
+	}
     }
     myfree((char *) PLDB->db_hosts);
     myfree((char *) (PLDB));
+
+    for (i = 0; i < len_caches; i++) {
+	if (cache[i].count > 0)
+	    return;
+    }
+    myfree((char *)cache);
+    cache = NULL;
+    len_caches = 0;
 }
 
 #endif
