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