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