/*
 * Copyright (c) 1983, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)getservent.c	8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef YP
#include <rpc/rpc.h>
#include <rpcsvc/yp_prot.h>
#include <rpcsvc/ypclnt.h>
static int serv_stepping_yp = 0;
extern int _yp_check __P(( char ** ));
#endif


#define	MAXALIASES	35

static FILE *servf = NULL;
static char line[BUFSIZ+1];
static struct servent serv;
static char *serv_aliases[MAXALIASES];
int _serv_stayopen;

#ifdef YP
char *___getservbyname_yp = NULL;
char *___getservbyproto_yp = NULL;
int ___getservbyport_yp = 0;
static char *yp_domain = NULL;

static int
_getservbyport_yp(line)
	char *line;
{
	char *result;
	int resultlen;
	char buf[YPMAXRECORD + 2];
	int rv;

	snprintf(buf, sizeof(buf), "%d/%s", ntohs(___getservbyport_yp),
						___getservbyproto_yp);

	___getservbyport_yp = 0;
	___getservbyproto_yp = NULL;

	if(!yp_domain) {
		if(yp_get_default_domain(&yp_domain))
			return (0);
	}

	/*
	 * We have to be a little flexible here. Ideally you're supposed
	 * to have both a services.byname and a services.byport map, but
	 * some systems have only services.byname. FreeBSD cheats a little
	 * by putting the services.byport information in the same map as
	 * services.byname so that either case will work. We allow for both
	 * possibilities here: if there is no services.byport map, we try
	 * services.byname instead.
	 */
	if ((rv = yp_match(yp_domain, "services.byport", buf, strlen(buf),
						&result, &resultlen))) {
		if (rv == YPERR_MAP) {
			if (yp_match(yp_domain, "services.byname", buf,
					strlen(buf), &result, &resultlen))
			return(0);
		} else
			return(0);
	}
		
	/* getservent() expects lines terminated with \n -- make it happy */
	snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);

	free(result);
	return(1);
}

static int
_getservbyname_yp(line)
	char *line;
{
	char *result;
	int resultlen;
	char buf[YPMAXRECORD + 2];

	if(!yp_domain) {
		if(yp_get_default_domain(&yp_domain))
			return (0);
	}

	snprintf(buf, sizeof(buf), "%s/%s", ___getservbyname_yp,
						___getservbyproto_yp);

	___getservbyname_yp = 0;
	___getservbyproto_yp = NULL;

	if (yp_match(yp_domain, "services.byname", buf, strlen(buf),
						&result, &resultlen)) {
		return(0);
	}
		
	/* getservent() expects lines terminated with \n -- make it happy */
	snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);

	free(result);
	return(1);
}

static int
_getservent_yp(line)
	char *line;
{
	static char *key = NULL;
	static int keylen;
	char *lastkey, *result;
	int resultlen;
	int rv;

	if(!yp_domain) {
		if(yp_get_default_domain(&yp_domain))
			return (0);
	}

	if (!serv_stepping_yp) {
		if (key)
			free(key);
		if ((rv = yp_first(yp_domain, "services.byname", &key, &keylen,
			     &result, &resultlen))) {
			serv_stepping_yp = 0;
			return(0);
		}
		serv_stepping_yp = 1;
	} else {
		lastkey = key;
		rv = yp_next(yp_domain, "services.byname", key, keylen, &key,
			     &keylen, &result, &resultlen);
		free(lastkey);
		if (rv) {
			serv_stepping_yp = 0;
			return (0);
		}
	}

	/* getservent() expects lines terminated with \n -- make it happy */
	snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);

	free(result);

	return(1);
}
#endif

void
setservent(int f)
{
	if (servf == NULL)
		servf = fopen(_PATH_SERVICES, "r" );
	else
		rewind(servf);
	_serv_stayopen |= f;
}

void
endservent()
{
	if (servf) {
		fclose(servf);
		servf = NULL;
	}
	_serv_stayopen = 0;
}

struct servent *
getservent()
{
	char *p;
	register char *cp, **q;

#ifdef YP
	if (serv_stepping_yp && _getservent_yp(line)) {
		p = (char *)&line;
		goto unpack;
	}
tryagain:
#endif
	if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL)
		return (NULL);
again:
	if ((p = fgets(line, BUFSIZ, servf)) == NULL)
		return (NULL);
#ifdef YP
	if (*p == '+' && _yp_check(NULL)) {
		if (___getservbyname_yp != NULL) {
			if (!_getservbyname_yp(line))
				goto tryagain;
		} 
		else if (___getservbyport_yp != 0) {
			if (!_getservbyport_yp(line))
				goto tryagain;
		}
		else if (!_getservent_yp(line))
			goto tryagain;
	}
unpack:
#endif
	if (*p == '#')
		goto again;
	cp = strpbrk(p, "#\n");
	if (cp == NULL)
		goto again;
	*cp = '\0';
	serv.s_name = p;
	p = strpbrk(p, " \t");
	if (p == NULL)
		goto again;
	*p++ = '\0';
	while (*p == ' ' || *p == '\t')
		p++;
	cp = strpbrk(p, ",/");
	if (cp == NULL)
		goto again;
	*cp++ = '\0';
	serv.s_port = htons((u_short)atoi(p));
	serv.s_proto = cp;
	q = serv.s_aliases = serv_aliases;
	cp = strpbrk(cp, " \t");
	if (cp != NULL)
		*cp++ = '\0';
	while (cp && *cp) {
		if (*cp == ' ' || *cp == '\t') {
			cp++;
			continue;
		}
		if (q < &serv_aliases[MAXALIASES - 1])
			*q++ = cp;
		cp = strpbrk(cp, " \t");
		if (cp != NULL)
			*cp++ = '\0';
	}
	*q = NULL;
	return (&serv);
}
