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 getnetent_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 NET_R_RETURN 32 33 static NET_R_RETURN 34 copy_netent(struct netent *, struct netent *, NET_R_COPY_ARGS); 35 36 NET_R_RETURN 37 getnetbyname_r(const char *name, struct netent *nptr, NET_R_ARGS) { 38 struct netent *ne = getnetbyname(name); 39 #ifdef NET_R_SETANSWER 40 int n = 0; 41 42 if (ne == NULL || (n = copy_netent(ne, nptr, NET_R_COPY)) != 0) 43 *answerp = NULL; 44 else 45 *answerp = ne; 46 if (ne == NULL) 47 *h_errnop = h_errno; 48 return (n); 49 #else 50 if (ne == NULL) 51 return (NET_R_BAD); 52 53 return (copy_netent(ne, nptr, NET_R_COPY)); 54 #endif 55 } 56 57 #ifndef GETNETBYADDR_ADDR_T 58 #define GETNETBYADDR_ADDR_T long 59 #endif 60 NET_R_RETURN 61 getnetbyaddr_r(GETNETBYADDR_ADDR_T addr, int type, struct netent *nptr, NET_R_ARGS) { 62 struct netent *ne = getnetbyaddr(addr, type); 63 #ifdef NET_R_SETANSWER 64 int n = 0; 65 66 if (ne == NULL || (n = copy_netent(ne, nptr, NET_R_COPY)) != 0) 67 *answerp = NULL; 68 else 69 *answerp = ne; 70 if (ne == NULL) 71 *h_errnop = h_errno; 72 return (n); 73 #else 74 75 if (ne == NULL) 76 return (NET_R_BAD); 77 78 return (copy_netent(ne, nptr, NET_R_COPY)); 79 #endif 80 } 81 82 /*% 83 * These assume a single context is in operation per thread. 84 * If this is not the case we will need to call irs directly 85 * rather than through the base functions. 86 */ 87 88 NET_R_RETURN 89 getnetent_r(struct netent *nptr, NET_R_ARGS) { 90 struct netent *ne = getnetent(); 91 #ifdef NET_R_SETANSWER 92 int n = 0; 93 94 if (ne == NULL || (n = copy_netent(ne, nptr, NET_R_COPY)) != 0) 95 *answerp = NULL; 96 else 97 *answerp = ne; 98 if (ne == NULL) 99 *h_errnop = h_errno; 100 return (n); 101 #else 102 103 if (ne == NULL) 104 return (NET_R_BAD); 105 106 return (copy_netent(ne, nptr, NET_R_COPY)); 107 #endif 108 } 109 110 NET_R_SET_RETURN 111 #ifdef NET_R_ENT_ARGS 112 setnetent_r(int stay_open, NET_R_ENT_ARGS) 113 #else 114 setnetent_r(int stay_open) 115 #endif 116 { 117 #ifdef NET_R_ENT_ARGS 118 UNUSED(ndptr); 119 #endif 120 setnetent(stay_open); 121 #ifdef NET_R_SET_RESULT 122 return (NET_R_SET_RESULT); 123 #endif 124 } 125 126 NET_R_END_RETURN 127 #ifdef NET_R_ENT_ARGS 128 endnetent_r(NET_R_ENT_ARGS) 129 #else 130 endnetent_r() 131 #endif 132 { 133 #ifdef NET_R_ENT_ARGS 134 UNUSED(ndptr); 135 #endif 136 endnetent(); 137 NET_R_END_RESULT(NET_R_OK); 138 } 139 140 /* Private */ 141 142 #ifndef NETENT_DATA 143 static NET_R_RETURN 144 copy_netent(struct netent *ne, struct netent *nptr, NET_R_COPY_ARGS) { 145 char *cp; 146 int i, n; 147 int numptr, len; 148 149 /* Find out the amount of space required to store the answer. */ 150 numptr = 1; /*%< NULL ptr */ 151 len = (char *)ALIGN(buf) - buf; 152 for (i = 0; ne->n_aliases[i]; i++, numptr++) { 153 len += strlen(ne->n_aliases[i]) + 1; 154 } 155 len += strlen(ne->n_name) + 1; 156 len += numptr * sizeof(char*); 157 158 if (len > (int)buflen) { 159 errno = ERANGE; 160 return (NET_R_BAD); 161 } 162 163 /* copy net value and type */ 164 nptr->n_addrtype = ne->n_addrtype; 165 nptr->n_net = ne->n_net; 166 167 cp = (char *)ALIGN(buf) + numptr * sizeof(char *); 168 169 /* copy official name */ 170 n = strlen(ne->n_name) + 1; 171 strcpy(cp, ne->n_name); 172 nptr->n_name = cp; 173 cp += n; 174 175 /* copy aliases */ 176 nptr->n_aliases = (char **)ALIGN(buf); 177 for (i = 0 ; ne->n_aliases[i]; i++) { 178 n = strlen(ne->n_aliases[i]) + 1; 179 strcpy(cp, ne->n_aliases[i]); 180 nptr->n_aliases[i] = cp; 181 cp += n; 182 } 183 nptr->n_aliases[i] = NULL; 184 185 return (NET_R_OK); 186 } 187 #else /* !NETENT_DATA */ 188 static int 189 copy_netent(struct netent *ne, struct netent *nptr, NET_R_COPY_ARGS) { 190 char *cp, *eob; 191 int i, n; 192 193 /* copy net value and type */ 194 nptr->n_addrtype = ne->n_addrtype; 195 nptr->n_net = ne->n_net; 196 197 /* copy official name */ 198 cp = ndptr->line; 199 eob = ndptr->line + sizeof(ndptr->line); 200 if ((n = strlen(ne->n_name) + 1) < (eob - cp)) { 201 strcpy(cp, ne->n_name); 202 nptr->n_name = cp; 203 cp += n; 204 } else { 205 return (-1); 206 } 207 208 /* copy aliases */ 209 i = 0; 210 nptr->n_aliases = ndptr->net_aliases; 211 while (ne->n_aliases[i] && i < (_MAXALIASES-1)) { 212 if ((n = strlen(ne->n_aliases[i]) + 1) < (eob - cp)) { 213 strcpy(cp, ne->n_aliases[i]); 214 nptr->n_aliases[i] = cp; 215 cp += n; 216 } else { 217 break; 218 } 219 i++; 220 } 221 nptr->n_aliases[i] = NULL; 222 223 return (NET_R_OK); 224 } 225 #endif /* !NETENT_DATA */ 226 #else /* NET_R_RETURN */ 227 static int getnetent_r_unknown_system = 0; 228 #endif /* NET_R_RETURN */ 229 #endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */ 230 /*! \file */ 231