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