X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Flookups%2Fdnsdb.c;h=a8633826135d1212cdf12ab3489cfbca6e6099ab;hb=f9ba5e2255cf18092750fffacb6a9603571a2be5;hp=da3495beb581c3d9aab5a926a29e357e7a3fd94e;hpb=c2f669a4994192344613569e198c7b503d46d45e;p=exim.git diff --git a/src/src/lookups/dnsdb.c b/src/src/lookups/dnsdb.c index da3495beb..a86338261 100644 --- a/src/src/lookups/dnsdb.c +++ b/src/src/lookups/dnsdb.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2015 */ +/* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ #include "../exim.h" @@ -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; @@ -261,17 +259,15 @@ if ((equals = Ustrchr(keystring, '=')) != NULL) while (tend > keystring && isspace(tend[-1])) tend--; len = tend - keystring; - for (i = 0; i < sizeof(type_names)/sizeof(uschar *); i++) - { + for (i = 0; i < nelem(type_names); i++) if (len == Ustrlen(type_names[i]) && strncmpic(keystring, US type_names[i], len) == 0) { type = type_values[i]; break; } - } - if (i >= sizeof(type_names)/sizeof(uschar *)) + if (i >= nelem(type_names)) { *errmsg = US"unsupported DNS record type"; return DEFER; @@ -382,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; @@ -396,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; } @@ -405,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, (uschar *)(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 */ @@ -423,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; } } @@ -451,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 */ { @@ -469,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: @@ -478,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: @@ -507,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: @@ -528,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)); @@ -545,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); @@ -553,30 +541,30 @@ 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 */ - /* Loop for set of A-lookupu types */ + /* Loop for set of A-lookup types */ } while (type == T_ADDRESSES && searchtype != T_A); } /* Loop for list of domains */ /* 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; }