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