diff --git a/postfix/.indent.pro b/postfix/.indent.pro index 693a39fb8..7223e9d27 100644 --- a/postfix/.indent.pro +++ b/postfix/.indent.pro @@ -73,6 +73,7 @@ -TMKMAP_OPEN_INFO -TMULTI_SERVER -TMVECT +-TMYSQL -TMYSQL_NAME -TNAMADR_LIST -TNAME_MASK diff --git a/postfix/DB_README b/postfix/DB_README index 6f6b3dc2d..49cf41c30 100644 --- a/postfix/DB_README +++ b/postfix/DB_README @@ -18,7 +18,7 @@ use something like: % make tidy % make makefiles CCARGS="-DHAS_DB -I/usr/local/BerkeleyDB.3.1/include" \ - AUXLIBS=/usr/local/BerkeleyDB.3.1/lib/libdb.a + AUXLIBS="-L/usr/local/BerkeleyDB.3.1/lib -ldb" % make The exact pathnames depend on the DB version that you installed. diff --git a/postfix/HISTORY b/postfix/HISTORY index 9afd9d3b6..77218e7ce 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -4654,6 +4654,13 @@ Apologies for any names omitted. Code cleanup: in a CONFIG_TIME_TABLE, the default time unit is now always the last character of a default time value. It is no longer necessary to specify the default time unit - separately. This change means that it is not longer possible - to specify default values in the form of function calls. - Files: global/mail_conf_time.c, and user code. + separately. This change means that it will not be possible + to specify default values in the form of function calls, + but that was unused anyway. Files: global/mail_conf_time.c, + and user code. + +20001217 + + Bugfix: reorganized some code in the MYSQL client to end + a number of memory allocation/deallocation problems. + This code needs more work. File: dict_mysql.c. diff --git a/postfix/LDAP_README b/postfix/LDAP_README index 9dca5663c..07660e031 100644 --- a/postfix/LDAP_README +++ b/postfix/LDAP_README @@ -23,12 +23,16 @@ If you're using the libraries from the UM distribution Postfix source tree should work: % make tidy - % make makefiles CCARGS="-I/some/where/include -DHAS_LDAP" \ - AUXLIBS="/some/where/lib/libldap.a /some/where/lib/liblber.a" + % make makefiles CCARGS="-I/usr/local/include -DHAS_LDAP" \ + AUXLIBS="-L/usr/local/lib -lldap -L/usr/local/lib -llber" The 'make tidy' command is needed only if you have previously built Postfix without LDAP support. +Instead of '/usr/local' specify the actual locations of your LDAP +include files and libraries. Be sure to not mix LDAP include files +and LDAP libraries of different versions!! + If your LDAP libraries were built with Kerberos support, you'll also need to include your Kerberos libraries in this line. Note that the KTH Kerberos IV libraries might conflict with Postfix's lib/libdns.a, which diff --git a/postfix/MYSQL_README b/postfix/MYSQL_README index 31cdcdc55..e5c0c27f8 100644 --- a/postfix/MYSQL_README +++ b/postfix/MYSQL_README @@ -10,8 +10,8 @@ In order to build postfix with mysql map support, you will need to add the mysqlclient library (and libm) to AUXLIBS, for example: make -f Makefile.init makefiles \ - 'CCARGS=-DHAS_MYSQL -I/some/where/include/mysql' \ - 'AUXLIBS=/some/where/lib/mysql/libmysqlclient.a -lm' + 'CCARGS=-DHAS_MYSQL -I/usr/local/mysql/include' \ + 'AUXLIBS=-L/usr/local/mysql/lib -lmysqlclient -lm' then, just run 'make'. diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index 2fa074567..3e92932c6 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -1,4 +1,4 @@ -Major changes with snapshot-20001215 +Major changes with snapshot-20001217 ==================================== This release involves little change in functionality and a lot of @@ -10,11 +10,16 @@ suffix to indicate the time unit (s: second, m: minute, h: hour, d: day, w: week). The exceptions are the LDAP and MYSQL modules which are maintained separately. +The mysql client was partially rewritten in order to elimimate some +memory allocation/deallocation problems. The code needs more work, +and needs to be tested in a real production environment. + The local_transport and default_transport configuration parameters can now be specified in transport:destination notation, just like the mailbox_transport and fallback_transport parameters. The -:destination part is optional. This change makes the relayhost -parameter obsolescent. +:destination part is optional. However, these parameters take only +one destination, unlike relayhost and fallback-relay which take +any number of destinations. Incompatible changes with snapshot-20001210 =========================================== diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 14dc1a5a4..b5a18b66b 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -15,7 +15,7 @@ * Version of this program. */ #define VAR_MAIL_VERSION "mail_version" -#define DEF_MAIL_VERSION "Snapshot-20001216" +#define DEF_MAIL_VERSION "Snapshot-20001217" extern char *var_mail_version; /* LICENSE diff --git a/postfix/src/util/dict_mysql.c b/postfix/src/util/dict_mysql.c index 135917b83..5f40644b0 100644 --- a/postfix/src/util/dict_mysql.c +++ b/postfix/src/util/dict_mysql.c @@ -89,7 +89,7 @@ extern int dict_errno; /* need some structs to help organize things */ typedef struct { - MYSQL db; + MYSQL *db; char *hostname; int stat; /* STATUNTRIED | STATFAIL | STATCUR */ time_t ts; /* used for attempting reconnection @@ -126,7 +126,7 @@ static MYSQL_RES *plmysql_query(PLMYSQL *, const char *, char *, char *, char *) static void plmysql_dealloc(PLMYSQL *); static void plmysql_down_host(HOST *); static void plmysql_connect_single(HOST *, char *, char *, char *); -static int plmysql_ready_reconn(HOST); +static int plmysql_ready_reconn(HOST *); static void dict_mysql_update(DICT *, const char *, const char *); static const char *dict_mysql_lookup(DICT *, const char *); DICT *dict_mysql_open(const char *, int, int); @@ -235,13 +235,16 @@ static MYSQL_RES *plmysql_query(PLMYSQL *PLDB, /* answer already found */ if (res != 0 && host->stat == STATACTIVE) { - msg_info("dict_mysql: closing unnessary connection to %s", host->hostname); - mysql_close(&(host->db)); + if (msg_verbose) + msg_info("dict_mysql: closing unnessary connection to %s", + host->hostname); plmysql_down_host(host); } /* try to connect for the first time if we don't have a result yet */ if (res == 0 && host->stat == STATUNTRIED) { - msg_info("dict_mysql: attempting to connect to host %s", host->hostname); + if (msg_verbose) + msg_info("dict_mysql: attempting to connect to host %s", + host->hostname); plmysql_connect_single(host, dbname, username, password); } @@ -249,8 +252,10 @@ static MYSQL_RES *plmysql_query(PLMYSQL *PLDB, * try to reconnect if we don't have an answer and the host had a * prob in the past and it's time for it to reconnect */ - if (res == 0 && host->stat == STATFAIL && (plmysql_ready_reconn(*host))) { - msg_warn("dict_mysql: attempting to reconnect to host %s", host->hostname); + if (res == 0 && host->stat == STATFAIL && host->ts < time((time_t *) 0)) { + if (msg_verbose) + msg_info("dict_mysql: attempting to reconnect to host %s", + host->hostname); plmysql_connect_single(host, dbname, username, password); } @@ -259,16 +264,16 @@ static MYSQL_RES *plmysql_query(PLMYSQL *PLDB, * try the query. If the query fails, mark the host STATFAIL */ if (res == 0 && host->stat == STATACTIVE) { - if (!(mysql_query(&(host->db), query))) { - if ((res = mysql_store_result(&(host->db))) == 0) { - msg_warn("%s", mysql_error(&(host->db))); + if (!(mysql_query(host->db, query))) { + if ((res = mysql_store_result(host->db)) == 0) { + msg_warn("%s", mysql_error(host->db)); plmysql_down_host(host); } else { if (msg_verbose) msg_info("dict_mysql: successful query from host %s", host->hostname); } } else { - msg_warn("%s", mysql_error(&(host->db))); + msg_warn("%s", mysql_error(host->db)); plmysql_down_host(host); } } @@ -303,13 +308,15 @@ static void plmysql_connect_single(HOST *host, char *dbname, char *username, cha port = ntohs(find_inet_port(service, "tcp")); } - host->db = *((MYSQL *) mysql_init(NULL)); - if (mysql_real_connect(&(host->db), hostname, username, password, dbname, port, unix_socket, 0)) { - msg_info("dict_mysql: successful connection to host %s", host->hostname); + host->db = mysql_init(NULL); + if (mysql_real_connect(host->db, hostname, username, password, dbname, port, unix_socket, 0)) { + if (msg_verbose) + msg_info("dict_mysql: successful connection to host %s", + host->hostname); host->stat = STATACTIVE; } else { + msg_warn("%s", mysql_error(host->db)); plmysql_down_host(host); - msg_warn("%s", mysql_error(&(host->db))); } if (hostname) myfree(hostname); @@ -322,37 +329,11 @@ static void plmysql_connect_single(HOST *host, char *dbname, char *username, cha static void plmysql_down_host(HOST *host) { if (host->stat != STATFAIL) { - host->ts = time(&(host->ts)); + host->ts = time((time_t *) 0) + RETRY_CONN_INTV; host->stat = STATFAIL; } -} - -/* - * plmysql_ready_reconn - - * given a downed HOST, return whether or not it should retry connection - */ -static int plmysql_ready_reconn(HOST host) -{ - time_t t; - long now; - - now = (long) time(&t); - if (msg_verbose > 1) { - msg_info("dict_mysql: plmysql_ready_reconn(): now is %d", now); - msg_info("dict_mysql: plmysql_ready_reconn(): ts is %d", (long) host.ts); - msg_info("dict_mysql: plmysql_ready_reconn(): RETRY_CONN_INTV is %d", RETRY_CONN_INTV); - if ((now - ((long) host.ts)) >= RETRY_CONN_INTV) { - msg_info("dict_mysql: plymsql_ready_reconn(): returning TRUE"); - return 1; - } else { - msg_info("dict_mysql: plymsql_ready_reconn(): returning FALSE"); - return 0; - } - } else { - if ((now - ((long) host.ts)) >= RETRY_CONN_INTV) - return 1; - return 0; - } + mysql_close(host->db); + host->db = 0; } /********************************************************************** @@ -372,7 +353,6 @@ DICT *dict_mysql_open(const char *name, int unused_flags, int unused_dict_flag dict_mysql->dict.close = dict_mysql_close; dict_mysql->dict.fd = -1; /* there's no file descriptor * for locking */ - dict_mysql->name = (MYSQL_NAME *) mymalloc(sizeof(MYSQL_NAME)); dict_mysql->name = mysqlname_parse(name); dict_mysql->pldb = plmysql_init(dict_mysql->name->hostnames, dict_mysql->name->len_hosts); @@ -463,25 +443,23 @@ static MYSQL_NAME *mysqlname_parse(const char *mysqlcf_path) else hosts = mystrdup(nameval); /* coo argv interface */ - hosts_argv = argv_split(hosts, " "); - argv_terminate(hosts_argv); + hosts_argv = argv_split(hosts, " ,\t\r\n"); if (hosts_argv->argc == 0) { /* no hosts specified, * default to 'localhost' */ - msg_info("mysqlname_parse(): no hostnames specified, defaulting to 'localhost'"); - name->len_hosts = 1; - name->hostnames = (char **) mymalloc(sizeof(char *)); - name->hostnames[0] = mystrdup("localhost"); - } else { - name->len_hosts = hosts_argv->argc; - name->hostnames = (char **) mymalloc((sizeof(char *)) * name->len_hosts); - i = 0; - for (i = 0; hosts_argv->argv[i] != NULL; i++) { - name->hostnames[i] = mystrdup(hosts_argv->argv[i]); - if (msg_verbose) - msg_info("mysqlname_parse(): adding host '%s' to list of mysql server hosts", - name->hostnames[i]); - } + if (msg_verbose) + msg_info("mysqlname_parse(): no hostnames specified, defaulting to 'localhost'"); + argv_add(hosts_argv, "localhost", ARGV_END); + argv_terminate(hosts_argv); + } + name->len_hosts = hosts_argv->argc; + name->hostnames = (char **) mymalloc((sizeof(char *)) * name->len_hosts); + i = 0; + for (i = 0; hosts_argv->argv[i] != NULL; i++) { + name->hostnames[i] = mystrdup(hosts_argv->argv[i]); + if (msg_verbose) + msg_info("mysqlname_parse(): adding host '%s' to list of mysql server hosts", + name->hostnames[i]); } myfree(hosts); vstring_free(opt_dict_name); @@ -494,8 +472,7 @@ static MYSQL_NAME *mysqlname_parse(const char *mysqlcf_path) * 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) { PLMYSQL *PLDB; MYSQL *dbs; @@ -518,15 +495,12 @@ static PLMYSQL *plmysql_init(char *hostnames[], /* host_init - initialize HOST structure */ static HOST host_init(char *hostname) { - int stat; - MYSQL db; - time_t ts; HOST host; host.stat = STATUNTRIED; - host.hostname = hostname; - host.db = db; - host.ts = ts; + host.hostname = mystrdup(hostname); + host.db = 0; + host.ts = 0; return host; } @@ -550,6 +524,7 @@ static void dict_mysql_close(DICT *dict) for (i = 0; i < dict_mysql->name->len_hosts; i++) { myfree(dict_mysql->name->hostnames[i]); } + myfree((char *) dict_mysql->name->hostnames); myfree((char *) dict_mysql->name); } @@ -559,7 +534,8 @@ static void plmysql_dealloc(PLMYSQL *PLDB) int i; for (i = 0; i < PLDB->len_hosts; i++) { - mysql_close(&(PLDB->db_hosts[i].db)); + if (PLDB->db_hosts[i].db) + mysql_close(PLDB->db_hosts[i].db); myfree(PLDB->db_hosts[i].hostname); } myfree((char *) PLDB->db_hosts);