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: getservent_r.c,v 8.5 2001/11/01 08:02:16 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 getservent_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 <sys/param.h> 40 #include <port_after.h> 41 42 #ifdef SERV_R_RETURN 43 44 static SERV_R_RETURN 45 copy_servent(struct servent *, struct servent *, SERV_R_COPY_ARGS); 46 47 SERV_R_RETURN 48 getservbyname_r(const char *name, const char *proto, 49 struct servent *sptr, SERV_R_ARGS) { 50 struct servent *se = getservbyname(name, proto); 51 #ifdef SERV_R_SETANSWER 52 int n = 0; 53 54 if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0) 55 *answerp = NULL; 56 else 57 *answerp = sptr; 58 59 return (n); 60 #else 61 if (se == NULL) 62 return (SERV_R_BAD); 63 64 return (copy_servent(se, sptr, SERV_R_COPY)); 65 #endif 66 } 67 68 SERV_R_RETURN 69 getservbyport_r(int port, const char *proto, 70 struct servent *sptr, SERV_R_ARGS) { 71 struct servent *se = getservbyport(port, proto); 72 #ifdef SERV_R_SETANSWER 73 int n = 0; 74 75 if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0) 76 *answerp = NULL; 77 else 78 *answerp = sptr; 79 80 return (n); 81 #else 82 if (se == NULL) 83 return (SERV_R_BAD); 84 85 return (copy_servent(se, sptr, SERV_R_COPY)); 86 #endif 87 } 88 89 /* 90 * These assume a single context is in operation per thread. 91 * If this is not the case we will need to call irs directly 92 * rather than through the base functions. 93 */ 94 95 SERV_R_RETURN 96 getservent_r(struct servent *sptr, SERV_R_ARGS) { 97 struct servent *se = getservent(); 98 #ifdef SERV_R_SETANSWER 99 int n = 0; 100 101 if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0) 102 *answerp = NULL; 103 else 104 *answerp = sptr; 105 106 return (n); 107 #else 108 if (se == NULL) 109 return (SERV_R_BAD); 110 111 return (copy_servent(se, sptr, SERV_R_COPY)); 112 #endif 113 } 114 115 SERV_R_SET_RETURN 116 #ifdef SERV_R_ENT_ARGS 117 setservent_r(int stay_open, SERV_R_ENT_ARGS) 118 #else 119 setservent_r(int stay_open) 120 #endif 121 { 122 123 setservent(stay_open); 124 #ifdef SERV_R_SET_RESULT 125 return (SERV_R_SET_RESULT); 126 #endif 127 } 128 129 SERV_R_END_RETURN 130 #ifdef SERV_R_ENT_ARGS 131 endservent_r(SERV_R_ENT_ARGS) 132 #else 133 endservent_r() 134 #endif 135 { 136 137 endservent(); 138 SERV_R_END_RESULT(SERV_R_OK); 139 } 140 141 /* Private */ 142 143 #ifndef SERVENT_DATA 144 static SERV_R_RETURN 145 copy_servent(struct servent *se, struct servent *sptr, SERV_R_COPY_ARGS) { 146 char *cp; 147 int i, n; 148 int numptr, len; 149 150 /* Find out the amount of space required to store the answer. */ 151 numptr = 1; /* NULL ptr */ 152 len = (char *)ALIGN(buf) - buf; 153 for (i = 0; se->s_aliases[i]; i++, numptr++) { 154 len += strlen(se->s_aliases[i]) + 1; 155 } 156 len += strlen(se->s_name) + 1; 157 len += strlen(se->s_proto) + 1; 158 len += numptr * sizeof(char*); 159 160 if (len > (int)buflen) { 161 errno = ERANGE; 162 return (SERV_R_BAD); 163 } 164 165 /* copy port value */ 166 sptr->s_port = se->s_port; 167 168 cp = (char *)ALIGN(buf) + numptr * sizeof(char *); 169 170 /* copy official name */ 171 n = strlen(se->s_name) + 1; 172 strcpy(cp, se->s_name); 173 sptr->s_name = cp; 174 cp += n; 175 176 /* copy aliases */ 177 sptr->s_aliases = (char **)ALIGN(buf); 178 for (i = 0 ; se->s_aliases[i]; i++) { 179 n = strlen(se->s_aliases[i]) + 1; 180 strcpy(cp, se->s_aliases[i]); 181 sptr->s_aliases[i] = cp; 182 cp += n; 183 } 184 sptr->s_aliases[i] = NULL; 185 186 /* copy proto */ 187 n = strlen(se->s_proto) + 1; 188 strcpy(cp, se->s_proto); 189 sptr->s_proto = cp; 190 cp += n; 191 192 return (SERV_R_OK); 193 } 194 #else /* !SERVENT_DATA */ 195 static int 196 copy_servent(struct servent *se, struct servent *sptr, SERV_R_COPY_ARGS) { 197 char *cp, *eob; 198 int i, n; 199 200 /* copy port value */ 201 sptr->s_port = se->s_port; 202 203 /* copy official name */ 204 cp = ndptr->line; 205 eob = ndptr->line + sizeof(ndptr->line); 206 if ((n = strlen(se->s_name) + 1) < (eob - cp)) { 207 strcpy(cp, se->s_name); 208 sptr->s_name = cp; 209 cp += n; 210 } else { 211 return (-1); 212 } 213 214 /* copy aliases */ 215 i = 0; 216 sptr->s_aliases = ndptr->serv_aliases; 217 while (se->s_aliases[i] && i < (_MAXALIASES-1)) { 218 if ((n = strlen(se->s_aliases[i]) + 1) < (eob - cp)) { 219 strcpy(cp, se->s_aliases[i]); 220 sptr->s_aliases[i] = cp; 221 cp += n; 222 } else { 223 break; 224 } 225 i++; 226 } 227 sptr->s_aliases[i] = NULL; 228 229 /* copy proto */ 230 if ((n = strlen(se->s_proto) + 1) < (eob - cp)) { 231 strcpy(cp, se->s_proto); 232 sptr->s_proto = cp; 233 cp += n; 234 } else { 235 return (-1); 236 } 237 238 return (SERV_R_OK); 239 } 240 #endif /* !SERVENT_DATA */ 241 #else /*SERV_R_RETURN */ 242 static int getservent_r_unknown_system = 0; 243 #endif /*SERV_R_RETURN */ 244 #endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */ 245