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 #if defined(LIBC_SCCS) && !defined(lint) 19 static const char rcsid[] = "$Id: gethostent_r.c,v 1.9 2005/09/03 12:41:37 marka Exp $"; 20 #endif /* LIBC_SCCS and not lint */ 21 22 #include <port_before.h> 23 #if !defined(_REENTRANT) || !defined(DO_PTHREADS) 24 static int gethostent_r_not_required = 0; 25 #else 26 #include <errno.h> 27 #include <string.h> 28 #include <stdio.h> 29 #include <sys/types.h> 30 #include <netinet/in.h> 31 #include <netdb.h> 32 #include <sys/param.h> 33 #include <port_after.h> 34 35 #ifdef HOST_R_RETURN 36 37 static HOST_R_RETURN 38 copy_hostent(struct hostent *, struct hostent *, HOST_R_COPY_ARGS); 39 40 HOST_R_RETURN 41 gethostbyname_r(const char *name, struct hostent *hptr, HOST_R_ARGS) { 42 struct hostent *he = gethostbyname(name); 43 #ifdef HOST_R_SETANSWER 44 int n = 0; 45 #endif 46 47 #ifdef HOST_R_ERRNO 48 HOST_R_ERRNO; 49 #endif 50 51 #ifdef HOST_R_SETANSWER 52 if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) != 0) 53 *answerp = NULL; 54 else 55 *answerp = hptr; 56 57 return (n); 58 #else 59 if (he == NULL) 60 return (HOST_R_BAD); 61 62 return (copy_hostent(he, hptr, HOST_R_COPY)); 63 #endif 64 } 65 66 HOST_R_RETURN 67 gethostbyaddr_r(const char *addr, int len, int type, 68 struct hostent *hptr, HOST_R_ARGS) { 69 struct hostent *he = gethostbyaddr(addr, len, type); 70 #ifdef HOST_R_SETANSWER 71 int n = 0; 72 #endif 73 74 #ifdef HOST_R_ERRNO 75 HOST_R_ERRNO; 76 #endif 77 78 #ifdef HOST_R_SETANSWER 79 if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) != 0) 80 *answerp = NULL; 81 else 82 *answerp = hptr; 83 84 return (n); 85 #else 86 if (he == NULL) 87 return (HOST_R_BAD); 88 89 return (copy_hostent(he, hptr, HOST_R_COPY)); 90 #endif 91 } 92 93 /*% 94 * These assume a single context is in operation per thread. 95 * If this is not the case we will need to call irs directly 96 * rather than through the base functions. 97 */ 98 99 HOST_R_RETURN 100 gethostent_r(struct hostent *hptr, HOST_R_ARGS) { 101 struct hostent *he = gethostent(); 102 #ifdef HOST_R_SETANSWER 103 int n = 0; 104 #endif 105 106 #ifdef HOST_R_ERRNO 107 HOST_R_ERRNO; 108 #endif 109 110 #ifdef HOST_R_SETANSWER 111 if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) != 0) 112 *answerp = NULL; 113 else 114 *answerp = hptr; 115 116 return (n); 117 #else 118 if (he == NULL) 119 return (HOST_R_BAD); 120 121 return (copy_hostent(he, hptr, HOST_R_COPY)); 122 #endif 123 } 124 125 HOST_R_SET_RETURN 126 #ifdef HOST_R_ENT_ARGS 127 sethostent_r(int stay_open, HOST_R_ENT_ARGS) 128 #else 129 sethostent_r(int stay_open) 130 #endif 131 { 132 #ifdef HOST_R_ENT_ARGS 133 UNUSED(hdptr); 134 #endif 135 sethostent(stay_open); 136 #ifdef HOST_R_SET_RESULT 137 return (HOST_R_SET_RESULT); 138 #endif 139 } 140 141 HOST_R_END_RETURN 142 #ifdef HOST_R_ENT_ARGS 143 endhostent_r(HOST_R_ENT_ARGS) 144 #else 145 endhostent_r(void) 146 #endif 147 { 148 #ifdef HOST_R_ENT_ARGS 149 UNUSED(hdptr); 150 #endif 151 endhostent(); 152 HOST_R_END_RESULT(HOST_R_OK); 153 } 154 155 /* Private */ 156 157 #ifndef HOSTENT_DATA 158 static HOST_R_RETURN 159 copy_hostent(struct hostent *he, struct hostent *hptr, HOST_R_COPY_ARGS) { 160 char *cp; 161 char **ptr; 162 int i, n; 163 int nptr, len; 164 165 /* Find out the amount of space required to store the answer. */ 166 nptr = 2; /*%< NULL ptrs */ 167 len = (char *)ALIGN(buf) - buf; 168 for (i = 0; he->h_addr_list[i]; i++, nptr++) { 169 len += he->h_length; 170 } 171 for (i = 0; he->h_aliases[i]; i++, nptr++) { 172 len += strlen(he->h_aliases[i]) + 1; 173 } 174 len += strlen(he->h_name) + 1; 175 len += nptr * sizeof(char*); 176 177 if (len > buflen) { 178 errno = ERANGE; 179 return (HOST_R_BAD); 180 } 181 182 /* copy address size and type */ 183 hptr->h_addrtype = he->h_addrtype; 184 n = hptr->h_length = he->h_length; 185 186 ptr = (char **)ALIGN(buf); 187 cp = (char *)ALIGN(buf) + nptr * sizeof(char *); 188 189 /* copy address list */ 190 hptr->h_addr_list = ptr; 191 for (i = 0; he->h_addr_list[i]; i++ , ptr++) { 192 memcpy(cp, he->h_addr_list[i], n); 193 hptr->h_addr_list[i] = cp; 194 cp += n; 195 } 196 hptr->h_addr_list[i] = NULL; 197 ptr++; 198 199 /* copy official name */ 200 n = strlen(he->h_name) + 1; 201 strcpy(cp, he->h_name); 202 hptr->h_name = cp; 203 cp += n; 204 205 /* copy aliases */ 206 hptr->h_aliases = ptr; 207 for (i = 0 ; he->h_aliases[i]; i++) { 208 n = strlen(he->h_aliases[i]) + 1; 209 strcpy(cp, he->h_aliases[i]); 210 hptr->h_aliases[i] = cp; 211 cp += n; 212 } 213 hptr->h_aliases[i] = NULL; 214 215 return (HOST_R_OK); 216 } 217 #else /* !HOSTENT_DATA */ 218 static int 219 copy_hostent(struct hostent *he, struct hostent *hptr, HOST_R_COPY_ARGS) { 220 char *cp, *eob; 221 int i, n; 222 223 /* copy address size and type */ 224 hptr->h_addrtype = he->h_addrtype; 225 n = hptr->h_length = he->h_length; 226 227 /* copy up to first 35 addresses */ 228 i = 0; 229 cp = hdptr->hostbuf; 230 eob = hdptr->hostbuf + sizeof(hdptr->hostbuf); 231 hptr->h_addr_list = hdptr->h_addr_ptrs; 232 while (he->h_addr_list[i] && i < (_MAXADDRS)) { 233 if (n < (eob - cp)) { 234 memcpy(cp, he->h_addr_list[i], n); 235 hptr->h_addr_list[i] = cp; 236 cp += n; 237 } else { 238 break; 239 } 240 i++; 241 } 242 hptr->h_addr_list[i] = NULL; 243 244 /* copy official name */ 245 if ((n = strlen(he->h_name) + 1) < (eob - cp)) { 246 strcpy(cp, he->h_name); 247 hptr->h_name = cp; 248 cp += n; 249 } else { 250 return (-1); 251 } 252 253 /* copy aliases */ 254 i = 0; 255 hptr->h_aliases = hdptr->host_aliases; 256 while (he->h_aliases[i] && i < (_MAXALIASES-1)) { 257 if ((n = strlen(he->h_aliases[i]) + 1) < (eob - cp)) { 258 strcpy(cp, he->h_aliases[i]); 259 hptr->h_aliases[i] = cp; 260 cp += n; 261 } else { 262 break; 263 } 264 i++; 265 } 266 hptr->h_aliases[i] = NULL; 267 268 return (HOST_R_OK); 269 } 270 #endif /* !HOSTENT_DATA */ 271 #else /* HOST_R_RETURN */ 272 static int gethostent_r_unknown_system = 0; 273 #endif /* HOST_R_RETURN */ 274 #endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */ 275 /*! \file */ 276