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 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 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 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 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 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 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 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