Fri Jul 19 15:45:20 1996 Ulrich Drepper <drepper@cygnus.com>
[glibc.git] / nss / getXXent_r.c
bloba4327c81af6ca9c54b053cf85a951bb8fd1c1ba3
1 /* Copyright (C) 1996 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If
17 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
20 #include <libc-lock.h>
22 #include "nsswitch.h"
24 /*******************************************************************\
25 |* Here we assume several symbols to be defined: *|
26 |* *|
27 |* LOOKUP_TYPE - the return type of the function *|
28 |* *|
29 |* SETFUNC_NAME - name of the non-reentrant setXXXent function *|
30 |* *|
31 |* GETFUNC_NAME - name of the non-reentrant getXXXent function *|
32 |* *|
33 |* ENDFUNC_NAME - name of the non-reentrant endXXXent function *|
34 |* *|
35 |* DATABASE_NAME - name of the database the function accesses *|
36 |* (e.g., host, services, ...) *|
37 |* *|
38 |* Optionally the following vars can be defined: *|
39 |* *|
40 |* STAYOPEN - variable declaration for setXXXent function *|
41 |* *|
42 |* STAYOPEN_VAR - variable name for setXXXent function *|
43 |* *|
44 |* NEED_H_ERRNO - an extra parameter will be passed to point to *|
45 |* the global `h_errno' variable. *|
46 |* *|
47 \*******************************************************************/
49 /* To make the real sources a bit prettier. */
50 #define REENTRANT_GETNAME APPEND_R (GETFUNC_NAME)
51 #define APPEND_R(name) APPEND_R1 (name)
52 #define APPEND_R1(name) name##_r
54 #define SETFUNC_NAME_STRING STRINGIZE (SETFUNC_NAME)
55 #define GETFUNC_NAME_STRING STRINGIZE (REENTRANT_GETNAME)
56 #define ENDFUNC_NAME_STRING STRINGIZE (ENDFUNC_NAME)
57 #define DATABASE_NAME_STRING STRINGIZE (DATABASE_NAME)
58 #define STRINGIZE(name) STRINGIZE1 (name)
59 #define STRINGIZE1(name) #name
61 #define DB_LOOKUP_FCT CONCAT3_1 (__nss_, DATABASE_NAME, _lookup)
62 #define CONCAT3_1(Pre, Name, Post) CONCAT3_2 (Pre, Name, Post)
63 #define CONCAT3_2(Pre, Name, Post) Pre##Name##Post
65 /* Sometimes we need to store error codes in the `h_errno' variable. */
66 #ifdef NEED_H_ERRNO
67 # define H_ERRNO_PARM , int *h_errnop
68 # define H_ERRNO_VAR , &h_errno
69 #else
70 # define H_ERRNO_PARM
71 # define H_ERRNO_VAR
72 #endif
74 /* Some databases take the `stayopen' flag. */
75 #ifndef STAYOPEN
76 #define STAYOPEN void
77 #define STAYOPEN_VAR
78 #endif
80 /* Prototype for the setXXXent functions we use here. */
81 typedef int (*set_function) (STAYOPEN);
83 /* Prototype for the endXXXent functions we use here. */
84 typedef int (*end_function) (void);
86 /* Prototype for the setXXXent functions we use here. */
87 typedef int (*get_function) (LOOKUP_TYPE *, char *, int H_ERRNO_PARM);
90 /* This handle for the NSS data base is shared between all
91 set/get/endXXXent functions. */
92 static service_user *nip;
93 /* Remember the first service_entry, it's always the same. */
94 static service_user *startp;
96 /* Protect above variable against multiple uses at the same time. */
97 __libc_lock_define_initialized (static, lock);
99 /* The lookup function for the first entry of this service. */
100 extern int DB_LOOKUP_FCT (service_user **nip, const char *name, void **fctp);
102 /* Set up NIP to run through the services. If ALL is zero, use NIP's
103 current location if it's not nil. Return nonzero if there are no
104 services (left). */
105 static enum nss_status
106 setup (void **fctp, const char *func_name, int all)
108 int no_more;
109 if (startp == NULL)
111 no_more = DB_LOOKUP_FCT (&nip, func_name, fctp);
112 startp = no_more ? (service_user *) -1 : nip;
114 else if (startp == (service_user *) -1)
115 /* No services at all. */
116 return 1;
117 else
119 if (all || !nip)
120 /* Reset to the beginning of the service list. */
121 nip = startp;
122 /* Look up the first function. */
123 no_more = __nss_lookup (&nip, func_name, fctp);
125 return no_more;
128 void
129 SETFUNC_NAME (STAYOPEN)
131 set_function fct;
132 int no_more;
134 #ifdef NEED__RES
135 if ((_res.options & RES_INIT) == 0 && res_init () == -1)
137 h_errno = NETDB_INTERNAL;
138 return NULL;
140 #endif /* need _res */
142 __libc_lock_lock (lock);
144 /* Cycle through all the services and run their setXXent functions. */
145 no_more = setup ((void **) &fct, SETFUNC_NAME_STRING, 1);
146 while (! no_more)
148 /* Ignore status, we force check in __NSS_NEXT. */
149 (void) (*fct) (STAYOPEN_VAR);
151 no_more = __nss_next (&nip, SETFUNC_NAME_STRING, (void **) &fct, 0, 1);
154 __libc_lock_unlock (lock);
158 void
159 ENDFUNC_NAME (void)
161 end_function fct;
162 int no_more;
164 #ifdef NEED__RES
165 if ((_res.options & RES_INIT) == 0 && res_init () == -1)
167 h_errno = NETDB_INTERNAL;
168 return NULL;
170 #endif /* need _res */
172 __libc_lock_lock (lock);
174 /* Cycle through all the services and run their endXXent functions. */
175 no_more = setup ((void **) &fct, ENDFUNC_NAME_STRING, 1);
176 while (! no_more)
178 /* Ignore status, we force check in __NSS_NEXT. */
179 (void) (*fct) ();
181 no_more = __nss_next (&nip, ENDFUNC_NAME_STRING, (void **) &fct, 0, 1);
184 __libc_lock_unlock (lock);
188 LOOKUP_TYPE *
189 REENTRANT_GETNAME (LOOKUP_TYPE *result, char *buffer, int buflen H_ERRNO_PARM)
191 get_function fct;
192 int no_more;
193 enum nss_status status;
195 #ifdef NEED__RES
196 if ((_res.options & RES_INIT) == 0 && res_init () == -1)
198 h_errno = NETDB_INTERNAL;
199 return NULL;
201 #endif /* need _res */
203 /* Initialize status to return if no more functions are found. */
204 status = NSS_STATUS_NOTFOUND;
206 __libc_lock_lock (lock);
208 /* Run through available functions, starting with the same function last
209 run. We will repeat each function as long as it succeeds, and then go
210 on to the next service action. */
211 no_more = setup ((void **) &fct, GETFUNC_NAME_STRING, 0);
212 while (! no_more)
214 status = (*fct) (result, buffer, buflen H_ERRNO_VAR);
216 no_more = __nss_next (&nip, GETFUNC_NAME_STRING, (void **) &fct,
217 status, 0);
220 __libc_lock_unlock (lock);
222 return status == NSS_STATUS_SUCCESS ? result : NULL;