2N/A/*
2N/A * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A/*
2N/A * As of BIND 8.2.2, ISC (a) removed res_mkupdate(), res_update(), and
2N/A * res_mkupdrec() from what they consider the supported interface. The
2N/A * functions still exist, but their calling interface has changed, since
2N/A * the ns_updrec structure has changed.
2N/A *
2N/A * It seems probable that res_mkupdate() etc. will return, though possibly
2N/A * with other changes, in some future BIND release. In order to avoid
2N/A * going to PSARC twice (once to remove the functions, and then again to
2N/A * add them back), we retain the old interface as a wrapper around the
2N/A * new one.
2N/A */
2N/A
2N/A#include <port_before.h>
2N/A
2N/A#include <malloc.h>
2N/A#include <strings.h>
2N/A#include <sys/types.h>
2N/A#include <netinet/in.h>
2N/A
2N/A/* get the Solaris ns_updrec before any renaming happens */
2N/A#include <arpa/nameser.h>
2N/A
2N/A/* get the __ISC_ns_updrec */
2N/A#include <res_update.h>
2N/A
2N/A#include <port_after.h>
2N/A
2N/A/* un-rename ns_updrec and res_* functions so we can wrap them */
2N/A#undef ns_updrec
2N/A#undef res_mkupdate
2N/A#undef res_update
2N/A#undef res_mkupdrec
2N/A#undef res_freeupdrec
2N/A#undef res_nmkupdate
2N/A#undef res_nupdate
2N/A
2N/Avoid res_freeupdrec(ns_updrec *);
2N/A
2N/Astatic int
2N/Aold2new(ns_updrec *old, __ISC_ns_updrec *new) {
2N/A
2N/A if (old->r_dname != 0) {
2N/A if ((new->r_dname = strdup(old->r_dname)) == 0)
2N/A return (-1);
2N/A } else {
2N/A new->r_dname = 0;
2N/A }
2N/A
2N/A new->r_glink.prev =
2N/A new->r_glink.next =
2N/A new->r_link.prev =
2N/A new->r_link.next = 0;
2N/A
2N/A new->r_section = old->r_section;
2N/A new->r_class = old->r_class;
2N/A new->r_type = old->r_type;
2N/A new->r_ttl = old->r_ttl;
2N/A new->r_data = old->r_data;
2N/A new->r_size = old->r_size;
2N/A new->r_opcode = old->r_opcode;
2N/A new->r_dp = old->r_dp;
2N/A new->r_deldp = old->r_deldp;
2N/A new->r_zone = old->r_zone;
2N/A
2N/A return (0);
2N/A}
2N/A
2N/A
2N/Astatic int
2N/Anew2old(__ISC_ns_updrec *new, ns_updrec *old) {
2N/A /* XXX r_prev and r_next unchanged */
2N/A if (new->r_dname != 0) {
2N/A if ((old->r_dname = strdup(new->r_dname)) == 0)
2N/A return (-1);
2N/A } else {
2N/A old->r_dname = 0;
2N/A }
2N/A old->r_section = new->r_section;
2N/A old->r_class = new->r_class;
2N/A old->r_type = new->r_type;
2N/A old->r_ttl = new->r_ttl;
2N/A old->r_data = new->r_data;
2N/A old->r_size = new->r_size;
2N/A old->r_opcode = new->r_opcode;
2N/A old->r_grpnext = 0; /* XXX */
2N/A old->r_dp = new->r_dp;
2N/A old->r_deldp = new->r_deldp;
2N/A old->r_zone = new->r_zone;
2N/A
2N/A return (0);
2N/A}
2N/A
2N/A
2N/Astatic void
2N/Adelete_list(__ISC_ns_updrec *list) {
2N/A
2N/A __ISC_ns_updrec *next;
2N/A
2N/A for (; list != 0; list = next) {
2N/A next = list->r_link.next;
2N/A __ISC_res_freeupdrec(list);
2N/A }
2N/A}
2N/A
2N/A
2N/Astatic __ISC_ns_updrec *
2N/Acopy_list(ns_updrec *old, int do_glink) {
2N/A
2N/A __ISC_ns_updrec *list = 0, *r, *p;
2N/A
2N/A if (old == 0)
2N/A return (0);
2N/A
2N/A for (p = 0; old != 0; old = old->r_next, p = r) {
2N/A if ((r = calloc(1, sizeof (*r))) == 0 ||
2N/A old2new(old, r) != 0) {
2N/A free(r);
2N/A delete_list(list);
2N/A return (0);
2N/A }
2N/A r->r_link.prev = p;
2N/A r->r_link.next = 0;
2N/A /* res_update and res_nupdate want r_glink set up like this */
2N/A if (do_glink) {
2N/A r->r_glink.prev = p;
2N/A r->r_glink.next = 0;
2N/A } else {
2N/A r->r_glink.prev = (void *)-1;
2N/A r->r_glink.next = (void *)-1;
2N/A }
2N/A if (p != 0) {
2N/A p->r_link.next = r;
2N/A if (do_glink) {
2N/A p->r_glink.next = r;
2N/A }
2N/A } else {
2N/A list = r;
2N/A }
2N/A }
2N/A return (list);
2N/A}
2N/A
2N/A
2N/Aint
2N/Ares_mkupdate(ns_updrec *rrecp_in, uchar_t *buf, int length) {
2N/A
2N/A __ISC_ns_updrec *r;
2N/A int ret;
2N/A
2N/A if ((r = copy_list(rrecp_in, 1)) == 0)
2N/A return (-1);
2N/A
2N/A ret = __ISC_res_mkupdate(r, buf, length);
2N/A
2N/A delete_list(r);
2N/A
2N/A return (ret);
2N/A}
2N/A
2N/Aint
2N/Ares_nmkupdate(res_state statp, ns_updrec *rrecp_in, uchar_t *buf, int length) {
2N/A
2N/A __ISC_ns_updrec *r;
2N/A int ret;
2N/A
2N/A if ((r = copy_list(rrecp_in, 1)) == 0)
2N/A return (-1);
2N/A
2N/A ret = __ISC_res_nmkupdate(statp, r, buf, length);
2N/A
2N/A delete_list(r);
2N/A
2N/A return (ret);
2N/A}
2N/A
2N/A
2N/Aint
2N/Ares_update(ns_updrec *rrecp_in) {
2N/A
2N/A __ISC_ns_updrec *r;
2N/A int ret;
2N/A
2N/A if ((r = copy_list(rrecp_in, 0)) == 0)
2N/A return (-1);
2N/A
2N/A ret = __ISC_res_update(r);
2N/A
2N/A delete_list(r);
2N/A
2N/A return (ret);
2N/A}
2N/A
2N/Aint
2N/Ares_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) {
2N/A
2N/A __ISC_ns_updrec *r;
2N/A int ret;
2N/A
2N/A if ((r = copy_list(rrecp_in, 0)) == 0)
2N/A return (-1);
2N/A
2N/A ret = __ISC_res_nupdate(statp, r, key);
2N/A
2N/A delete_list(r);
2N/A
2N/A return (ret);
2N/A}
2N/A
2N/A
2N/A
2N/Ans_updrec *
2N/Ares_mkupdrec(int section, const char *dname, uint_t class, uint_t type,
2N/A uint_t ttl) {
2N/A
2N/A __ISC_ns_updrec *n;
2N/A ns_updrec *o;
2N/A
2N/A n = __ISC_res_mkupdrec(section, dname, class, type, ttl);
2N/A if (n == 0)
2N/A return (0);
2N/A
2N/A if ((o = calloc(1, sizeof (*o))) != 0) {
2N/A if (new2old(n, o) != 0) {
2N/A res_freeupdrec(o);
2N/A o = 0;
2N/A }
2N/A }
2N/A
2N/A __ISC_res_freeupdrec(n);
2N/A
2N/A return (o);
2N/A}
2N/A
2N/A
2N/Avoid
2N/Ares_freeupdrec(ns_updrec *rrecp) {
2N/A if (rrecp == 0)
2N/A return;
2N/A /* Note: freeing r_dp is the caller's responsibility. */
2N/A if (rrecp->r_dname != NULL)
2N/A free(rrecp->r_dname);
2N/A free(rrecp);
2N/A}