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) 19 static 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 36 static PROTO_R_RETURN 37 copy_protoent(struct protoent *, struct protoent *, PROTO_R_COPY_ARGS); 38 39 PROTO_R_RETURN 40 getprotobyname_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 59 PROTO_R_RETURN 60 getprotobynumber_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 85 PROTO_R_RETURN 86 getprotoent_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 105 PROTO_R_SET_RETURN 106 #ifdef PROTO_R_ENT_ARGS 107 setprotoent_r(int stay_open, PROTO_R_ENT_ARGS) 108 #else 109 setprotoent_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 121 PROTO_R_END_RETURN 122 #ifdef PROTO_R_ENT_ARGS 123 endprotoent_r(PROTO_R_ENT_ARGS) 124 #else 125 endprotoent_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 138 static PROTO_R_RETURN 139 copy_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 */ 182 static int 183 copy_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