10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*2830Sdjl * Common Development and Distribution License (the "License").
6*2830Sdjl * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*2830Sdjl * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23*2830Sdjl * Use is subject to license terms.
240Sstevel@tonic-gate *
250Sstevel@tonic-gate * lib/libsocket/inet/getservent_r.c
260Sstevel@tonic-gate *
270Sstevel@tonic-gate * This file defines and implements the re-entrant enumeration routines for
280Sstevel@tonic-gate * services: setservent(), getservent_r(), and endservent(). They consult
290Sstevel@tonic-gate * the switch policy directly and do not "share" their enumeration state
300Sstevel@tonic-gate * nor the stayopen flag with the implentation of the more common
310Sstevel@tonic-gate * getservbyname_r()/getservbyport_r(). The latter follows a tortuous
320Sstevel@tonic-gate * route in order to be consistent with netdir_getbyYY() (see
330Sstevel@tonic-gate * getservbyname_r.c and lib/libnsl/nss/netdir_inet.c).
340Sstevel@tonic-gate */
350Sstevel@tonic-gate
360Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
370Sstevel@tonic-gate
380Sstevel@tonic-gate #include <sys/types.h>
390Sstevel@tonic-gate #include <nss_dbdefs.h>
400Sstevel@tonic-gate
410Sstevel@tonic-gate /*
420Sstevel@tonic-gate * str2servent is implemented in libnsl, libnsl/nss/netdir_inet.c, since
430Sstevel@tonic-gate * the "engine" of the new gethost/getserv/netdir lives in libnsl.
440Sstevel@tonic-gate */
450Sstevel@tonic-gate int str2servent(const char *, int, void *, char *, int);
460Sstevel@tonic-gate
470Sstevel@tonic-gate /*
480Sstevel@tonic-gate * Unsynchronized, but it affects only
490Sstevel@tonic-gate * efficiency, not correctness.
500Sstevel@tonic-gate */
510Sstevel@tonic-gate static int services_stayopen;
520Sstevel@tonic-gate static DEFINE_NSS_DB_ROOT(db_root);
530Sstevel@tonic-gate static DEFINE_NSS_GETENT(context);
540Sstevel@tonic-gate
55*2830Sdjl void
_nss_initf_services(nss_db_params_t * p)560Sstevel@tonic-gate _nss_initf_services(nss_db_params_t *p)
570Sstevel@tonic-gate {
580Sstevel@tonic-gate p->name = NSS_DBNAM_SERVICES;
590Sstevel@tonic-gate p->default_config = NSS_DEFCONF_SERVICES;
600Sstevel@tonic-gate }
610Sstevel@tonic-gate
620Sstevel@tonic-gate int
setservent(int stay)630Sstevel@tonic-gate setservent(int stay)
640Sstevel@tonic-gate {
650Sstevel@tonic-gate services_stayopen |= stay;
660Sstevel@tonic-gate nss_setent(&db_root, _nss_initf_services, &context);
670Sstevel@tonic-gate return (0);
680Sstevel@tonic-gate }
690Sstevel@tonic-gate
700Sstevel@tonic-gate int
endservent()710Sstevel@tonic-gate endservent()
720Sstevel@tonic-gate {
730Sstevel@tonic-gate services_stayopen = 0;
740Sstevel@tonic-gate nss_endent(&db_root, _nss_initf_services, &context);
750Sstevel@tonic-gate nss_delete(&db_root);
760Sstevel@tonic-gate return (0);
770Sstevel@tonic-gate }
780Sstevel@tonic-gate
790Sstevel@tonic-gate struct servent *
getservent_r(struct servent * result,char * buffer,int buflen)800Sstevel@tonic-gate getservent_r(struct servent *result, char *buffer, int buflen)
810Sstevel@tonic-gate {
820Sstevel@tonic-gate nss_XbyY_args_t arg;
830Sstevel@tonic-gate nss_status_t res;
840Sstevel@tonic-gate
850Sstevel@tonic-gate NSS_XbyY_INIT(&arg, result, buffer, buflen, str2servent);
860Sstevel@tonic-gate /*
870Sstevel@tonic-gate * Setting proto to NULL here is a bit of a hack since we share
880Sstevel@tonic-gate * the parsing code in the NIS+ backend with our getservbyYY()
890Sstevel@tonic-gate * brethren who can search on 1-1/2 key. If they pass a NULL
900Sstevel@tonic-gate * proto, the parsing code deals with it by picking the protocol
910Sstevel@tonic-gate * from the first NIS+ matching object and combining all entries
920Sstevel@tonic-gate * with "that" proto field. NIS+ is the only name service, so far,
930Sstevel@tonic-gate * that can return multiple entries on a lookup.
940Sstevel@tonic-gate */
950Sstevel@tonic-gate arg.key.serv.proto = NULL;
960Sstevel@tonic-gate /* === No stayopen flag; of course you stay open for iteration */
970Sstevel@tonic-gate res = nss_getent(&db_root, _nss_initf_services, &context, &arg);
980Sstevel@tonic-gate arg.status = res;
990Sstevel@tonic-gate return (struct servent *)NSS_XbyY_FINI(&arg);
1000Sstevel@tonic-gate }
101