summaryrefslogtreecommitdiff
path: root/src/src/lookups
diff options
context:
space:
mode:
Diffstat (limited to 'src/src/lookups')
-rw-r--r--src/src/lookups/dnsdb.c64
-rw-r--r--src/src/lookups/ibase.c560
-rw-r--r--src/src/lookups/ldap.c54
-rw-r--r--src/src/lookups/lf_functions.h2
-rw-r--r--src/src/lookups/lf_quote.c23
-rw-r--r--src/src/lookups/lsearch.c20
-rw-r--r--src/src/lookups/mysql.c35
-rw-r--r--src/src/lookups/nisplus.c39
-rw-r--r--src/src/lookups/oracle.c63
-rw-r--r--src/src/lookups/pgsql.c70
-rw-r--r--src/src/lookups/redis.c45
-rw-r--r--src/src/lookups/sqlite.c31
12 files changed, 473 insertions, 533 deletions
diff --git a/src/src/lookups/dnsdb.c b/src/src/lookups/dnsdb.c
index bf3acd6ef..9e95b9038 100644
--- a/src/src/lookups/dnsdb.c
+++ b/src/src/lookups/dnsdb.c
@@ -14,17 +14,17 @@
header files. */
#ifndef T_TXT
-#define T_TXT 16
+# define T_TXT 16
#endif
/* Many systems do not have T_SPF. */
#ifndef T_SPF
-#define T_SPF 99
+# define T_SPF 99
#endif
/* New TLSA record for DANE */
#ifndef T_TLSA
-#define T_TLSA 52
+# define T_TLSA 52
#endif
/* Table of recognized DNS record types and their integer values. */
@@ -134,8 +134,6 @@ dnsdb_find(void *handle, uschar *filename, const uschar *keystring, int length,
uschar **result, uschar **errmsg, uint *do_cache)
{
int rc;
-int size = 256;
-int ptr = 0;
int sep = 0;
int defer_mode = PASS;
int dnssec_mode = OK;
@@ -147,10 +145,10 @@ const uschar *outsep = CUS"\n";
const uschar *outsep2 = NULL;
uschar *equals, *domain, *found;
-/* Because we're the working in the search pool, we try to reclaim as much
+/* Because we're working in the search pool, we try to reclaim as much
store as possible later, so we preallocate the result here */
-uschar *yield = store_get(size);
+gstring * yield = string_get(256);
dns_record *rr;
dns_answer dnsa;
@@ -380,12 +378,9 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0)))
/* Search the returned records */
- for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
- rr != NULL;
- rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
+ for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS); rr;
+ rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT)) if (rr->type == searchtype)
{
- if (rr->type != searchtype) continue;
-
if (*do_cache > rr->ttl)
*do_cache = rr->ttl;
@@ -394,8 +389,8 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0)))
dns_address *da;
for (da = dns_address_from_rr(&dnsa, rr); da; da = da->next)
{
- if (ptr != 0) yield = string_catn(yield, &size, &ptr, outsep, 1);
- yield = string_cat(yield, &size, &ptr, da->address);
+ if (yield->ptr) yield = string_catn(yield, outsep, 1);
+ yield = string_cat(yield, da->address);
}
continue;
}
@@ -403,16 +398,12 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0)))
/* Other kinds of record just have one piece of data each, but there may be
several of them, of course. */
- if (ptr != 0) yield = string_catn(yield, &size, &ptr, outsep, 1);
+ if (yield->ptr) yield = string_catn(yield, outsep, 1);
if (type == T_TXT || type == T_SPF)
{
- if (outsep2 == NULL)
- {
- /* output only the first item of data */
- yield = string_catn(yield, &size, &ptr, US (rr->data+1),
- (rr->data)[0]);
- }
+ if (outsep2 == NULL) /* output only the first item of data */
+ yield = string_catn(yield, US (rr->data+1), (rr->data)[0]);
else
{
/* output all items */
@@ -421,9 +412,8 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0)))
{
uschar chunk_len = (rr->data)[data_offset++];
if (outsep2[0] != '\0' && data_offset != 1)
- yield = string_catn(yield, &size, &ptr, outsep2, 1);
- yield = string_catn(yield, &size, &ptr,
- US ((rr->data)+data_offset), chunk_len);
+ yield = string_catn(yield, outsep2, 1);
+ yield = string_catn(yield, US ((rr->data)+data_offset), chunk_len);
data_offset += chunk_len;
}
}
@@ -449,7 +439,7 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0)))
i++)
sp += sprintf(CS sp, "%02x", (unsigned char)p[i]);
- yield = string_cat(yield, &size, &ptr, s);
+ yield = string_cat(yield, s);
}
else /* T_CNAME, T_CSA, T_MX, T_MXH, T_NS, T_PTR, T_SOA, T_SRV */
{
@@ -467,7 +457,7 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0)))
case T_MX:
GETSHORT(priority, p);
sprintf(CS s, "%d%c", priority, *outsep2);
- yield = string_cat(yield, &size, &ptr, s);
+ yield = string_cat(yield, s);
break;
case T_SRV:
@@ -476,7 +466,7 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0)))
GETSHORT(port, p);
sprintf(CS s, "%d%c%d%c%d%c", priority, *outsep2,
weight, *outsep2, port, *outsep2);
- yield = string_cat(yield, &size, &ptr, s);
+ yield = string_cat(yield, s);
break;
case T_CSA:
@@ -505,7 +495,7 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0)))
}
s[1] = ' ';
- yield = string_catn(yield, &size, &ptr, s, 2);
+ yield = string_catn(yield, s, 2);
break;
default:
@@ -526,14 +516,14 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0)))
"domain=%s", dns_text_type(type), domain);
break;
}
- else yield = string_cat(yield, &size, &ptr, s);
+ else yield = string_cat(yield, s);
if (type == T_SOA && outsep2 != NULL)
{
unsigned long serial, refresh, retry, expire, minimum;
p += rc;
- yield = string_catn(yield, &size, &ptr, outsep2, 1);
+ yield = string_catn(yield, outsep2, 1);
rc = dn_expand(dnsa.answer, dnsa.answer + dnsa.answerlen, p,
(DN_EXPAND_ARG4_TYPE)s, sizeof(s));
@@ -543,7 +533,7 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0)))
"domain=%s", dns_text_type(type), domain);
break;
}
- else yield = string_cat(yield, &size, &ptr, s);
+ else yield = string_cat(yield, s);
p += rc;
GETLONG(serial, p); GETLONG(refresh, p);
@@ -551,7 +541,7 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0)))
sprintf(CS s, "%c%lu%c%lu%c%lu%c%lu%c%lu",
*outsep2, serial, *outsep2, refresh,
*outsep2, retry, *outsep2, expire, *outsep2, minimum);
- yield = string_cat(yield, &size, &ptr, s);
+ yield = string_cat(yield, s);
}
}
} /* Loop for list of returned records */
@@ -563,18 +553,18 @@ while ((domain = string_nextinlist(&keystring, &sep, NULL, 0)))
/* Reclaim unused memory */
-store_reset(yield + ptr + 1);
+store_reset(yield->s + yield->ptr + 1);
-/* If ptr == 0 we have not found anything. Otherwise, insert the terminating
+/* If yield NULL we have not found anything. Otherwise, insert the terminating
zero and return the result. */
dns_retrans = save_retrans;
dns_retry = save_retry;
dns_init(FALSE, FALSE, FALSE); /* clear the dnssec bit for getaddrbyname */
-if (ptr == 0) return failrc;
-yield[ptr] = 0;
-*result = yield;
+if (!yield || !yield->ptr) return failrc;
+
+*result = string_from_gstring(yield);
return OK;
}
diff --git a/src/src/lookups/ibase.c b/src/src/lookups/ibase.c
index 7f1775c1f..58bced201 100644
--- a/src/src/lookups/ibase.c
+++ b/src/src/lookups/ibase.c
@@ -109,332 +109,334 @@ static int
perform_ibase_search(uschar * query, uschar * server, uschar ** resultptr,
uschar ** errmsg, BOOL * defer_break)
{
- isc_stmt_handle stmth = NULL;
- XSQLDA *out_sqlda;
- XSQLVAR *var;
-
- char buffer[256];
- ISC_STATUS status[20], *statusp = status;
-
- int i;
- int ssize = 0;
- int offset = 0;
- int yield = DEFER;
- uschar *result = NULL;
- ibase_connection *cn;
- uschar *server_copy = NULL;
- uschar *sdata[3];
+isc_stmt_handle stmth = NULL;
+XSQLDA *out_sqlda;
+XSQLVAR *var;
+
+char buffer[256];
+ISC_STATUS status[20], *statusp = status;
+
+gstring * result;
+int i;
+int yield = DEFER;
+ibase_connection *cn;
+uschar *server_copy = NULL;
+uschar *sdata[3];
/* Disaggregate the parameters from the server argument. The order is host,
database, user, password. We can write to the string, since it is in a
nextinlist temporary buffer. The copy of the string that is used for caching
has the password removed. This copy is also used for debugging output. */
- for (i = 2; i > 0; i--) {
- uschar *pp = Ustrrchr(server, '|');
- if (pp == NULL) {
- *errmsg =
- string_sprintf("incomplete Interbase server data: %s",
- (i == 3) ? server : server_copy);
- *defer_break = TRUE;
- return DEFER;
- }
- *pp++ = 0;
- sdata[i] = pp;
- if (i == 2)
- server_copy = string_copy(server); /* sans password */
+for (i = 2; i > 0; i--)
+ {
+ uschar *pp = Ustrrchr(server, '|');
+
+ if (pp == NULL)
+ {
+ *errmsg = string_sprintf("incomplete Interbase server data: %s",
+ (i == 3) ? server : server_copy);
+ *defer_break = TRUE;
+ return DEFER;
}
- sdata[0] = server; /* What's left at the start */
+ *pp++ = 0;
+ sdata[i] = pp;
+ if (i == 2)
+ server_copy = string_copy(server); /* sans password */
+ }
+sdata[0] = server; /* What's left at the start */
/* See if we have a cached connection to the server */
- for (cn = ibase_connections; cn != NULL; cn = cn->next) {
- if (Ustrcmp(cn->server, server_copy) == 0) {
- break;
- }
- }
+for (cn = ibase_connections; cn != NULL; cn = cn->next)
+ if (Ustrcmp(cn->server, server_copy) == 0)
+ break;
/* Use a previously cached connection ? */
- if (cn != NULL) {
- static char db_info_options[] = { isc_info_base_level };
-
- /* test if the connection is alive */
- if (isc_database_info
- (status, &cn->dbh, sizeof(db_info_options), db_info_options,
- sizeof(buffer), buffer)) {
- /* error occurred: assume connection is down */
- DEBUG(D_lookup)
- debug_printf
- ("Interbase cleaning up cached connection: %s\n",
- cn->server);
- isc_detach_database(status, &cn->dbh);
- } else {
- DEBUG(D_lookup)
- debug_printf("Interbase using cached connection for %s\n",
- server_copy);
- }
- } else {
- cn = store_get(sizeof(ibase_connection));
- cn->server = server_copy;
- cn->dbh = NULL;
- cn->transh = NULL;
- cn->next = ibase_connections;
- ibase_connections = cn;
+if (cn)
+ {
+ static char db_info_options[] = { isc_info_base_level };
+
+ /* test if the connection is alive */
+ if (isc_database_info(status, &cn->dbh, sizeof(db_info_options),
+ db_info_options, sizeof(buffer), buffer))
+ {
+ /* error occurred: assume connection is down */
+ DEBUG(D_lookup)
+ debug_printf
+ ("Interbase cleaning up cached connection: %s\n",
+ cn->server);
+ isc_detach_database(status, &cn->dbh);
}
+ else
+ {
+ DEBUG(D_lookup) debug_printf("Interbase using cached connection for %s\n",
+ server_copy);
+ }
+ }
+else
+ {
+ cn = store_get(sizeof(ibase_connection));
+ cn->server = server_copy;
+ cn->dbh = NULL;
+ cn->transh = NULL;
+ cn->next = ibase_connections;
+ ibase_connections = cn;
+ }
/* If no cached connection, we must set one up. */
- if (cn->dbh == NULL || cn->transh == NULL) {
-
- char *dpb, *p;
- short dpb_length;
- static char trans_options[] =
- { isc_tpb_version3, isc_tpb_read, isc_tpb_read_committed,
- isc_tpb_rec_version
- };
-
- /* Construct the database parameter buffer. */
- dpb = buffer;
- *dpb++ = isc_dpb_version1;
- *dpb++ = isc_dpb_user_name;
- *dpb++ = strlen(sdata[1]);
- for (p = sdata[1]; *p;)
- *dpb++ = *p++;
- *dpb++ = isc_dpb_password;
- *dpb++ = strlen(sdata[2]);
- for (p = sdata[2]; *p;)
- *dpb++ = *p++;
- dpb_length = dpb - buffer;
-
- DEBUG(D_lookup)
- debug_printf("new Interbase connection: database=%s user=%s\n",
- sdata[0], sdata[1]);
-
- /* Connect to the database */
- if (isc_attach_database
- (status, 0, sdata[0], &cn->dbh, dpb_length, buffer)) {
- isc_interprete(buffer, &statusp);
- *errmsg =
- string_sprintf("Interbase attach() failed: %s", buffer);
- *defer_break = FALSE;
- goto IBASE_EXIT;
- }
-
- /* Now start a read-only read-committed transaction */
- if (isc_start_transaction
- (status, &cn->transh, 1, &cn->dbh, sizeof(trans_options),
- trans_options)) {
- isc_interprete(buffer, &statusp);
- isc_detach_database(status, &cn->dbh);
- *errmsg =
- string_sprintf("Interbase start_transaction() failed: %s",
- buffer);
- *defer_break = FALSE;
- goto IBASE_EXIT;
- }
+if (cn->dbh == NULL || cn->transh == NULL)
+ {
+ char *dpb, *p;
+ short dpb_length;
+ static char trans_options[] =
+ { isc_tpb_version3, isc_tpb_read, isc_tpb_read_committed,
+ isc_tpb_rec_version
+ };
+
+ /* Construct the database parameter buffer. */
+ dpb = buffer;
+ *dpb++ = isc_dpb_version1;
+ *dpb++ = isc_dpb_user_name;
+ *dpb++ = strlen(sdata[1]);
+ for (p = sdata[1]; *p;)
+ *dpb++ = *p++;
+ *dpb++ = isc_dpb_password;
+ *dpb++ = strlen(sdata[2]);
+ for (p = sdata[2]; *p;)
+ *dpb++ = *p++;
+ dpb_length = dpb - buffer;
+
+ DEBUG(D_lookup)
+ debug_printf("new Interbase connection: database=%s user=%s\n",
+ sdata[0], sdata[1]);
+
+ /* Connect to the database */
+ if (isc_attach_database
+ (status, 0, sdata[0], &cn->dbh, dpb_length, buffer))
+ {
+ isc_interprete(buffer, &statusp);
+ *errmsg =
+ string_sprintf("Interbase attach() failed: %s", buffer);
+ *defer_break = FALSE;
+ goto IBASE_EXIT;
}
-/* Run the query */
- if (isc_dsql_allocate_statement(status, &cn->dbh, &stmth)) {
- isc_interprete(buffer, &statusp);
- *errmsg =
- string_sprintf("Interbase alloc_statement() failed: %s",
- buffer);
- *defer_break = FALSE;
- goto IBASE_EXIT;
+ /* Now start a read-only read-committed transaction */
+ if (isc_start_transaction
+ (status, &cn->transh, 1, &cn->dbh, sizeof(trans_options),
+ trans_options))
+ {
+ isc_interprete(buffer, &statusp);
+ isc_detach_database(status, &cn->dbh);
+ *errmsg =
+ string_sprintf("Interbase start_transaction() failed: %s",
+ buffer);
+ *defer_break = FALSE;
+ goto IBASE_EXIT;
}
+ }
- out_sqlda = store_get(XSQLDA_LENGTH(1));
- out_sqlda->version = SQLDA_VERSION1;
- out_sqlda->sqln = 1;
-
- if (isc_dsql_prepare
- (status, &cn->transh, &stmth, 0, query, 1, out_sqlda)) {
- isc_interprete(buffer, &statusp);
- store_reset(out_sqlda);
- out_sqlda = NULL;
- *errmsg =
- string_sprintf("Interbase prepare_statement() failed: %s",
- buffer);
- *defer_break = FALSE;
- goto IBASE_EXIT;
- }
+/* Run the query */
+if (isc_dsql_allocate_statement(status, &cn->dbh, &stmth))
+ {
+ isc_interprete(buffer, &statusp);
+ *errmsg =
+ string_sprintf("Interbase alloc_statement() failed: %s",
+ buffer);
+ *defer_break = FALSE;
+ goto IBASE_EXIT;
+ }
+
+out_sqlda = store_get(XSQLDA_LENGTH(1));
+out_sqlda->version = SQLDA_VERSION1;
+out_sqlda->sqln = 1;
+
+if (isc_dsql_prepare
+ (status, &cn->transh, &stmth, 0, query, 1, out_sqlda))
+ {
+ isc_interprete(buffer, &statusp);
+ store_reset(out_sqlda);
+ out_sqlda = NULL;
+ *errmsg =
+ string_sprintf("Interbase prepare_statement() failed: %s",
+ buffer);
+ *defer_break = FALSE;
+ goto IBASE_EXIT;
+ }
/* re-allocate the output structure if there's more than one field */
- if (out_sqlda->sqln < out_sqlda->sqld) {
- XSQLDA *new_sqlda = store_get(XSQLDA_LENGTH(out_sqlda->sqld));
- if (isc_dsql_describe
- (status, &stmth, out_sqlda->version, new_sqlda)) {
- isc_interprete(buffer, &statusp);
- isc_dsql_free_statement(status, &stmth, DSQL_drop);
- store_reset(out_sqlda);
- out_sqlda = NULL;
- *errmsg =
- string_sprintf("Interbase describe_statement() failed: %s",
- buffer);
- *defer_break = FALSE;
- goto IBASE_EXIT;
- }
- out_sqlda = new_sqlda;
+if (out_sqlda->sqln < out_sqlda->sqld)
+ {
+ XSQLDA *new_sqlda = store_get(XSQLDA_LENGTH(out_sqlda->sqld));
+ if (isc_dsql_describe
+ (status, &stmth, out_sqlda->version, new_sqlda))
+ {
+ isc_interprete(buffer, &statusp);
+ isc_dsql_free_statement(status, &stmth, DSQL_drop);
+ store_reset(out_sqlda);
+ out_sqlda = NULL;
+ *errmsg = string_sprintf("Interbase describe_statement() failed: %s",
+ buffer);
+ *defer_break = FALSE;
+ goto IBASE_EXIT;
}
+ out_sqlda = new_sqlda;
+ }
/* allocate storage for every returned field */
- for (i = 0, var = out_sqlda->sqlvar; i < out_sqlda->sqld; i++, var++) {
- switch (var->sqltype & ~1) {
- case SQL_VARYING:
- var->sqldata =
- (char *) store_get(sizeof(char) * var->sqllen + 2);
- break;
- case SQL_TEXT:
- var->sqldata =
- (char *) store_get(sizeof(char) * var->sqllen);
- break;
- case SQL_SHORT:
- var->sqldata = CS store_get(sizeof(short));
- break;
- case SQL_LONG:
- var->sqldata = CS store_get(sizeof(ISC_LONG));
- break;
+for (i = 0, var = out_sqlda->sqlvar; i < out_sqlda->sqld; i++, var++)
+ {
+ switch (var->sqltype & ~1)
+ {
+ case SQL_VARYING:
+ var->sqldata = CS store_get(sizeof(char) * var->sqllen + 2);
+ break;
+ case SQL_TEXT:
+ var->sqldata = CS store_get(sizeof(char) * var->sqllen);
+ break;
+ case SQL_SHORT:
+ var->sqldata = CS store_get(sizeof(short));
+ break;
+ case SQL_LONG:
+ var->sqldata = CS store_get(sizeof(ISC_LONG));
+ break;
#ifdef SQL_INT64
- case SQL_INT64:
- var->sqldata = CS store_get(sizeof(ISC_INT64));
- break;
+ case SQL_INT64:
+ var->sqldata = CS store_get(sizeof(ISC_INT64));
+ break;
#endif
- case SQL_FLOAT:
- var->sqldata = CS store_get(sizeof(float));
- break;
- case SQL_DOUBLE:
- var->sqldata = CS store_get(sizeof(double));
- break;
+ case SQL_FLOAT:
+ var->sqldata = CS store_get(sizeof(float));
+ break;
+ case SQL_DOUBLE:
+ var->sqldata = CS store_get(sizeof(double));
+ break;
#ifdef SQL_TIMESTAMP
- case SQL_DATE:
- var->sqldata = CS store_get(sizeof(ISC_QUAD));
- break;
+ case SQL_DATE:
+ var->sqldata = CS store_get(sizeof(ISC_QUAD));
+ break;
#else
- case SQL_TIMESTAMP:
- var->sqldata = CS store_get(sizeof(ISC_TIMESTAMP));
- break;
- case SQL_TYPE_DATE:
- var->sqldata = CS store_get(sizeof(ISC_DATE));
- break;
- case SQL_TYPE_TIME:
- var->sqldata = CS store_get(sizeof(ISC_TIME));
- break;
-#endif
- }
- if (var->sqltype & 1) {
- var->sqlind = (short *) store_get(sizeof(short));
- }
+ case SQL_TIMESTAMP:
+ var->sqldata = CS store_get(sizeof(ISC_TIMESTAMP));
+ break;
+ case SQL_TYPE_DATE:
+ var->sqldata = CS store_get(sizeof(ISC_DATE));
+ break;
+ case SQL_TYPE_TIME:
+ var->sqldata = CS store_get(sizeof(ISC_TIME));
+ break;
+ #endif
}
-
- /* finally, we're ready to execute the statement */
- if (isc_dsql_execute
- (status, &cn->transh, &stmth, out_sqlda->version, NULL)) {
- isc_interprete(buffer, &statusp);
- *errmsg =
- string_sprintf("Interbase describe_statement() failed: %s",
- buffer);
- isc_dsql_free_statement(status, &stmth, DSQL_drop);
- *defer_break = FALSE;
- goto IBASE_EXIT;
+ if (var->sqltype & 1)
+ var->sqlind = (short *) store_get(sizeof(short));
+ }
+
+/* finally, we're ready to execute the statement */
+if (isc_dsql_execute
+ (status, &cn->transh, &stmth, out_sqlda->version, NULL))
+ {
+ isc_interprete(buffer, &statusp);
+ *errmsg = string_sprintf("Interbase describe_statement() failed: %s",
+ buffer);
+ isc_dsql_free_statement(status, &stmth, DSQL_drop);
+ *defer_break = FALSE;
+ goto IBASE_EXIT;
+ }
+
+while (isc_dsql_fetch(status, &stmth, out_sqlda->version, out_sqlda) != 100L)
+ {
+ /* check if an error occurred */
+ if (status[0] & status[1])
+ {
+ isc_interprete(buffer, &statusp);
+ *errmsg =
+ string_sprintf("Interbase fetch() failed: %s", buffer);
+ isc_dsql_free_statement(status, &stmth, DSQL_drop);
+ *defer_break = FALSE;
+ goto IBASE_EXIT;
}
- while (isc_dsql_fetch(status, &stmth, out_sqlda->version, out_sqlda) !=
- 100L) {
- /* check if an error occurred */
- if (status[0] & status[1]) {
- isc_interprete(buffer, &statusp);
- *errmsg =
- string_sprintf("Interbase fetch() failed: %s", buffer);
- isc_dsql_free_statement(status, &stmth, DSQL_drop);
- *defer_break = FALSE;
- goto IBASE_EXIT;
- }
-
- if (result != NULL)
- result = string_catn(result, &ssize, &offset, US "\n", 1);
-
- /* Find the number of fields returned. If this is one, we don't add field
- names to the data. Otherwise we do. */
- if (out_sqlda->sqld == 1) {
- if (out_sqlda->sqlvar[0].sqlind == NULL || *out_sqlda->sqlvar[0].sqlind != -1) /* NULL value yields nothing */
- result =
- string_catn(result, &ssize, &offset, US buffer,
- fetch_field(buffer, sizeof(buffer),
- &out_sqlda->sqlvar[0]));
- }
-
- else
- for (i = 0; i < out_sqlda->sqld; i++) {
- int len = fetch_field(buffer, sizeof(buffer),
- &out_sqlda->sqlvar[i]);
-
- result =
- string_cat(result, &ssize, &offset,
- US out_sqlda->sqlvar[i].aliasname,
- out_sqlda->sqlvar[i].aliasname_length);
- result = string_catn(result, &ssize, &offset, US "=", 1);
-
- /* Quote the value if it contains spaces or is empty */
-
- if (*out_sqlda->sqlvar[i].sqlind == -1) { /* NULL value */
- result =
- string_catn(result, &ssize, &offset, US "\"\"", 2);
- }
-
- else if (buffer[0] == 0 || Ustrchr(buffer, ' ') != NULL) {
- int j;
- result =
- string_catn(result, &ssize, &offset, US "\"", 1);
- for (j = 0; j < len; j++) {
- if (buffer[j] == '\"' || buffer[j] == '\\')
- result =
- string_cat(result, &ssize, &offset,
- US "\\", 1);
- result =
- string_cat(result, &ssize, &offset,
- US buffer + j, 1);
- }
- result =
- string_catn(result, &ssize, &offset, US "\"", 1);
- } else {
- result =
- string_catn(result, &ssize, &offset, US buffer, len);
- }
- result = string_catn(result, &ssize, &offset, US " ", 1);
- }
+ if (result)
+ result = string_catn(result, US "\n", 1);
+
+ /* Find the number of fields returned. If this is one, we don't add field
+ names to the data. Otherwise we do. */
+ if (out_sqlda->sqld == 1)
+ {
+ if (out_sqlda->sqlvar[0].sqlind == NULL || *out_sqlda->sqlvar[0].sqlind != -1) /* NULL value yields nothing */
+ result = string_catn(result, US buffer,
+ fetch_field(buffer, sizeof(buffer),
+ &out_sqlda->sqlvar[0]));
}
+ else
+ for (i = 0; i < out_sqlda->sqld; i++)
+ {
+ int len = fetch_field(buffer, sizeof(buffer), &out_sqlda->sqlvar[i]);
+
+ result = string_catn(result, US out_sqlda->sqlvar[i].aliasname,
+ out_sqlda->sqlvar[i].aliasname_length);
+ result = string_catn(result, US "=", 1);
+
+ /* Quote the value if it contains spaces or is empty */
+
+ if (*out_sqlda->sqlvar[i].sqlind == -1) /* NULL value */
+ result = string_catn(result, US "\"\"", 2);
+
+ else if (buffer[0] == 0 || Ustrchr(buffer, ' ') != NULL)
+ {
+ int j;
+
+ result = string_catn(result, US "\"", 1);
+ for (j = 0; j < len; j++)
+ {
+ if (buffer[j] == '\"' || buffer[j] == '\\')
+ result = string_cat(result, US "\\", 1);
+ result = string_cat(result, US buffer + j, 1);
+ }
+ result = string_catn(result, US "\"", 1);
+ }
+ else
+ result = string_catn(result, US buffer, len);
+ result = string_catn(result, US " ", 1);
+ }
+ }
+
/* If result is NULL then no data has been found and so we return FAIL.
Otherwise, we must terminate the string which has been built; string_cat()
always leaves enough room for a terminating zero. */
- if (result == NULL) {
- yield = FAIL;
- *errmsg = US "Interbase: no data found";
- } else {
- result[offset] = 0;
- store_reset(result + offset + 1);
- }
+if (!result)
+ {
+ yield = FAIL;
+ *errmsg = US "Interbase: no data found";
+ }
+else
+ store_reset(result->s + result->ptr + 1);
/* Get here by goto from various error checks. */
- IBASE_EXIT:
+IBASE_EXIT:
- if (stmth != NULL)
- isc_dsql_free_statement(status, &stmth, DSQL_drop);
+if (stmth)
+ isc_dsql_free_statement(status, &stmth, DSQL_drop);
/* Non-NULL result indicates a successful result */
- if (result != NULL) {
- *resultptr = result;
- return OK;
- } else {
- DEBUG(D_lookup) debug_printf("%s\n", *errmsg);
- return yield; /* FAIL or DEFER */
- }
+if (result)
+ {
+ *resultptr = string_from_gstring(result);
+ return OK;
+ }
+else
+ {
+ DEBUG(D_lookup) debug_printf("%s\n", *errmsg);
+ return yield; /* FAIL or DEFER */
+ }
}
diff --git a/src/src/lookups/ldap.c b/src/src/lookups/ldap.c
index b52ef2221..8d6ac2674 100644
--- a/src/src/lookups/ldap.c
+++ b/src/src/lookups/ldap.c
@@ -145,7 +145,7 @@ struct timeval *timeoutptr = NULL;
uschar *attr;
uschar **attrp;
-uschar *data = NULL;
+gstring * data = NULL;
uschar *dn = NULL;
uschar *host;
uschar **values;
@@ -161,9 +161,7 @@ int error_yield = DEFER;
int msgid;
int rc, ldap_rc, ldap_parse_rc;
int port;
-int ptr = 0;
int rescount = 0;
-int size = 0;
BOOL attribute_found = FALSE;
BOOL ldapi = FALSE;
@@ -722,7 +720,7 @@ while ((rc = ldap_result(lcp->ld, msgid, 0, timeoutptr, &result)) ==
DEBUG(D_lookup) debug_printf("LDAP result loop\n");
for(e = ldap_first_entry(lcp->ld, result), valuecount = 0;
- e != NULL;
+ e;
e = ldap_next_entry(lcp->ld, e))
{
uschar *new_dn;
@@ -734,7 +732,7 @@ while ((rc = ldap_result(lcp->ld, msgid, 0, timeoutptr, &result)) ==
/* Results for multiple entries values are separated by newlines. */
- if (data != NULL) data = string_catn(data, &size, &ptr, US"\n", 1);
+ if (data) data = string_catn(data, US"\n", 1);
/* Get the DN from the last result. */
@@ -762,8 +760,8 @@ while ((rc = ldap_result(lcp->ld, msgid, 0, timeoutptr, &result)) ==
{ /* condition, because of the else */
if (new_dn != NULL) /* below, that's for the first only */
{
- data = string_cat(data, &size, &ptr, new_dn);
- data[ptr] = 0;
+ data = string_cat(data, new_dn);
+ (void) string_from_gstring(data);
attribute_found = TRUE;
}
}
@@ -776,8 +774,7 @@ while ((rc = ldap_result(lcp->ld, msgid, 0, timeoutptr, &result)) ==
If there are multiple values, they are given within the quotes, comma separated. */
else for (attr = US ldap_first_attribute(lcp->ld, e, &ber);
- attr != NULL;
- attr = US ldap_next_attribute(lcp->ld, e, ber))
+ attr; attr = US ldap_next_attribute(lcp->ld, e, ber))
{
DEBUG(D_lookup) debug_printf("LDAP attr loop\n");
@@ -789,21 +786,20 @@ while ((rc = ldap_result(lcp->ld, msgid, 0, timeoutptr, &result)) ==
{
/* Get array of values for this attribute. */
- if ((firstval = values = USS ldap_get_values(lcp->ld, e, CS attr))
- != NULL)
+ if ((firstval = values = USS ldap_get_values(lcp->ld, e, CS attr)))
{
if (attrs_requested != 1)
{
if (insert_space)
- data = string_catn(data, &size, &ptr, US" ", 1);
+ data = string_catn(data, US" ", 1);
else
insert_space = TRUE;
- data = string_cat(data, &size, &ptr, attr);
- data = string_catn(data, &size, &ptr, US"=\"", 2);
+ data = string_cat(data, attr);
+ data = string_catn(data, US"=\"", 2);
}
- while (*values != NULL)
+ while (*values)
{
uschar *value = *values;
int len = Ustrlen(value);
@@ -818,7 +814,7 @@ while ((rc = ldap_result(lcp->ld, msgid, 0, timeoutptr, &result)) ==
attribute and append only every non first value. */
if (data && valuecount > 1)
- data = string_catn(data, &size, &ptr, US",", 1);
+ data = string_catn(data, US",", 1);
/* For multiple attributes, the data is in quotes. We must escape
internal quotes, backslashes, newlines, and must double commas. */
@@ -829,14 +825,14 @@ while ((rc = ldap_result(lcp->ld, msgid, 0, timeoutptr, &result)) ==
for (j = 0; j < len; j++)
{
if (value[j] == '\n')
- data = string_catn(data, &size, &ptr, US"\\n", 2);
+ data = string_catn(data, US"\\n", 2);
else if (value[j] == ',')
- data = string_catn(data, &size, &ptr, US",,", 2);
+ data = string_catn(data, US",,", 2);
else
{
if (value[j] == '\"' || value[j] == '\\')
- data = string_catn(data, &size, &ptr, US"\\", 1);
- data = string_catn(data, &size, &ptr, value+j, 1);
+ data = string_catn(data, US"\\", 1);
+ data = string_catn(data, value+j, 1);
}
}
}
@@ -848,9 +844,9 @@ while ((rc = ldap_result(lcp->ld, msgid, 0, timeoutptr, &result)) ==
int j;
for (j = 0; j < len; j++)
if (value[j] == ',')
- data = string_catn(data, &size, &ptr, US",,", 2);
+ data = string_catn(data, US",,", 2);
else
- data = string_catn(data, &size, &ptr, value+j, 1);
+ data = string_catn(data, value+j, 1);
}
@@ -863,7 +859,7 @@ while ((rc = ldap_result(lcp->ld, msgid, 0, timeoutptr, &result)) ==
/* Closing quote at the end of the data for a named attribute. */
if (attrs_requested != 1)
- data = string_catn(data, &size, &ptr, US"\"", 1);
+ data = string_catn(data, US"\"", 1);
/* Free the values */
@@ -890,15 +886,15 @@ while ((rc = ldap_result(lcp->ld, msgid, 0, timeoutptr, &result)) ==
/* Terminate the dynamic string that we have built and reclaim unused store */
-if (data != NULL)
+if (data)
{
- data[ptr] = 0;
- store_reset(data + ptr + 1);
+ (void) string_from_gstring(data);
+ store_reset(data->s + data->ptr + 1);
}
/* Copy the last dn into eldap_dn */
-if (dn != NULL)
+if (dn)
{
eldap_dn = string_copy(dn);
#if defined LDAP_LIB_NETSCAPE || defined LDAP_LIB_OPENLDAP2
@@ -1077,8 +1073,8 @@ if (!attribute_found)
/* Otherwise, it's all worked */
-DEBUG(D_lookup) debug_printf("LDAP search: returning: %s\n", data);
-*res = data;
+DEBUG(D_lookup) debug_printf("LDAP search: returning: %s\n", data->s);
+*res = data->s;
RETURN_OK:
if (result != NULL) ldap_msgfree(result);
diff --git a/src/src/lookups/lf_functions.h b/src/src/lookups/lf_functions.h
index d2487d362..210aae4d5 100644
--- a/src/src/lookups/lf_functions.h
+++ b/src/src/lookups/lf_functions.h
@@ -9,7 +9,7 @@
extern int lf_check_file(int, uschar *, int, int, uid_t *, gid_t *,
const char *, uschar **);
-extern uschar *lf_quote(uschar *, uschar *, int, uschar *, int *, int *);
+extern gstring *lf_quote(uschar *, uschar *, int, gstring *);
extern int lf_sqlperform(const uschar *, const uschar *, const uschar *,
const uschar *, uschar **,
uschar **, uint *, int(*)(const uschar *, uschar *, uschar **,
diff --git a/src/src/lookups/lf_quote.c b/src/src/lookups/lf_quote.c
index 2a76756e9..1541d0d16 100644
--- a/src/src/lookups/lf_quote.c
+++ b/src/src/lookups/lf_quote.c
@@ -22,18 +22,15 @@ Arguments:
name the field name
value the data value
vlength the data length
- result the result pointer
- asize points to the size variable
- aoffset points to the offset variable
+ result the result expanding-string
Returns: the result pointer (possibly updated)
*/
-uschar *
-lf_quote(uschar *name, uschar *value, int vlength, uschar *result, int *asize,
- int *aoffset)
+gstring *
+lf_quote(uschar *name, uschar *value, int vlength, gstring * result)
{
-result = string_append(result, asize, aoffset, 2, name, US"=");
+result = string_append(result, 2, name, US"=");
/* NULL is handled as an empty string */
@@ -49,19 +46,19 @@ character. */
if (value[0] == 0 || Ustrpbrk(value, " \t\n\r") != NULL || value[0] == '\"')
{
int j;
- result = string_catn(result, asize, aoffset, US"\"", 1);
+ result = string_catn(result, US"\"", 1);
for (j = 0; j < vlength; j++)
{
if (value[j] == '\"' || value[j] == '\\')
- result = string_catn(result, asize, aoffset, US"\\", 1);
- result = string_catn(result, asize, aoffset, US value+j, 1);
+ result = string_catn(result, US"\\", 1);
+ result = string_catn(result, US value+j, 1);
}
- result = string_catn(result, asize, aoffset, US"\"", 1);
+ result = string_catn(result, US"\"", 1);
}
else
- result = string_catn(result, asize, aoffset, US value, vlength);
+ result = string_catn(result, US value, vlength);
-return string_catn(result, asize, aoffset, US" ", 1);
+return string_catn(result, US" ", 1);
}
/* End of lf_quote.c */
diff --git a/src/src/lookups/lsearch.c b/src/src/lookups/lsearch.c
index 6101d00ac..745856d02 100644
--- a/src/src/lookups/lsearch.c
+++ b/src/src/lookups/lsearch.c
@@ -101,11 +101,10 @@ for (last_was_eol = TRUE;
Ufgets(buffer, sizeof(buffer), f) != NULL;
last_was_eol = this_is_eol)
{
- int ptr, size;
int p = Ustrlen(buffer);
int linekeylength;
BOOL this_is_comment;
- uschar *yield;
+ gstring * yield;
uschar *s = buffer;
/* Check whether this the final segment of a line. If it follows an
@@ -240,7 +239,7 @@ for (last_was_eol = TRUE;
/* Reset dynamic store, if we need to, and revert to the search pool */
- if (reset_point != NULL)
+ if (reset_point)
{
store_reset(reset_point);
store_pool = old_pool;
@@ -254,11 +253,9 @@ for (last_was_eol = TRUE;
Initialize, and copy the first segment of data. */
this_is_comment = FALSE;
- size = 100;
- ptr = 0;
- yield = store_get(size);
+ yield = string_get(100);
if (*s != 0)
- yield = string_cat(yield, &size, &ptr, s);
+ yield = string_cat(yield, s);
/* Now handle continuations */
@@ -294,18 +291,17 @@ for (last_was_eol = TRUE;
/* Join a physical or logical line continuation onto the result string. */
- yield = string_cat(yield, &size, &ptr, s);
+ yield = string_cat(yield, s);
}
- yield[ptr] = 0;
- store_reset(yield + ptr + 1);
- *result = yield;
+ store_reset(yield->s + yield->ptr + 1);
+ *result = string_from_gstring(yield);
return OK;
}
/* Reset dynamic store, if we need to */
-if (reset_point != NULL)
+if (reset_point)
{
store_reset(reset_point);
store_pool = old_pool;
diff --git a/src/src/lookups/mysql.c b/src/src/lookups/mysql.c
index b5133bc00..0d3d92aa8 100644
--- a/src/src/lookups/mysql.c
+++ b/src/src/lookups/mysql.c
@@ -140,11 +140,9 @@ MYSQL_ROW mysql_row_data;
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];
@@ -288,7 +286,8 @@ if ((mysql_result = mysql_use_result(mysql_handle)) == NULL)
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;
}
@@ -308,25 +307,25 @@ row, we insert '\n' between them. */
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_catn(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_catn(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)
@@ -348,15 +347,15 @@ while((i = mysql_next_result(mysql_handle)) >= 0) {
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
@@ -367,13 +366,13 @@ MYSQL_EXIT:
/* 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 successful result */
-if (result != NULL)
+if (result)
{
- *resultptr = result;
+ *resultptr = result->s;
return OK;
}
else
diff --git a/src/src/lookups/nisplus.c b/src/src/lookups/nisplus.c
index ff632a1ca..03c343103 100644
--- a/src/src/lookups/nisplus.c
+++ b/src/src/lookups/nisplus.c
@@ -46,8 +46,6 @@ nisplus_find(void *handle, uschar *filename, uschar *query, int length,
uschar **result, uschar **errmsg, uint *do_cache)
{
int i;
-int ssize = 0;
-int offset = 0;
int error_error = FAIL;
uschar *field_name = NULL;
nis_result *nrt = NULL;
@@ -57,6 +55,7 @@ struct entry_obj *eo;
struct table_obj *ta;
uschar *p = query + length;
uschar *yield = NULL;
+gstring * yield = NULL;
do_cache = do_cache; /* Placate picky compilers */
@@ -156,33 +155,34 @@ for (i = 0; i < eo->en_cols.en_cols_len; i++)
if (field_name == NULL)
{
- yield = string_cat(yield, &ssize, &offset,US tc->tc_name);
- yield = string_catn(yield, &ssize, &offset, US"=", 1);
+ yield = string_cat (yield, tc->tc_name);
+ yield = string_catn(yield, US"=", 1);
/* Quote the value if it contains spaces or is empty */
if (value[0] == 0 || Ustrchr(value, ' ') != NULL)
{
int j;
- yield = string_catn(yield, &ssize, &offset, US"\"", 1);
+ yield = string_catn(yield, US"\"", 1);
for (j = 0; j < len; j++)
{
if (value[j] == '\"' || value[j] == '\\')
- yield = string_catn(yield, &ssize, &offset, US"\\", 1);
- yield = string_catn(yield, &ssize, &offset, value+j, 1);
+ yield = string_catn(yield, US"\\", 1);
+ yield = string_catn(yield, value+j, 1);
}
- yield = string_catn(yield, &ssize, &offset, US"\"", 1);
+ yield = string_catn(yield, US"\"", 1);
}
- else yield = string_catn(yield, &ssize, &offset, value, len);
+ else
+ eyield = string_catn(yield, value, len);
- yield = string_catn(yield, &ssize, &offset, US" ", 1);
+ yield = string_catn(yield, US" ", 1);
}
/* When the specified field is found, grab its data and finish */
else if (Ustrcmp(field_name, tc->tc_name) == 0)
{
- yield = string_copyn(value, len);
+ yield = string_catn(yield, value, len);
goto NISPLUS_EXIT;
}
}
@@ -190,26 +190,23 @@ for (i = 0; i < eo->en_cols.en_cols_len; i++)
/* Error if a field name was specified and we didn't find it; if no
field name, ensure the concatenated data is zero-terminated. */
-if (field_name != NULL)
+if (field_name)
*errmsg = string_sprintf("NIS+ field %s not found for %s", field_name,
query);
else
- {
- yield[offset] = 0;
- store_reset(yield + offset + 1);
- }
+ store_reset(yield->s + yield->ptr + 1);
/* Restore the colon in the query, and free result store before
finishing. */
NISPLUS_EXIT:
-if (field_name != NULL) field_name[-1] = ':';
-if (nrt != NULL) nis_freeresult(nrt);
-if (nre != NULL) nis_freeresult(nre);
+if (field_name) field_name[-1] = ':';
+if (nrt) nis_freeresult(nrt);
+if (nre) nis_freeresult(nre);
-if (yield != NULL)
+if (yield)
{
- *result = yield;
+ *result = string_from_gstring(yield);
return OK;
}
diff --git a/src/src/lookups/oracle.c b/src/src/lookups/oracle.c
index eca15f1b4..bc14def70 100644
--- a/src/src/lookups/oracle.c
+++ b/src/src/lookups/oracle.c
@@ -255,15 +255,12 @@ Ora_Define *def = NULL;
void *hda = NULL;
int i;
-int ssize = 0;
-int offset = 0;
int yield = DEFER;
unsigned int num_fields = 0;
-uschar *result = NULL;
+gstring * result = NULL;
oracle_connection *cn = NULL;
uschar *server_copy = NULL;
uschar *sdata[4];
-uschar tmp[1024];
/* Disaggregate the parameters from the server argument. The order is host,
database, user, password. We can write to the string, since it is in a
@@ -292,19 +289,17 @@ if (sdata[1][0] == 0) sdata[1] = NULL;
/* See if we have a cached connection to the server */
-for (cn = oracle_connections; cn != NULL; cn = cn->next)
- {
+for (cn = oracle_connections; cn; cn = cn->next)
if (strcmp(cn->server, server_copy) == 0)
{
oracle_handle = cn->handle;
hda = cn->hda_mem;
break;
}
- }
/* If no cached connection, we must set one up */
-if (cn == NULL)
+if (!cn)
{
DEBUG(D_lookup) debug_printf("ORACLE new connection: host=%s database=%s "
"user=%s\n", sdata[0], sdata[1], sdata[2]);
@@ -400,12 +395,12 @@ while (cda->rc != NO_DATA_FOUND) /* Loop for each row */
ofetch(cda);
if(cda->rc == NO_DATA_FOUND) break;
- if (result) result = string_catn(result, &ssize, &offset, "\n", 1);
+ if (result) result = string_catn(result, "\n", 1);
/* Single field - just add on the data */
if (num_fields == 1)
- result = string_catn(result, &ssize, &offset, def[0].buf, def[0].col_retlen);
+ result = string_catn(result, def[0].buf, def[0].col_retlen);
/* Multiple fields - precede by file name, removing {lead,trail}ing WS */
@@ -417,8 +412,8 @@ while (cda->rc != NO_DATA_FOUND) /* Loop for each row */
while (*s != 0 && isspace(*s)) s++;
slen = Ustrlen(s);
while (slen > 0 && isspace(s[slen-1])) slen--;
- result = string_catn(result, &ssize, &offset, s, slen);
- result = string_catn(result, &ssize, &offset, US"=", 1);
+ result = string_catn(result, s, slen);
+ result = string_catn(result, US"=", 1);
/* int and float type wont ever need escaping. Otherwise, quote the value
if it contains spaces or is empty. */
@@ -427,41 +422,38 @@ while (cda->rc != NO_DATA_FOUND) /* Loop for each row */
(def[i].buf[0] == 0 || strchr(def[i].buf, ' ') != NULL))
{
int j;
- result = string_catn(result, &ssize, &offset, "\"", 1);
+ result = string_catn(result, "\"", 1);
for (j = 0; j < def[i].col_retlen; j++)
{
if (def[i].buf[j] == '\"' || def[i].buf[j] == '\\')
- result = string_catn(result, &ssize, &offset, "\\", 1);
- result = string_catn(result, &ssize, &offset, def[i].buf+j, 1);
+ result = string_catn(result, "\\", 1);
+ result = string_catn(result, def[i].buf+j, 1);
}
- result = string_catn(result, &ssize, &offset, "\"", 1);
+ result = string_catn(result, "\"", 1);
}
else switch(desc[i].dbtype)
{
case INT_TYPE:
- sprintf(CS tmp, "%d", def[i].int_buf);
- result = string_cat(result, &ssize, &offset, tmp);
- break;
+ result = string_cat(result, string_sprintf("%d", def[i].int_buf));
+ break;
case FLOAT_TYPE:
- sprintf(CS tmp, "%f", def[i].flt_buf);
- result = string_cat(result, &ssize, &offset, tmp);
- break;
+ result = string_cat(result, string_sprintf("%f", def[i].flt_buf));
+ break;
case STRING_TYPE:
- result = string_catn(result, &ssize, &offset, def[i].buf,
- def[i].col_retlen);
- break;
+ result = string_catn(result, def[i].buf, def[i].col_retlen);
+ break;
default:
- *errmsg = string_sprintf("ORACLE: unknown field type %d", desc[i].dbtype);
- *defer_break = FALSE;
- result = NULL;
- goto ORACLE_EXIT;
+ *errmsg = string_sprintf("ORACLE: unknown field type %d", desc[i].dbtype);
+ *defer_break = FALSE;
+ result = NULL;
+ goto ORACLE_EXIT;
}
- result = string_catn(result, &ssize, &offset, " ", 1);
+ result = string_catn(result, " ", 1);
}
}
@@ -469,16 +461,13 @@ while (cda->rc != NO_DATA_FOUND) /* Loop for each row */
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 = "ORACLE: no data found";
}
else
- {
- result[offset] = 0;
- store_reset(result + offset + 1);
- }
+ store_reset(result->s + result->ptr + 1);
/* Get here by goto from various error checks. */
@@ -492,9 +481,9 @@ ORACLE_EXIT_NO_VALS:
/* Non-NULL result indicates a successful result */
-if (result != NULL)
+if (result)
{
- *resultptr = result;
+ *resultptr = string_from_gstring(result);
return OK;
}
else
diff --git a/src/src/lookups/pgsql.c b/src/src/lookups/pgsql.c
index d71f97b33..ef8f0997d 100644
--- a/src/src/lookups/pgsql.c
+++ b/src/src/lookups/pgsql.c
@@ -125,9 +125,7 @@ PGconn *pg_conn = NULL;
PGresult *pg_result = NULL;
int i;
-uschar *result = NULL;
-int ssize = 0;
-int offset = 0;
+gstring * result = NULL;
int yield = DEFER;
unsigned int num_fields, num_tuples;
pgsql_connection *cn;
@@ -287,30 +285,31 @@ else
{
case PGRES_EMPTY_QUERY:
case PGRES_COMMAND_OK:
- /* The command was successful but did not return any data since it was
- * not SELECT but either an INSERT, UPDATE or DELETE statement. Tell the
- * high level code to not cache this query, and clean the current cache for
- * this handle by setting *do_cache zero. */
- result = string_copy(US PQcmdTuples(pg_result));
- offset = Ustrlen(result);
- *do_cache = 0;
- DEBUG(D_lookup) debug_printf("PGSQL: command does not return any data "
- "but was successful. Rows affected: %s\n", result);
+ /* The command was successful but did not return any data since it was
+ not SELECT but either an INSERT, UPDATE or DELETE statement. Tell the
+ high level code to not cache this query, and clean the current cache for
+ this handle by setting *do_cache zero. */
+
+ result = string_cat(result, US PQcmdTuples(pg_result));
+ *do_cache = 0;
+ DEBUG(D_lookup) debug_printf("PGSQL: command does not return any data "
+ "but was successful. Rows affected: %s\n", result->s);
+ break;
case PGRES_TUPLES_OK:
- break;
+ break;
default:
- /* This was the original code:
- *errmsg = string_sprintf("PGSQL: query failed: %s\n",
- PQresultErrorMessage(pg_result));
- This was suggested by a user:
- */
+ /* This was the original code:
+ *errmsg = string_sprintf("PGSQL: query failed: %s\n",
+ PQresultErrorMessage(pg_result));
+ This was suggested by a user:
+ */
- *errmsg = string_sprintf("PGSQL: query failed: %s (%s) (%s)\n",
+ *errmsg = string_sprintf("PGSQL: query failed: %s (%s) (%s)\n",
PQresultErrorMessage(pg_result),
PQresStatus(PQresultStatus(pg_result)), query);
- goto PGSQL_EXIT;
+ goto PGSQL_EXIT;
}
/* Result is in pg_result. Find the number of fields returned. If this is one,
@@ -326,23 +325,19 @@ row, we insert '\n' between them. */
for (i = 0; i < num_tuples; i++)
{
- if (result != NULL)
- result = string_catn(result, &ssize, &offset, US"\n", 1);
-
- if (num_fields == 1)
- {
- result = string_catn(result, &ssize, &offset,
- US PQgetvalue(pg_result, i, 0), PQgetlength(pg_result, i, 0));
- }
+ if (result)
+ result = string_catn(result, US"\n", 1);
- else
+ if (num_fields == 1)
+ result = string_catn(NULL,
+ US PQgetvalue(pg_result, i, 0), PQgetlength(pg_result, i, 0));
+ else
{
int j;
for (j = 0; j < num_fields; j++)
{
uschar *tmp = US PQgetvalue(pg_result, i, j);
- result = lf_quote(US PQfname(pg_result, j), tmp, Ustrlen(tmp), result,
- &ssize, &offset);
+ result = lf_quote(US PQfname(pg_result, j), tmp, Ustrlen(tmp), result);
}
}
}
@@ -351,16 +346,13 @@ for (i = 0; i < num_tuples; i++)
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"PGSQL: no data found";
}
else
- {
- result[offset] = 0;
- store_reset(result + offset + 1);
- }
+ store_reset(result->s + result->ptr + 1);
/* Get here by goto from various error checks. */
@@ -369,13 +361,13 @@ PGSQL_EXIT:
/* Free store for any result that was got; don't close the connection, as
it is cached. */
-if (pg_result != NULL) PQclear(pg_result);
+if (pg_result) PQclear(pg_result);
/* Non-NULL result indicates a successful result */
-if (result != NULL)
+if (result)
{
- *resultptr = result;
+ *resultptr = string_from_gstring(result);
return OK;
}
else
diff --git a/src/src/lookups/redis.c b/src/src/lookups/redis.c
index 3a96f5ef9..e8989ca3a 100644
--- a/src/src/lookups/redis.c
+++ b/src/src/lookups/redis.c
@@ -80,13 +80,10 @@ redisReply *redis_reply = NULL;
redisReply *entry = NULL;
redisReply *tentry = NULL;
redis_connection *cn;
-int ssize = 0;
-int offset = 0;
int yield = DEFER;
int i, j;
-uschar *result = NULL;
+gstring * result = NULL;
uschar *server_copy = NULL;
-uschar *tmp, *ttmp;
uschar *sdata[3];
/* Disaggregate the parameters from the server argument.
@@ -217,10 +214,13 @@ if(sdata[1])
for (i = 0; *s && i < nele(argv); i++)
{
- for (argv[i] = NULL, siz = ptr = 0; (c = *s) && !isspace(c); s++)
+ gstring * g;
+
+ for (g = NULL; (c = *s) && !isspace(c); s++)
if (c != '\\' || *++s) /* backslash protects next char */
- argv[i] = string_catn(argv[i], &siz, &ptr, s, 1);
- *(argv[i]+ptr) = '\0';
+ g = string_catn(g, s, 1);
+ argv[i] = string_from_gstring(g);
+
DEBUG(D_lookup) debug_printf("REDIS: argv[%d] '%s'\n", i, argv[i]);
while (isspace(*s)) s++;
}
@@ -249,20 +249,18 @@ switch (redis_reply->type)
case REDIS_REPLY_NIL:
DEBUG(D_lookup)
debug_printf("REDIS: query was not one that returned any data\n");
- result = string_sprintf("");
+ result = string_catn(result, US"", 1);
*do_cache = 0;
goto REDIS_EXIT;
/* NOTREACHED */
case REDIS_REPLY_INTEGER:
- ttmp = (redis_reply->integer != 0) ? US"true" : US"false";
- result = string_cat(result, &ssize, &offset, US ttmp);
+ result = string_cat(result, redis_reply->integer != 0 ? US"true" : US"false");
break;
case REDIS_REPLY_STRING:
case REDIS_REPLY_STATUS:
- result = string_catn(result, &ssize, &offset,
- US redis_reply->str, redis_reply->len);
+ result = string_catn(result, US redis_reply->str, redis_reply->len);
break;
case REDIS_REPLY_ARRAY:
@@ -275,17 +273,15 @@ switch (redis_reply->type)
entry = redis_reply->element[i];
if (result)
- result = string_catn(result, &ssize, &offset, US"\n", 1);
+ result = string_catn(result, US"\n", 1);
switch (entry->type)
{
case REDIS_REPLY_INTEGER:
- tmp = string_sprintf("%d", entry->integer);
- result = string_cat(result, &ssize, &offset, US tmp);
+ result = string_cat(result, string_sprintf("%d", entry->integer));
break;
case REDIS_REPLY_STRING:
- result = string_catn(result, &ssize, &offset,
- US entry->str, entry->len);
+ result = string_catn(result, US entry->str, entry->len);
break;
case REDIS_REPLY_ARRAY:
for (j = 0; j < entry->elements; j++)
@@ -293,17 +289,15 @@ switch (redis_reply->type)
tentry = entry->element[j];
if (result)
- result = string_catn(result, &ssize, &offset, US"\n", 1);
+ result = string_catn(result, US"\n", 1);
switch (tentry->type)
{
case REDIS_REPLY_INTEGER:
- ttmp = string_sprintf("%d", tentry->integer);
- result = string_cat(result, &ssize, &offset, US ttmp);
+ result = string_cat(result, string_sprintf("%d", tentry->integer));
break;
case REDIS_REPLY_STRING:
- result = string_catn(result, &ssize, &offset,
- US tentry->str, tentry->len);
+ result = string_catn(result, US tentry->str, tentry->len);
break;
case REDIS_REPLY_ARRAY:
DEBUG(D_lookup)
@@ -327,10 +321,7 @@ switch (redis_reply->type)
if (result)
- {
- result[offset] = 0;
- store_reset(result + offset + 1);
- }
+ store_reset(result->s + result->ptr + 1);
else
{
yield = FAIL;
@@ -348,7 +339,7 @@ if (redis_reply) freeReplyObject(redis_reply);
if (result)
{
- *resultptr = result;
+ *resultptr = string_from_gstring(result);
return OK;
}
else
diff --git a/src/src/lookups/sqlite.c b/src/src/lookups/sqlite.c
index 0b01fdbce..0df853736 100644
--- a/src/src/lookups/sqlite.c
+++ b/src/src/lookups/sqlite.c
@@ -41,21 +41,16 @@ return db;
/* See local README for interface description. */
-struct strbuf {
- uschar *string;
- int size;
- int len;
-};
-
-static int sqlite_callback(void *arg, int argc, char **argv, char **azColName)
+static int
+sqlite_callback(void *arg, int argc, char **argv, char **azColName)
{
-struct strbuf *res = arg;
+gstring * res = *(gstring **)arg;
int i;
/* For second and subsequent results, insert \n */
-if (res->string != NULL)
- res->string = string_catn(res->string, &res->size, &res->len, US"\n", 1);
+if (res)
+ res = string_catn(res, US"\n", 1);
if (argc > 1)
{
@@ -63,18 +58,14 @@ if (argc > 1)
for (i = 0; i < argc; i++)
{
uschar *value = US((argv[i] != NULL)? argv[i]:"<NULL>");
- res->string = lf_quote(US azColName[i], value, Ustrlen(value), res->string,
- &res->size, &res->len);
+ res = lf_quote(US azColName[i], value, Ustrlen(value), res);
}
}
else
- {
- res->string = string_append(res->string, &res->size, &res->len, 1,
- (argv[0] != NULL)? argv[0]:"<NULL>");
- }
+ res = string_cat(res, argv[0] ? US argv[0] : US "<NULL>");
-res->string[res->len] = 0;
+*(gstring **)arg = res;
return 0;
}
@@ -84,7 +75,7 @@ sqlite_find(void *handle, uschar *filename, const uschar *query, int length,
uschar **result, uschar **errmsg, uint *do_cache)
{
int ret;
-struct strbuf res = { NULL, 0, 0 };
+gstring * res = NULL;
ret = sqlite3_exec(handle, CS query, sqlite_callback, &res, (char **)errmsg);
if (ret != SQLITE_OK)
@@ -93,9 +84,9 @@ if (ret != SQLITE_OK)
return FAIL;
}
-if (res.string == NULL) *do_cache = 0;
+if (!res) *do_cache = 0;
-*result = res.string;
+*result = string_from_gstring(res);
return OK;
}