summaryrefslogtreecommitdiff
path: root/src/libs6dns/s6dns_hosts_aaaaa_string.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs6dns/s6dns_hosts_aaaaa_string.c')
-rw-r--r--src/libs6dns/s6dns_hosts_aaaaa_string.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/libs6dns/s6dns_hosts_aaaaa_string.c b/src/libs6dns/s6dns_hosts_aaaaa_string.c
new file mode 100644
index 0000000..f4b00f0
--- /dev/null
+++ b/src/libs6dns/s6dns_hosts_aaaaa_string.c
@@ -0,0 +1,40 @@
+/* ISC license. */
+
+#include <errno.h>
+#include <string.h>
+
+#include <skalibs/ip46.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/genalloc.h>
+
+#include <s6-dns/hosts.h>
+
+extern int s6dns_hosts_aaaaa_string_r (cdb const *c, char const *name, genalloc *ga, int isunq)
+{
+ stralloc sa = STRALLOC_ZERO ;
+ int gawn = !genalloc_s(ip46full, ga) ;
+ size_t gabase = genalloc_len(ip46full, ga) ;
+ int r = s6dns_hosts_a_string_r(c, name, &sa, isunq) ;
+ if (r <= 0) return r ;
+ if (!genalloc_readyplus(ip46full, ga, r)) return -1 ;
+ for (size_t i = 0 ; i < r ; i++)
+ ip46full_from_ip4(genalloc_s(ip46full, ga) + i, sa.s + (i << 2)) ;
+ genalloc_setlen(ip46full, ga, gabase + r) ;
+ sa.len = 0 ;
+ r = s6dns_hosts_aaaa_string_r(c, name, &sa, isunq) ;
+ if (r == -1) goto err ;
+ if (r)
+ {
+ if (!genalloc_readyplus(ip46full, ga, r)) goto err ;
+ for (size_t i = 0 ; i < r ; i++)
+ ip46full_from_ip6(genalloc_s(ip46full, ga) + i, sa.s + (i << 4)) ;
+ genalloc_setlen(ip46full, ga, genalloc_len(ip46full, ga) + r) ;
+ }
+ stralloc_free(&sa) ;
+ return genalloc_len(ip46full, ga) - gabase ;
+
+ err:
+ if (gawn) genalloc_free(ip46full, ga) ; else genalloc_setlen(ip46full, ga, gabase) ;
+ stralloc_free(&sa) ;
+ return -1 ;
+}