diff options
Diffstat (limited to 'usr/src/lib/libresolv2_joy/common/sunw')
-rw-r--r-- | usr/src/lib/libresolv2_joy/common/sunw/sunw_mtctxres.c | 126 | ||||
-rw-r--r-- | usr/src/lib/libresolv2_joy/common/sunw/sunw_updrec.c | 249 | ||||
-rw-r--r-- | usr/src/lib/libresolv2_joy/common/sunw/sunw_wrappers.c | 23 |
3 files changed, 398 insertions, 0 deletions
diff --git a/usr/src/lib/libresolv2_joy/common/sunw/sunw_mtctxres.c b/usr/src/lib/libresolv2_joy/common/sunw/sunw_mtctxres.c new file mode 100644 index 0000000000..cc2a485ede --- /dev/null +++ b/usr/src/lib/libresolv2_joy/common/sunw/sunw_mtctxres.c @@ -0,0 +1,126 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <port_before.h> +#include <thread.h> +#include <errno.h> +#include <netdb.h> +#include <malloc.h> +#include <string.h> +#include <resolv_mt.h> +#include <irs.h> +#include <port_after.h> + +#pragma redefine_extname __h_errno __joy_h_errno + +/* + * much of the original version of sunw_mtxtxres.c was incorporated into + * ISC libbind as resolv/mtctxres.c. The following bits have not yet made + * it into ISC libbind. + */ + +/* + * There used to be a private, MT-safe resolver interface that used TSD + * to store per-thread _res, h_errno, etc. We continue to provide the + * access functions __res_get_res() and __res_get_h_errno() so that binaries + * that used the private interface will continue to work. + */ + +#ifdef _res +#undef _res +#endif + +extern struct __res_state *__res_state(void); + +struct __res_state * +__res_get_res(void) { + return (__res_state()); +} + + +#ifdef h_errno +#undef h_errno +#endif + +extern int *__h_errno(void); + +int * +__res_get_h_errno(void) { + return (__h_errno()); +} + + +#ifdef SUNW_HOSTS_FALLBACK + +/* + * When the name service switch calls libresolv, it doesn't want fallback + * to /etc/hosts, so we provide a method to turn it off. + */ + +void +__joy_res_set_no_hosts_fallback(void) { + ___mtctxres()->no_hosts_fallback_private = 1; +} + +void +__joy_res_unset_no_hosts_fallback(void) { + ___mtctxres()->no_hosts_fallback_private = 0; +} + +int +__res_no_hosts_fallback(void) { + return (___mtctxres()->no_hosts_fallback_private); +} + +#endif /* SUNW_HOSTS_FALLBACK */ + +#ifdef SUNW_OVERRIDE_RETRY + +/* + * The NS switch wants to be able to override the number of retries. + */ + +int +__joy_res_override_retry(int retry) { + ___mtctxres()->retry_private = retry; + /* + * This function doesn't really need a return value; saving the + * old retry setting, and restoring it, is handled by __res_retry() + * and __res_retry_reset() below. However, the nss_dns library + * must have a private version of this function to be used when + * running with an old libresolv. That private nss_dns function + * needs a return value, and a function pointer is used to select + * the right function at runtime. Thus, __res_override_retry + * must have a function prototype consistent with the private + * nss_dns function, i.e., one that returns an int. + * + * Given that we do have a return value, that value must be zero. + * That's because retry_private == 0 is used to indicate that + * no override retry value is in effect, and the way we expect + * nss_dns to call us is: + * + * int oldretry = __res_override_retry(N); + * <whatever> + * (void)__res_override_retry(old_retry); + */ + return (0); +} + +int +__res_retry(int retry) { + mtctxres_t *mt = ___mtctxres(); + + mt->retry_save = retry; + return ((mt->retry_private != 0) ? mt->retry_private : retry); +} + +int +__res_retry_reset(void) { + mtctxres_t *mt = ___mtctxres(); + + return (mt->retry_save); +} + +#endif /* SUNW_OVERRIDE_RETRY */ diff --git a/usr/src/lib/libresolv2_joy/common/sunw/sunw_updrec.c b/usr/src/lib/libresolv2_joy/common/sunw/sunw_updrec.c new file mode 100644 index 0000000000..3b0ffc49df --- /dev/null +++ b/usr/src/lib/libresolv2_joy/common/sunw/sunw_updrec.c @@ -0,0 +1,249 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * As of BIND 8.2.2, ISC (a) removed res_mkupdate(), res_update(), and + * res_mkupdrec() from what they consider the supported interface. The + * functions still exist, but their calling interface has changed, since + * the ns_updrec structure has changed. + * + * It seems probable that res_mkupdate() etc. will return, though possibly + * with other changes, in some future BIND release. In order to avoid + * going to PSARC twice (once to remove the functions, and then again to + * add them back), we retain the old interface as a wrapper around the + * new one. + */ + +#include <port_before.h> + +#include <malloc.h> +#include <strings.h> +#include <sys/types.h> +#include <netinet/in.h> + +/* get the Solaris ns_updrec before any renaming happens */ +#include <arpa/nameser.h> + +/* get the __ISC_ns_updrec */ +#include <res_update.h> + +#include <port_after.h> + +/* un-rename ns_updrec and res_* functions so we can wrap them */ +#undef ns_updrec +#undef res_mkupdate +#undef res_update +#undef res_mkupdrec +#undef res_freeupdrec +#undef res_nmkupdate +#undef res_nupdate + +void res_freeupdrec(ns_updrec *); + +static int +old2new(ns_updrec *old, __ISC_ns_updrec *new) { + + if (old->r_dname != 0) { + if ((new->r_dname = strdup(old->r_dname)) == 0) + return (-1); + } else { + new->r_dname = 0; + } + + new->r_glink.prev = + new->r_glink.next = + new->r_link.prev = + new->r_link.next = 0; + + new->r_section = old->r_section; + new->r_class = old->r_class; + new->r_type = old->r_type; + new->r_ttl = old->r_ttl; + new->r_data = old->r_data; + new->r_size = old->r_size; + new->r_opcode = old->r_opcode; + new->r_dp = old->r_dp; + new->r_deldp = old->r_deldp; + new->r_zone = old->r_zone; + + return (0); +} + + +static int +new2old(__ISC_ns_updrec *new, ns_updrec *old) { + /* XXX r_prev and r_next unchanged */ + if (new->r_dname != 0) { + if ((old->r_dname = strdup(new->r_dname)) == 0) + return (-1); + } else { + old->r_dname = 0; + } + old->r_section = new->r_section; + old->r_class = new->r_class; + old->r_type = new->r_type; + old->r_ttl = new->r_ttl; + old->r_data = new->r_data; + old->r_size = new->r_size; + old->r_opcode = new->r_opcode; + old->r_grpnext = 0; /* XXX */ + old->r_dp = new->r_dp; + old->r_deldp = new->r_deldp; + old->r_zone = new->r_zone; + + return (0); +} + + +static void +delete_list(__ISC_ns_updrec *list) { + + __ISC_ns_updrec *next; + + for (; list != 0; list = next) { + next = list->r_link.next; + __ISC_res_freeupdrec(list); + } +} + + +static __ISC_ns_updrec * +copy_list(ns_updrec *old, int do_glink) { + + __ISC_ns_updrec *list = 0, *r, *p; + + if (old == 0) + return (0); + + for (p = 0; old != 0; old = old->r_next, p = r) { + if ((r = calloc(1, sizeof (*r))) == 0 || + old2new(old, r) != 0) { + free(r); + delete_list(list); + return (0); + } + r->r_link.prev = p; + r->r_link.next = 0; + /* res_update and res_nupdate want r_glink set up like this */ + if (do_glink) { + r->r_glink.prev = p; + r->r_glink.next = 0; + } else { + r->r_glink.prev = (void *)-1; + r->r_glink.next = (void *)-1; + } + if (p != 0) { + p->r_link.next = r; + if (do_glink) { + p->r_glink.next = r; + } + } else { + list = r; + } + } + return (list); +} + + +int +res_mkupdate(ns_updrec *rrecp_in, uchar_t *buf, int length) { + + __ISC_ns_updrec *r; + int ret; + + if ((r = copy_list(rrecp_in, 1)) == 0) + return (-1); + + ret = __ISC_res_mkupdate(r, buf, length); + + delete_list(r); + + return (ret); +} + +int +res_nmkupdate(res_state statp, ns_updrec *rrecp_in, uchar_t *buf, int length) { + + __ISC_ns_updrec *r; + int ret; + + if ((r = copy_list(rrecp_in, 1)) == 0) + return (-1); + + ret = __ISC_res_nmkupdate(statp, r, buf, length); + + delete_list(r); + + return (ret); +} + + +int +res_update(ns_updrec *rrecp_in) { + + __ISC_ns_updrec *r; + int ret; + + if ((r = copy_list(rrecp_in, 0)) == 0) + return (-1); + + ret = __ISC_res_update(r); + + delete_list(r); + + return (ret); +} + +int +res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) { + + __ISC_ns_updrec *r; + int ret; + + if ((r = copy_list(rrecp_in, 0)) == 0) + return (-1); + + ret = __ISC_res_nupdate(statp, r, key); + + delete_list(r); + + return (ret); +} + + + +ns_updrec * +res_mkupdrec(int section, const char *dname, uint_t class, uint_t type, + uint_t ttl) { + + __ISC_ns_updrec *n; + ns_updrec *o; + + n = __ISC_res_mkupdrec(section, dname, class, type, ttl); + if (n == 0) + return (0); + + if ((o = calloc(1, sizeof (*o))) != 0) { + if (new2old(n, o) != 0) { + res_freeupdrec(o); + o = 0; + } + } + + __ISC_res_freeupdrec(n); + + return (o); +} + + +void +res_freeupdrec(ns_updrec *rrecp) { + if (rrecp == 0) + return; + /* Note: freeing r_dp is the caller's responsibility. */ + if (rrecp->r_dname != NULL) + free(rrecp->r_dname); + free(rrecp); +} diff --git a/usr/src/lib/libresolv2_joy/common/sunw/sunw_wrappers.c b/usr/src/lib/libresolv2_joy/common/sunw/sunw_wrappers.c new file mode 100644 index 0000000000..55bbe07024 --- /dev/null +++ b/usr/src/lib/libresolv2_joy/common/sunw/sunw_wrappers.c @@ -0,0 +1,23 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <port_before.h> +#include <resolv_joy.h> +#include <arpa/inet.h> +#include <port_after.h> + +#undef p_option +/* extern const char * isc_p_option(); */ +const char *p_option(uint_t option) { + return (isc_p_option((ulong_t)option)); +} +#pragma weak __p_option = p_option + +#undef p_secstodate +/* extern char * isc_p_secstodate (); */ +char *p_secstodate(uint_t secs) { + return (isc_p_secstodate((ulong_t)secs)); +} +#pragma weak __p_secstodate = p_secstodate |