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