Home | History | Annotate | Line # | Download | only in irs
getservent_r.c revision 1.1.1.1.14.1
      1 /*	$NetBSD: getservent_r.c,v 1.1.1.1.14.1 2012/10/30 18:55:28 yamt 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