1 /* 2 * Copyright (c) 1999 by Sun Microsystems, Inc. 3 * All rights reserved. 4 */ 5 6 #pragma ident "%Z%%M% %I% %E% SMI" 7 8 /* 9 * As of BIND 8.2.2, ISC (a) removed res_mkupdate(), res_update(), and 10 * res_mkupdrec() from what they consider the supported interface. The 11 * functions still exist, but their calling interface has changed, since 12 * the ns_updrec structure has changed. 13 * 14 * It seems probable that res_mkupdate() etc. will return, though possibly 15 * with other changes, in some future BIND release. In order to avoid 16 * going to PSARC twice (once to remove the functions, and then again to 17 * add them back), we retain the old interface as a wrapper around the 18 * new one. 19 */ 20 21 #include <port_before.h> 22 23 #include <malloc.h> 24 #include <strings.h> 25 #include <sys/types.h> 26 #include <netinet/in.h> 27 28 #include <res_update.h> 29 #undef ns_updrec 30 #undef res_mkupdate 31 #undef res_update 32 #undef res_mkupdrec 33 #undef res_freeupdrec 34 #include <arpa/nameser.h> 35 36 #include <port_after.h> 37 38 void res_freeupdrec(ns_updrec *); 39 40 41 static int 42 old2new(ns_updrec *old, __ISC_ns_updrec *new) { 43 44 if (old->r_dname != 0) { 45 if ((new->r_dname = strdup(old->r_dname)) == 0) 46 return (-1); 47 } else { 48 new->r_dname = 0; 49 } 50 51 new->r_glink.prev = 52 new->r_glink.next = 53 new->r_link.prev = 54 new->r_link.next = 0; 55 56 new->r_section = old->r_section; 57 new->r_class = old->r_class; 58 new->r_type = old->r_type; 59 new->r_ttl = old->r_ttl; 60 new->r_data = old->r_data; 61 new->r_size = old->r_size; 62 new->r_opcode = old->r_opcode; 63 new->r_dp = old->r_dp; 64 new->r_deldp = old->r_deldp; 65 new->r_zone = old->r_zone; 66 67 return (0); 68 } 69 70 71 static int 72 new2old(__ISC_ns_updrec *new, ns_updrec *old) { 73 /* XXX r_prev and r_next unchanged */ 74 if (new->r_dname != 0) { 75 if ((old->r_dname = strdup(new->r_dname)) == 0) 76 return (-1); 77 } else { 78 old->r_dname = 0; 79 } 80 old->r_section = new->r_section; 81 old->r_class = new->r_class; 82 old->r_type = new->r_type; 83 old->r_ttl = new->r_ttl; 84 old->r_data = new->r_data; 85 old->r_size = new->r_size; 86 old->r_opcode = new->r_opcode; 87 old->r_grpnext = 0; /* XXX */ 88 old->r_dp = new->r_dp; 89 old->r_deldp = new->r_deldp; 90 old->r_zone = new->r_zone; 91 92 return (0); 93 } 94 95 96 static void 97 delete_list(__ISC_ns_updrec *list) { 98 99 __ISC_ns_updrec *next; 100 101 for (; list != 0; list = next) { 102 next = list->r_link.next; 103 __ISC_res_freeupdrec(list); 104 } 105 } 106 107 108 static __ISC_ns_updrec * 109 copy_list(ns_updrec *old) { 110 111 __ISC_ns_updrec *list = 0, *r, *p; 112 113 if (old == 0) 114 return (0); 115 116 for (p = 0; old != 0; old = old->r_next, p = r) { 117 if ((r = calloc(1, sizeof (*r))) == 0 || 118 old2new(old, r) != 0) { 119 free(r); 120 delete_list(list); 121 return (0); 122 } 123 r->r_link.prev = p; 124 r->r_link.next = 0; 125 if (p != 0) 126 p->r_link.next = r; 127 else 128 list = r; 129 } 130 131 return (list); 132 } 133 134 135 int 136 res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int length) { 137 138 __ISC_ns_updrec *r; 139 int ret; 140 141 if ((r = copy_list(rrecp_in)) == 0) 142 return (-1); 143 144 ret = __ISC_res_mkupdate(r, buf, length); 145 146 delete_list(r); 147 148 return (ret); 149 } 150 151 152 int 153 res_update(ns_updrec *rrecp_in) { 154 155 __ISC_ns_updrec *r; 156 int ret; 157 158 if ((r = copy_list(rrecp_in)) == 0) 159 return (-1); 160 161 ret = __ISC_res_update(r); 162 163 delete_list(r); 164 165 return (ret); 166 } 167 168 169 170 ns_updrec * 171 res_mkupdrec(int section, const char *dname, uint_t class, uint_t type, 172 uint_t ttl) { 173 174 __ISC_ns_updrec *n; 175 ns_updrec *o; 176 177 n = __ISC_res_mkupdrec(section, dname, class, type, ttl); 178 if (n == 0) 179 return (0); 180 181 if ((o = calloc(1, sizeof (*o))) != 0) { 182 if (new2old(n, o) != 0) { 183 res_freeupdrec(o); 184 o = 0; 185 } 186 } 187 188 __ISC_res_freeupdrec(n); 189 190 return (o); 191 } 192 193 194 void 195 res_freeupdrec(ns_updrec *rrecp) { 196 if (rrecp == 0) 197 return; 198 /* Note: freeing r_dp is the caller's responsibility. */ 199 if (rrecp->r_dname != NULL) 200 free(rrecp->r_dname); 201 free(rrecp); 202 } 203