10Sstevel@tonic-gate /*
2*11038SRao.Shoaib@Sun.COM * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
30Sstevel@tonic-gate * Copyright (c) 1998-1999 by Internet Software Consortium.
40Sstevel@tonic-gate *
50Sstevel@tonic-gate * Permission to use, copy, modify, and distribute this software for any
60Sstevel@tonic-gate * purpose with or without fee is hereby granted, provided that the above
70Sstevel@tonic-gate * copyright notice and this permission notice appear in all copies.
80Sstevel@tonic-gate *
9*11038SRao.Shoaib@Sun.COM * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
10*11038SRao.Shoaib@Sun.COM * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11*11038SRao.Shoaib@Sun.COM * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
12*11038SRao.Shoaib@Sun.COM * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13*11038SRao.Shoaib@Sun.COM * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14*11038SRao.Shoaib@Sun.COM * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
15*11038SRao.Shoaib@Sun.COM * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
160Sstevel@tonic-gate */
170Sstevel@tonic-gate
180Sstevel@tonic-gate #if defined(LIBC_SCCS) && !defined(lint)
19*11038SRao.Shoaib@Sun.COM static const char rcsid[] = "$Id: getservent_r.c,v 1.6 2006/08/01 01:14:16 marka Exp $";
200Sstevel@tonic-gate #endif /* LIBC_SCCS and not lint */
210Sstevel@tonic-gate
220Sstevel@tonic-gate #include <port_before.h>
230Sstevel@tonic-gate #if !defined(_REENTRANT) || !defined(DO_PTHREADS)
240Sstevel@tonic-gate static int getservent_r_not_required = 0;
250Sstevel@tonic-gate #else
260Sstevel@tonic-gate #include <errno.h>
270Sstevel@tonic-gate #include <string.h>
280Sstevel@tonic-gate #include <stdio.h>
290Sstevel@tonic-gate #include <sys/types.h>
300Sstevel@tonic-gate #include <netinet/in.h>
310Sstevel@tonic-gate #include <netdb.h>
320Sstevel@tonic-gate #include <sys/param.h>
330Sstevel@tonic-gate #include <port_after.h>
340Sstevel@tonic-gate
350Sstevel@tonic-gate #ifdef SERV_R_RETURN
360Sstevel@tonic-gate
370Sstevel@tonic-gate static SERV_R_RETURN
380Sstevel@tonic-gate copy_servent(struct servent *, struct servent *, SERV_R_COPY_ARGS);
390Sstevel@tonic-gate
400Sstevel@tonic-gate SERV_R_RETURN
getservbyname_r(const char * name,const char * proto,struct servent * sptr,SERV_R_ARGS)410Sstevel@tonic-gate getservbyname_r(const char *name, const char *proto,
420Sstevel@tonic-gate struct servent *sptr, SERV_R_ARGS) {
430Sstevel@tonic-gate struct servent *se = getservbyname(name, proto);
440Sstevel@tonic-gate #ifdef SERV_R_SETANSWER
450Sstevel@tonic-gate int n = 0;
460Sstevel@tonic-gate
470Sstevel@tonic-gate if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0)
480Sstevel@tonic-gate *answerp = NULL;
490Sstevel@tonic-gate else
500Sstevel@tonic-gate *answerp = sptr;
510Sstevel@tonic-gate
520Sstevel@tonic-gate return (n);
530Sstevel@tonic-gate #else
540Sstevel@tonic-gate if (se == NULL)
550Sstevel@tonic-gate return (SERV_R_BAD);
560Sstevel@tonic-gate
570Sstevel@tonic-gate return (copy_servent(se, sptr, SERV_R_COPY));
580Sstevel@tonic-gate #endif
590Sstevel@tonic-gate }
600Sstevel@tonic-gate
610Sstevel@tonic-gate SERV_R_RETURN
getservbyport_r(int port,const char * proto,struct servent * sptr,SERV_R_ARGS)620Sstevel@tonic-gate getservbyport_r(int port, const char *proto,
630Sstevel@tonic-gate struct servent *sptr, SERV_R_ARGS) {
640Sstevel@tonic-gate struct servent *se = getservbyport(port, proto);
650Sstevel@tonic-gate #ifdef SERV_R_SETANSWER
660Sstevel@tonic-gate int n = 0;
670Sstevel@tonic-gate
680Sstevel@tonic-gate if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0)
690Sstevel@tonic-gate *answerp = NULL;
700Sstevel@tonic-gate else
710Sstevel@tonic-gate *answerp = sptr;
720Sstevel@tonic-gate
730Sstevel@tonic-gate return (n);
740Sstevel@tonic-gate #else
750Sstevel@tonic-gate if (se == NULL)
760Sstevel@tonic-gate return (SERV_R_BAD);
770Sstevel@tonic-gate
780Sstevel@tonic-gate return (copy_servent(se, sptr, SERV_R_COPY));
790Sstevel@tonic-gate #endif
800Sstevel@tonic-gate }
810Sstevel@tonic-gate
82*11038SRao.Shoaib@Sun.COM /*%
830Sstevel@tonic-gate * These assume a single context is in operation per thread.
840Sstevel@tonic-gate * If this is not the case we will need to call irs directly
850Sstevel@tonic-gate * rather than through the base functions.
860Sstevel@tonic-gate */
870Sstevel@tonic-gate
880Sstevel@tonic-gate SERV_R_RETURN
getservent_r(struct servent * sptr,SERV_R_ARGS)890Sstevel@tonic-gate getservent_r(struct servent *sptr, SERV_R_ARGS) {
900Sstevel@tonic-gate struct servent *se = getservent();
910Sstevel@tonic-gate #ifdef SERV_R_SETANSWER
920Sstevel@tonic-gate int n = 0;
930Sstevel@tonic-gate
940Sstevel@tonic-gate if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0)
950Sstevel@tonic-gate *answerp = NULL;
960Sstevel@tonic-gate else
970Sstevel@tonic-gate *answerp = sptr;
980Sstevel@tonic-gate
990Sstevel@tonic-gate return (n);
1000Sstevel@tonic-gate #else
1010Sstevel@tonic-gate if (se == NULL)
1020Sstevel@tonic-gate return (SERV_R_BAD);
1030Sstevel@tonic-gate
1040Sstevel@tonic-gate return (copy_servent(se, sptr, SERV_R_COPY));
1050Sstevel@tonic-gate #endif
1060Sstevel@tonic-gate }
1070Sstevel@tonic-gate
1080Sstevel@tonic-gate SERV_R_SET_RETURN
1090Sstevel@tonic-gate #ifdef SERV_R_ENT_ARGS
setservent_r(int stay_open,SERV_R_ENT_ARGS)1100Sstevel@tonic-gate setservent_r(int stay_open, SERV_R_ENT_ARGS)
1110Sstevel@tonic-gate #else
1120Sstevel@tonic-gate setservent_r(int stay_open)
1130Sstevel@tonic-gate #endif
1140Sstevel@tonic-gate {
115*11038SRao.Shoaib@Sun.COM #ifdef SERV_R_ENT_UNUSED
116*11038SRao.Shoaib@Sun.COM SERV_R_ENT_UNUSED;
117*11038SRao.Shoaib@Sun.COM #endif
1180Sstevel@tonic-gate setservent(stay_open);
1190Sstevel@tonic-gate #ifdef SERV_R_SET_RESULT
1200Sstevel@tonic-gate return (SERV_R_SET_RESULT);
1210Sstevel@tonic-gate #endif
1220Sstevel@tonic-gate }
1230Sstevel@tonic-gate
1240Sstevel@tonic-gate SERV_R_END_RETURN
1250Sstevel@tonic-gate #ifdef SERV_R_ENT_ARGS
endservent_r(SERV_R_ENT_ARGS)1260Sstevel@tonic-gate endservent_r(SERV_R_ENT_ARGS)
1270Sstevel@tonic-gate #else
1280Sstevel@tonic-gate endservent_r()
1290Sstevel@tonic-gate #endif
1300Sstevel@tonic-gate {
131*11038SRao.Shoaib@Sun.COM #ifdef SERV_R_ENT_UNUSED
132*11038SRao.Shoaib@Sun.COM SERV_R_ENT_UNUSED;
133*11038SRao.Shoaib@Sun.COM #endif
1340Sstevel@tonic-gate endservent();
1350Sstevel@tonic-gate SERV_R_END_RESULT(SERV_R_OK);
1360Sstevel@tonic-gate }
1370Sstevel@tonic-gate
1380Sstevel@tonic-gate /* Private */
1390Sstevel@tonic-gate
1400Sstevel@tonic-gate #ifndef SERVENT_DATA
1410Sstevel@tonic-gate static SERV_R_RETURN
copy_servent(struct servent * se,struct servent * sptr,SERV_R_COPY_ARGS)1420Sstevel@tonic-gate copy_servent(struct servent *se, struct servent *sptr, SERV_R_COPY_ARGS) {
1430Sstevel@tonic-gate char *cp;
1440Sstevel@tonic-gate int i, n;
1450Sstevel@tonic-gate int numptr, len;
1460Sstevel@tonic-gate
1470Sstevel@tonic-gate /* Find out the amount of space required to store the answer. */
148*11038SRao.Shoaib@Sun.COM numptr = 1; /*%< NULL ptr */
1490Sstevel@tonic-gate len = (char *)ALIGN(buf) - buf;
1500Sstevel@tonic-gate for (i = 0; se->s_aliases[i]; i++, numptr++) {
1510Sstevel@tonic-gate len += strlen(se->s_aliases[i]) + 1;
1520Sstevel@tonic-gate }
1530Sstevel@tonic-gate len += strlen(se->s_name) + 1;
1540Sstevel@tonic-gate len += strlen(se->s_proto) + 1;
1550Sstevel@tonic-gate len += numptr * sizeof(char*);
1560Sstevel@tonic-gate
1570Sstevel@tonic-gate if (len > (int)buflen) {
1580Sstevel@tonic-gate errno = ERANGE;
1590Sstevel@tonic-gate return (SERV_R_BAD);
1600Sstevel@tonic-gate }
1610Sstevel@tonic-gate
1620Sstevel@tonic-gate /* copy port value */
1630Sstevel@tonic-gate sptr->s_port = se->s_port;
1640Sstevel@tonic-gate
1650Sstevel@tonic-gate cp = (char *)ALIGN(buf) + numptr * sizeof(char *);
1660Sstevel@tonic-gate
1670Sstevel@tonic-gate /* copy official name */
1680Sstevel@tonic-gate n = strlen(se->s_name) + 1;
1690Sstevel@tonic-gate strcpy(cp, se->s_name);
1700Sstevel@tonic-gate sptr->s_name = cp;
1710Sstevel@tonic-gate cp += n;
1720Sstevel@tonic-gate
1730Sstevel@tonic-gate /* copy aliases */
1740Sstevel@tonic-gate sptr->s_aliases = (char **)ALIGN(buf);
1750Sstevel@tonic-gate for (i = 0 ; se->s_aliases[i]; i++) {
1760Sstevel@tonic-gate n = strlen(se->s_aliases[i]) + 1;
1770Sstevel@tonic-gate strcpy(cp, se->s_aliases[i]);
1780Sstevel@tonic-gate sptr->s_aliases[i] = cp;
1790Sstevel@tonic-gate cp += n;
1800Sstevel@tonic-gate }
1810Sstevel@tonic-gate sptr->s_aliases[i] = NULL;
1820Sstevel@tonic-gate
1830Sstevel@tonic-gate /* copy proto */
1840Sstevel@tonic-gate n = strlen(se->s_proto) + 1;
1850Sstevel@tonic-gate strcpy(cp, se->s_proto);
1860Sstevel@tonic-gate sptr->s_proto = cp;
1870Sstevel@tonic-gate cp += n;
1880Sstevel@tonic-gate
1890Sstevel@tonic-gate return (SERV_R_OK);
1900Sstevel@tonic-gate }
1910Sstevel@tonic-gate #else /* !SERVENT_DATA */
1920Sstevel@tonic-gate static int
copy_servent(struct servent * se,struct servent * sptr,SERV_R_COPY_ARGS)1930Sstevel@tonic-gate copy_servent(struct servent *se, struct servent *sptr, SERV_R_COPY_ARGS) {
1940Sstevel@tonic-gate char *cp, *eob;
1950Sstevel@tonic-gate int i, n;
1960Sstevel@tonic-gate
1970Sstevel@tonic-gate /* copy port value */
1980Sstevel@tonic-gate sptr->s_port = se->s_port;
1990Sstevel@tonic-gate
2000Sstevel@tonic-gate /* copy official name */
201*11038SRao.Shoaib@Sun.COM cp = sdptr->line;
202*11038SRao.Shoaib@Sun.COM eob = sdptr->line + sizeof(sdptr->line);
2030Sstevel@tonic-gate if ((n = strlen(se->s_name) + 1) < (eob - cp)) {
2040Sstevel@tonic-gate strcpy(cp, se->s_name);
2050Sstevel@tonic-gate sptr->s_name = cp;
2060Sstevel@tonic-gate cp += n;
2070Sstevel@tonic-gate } else {
2080Sstevel@tonic-gate return (-1);
2090Sstevel@tonic-gate }
2100Sstevel@tonic-gate
2110Sstevel@tonic-gate /* copy aliases */
2120Sstevel@tonic-gate i = 0;
213*11038SRao.Shoaib@Sun.COM sptr->s_aliases = sdptr->serv_aliases;
2140Sstevel@tonic-gate while (se->s_aliases[i] && i < (_MAXALIASES-1)) {
2150Sstevel@tonic-gate if ((n = strlen(se->s_aliases[i]) + 1) < (eob - cp)) {
2160Sstevel@tonic-gate strcpy(cp, se->s_aliases[i]);
2170Sstevel@tonic-gate sptr->s_aliases[i] = cp;
2180Sstevel@tonic-gate cp += n;
2190Sstevel@tonic-gate } else {
2200Sstevel@tonic-gate break;
2210Sstevel@tonic-gate }
2220Sstevel@tonic-gate i++;
2230Sstevel@tonic-gate }
2240Sstevel@tonic-gate sptr->s_aliases[i] = NULL;
2250Sstevel@tonic-gate
2260Sstevel@tonic-gate /* copy proto */
2270Sstevel@tonic-gate if ((n = strlen(se->s_proto) + 1) < (eob - cp)) {
2280Sstevel@tonic-gate strcpy(cp, se->s_proto);
2290Sstevel@tonic-gate sptr->s_proto = cp;
2300Sstevel@tonic-gate cp += n;
2310Sstevel@tonic-gate } else {
2320Sstevel@tonic-gate return (-1);
2330Sstevel@tonic-gate }
2340Sstevel@tonic-gate
2350Sstevel@tonic-gate return (SERV_R_OK);
2360Sstevel@tonic-gate }
2370Sstevel@tonic-gate #endif /* !SERVENT_DATA */
2380Sstevel@tonic-gate #else /*SERV_R_RETURN */
2390Sstevel@tonic-gate static int getservent_r_unknown_system = 0;
2400Sstevel@tonic-gate #endif /*SERV_R_RETURN */
2410Sstevel@tonic-gate #endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
242*11038SRao.Shoaib@Sun.COM /*! \file */
243