1 /* 2 * Copyright 1999-2002 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * Copyright (c) 1998-1999 by Internet Software Consortium. 8 * 9 * Permission to use, copy, modify, and distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 14 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 15 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 16 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 17 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 18 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 19 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 20 * SOFTWARE. 21 */ 22 23 #pragma ident "%Z%%M% %I% %E% SMI" 24 25 #if defined(LIBC_SCCS) && !defined(lint) 26 static const char rcsid[] = "$Id: getprotoent_r.c,v 8.6 2001/11/01 08:02:14 marka Exp $"; 27 #endif /* LIBC_SCCS and not lint */ 28 29 #include <port_before.h> 30 #if !defined(_REENTRANT) || !defined(DO_PTHREADS) 31 static int getprotoent_r_not_required = 0; 32 #else 33 #include <errno.h> 34 #include <string.h> 35 #include <stdio.h> 36 #include <sys/types.h> 37 #include <netinet/in.h> 38 #include <netdb.h> 39 #include <port_after.h> 40 41 #ifdef PROTO_R_RETURN 42 43 static PROTO_R_RETURN 44 copy_protoent(struct protoent *, struct protoent *, PROTO_R_COPY_ARGS); 45 46 PROTO_R_RETURN 47 getprotobyname_r(const char *name, struct protoent *pptr, PROTO_R_ARGS) { 48 struct protoent *pe = getprotobyname(name); 49 #ifdef PROTO_R_SETANSWER 50 int n = 0; 51 52 if (pe == NULL || (n = copy_protoent(pe, pptr, PROTO_R_COPY)) != 0) 53 *answerp = NULL; 54 else 55 *answerp = pptr; 56 57 return (n); 58 #else 59 if (pe == NULL) 60 return (PROTO_R_BAD); 61 62 return (copy_protoent(pe, pptr, PROTO_R_COPY)); 63 #endif 64 } 65 66 PROTO_R_RETURN 67 getprotobynumber_r(int proto, struct protoent *pptr, PROTO_R_ARGS) { 68 struct protoent *pe = getprotobynumber(proto); 69 #ifdef PROTO_R_SETANSWER 70 int n = 0; 71 72 if (pe == NULL || (n = copy_protoent(pe, pptr, PROTO_R_COPY)) != 0) 73 *answerp = NULL; 74 else 75 *answerp = pptr; 76 77 return (n); 78 #else 79 if (pe == NULL) 80 return (PROTO_R_BAD); 81 82 return (copy_protoent(pe, pptr, PROTO_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 92 PROTO_R_RETURN 93 getprotoent_r(struct protoent *pptr, PROTO_R_ARGS) { 94 struct protoent *pe = getprotoent(); 95 #ifdef PROTO_R_SETANSWER 96 int n = 0; 97 98 if (pe == NULL || (n = copy_protoent(pe, pptr, PROTO_R_COPY)) != 0) 99 *answerp = NULL; 100 else 101 *answerp = pptr; 102 103 return (n); 104 #else 105 if (pe == NULL) 106 return (PROTO_R_BAD); 107 108 return (copy_protoent(pe, pptr, PROTO_R_COPY)); 109 #endif 110 } 111 112 PROTO_R_SET_RETURN 113 #ifdef PROTO_R_ENT_ARGS 114 setprotoent_r(int stay_open, PROTO_R_ENT_ARGS) 115 #else 116 setprotoent_r(int stay_open) 117 #endif 118 { 119 setprotoent(stay_open); 120 #ifdef PROTO_R_SET_RESULT 121 return (PROTO_R_SET_RESULT); 122 #endif 123 } 124 125 PROTO_R_END_RETURN 126 #ifdef PROTO_R_ENT_ARGS 127 endprotoent_r(PROTO_R_ENT_ARGS) 128 #else 129 endprotoent_r() 130 #endif 131 { 132 endprotoent(); 133 PROTO_R_END_RESULT(PROTO_R_OK); 134 } 135 136 /* Private */ 137 138 #ifndef PROTOENT_DATA 139 static PROTO_R_RETURN 140 copy_protoent(struct protoent *pe, struct protoent *pptr, PROTO_R_COPY_ARGS) { 141 char *cp; 142 int i, n; 143 int numptr, len; 144 145 /* Find out the amount of space required to store the answer. */ 146 numptr = 1; /* NULL ptr */ 147 len = (char *)ALIGN(buf) - buf; 148 for (i = 0; pe->p_aliases[i]; i++, numptr++) { 149 len += strlen(pe->p_aliases[i]) + 1; 150 } 151 len += strlen(pe->p_name) + 1; 152 len += numptr * sizeof(char*); 153 154 if (len > (int)buflen) { 155 errno = ERANGE; 156 return (PROTO_R_BAD); 157 } 158 159 /* copy protocol value*/ 160 pptr->p_proto = pe->p_proto; 161 162 cp = (char *)ALIGN(buf) + numptr * sizeof(char *); 163 164 /* copy official name */ 165 n = strlen(pe->p_name) + 1; 166 strcpy(cp, pe->p_name); 167 pptr->p_name = cp; 168 cp += n; 169 170 /* copy aliases */ 171 pptr->p_aliases = (char **)ALIGN(buf); 172 for (i = 0 ; pe->p_aliases[i]; i++) { 173 n = strlen(pe->p_aliases[i]) + 1; 174 strcpy(cp, pe->p_aliases[i]); 175 pptr->p_aliases[i] = cp; 176 cp += n; 177 } 178 pptr->p_aliases[i] = NULL; 179 180 return (PROTO_R_OK); 181 } 182 #else /* !PROTOENT_DATA */ 183 static int 184 copy_protoent(struct protoent *pe, struct protoent *pptr, PROTO_R_COPY_ARGS) { 185 char *cp, *eob; 186 int i, n; 187 188 /* copy protocol value */ 189 pptr->p_proto = pe->p_proto; 190 191 /* copy official name */ 192 cp = pdptr->line; 193 eob = pdptr->line + sizeof(pdptr->line); 194 if ((n = strlen(pe->p_name) + 1) < (eob - cp)) { 195 strcpy(cp, pe->p_name); 196 pptr->p_name = cp; 197 cp += n; 198 } else { 199 return (-1); 200 } 201 202 /* copy aliases */ 203 i = 0; 204 pptr->p_aliases = pdptr->proto_aliases; 205 while (pe->p_aliases[i] && i < (_MAXALIASES-1)) { 206 if ((n = strlen(pe->p_aliases[i]) + 1) < (eob - cp)) { 207 strcpy(cp, pe->p_aliases[i]); 208 pptr->p_aliases[i] = cp; 209 cp += n; 210 } else { 211 break; 212 } 213 i++; 214 } 215 pptr->p_aliases[i] = NULL; 216 217 return (PROTO_R_OK); 218 } 219 #endif /* PROTOENT_DATA */ 220 #else /* PROTO_R_RETURN */ 221 static int getprotoent_r_unknown_system = 0; 222 #endif /* PROTO_R_RETURN */ 223 #endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */ 224