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