1 /* 2 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (c) 1998-1999 by Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 15 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <port_before.h> 19 #if !defined(_REENTRANT) || !defined(DO_PTHREADS) 20 static int gethostent_r_not_required = 0; 21 #else 22 #include <errno.h> 23 #include <string.h> 24 #include <stdio.h> 25 #include <sys/types.h> 26 #include <netinet/in.h> 27 #include <netdb.h> 28 #include <sys/param.h> 29 #include <port_after.h> 30 31 #ifdef HOST_R_RETURN 32 33 static HOST_R_RETURN 34 copy_hostent(struct hostent *, struct hostent *, HOST_R_COPY_ARGS); 35 36 HOST_R_RETURN 37 gethostbyname_r(const char *name, struct hostent *hptr, HOST_R_ARGS) { 38 struct hostent *he = gethostbyname(name); 39 #ifdef HOST_R_SETANSWER 40 int n = 0; 41 #endif 42 43 #ifdef HOST_R_ERRNO 44 HOST_R_ERRNO; 45 #endif 46 47 #ifdef HOST_R_SETANSWER 48 if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) != 0) 49 *answerp = NULL; 50 else 51 *answerp = hptr; 52 53 return (n); 54 #else 55 if (he == NULL) 56 return (HOST_R_BAD); 57 58 return (copy_hostent(he, hptr, HOST_R_COPY)); 59 #endif 60 } 61 62 HOST_R_RETURN 63 gethostbyaddr_r(const char *addr, int len, int type, 64 struct hostent *hptr, HOST_R_ARGS) { 65 struct hostent *he = gethostbyaddr(addr, len, type); 66 #ifdef HOST_R_SETANSWER 67 int n = 0; 68 #endif 69 70 #ifdef HOST_R_ERRNO 71 HOST_R_ERRNO; 72 #endif 73 74 #ifdef HOST_R_SETANSWER 75 if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) != 0) 76 *answerp = NULL; 77 else 78 *answerp = hptr; 79 80 return (n); 81 #else 82 if (he == NULL) 83 return (HOST_R_BAD); 84 85 return (copy_hostent(he, hptr, HOST_R_COPY)); 86 #endif 87 } 88 89 /*% 90 * These assume a single context is in operation per thread. 91 * If this is not the case we will need to call irs directly 92 * rather than through the base functions. 93 */ 94 95 HOST_R_RETURN 96 gethostent_r(struct hostent *hptr, HOST_R_ARGS) { 97 struct hostent *he = gethostent(); 98 #ifdef HOST_R_SETANSWER 99 int n = 0; 100 #endif 101 102 #ifdef HOST_R_ERRNO 103 HOST_R_ERRNO; 104 #endif 105 106 #ifdef HOST_R_SETANSWER 107 if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) != 0) 108 *answerp = NULL; 109 else 110 *answerp = hptr; 111 112 return (n); 113 #else 114 if (he == NULL) 115 return (HOST_R_BAD); 116 117 return (copy_hostent(he, hptr, HOST_R_COPY)); 118 #endif 119 } 120 121 HOST_R_SET_RETURN 122 #ifdef HOST_R_ENT_ARGS 123 sethostent_r(int stay_open, HOST_R_ENT_ARGS) 124 #else 125 sethostent_r(int stay_open) 126 #endif 127 { 128 #ifdef HOST_R_ENT_ARGS 129 UNUSED(hdptr); 130 #endif 131 sethostent(stay_open); 132 #ifdef HOST_R_SET_RESULT 133 return (HOST_R_SET_RESULT); 134 #endif 135 } 136 137 HOST_R_END_RETURN 138 #ifdef HOST_R_ENT_ARGS 139 endhostent_r(HOST_R_ENT_ARGS) 140 #else 141 endhostent_r(void) 142 #endif 143 { 144 #ifdef HOST_R_ENT_ARGS 145 UNUSED(hdptr); 146 #endif 147 endhostent(); 148 HOST_R_END_RESULT(HOST_R_OK); 149 } 150 151 /* Private */ 152 153 #ifndef HOSTENT_DATA 154 static HOST_R_RETURN 155 copy_hostent(struct hostent *he, struct hostent *hptr, HOST_R_COPY_ARGS) { 156 char *cp; 157 char **ptr; 158 int i, n; 159 int nptr, len; 160 161 /* Find out the amount of space required to store the answer. */ 162 nptr = 2; /*%< NULL ptrs */ 163 len = (char *)ALIGN(buf) - buf; 164 for (i = 0; he->h_addr_list[i]; i++, nptr++) { 165 len += he->h_length; 166 } 167 for (i = 0; he->h_aliases[i]; i++, nptr++) { 168 len += strlen(he->h_aliases[i]) + 1; 169 } 170 len += strlen(he->h_name) + 1; 171 len += nptr * sizeof(char*); 172 173 if (len > buflen) { 174 errno = ERANGE; 175 return (HOST_R_BAD); 176 } 177 178 /* copy address size and type */ 179 hptr->h_addrtype = he->h_addrtype; 180 n = hptr->h_length = he->h_length; 181 182 ptr = (char **)ALIGN(buf); 183 cp = (char *)ALIGN(buf) + nptr * sizeof(char *); 184 185 /* copy address list */ 186 hptr->h_addr_list = ptr; 187 for (i = 0; he->h_addr_list[i]; i++ , ptr++) { 188 memcpy(cp, he->h_addr_list[i], n); 189 hptr->h_addr_list[i] = cp; 190 cp += n; 191 } 192 hptr->h_addr_list[i] = NULL; 193 ptr++; 194 195 /* copy official name */ 196 n = strlen(he->h_name) + 1; 197 strcpy(cp, he->h_name); 198 hptr->h_name = cp; 199 cp += n; 200 201 /* copy aliases */ 202 hptr->h_aliases = ptr; 203 for (i = 0 ; he->h_aliases[i]; i++) { 204 n = strlen(he->h_aliases[i]) + 1; 205 strcpy(cp, he->h_aliases[i]); 206 hptr->h_aliases[i] = cp; 207 cp += n; 208 } 209 hptr->h_aliases[i] = NULL; 210 211 return (HOST_R_OK); 212 } 213 #else /* !HOSTENT_DATA */ 214 static int 215 copy_hostent(struct hostent *he, struct hostent *hptr, HOST_R_COPY_ARGS) { 216 char *cp, *eob; 217 int i, n; 218 219 /* copy address size and type */ 220 hptr->h_addrtype = he->h_addrtype; 221 n = hptr->h_length = he->h_length; 222 223 /* copy up to first 35 addresses */ 224 i = 0; 225 cp = hdptr->hostbuf; 226 eob = hdptr->hostbuf + sizeof(hdptr->hostbuf); 227 hptr->h_addr_list = hdptr->h_addr_ptrs; 228 while (he->h_addr_list[i] && i < (_MAXADDRS)) { 229 if (n < (eob - cp)) { 230 memcpy(cp, he->h_addr_list[i], n); 231 hptr->h_addr_list[i] = cp; 232 cp += n; 233 } else { 234 break; 235 } 236 i++; 237 } 238 hptr->h_addr_list[i] = NULL; 239 240 /* copy official name */ 241 if ((n = strlen(he->h_name) + 1) < (eob - cp)) { 242 strcpy(cp, he->h_name); 243 hptr->h_name = cp; 244 cp += n; 245 } else { 246 return (-1); 247 } 248 249 /* copy aliases */ 250 i = 0; 251 hptr->h_aliases = hdptr->host_aliases; 252 while (he->h_aliases[i] && i < (_MAXALIASES-1)) { 253 if ((n = strlen(he->h_aliases[i]) + 1) < (eob - cp)) { 254 strcpy(cp, he->h_aliases[i]); 255 hptr->h_aliases[i] = cp; 256 cp += n; 257 } else { 258 break; 259 } 260 i++; 261 } 262 hptr->h_aliases[i] = NULL; 263 264 return (HOST_R_OK); 265 } 266 #endif /* !HOSTENT_DATA */ 267 #else /* HOST_R_RETURN */ 268 static int gethostent_r_unknown_system = 0; 269 #endif /* HOST_R_RETURN */ 270 #endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */ 271 /*! \file */ 272