#include "lf_functions.h"
#include <mysql.h> /* The system header */
+#include <mysql_version.h>
/* Structure and anchor for caching connections. */
MYSQL_FIELD *fields;
int i;
-int ssize = 0;
-int offset = 0;
int yield = DEFER;
unsigned int num_fields;
-uschar *result = NULL;
+gstring * result = NULL;
mysql_connection *cn;
uschar *server_copy = NULL;
uschar *sdata[4];
/* See if we have a cached connection to the server */
-for (cn = mysql_connections; cn != NULL; cn = cn->next)
- {
+for (cn = mysql_connections; cn; cn = cn->next)
if (Ustrcmp(cn->server, server_copy) == 0)
{
mysql_handle = cn->handle;
break;
}
- }
/* If no cached connection, we must set one up. Mysql allows for a host name
and port to be specified. It also allows the name of a Unix socket to be used.
Unfortunately, this contains slashes, but its use is expected to be rare, so
the rather cumbersome syntax shouldn't inconvenience too many people. We use
-this: host:port(socket) where all the parts are optional. */
+this: host:port(socket)[group] where all the parts are optional.
+The "group" parameter specifies an option group from a MySQL option file. */
-if (cn == NULL)
+if (!cn)
{
uschar *p;
uschar *socket = NULL;
int port = 0;
+ uschar *group = US"exim";
- if ((p = Ustrchr(sdata[0], '(')) != NULL)
+ if ((p = Ustrchr(sdata[0], '[')))
+ {
+ *p++ = 0;
+ group = p;
+ while (*p && *p != ']') p++;
+ *p = 0;
+ }
+
+ if ((p = Ustrchr(sdata[0], '(')))
{
*p++ = 0;
socket = p;
- while (*p != 0 && *p != ')') p++;
+ while (*p && *p != ')') p++;
*p = 0;
}
- if ((p = Ustrchr(sdata[0], ':')) != NULL)
+ if ((p = Ustrchr(sdata[0], ':')))
{
*p++ = 0;
port = Uatoi(p);
}
- if (Ustrchr(sdata[0], '/') != NULL)
+ if (Ustrchr(sdata[0], '/'))
{
*errmsg = string_sprintf("unexpected slash in MySQL server hostname: %s",
sdata[0]);
mysql_handle = store_get(sizeof(MYSQL));
mysql_init(mysql_handle);
+ mysql_options(mysql_handle, MYSQL_READ_DEFAULT_GROUP, CS group);
if (mysql_real_connect(mysql_handle,
/* host user passwd database */
CS sdata[0], CS sdata[2], CS sdata[3], CS sdata[1],
if ( mysql_field_count(mysql_handle) == 0 )
{
DEBUG(D_lookup) debug_printf("MYSQL: query was not one that returns data\n");
- result = string_sprintf("%d", mysql_affected_rows(mysql_handle));
+ result = string_cat(result,
+ string_sprintf("%d", mysql_affected_rows(mysql_handle)));
*do_cache = 0;
goto MYSQL_EXIT;
}
fields = mysql_fetch_fields(mysql_result);
-while ((mysql_row_data = mysql_fetch_row(mysql_result)) != NULL)
+while ((mysql_row_data = mysql_fetch_row(mysql_result)))
{
unsigned long *lengths = mysql_fetch_lengths(mysql_result);
- if (result != NULL)
- result = string_cat(result, &ssize, &offset, US"\n", 1);
+ if (result)
+ result = string_catn(result, US"\n", 1);
if (num_fields == 1)
{
if (mysql_row_data[0] != NULL) /* NULL value yields nothing */
- result = string_cat(result, &ssize, &offset, US mysql_row_data[0],
+ {
+ result = string_catn(result, US mysql_row_data[0],
lengths[0]);
+ (void) string_from_gstring(result);
+ }
}
else for (i = 0; i < num_fields; i++)
- {
- result = lf_quote(US fields[i].name, US mysql_row_data[i], lengths[i],
- result, &ssize, &offset);
- }
+ result = lf_quote(US fields[i].name, US mysql_row_data[i], lengths[i], result);
}
/* more results? -1 = no, >0 = error, 0 = yes (keep looping)
Otherwise, we must terminate the string which has been built; string_cat()
always leaves enough room for a terminating zero. */
-if (result == NULL)
+if (!result)
{
yield = FAIL;
*errmsg = US"MYSQL: no data found";
}
else
{
- result[offset] = 0;
- store_reset(result + offset + 1);
+ (void) string_from_gstring(result);
+ store_reset(result->s + result->ptr + 1);
}
/* Get here by goto from various error checks and from the case where no data
/* Free mysal store for any result that was got; don't close the connection, as
it is cached. */
-if (mysql_result != NULL) mysql_free_result(mysql_result);
+if (mysql_result) mysql_free_result(mysql_result);
-/* Non-NULL result indicates a sucessful result */
+/* Non-NULL result indicates a successful result */
-if (result != NULL)
+if (result)
{
- *resultptr = result;
+ *resultptr = result->s;
return OK;
}
else