1 /* $NetBSD: getservent_r.c,v 1.1.1.1 2009/04/12 15:33:44 christos Exp $ */ 2 3 /* 4 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (c) 1998-1999 by Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 17 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #if defined(LIBC_SCCS) && !defined(lint) 21 static const char rcsid[] = "Id: getservent_r.c,v 1.6 2006/08/01 01:14:16 marka Exp"; 22 #endif /* LIBC_SCCS and not lint */ 23 24 #include <port_before.h> 25 #if !defined(_REENTRANT) || !defined(DO_PTHREADS) 26 static int getservent_r_not_required = 0; 27 #else 28 #include <errno.h> 29 #include <string.h> 30 #include <stdio.h> 31 #include <sys/types.h> 32 #include <netinet/in.h> 33 #include <netdb.h> 34 #include <sys/param.h> 35 #include <port_after.h> 36 37 #ifdef SERV_R_RETURN 38 39 static SERV_R_RETURN 40 copy_servent(struct servent *, struct servent *, SERV_R_COPY_ARGS); 41 42 SERV_R_RETURN 43 getservbyname_r(const char *name, const char *proto, 44 struct servent *sptr, SERV_R_ARGS) { 45 struct servent *se = getservbyname(name, proto); 46 #ifdef SERV_R_SETANSWER 47 int n = 0; 48 49 if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0) 50 *answerp = NULL; 51 else 52 *answerp = sptr; 53 54 return (n); 55 #else 56 if (se == NULL) 57 return (SERV_R_BAD); 58 59 return (copy_servent(se, sptr, SERV_R_COPY)); 60 #endif 61 } 62 63 SERV_R_RETURN 64 getservbyport_r(int port, const char *proto, 65 struct servent *sptr, SERV_R_ARGS) { 66 struct servent *se = getservbyport(port, proto); 67 #ifdef SERV_R_SETANSWER 68 int n = 0; 69 70 if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0) 71 *answerp = NULL; 72 else 73 *answerp = sptr; 74 75 return (n); 76 #else 77 if (se == NULL) 78 return (SERV_R_BAD); 79 80 return (copy_servent(se, sptr, SERV_R_COPY)); 81 #endif 82 } 83 84 /*% 85 * These assume a single context is in operation per thread. 86 * If this is not the case we will need to call irs directly 87 * rather than through the base functions. 88 */ 89 90 SERV_R_RETURN 91 getservent_r(struct servent *sptr, SERV_R_ARGS) { 92 struct servent *se = getservent(); 93 #ifdef SERV_R_SETANSWER 94 int n = 0; 95 96 if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0) 97 *answerp = NULL; 98 else 99 *answerp = sptr; 100 101 return (n); 102 #else 103 if (se == NULL) 104 return (SERV_R_BAD); 105 106 return (copy_servent(se, sptr, SERV_R_COPY)); 107 #endif 108 } 109 110 SERV_R_SET_RETURN 111 #ifdef SERV_R_ENT_ARGS 112 setservent_r(int stay_open, SERV_R_ENT_ARGS) 113 #else 114 setservent_r(int stay_open) 115 #endif 116 { 117 #ifdef SERV_R_ENT_UNUSED 118 SERV_R_ENT_UNUSED; 119 #endif 120 setservent(stay_open); 121 #ifdef SERV_R_SET_RESULT 122 return (SERV_R_SET_RESULT); 123 #endif 124 } 125 126 SERV_R_END_RETURN 127 #ifdef SERV_R_ENT_ARGS 128 endservent_r(SERV_R_ENT_ARGS) 129 #else 130 endservent_r() 131 #endif 132 { 133 #ifdef SERV_R_ENT_UNUSED 134 SERV_R_ENT_UNUSED; 135 #endif 136 endservent(); 137 SERV_R_END_RESULT(SERV_R_OK); 138 } 139 140 /* Private */ 141 142 #ifndef SERVENT_DATA 143 static SERV_R_RETURN 144 copy_servent(struct servent *se, struct servent *sptr, SERV_R_COPY_ARGS) { 145 char *cp; 146 int i, n; 147 int numptr, len; 148 149 /* Find out the amount of space required to store the answer. */ 150 numptr = 1; /*%< NULL ptr */ 151 len = (char *)ALIGN(buf) - buf; 152 for (i = 0; se->s_aliases[i]; i++, numptr++) { 153 len += strlen(se->s_aliases[i]) + 1; 154 } 155 len += strlen(se->s_name) + 1; 156 len += strlen(se->s_proto) + 1; 157 len += numptr * sizeof(char*); 158 159 if (len > (int)buflen) { 160 errno = ERANGE; 161 return (SERV_R_BAD); 162 } 163 164 /* copy port value */ 165 sptr->s_port = se->s_port; 166 167 cp = (char *)ALIGN(buf) + numptr * sizeof(char *); 168 169 /* copy official name */ 170 n = strlen(se->s_name) + 1; 171 strcpy(cp, se->s_name); 172 sptr->s_name = cp; 173 cp += n; 174 175 /* copy aliases */ 176 sptr->s_aliases = (char **)ALIGN(buf); 177 for (i = 0 ; se->s_aliases[i]; i++) { 178 n = strlen(se->s_aliases[i]) + 1; 179 strcpy(cp, se->s_aliases[i]); 180 sptr->s_aliases[i] = cp; 181 cp += n; 182 } 183 sptr->s_aliases[i] = NULL; 184 185 /* copy proto */ 186 n = strlen(se->s_proto) + 1; 187 strcpy(cp, se->s_proto); 188 sptr->s_proto = cp; 189 cp += n; 190 191 return (SERV_R_OK); 192 } 193 #else /* !SERVENT_DATA */ 194 static int 195 copy_servent(struct servent *se, struct servent *sptr, SERV_R_COPY_ARGS) { 196 char *cp, *eob; 197 int i, n; 198 199 /* copy port value */ 200 sptr->s_port = se->s_port; 201 202 /* copy official name */ 203 cp = sdptr->line; 204 eob = sdptr->line + sizeof(sdptr->line); 205 if ((n = strlen(se->s_name) + 1) < (eob - cp)) { 206 strcpy(cp, se->s_name); 207 sptr->s_name = cp; 208 cp += n; 209 } else { 210 return (-1); 211 } 212 213 /* copy aliases */ 214 i = 0; 215 sptr->s_aliases = sdptr->serv_aliases; 216 while (se->s_aliases[i] && i < (_MAXALIASES-1)) { 217 if ((n = strlen(se->s_aliases[i]) + 1) < (eob - cp)) { 218 strcpy(cp, se->s_aliases[i]); 219 sptr->s_aliases[i] = cp; 220 cp += n; 221 } else { 222 break; 223 } 224 i++; 225 } 226 sptr->s_aliases[i] = NULL; 227 228 /* copy proto */ 229 if ((n = strlen(se->s_proto) + 1) < (eob - cp)) { 230 strcpy(cp, se->s_proto); 231 sptr->s_proto = cp; 232 cp += n; 233 } else { 234 return (-1); 235 } 236 237 return (SERV_R_OK); 238 } 239 #endif /* !SERVENT_DATA */ 240 #else /*SERV_R_RETURN */ 241 static int getservent_r_unknown_system = 0; 242 #endif /*SERV_R_RETURN */ 243 #endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */ 244 /*! \file */ 245