xref: /illumos-gate/usr/src/lib/libsocket/inet/getservent_r.c (revision 1da57d551424de5a9d469760be7c4b4d4f10a755)
1  /*
2   * CDDL HEADER START
3   *
4   * The contents of this file are subject to the terms of the
5   * Common Development and Distribution License (the "License").
6   * You may not use this file except in compliance with the License.
7   *
8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9   * or http://www.opensolaris.org/os/licensing.
10   * See the License for the specific language governing permissions
11   * and limitations under the License.
12   *
13   * When distributing Covered Code, include this CDDL HEADER in each
14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15   * If applicable, add the following below this CDDL HEADER, with the
16   * fields enclosed by brackets "[]" replaced with your own identifying
17   * information: Portions Copyright [yyyy] [name of copyright owner]
18   *
19   * CDDL HEADER END
20   */
21  /*
22   * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23   * Use is subject to license terms.
24   *
25   * lib/libsocket/inet/getservent_r.c
26   *
27   * This file defines and implements the re-entrant enumeration routines for
28   *   services: setservent(), getservent_r(), and endservent(). They consult
29   *   the switch policy directly and do not "share" their enumeration state
30   *   nor the stayopen flag with the implentation of the more common
31   *   getservbyname_r()/getservbyport_r(). The latter follows a tortuous
32   *   route in order to be consistent with netdir_getbyYY() (see
33   *   getservbyname_r.c and lib/libnsl/nss/netdir_inet.c).
34   */
35  
36  #include <sys/types.h>
37  #include <nss_dbdefs.h>
38  
39  /*
40   * str2servent is implemented in libnsl, libnsl/nss/netdir_inet.c, since
41   * the "engine" of the new gethost/getserv/netdir lives in libnsl.
42   */
43  int str2servent(const char *, int, void *, char *, int);
44  
45  /*
46   * Unsynchronized, but it affects only
47   * efficiency, not correctness.
48   */
49  static int services_stayopen;
50  static DEFINE_NSS_DB_ROOT(db_root);
51  static DEFINE_NSS_GETENT(context);
52  
53  void
_nss_initf_services(nss_db_params_t * p)54  _nss_initf_services(nss_db_params_t *p)
55  {
56  	p->name	= NSS_DBNAM_SERVICES;
57  	p->default_config = NSS_DEFCONF_SERVICES;
58  }
59  
60  int
setservent(int stay)61  setservent(int stay)
62  {
63  	services_stayopen |= stay;
64  	nss_setent(&db_root, _nss_initf_services, &context);
65  	return (0);
66  }
67  
68  int
endservent()69  endservent()
70  {
71  	services_stayopen = 0;
72  	nss_endent(&db_root, _nss_initf_services, &context);
73  	nss_delete(&db_root);
74  	return (0);
75  }
76  
77  struct servent *
getservent_r(struct servent * result,char * buffer,int buflen)78  getservent_r(struct servent *result, char *buffer, int buflen)
79  {
80  	nss_XbyY_args_t arg;
81  	nss_status_t	res;
82  
83  	NSS_XbyY_INIT(&arg, result, buffer, buflen, str2servent);
84  	/*
85  	 * Setting proto to NULL here is a bit of a hack since we share
86  	 * the parsing code in the NIS+ backend with our getservbyYY()
87  	 * brethren who can search on 1-1/2 key. If they pass a NULL
88  	 * proto, the parsing code deals with it by picking the protocol
89  	 * from the first NIS+ matching object and combining all entries
90  	 * with "that" proto field. NIS+ is the only name service, so far,
91  	 * that can return multiple entries on a lookup.
92  	 */
93  	arg.key.serv.proto	= NULL;
94  	/* === No stayopen flag;  of course you stay open for iteration */
95  	res = nss_getent(&db_root, _nss_initf_services, &context, &arg);
96  	arg.status = res;
97  	return (struct servent *)NSS_XbyY_FINI(&arg);
98  }
99