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: getprotoent_r.c,v 1.6 2006/08/01 01:14:16 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 getprotoent_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 <port_after.h> 33 34#ifdef PROTO_R_RETURN 35 36static PROTO_R_RETURN 37copy_protoent(struct protoent *, struct protoent *, PROTO_R_COPY_ARGS); 38 39PROTO_R_RETURN 40getprotobyname_r(const char *name, struct protoent *pptr, PROTO_R_ARGS) { 41 struct protoent *pe = getprotobyname(name); 42#ifdef PROTO_R_SETANSWER 43 int n = 0; 44 45 if (pe == NULL || (n = copy_protoent(pe, pptr, PROTO_R_COPY)) != 0) 46 *answerp = NULL; 47 else 48 *answerp = pptr; 49 50 return (n); 51#else 52 if (pe == NULL) 53 return (PROTO_R_BAD); 54 55 return (copy_protoent(pe, pptr, PROTO_R_COPY)); 56#endif 57} 58 59PROTO_R_RETURN 60getprotobynumber_r(int proto, struct protoent *pptr, PROTO_R_ARGS) { 61 struct protoent *pe = getprotobynumber(proto); 62#ifdef PROTO_R_SETANSWER 63 int n = 0; 64 65 if (pe == NULL || (n = copy_protoent(pe, pptr, PROTO_R_COPY)) != 0) 66 *answerp = NULL; 67 else 68 *answerp = pptr; 69 70 return (n); 71#else 72 if (pe == NULL) 73 return (PROTO_R_BAD); 74 75 return (copy_protoent(pe, pptr, PROTO_R_COPY)); 76#endif 77} 78 79/*% 80 * These assume a single context is in operation per thread. 81 * If this is not the case we will need to call irs directly 82 * rather than through the base functions. 83 */ 84 85PROTO_R_RETURN 86getprotoent_r(struct protoent *pptr, PROTO_R_ARGS) { 87 struct protoent *pe = getprotoent(); 88#ifdef PROTO_R_SETANSWER 89 int n = 0; 90 91 if (pe == NULL || (n = copy_protoent(pe, pptr, PROTO_R_COPY)) != 0) 92 *answerp = NULL; 93 else 94 *answerp = pptr; 95 96 return (n); 97#else 98 if (pe == NULL) 99 return (PROTO_R_BAD); 100 101 return (copy_protoent(pe, pptr, PROTO_R_COPY)); 102#endif 103} 104 105PROTO_R_SET_RETURN 106#ifdef PROTO_R_ENT_ARGS 107setprotoent_r(int stay_open, PROTO_R_ENT_ARGS) 108#else 109setprotoent_r(int stay_open) 110#endif 111{ 112#ifdef PROTO_R_ENT_UNUSED 113 PROTO_R_ENT_UNUSED; 114#endif 115 setprotoent(stay_open); 116#ifdef PROTO_R_SET_RESULT 117 return (PROTO_R_SET_RESULT); 118#endif 119} 120 121PROTO_R_END_RETURN 122#ifdef PROTO_R_ENT_ARGS 123endprotoent_r(PROTO_R_ENT_ARGS) 124#else 125endprotoent_r() 126#endif 127{ 128#ifdef PROTO_R_ENT_UNUSED 129 PROTO_R_ENT_UNUSED; 130#endif 131 endprotoent(); 132 PROTO_R_END_RESULT(PROTO_R_OK); 133} 134 135/* Private */ 136 137#ifndef PROTOENT_DATA 138static PROTO_R_RETURN 139copy_protoent(struct protoent *pe, struct protoent *pptr, PROTO_R_COPY_ARGS) { 140 char *cp; 141 int i, n; 142 int numptr, len; 143 144 /* Find out the amount of space required to store the answer. */ 145 numptr = 1; /*%< NULL ptr */ 146 len = (char *)ALIGN(buf) - buf; 147 for (i = 0; pe->p_aliases[i]; i++, numptr++) { 148 len += strlen(pe->p_aliases[i]) + 1; 149 } 150 len += strlen(pe->p_name) + 1; 151 len += numptr * sizeof(char*); 152 153 if (len > (int)buflen) { 154 errno = ERANGE; 155 return (PROTO_R_BAD); 156 } 157 158 /* copy protocol value*/ 159 pptr->p_proto = pe->p_proto; 160 161 cp = (char *)ALIGN(buf) + numptr * sizeof(char *); 162 163 /* copy official name */ 164 n = strlen(pe->p_name) + 1; 165 strcpy(cp, pe->p_name); 166 pptr->p_name = cp; 167 cp += n; 168 169 /* copy aliases */ 170 pptr->p_aliases = (char **)ALIGN(buf); 171 for (i = 0 ; pe->p_aliases[i]; i++) { 172 n = strlen(pe->p_aliases[i]) + 1; 173 strcpy(cp, pe->p_aliases[i]); 174 pptr->p_aliases[i] = cp; 175 cp += n; 176 } 177 pptr->p_aliases[i] = NULL; 178 179 return (PROTO_R_OK); 180} 181#else /* !PROTOENT_DATA */ 182static int 183copy_protoent(struct protoent *pe, struct protoent *pptr, PROTO_R_COPY_ARGS) { 184 char *cp, *eob; 185 int i, n; 186 187 /* copy protocol value */ 188 pptr->p_proto = pe->p_proto; 189 190 /* copy official name */ 191 cp = pdptr->line; 192 eob = pdptr->line + sizeof(pdptr->line); 193 if ((n = strlen(pe->p_name) + 1) < (eob - cp)) { 194 strcpy(cp, pe->p_name); 195 pptr->p_name = cp; 196 cp += n; 197 } else { 198 return (-1); 199 } 200 201 /* copy aliases */ 202 i = 0; 203 pptr->p_aliases = pdptr->proto_aliases; 204 while (pe->p_aliases[i] && i < (_MAXALIASES-1)) { 205 if ((n = strlen(pe->p_aliases[i]) + 1) < (eob - cp)) { 206 strcpy(cp, pe->p_aliases[i]); 207 pptr->p_aliases[i] = cp; 208 cp += n; 209 } else { 210 break; 211 } 212 i++; 213 } 214 pptr->p_aliases[i] = NULL; 215 216 return (PROTO_R_OK); 217} 218#endif /* PROTOENT_DATA */ 219#else /* PROTO_R_RETURN */ 220 static int getprotoent_r_unknown_system = 0; 221#endif /* PROTO_R_RETURN */ 222#endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */ 223/*! \file */ 224