]>
sourceware.org Git - glibc.git/blob - nss/getXXent_r.c
1 /* Copyright (C) 1996,97,98,99,2000 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 not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
21 #include <bits/libc-lock.h>
29 /*******************************************************************\
30 |* Here we assume several symbols to be defined: *|
32 |* LOOKUP_TYPE - the return type of the function *|
34 |* SETFUNC_NAME - name of the non-reentrant setXXXent function *|
36 |* GETFUNC_NAME - name of the non-reentrant getXXXent function *|
38 |* ENDFUNC_NAME - name of the non-reentrant endXXXent function *|
40 |* DATABASE_NAME - name of the database the function accesses *|
41 |* (e.g., host, services, ...) *|
43 |* Optionally the following vars can be defined: *|
45 |* STAYOPEN - variable declaration for setXXXent function *|
47 |* STAYOPEN_VAR - variable name for setXXXent function *|
49 |* NEED_H_ERRNO - an extra parameter will be passed to point to *|
50 |* the global `h_errno' variable. *|
52 \*******************************************************************/
54 /* To make the real sources a bit prettier. */
55 #define REENTRANT_GETNAME APPEND_R (GETFUNC_NAME)
56 #define APPEND_R(Name) CONCAT2_2 (Name, _r)
57 #define INTERNAL(Name) CONCAT2_2 (__, Name)
58 #define CONCAT2_1(Pre, Post) CONCAT2_2 (Pre, Post)
59 #define CONCAT2_2(Pre, Post) Pre##Post
61 #define SETFUNC_NAME_STRING STRINGIZE (SETFUNC_NAME)
62 #define GETFUNC_NAME_STRING STRINGIZE (REENTRANT_GETNAME)
63 #define ENDFUNC_NAME_STRING STRINGIZE (ENDFUNC_NAME)
64 #define DATABASE_NAME_STRING STRINGIZE (DATABASE_NAME)
65 #define STRINGIZE(Name) STRINGIZE1 (Name)
66 #define STRINGIZE1(Name) #Name
68 #define DB_LOOKUP_FCT CONCAT3_1 (__nss_, DATABASE_NAME, _lookup)
69 #define CONCAT3_1(Pre, Name, Post) CONCAT3_2 (Pre, Name, Post)
70 #define CONCAT3_2(Pre, Name, Post) Pre##Name##Post
72 /* Sometimes we need to store error codes in the `h_errno' variable. */
74 # define H_ERRNO_PARM , int *h_errnop
75 # define H_ERRNO_VAR , &h_errno
81 /* Some databases take the `stayopen' flag. */
83 # define STAYOPEN_TMP CONCAT2_1 (STAYOPEN, _tmp)
84 # define STAYOPEN_TMPVAR CONCAT2_1 (STAYOPEN_VAR, _tmp)
86 # define STAYOPEN void
88 # define STAYOPEN_TMPVAR
91 /* Prototype for the setXXXent functions we use here. */
92 typedef enum nss_status (*set_function
) (STAYOPEN
);
94 /* Prototype for the endXXXent functions we use here. */
95 typedef enum nss_status (*end_function
) (void);
97 /* Prototype for the setXXXent functions we use here. */
98 typedef enum nss_status (*get_function
) (LOOKUP_TYPE
*, char *, size_t, int *
102 /* This handle for the NSS data base is shared between all
103 set/get/endXXXent functions. */
104 static service_user
*nip
;
105 /* Remember the last service used since the last call to `endXXent'. */
106 static service_user
*last_nip
;
107 /* Remember the first service_entry, it's always the same. */
108 static service_user
*startp
;
111 /* We need to remember the last `stayopen' flag given by the user
112 since the `setent' function is only called for the first available
117 /* Protect above variable against multiple uses at the same time. */
118 __libc_lock_define_initialized (static, lock
)
120 /* The lookup function for the first entry of this service. */
121 extern int DB_LOOKUP_FCT (service_user
**nip
, const char *name
, void **fctp
);
123 /* Set up NIP to run through the services. If ALL is zero, use NIP's
124 current location if it's not nil. Return nonzero if there are no
126 static enum nss_status
127 setup (void **fctp
, const char *func_name
, int all
)
132 no_more
= DB_LOOKUP_FCT (&nip
, func_name
, fctp
);
133 startp
= no_more
? (service_user
*) -1l : nip
;
135 else if (startp
== (service_user
*) -1l)
136 /* No services at all. */
141 /* Reset to the beginning of the service list. */
143 /* Look up the first function. */
144 no_more
= __nss_lookup (&nip
, func_name
, fctp
);
150 SETFUNC_NAME (STAYOPEN
)
156 if ((_res
.options
& RES_INIT
) == 0 && __res_ninit (&_res
) == -1)
158 __set_h_errno (NETDB_INTERNAL
);
161 #endif /* need _res */
163 __libc_lock_lock (lock
);
165 /* Cycle through the services and run their `setXXent' functions until
166 we find an available service. */
167 no_more
= setup ((void **) &fct
, SETFUNC_NAME_STRING
, 1);
170 int is_last_nip
= nip
== last_nip
;
171 enum nss_status status
= DL_CALL_FCT (fct
, (STAYOPEN_VAR
));
173 no_more
= __nss_next (&nip
, SETFUNC_NAME_STRING
, (void **) &fct
,
180 STAYOPEN_TMPVAR
= STAYOPEN_VAR
;
183 __libc_lock_unlock (lock
);
194 if ((_res
.options
& RES_INIT
) == 0 && __res_ninit (&_res
) == -1)
196 __set_h_errno (NETDB_INTERNAL
);
199 #endif /* need _res */
201 __libc_lock_lock (lock
);
203 /* Cycle through all the services and run their endXXent functions. */
204 no_more
= setup ((void **) &fct
, ENDFUNC_NAME_STRING
, 1);
207 /* Ignore status, we force check in __NSS_NEXT. */
208 DL_CALL_FCT (fct
, ());
211 /* We have processed all services which were used. */
214 no_more
= __nss_next (&nip
, ENDFUNC_NAME_STRING
, (void **) &fct
, 0, 1);
216 last_nip
= nip
= NULL
;
218 __libc_lock_unlock (lock
);
223 INTERNAL (REENTRANT_GETNAME
) (LOOKUP_TYPE
*resbuf
, char *buffer
, size_t buflen
,
224 LOOKUP_TYPE
**result H_ERRNO_PARM
)
228 enum nss_status status
;
231 if ((_res
.options
& RES_INIT
) == 0 && __res_ninit (&_res
) == -1)
233 __set_h_errno (NETDB_INTERNAL
);
237 #endif /* need _res */
239 /* Initialize status to return if no more functions are found. */
240 status
= NSS_STATUS_NOTFOUND
;
242 __libc_lock_lock (lock
);
244 /* Run through available functions, starting with the same function last
245 run. We will repeat each function as long as it succeeds, and then go
246 on to the next service action. */
247 no_more
= setup ((void **) &fct
, GETFUNC_NAME_STRING
, 0);
250 int is_last_nip
= nip
== last_nip
;
252 status
= DL_CALL_FCT (fct
,
253 (resbuf
, buffer
, buflen
, &errno H_ERRNO_VAR
));
255 /* The the status is NSS_STATUS_TRYAGAIN and errno is ERANGE the
256 provided buffer is too small. In this case we should give
257 the user the possibility to enlarge the buffer and we should
258 not simply go on with the next service (even if the TRYAGAIN
259 action tells us so). */
260 if (status
== NSS_STATUS_TRYAGAIN
262 && *h_errnop
== NETDB_INTERNAL
269 no_more
= __nss_next (&nip
, GETFUNC_NAME_STRING
, (void **) &fct
,
277 /* Call the `setXXent' function. This wasn't done before. */
280 no_more
= __nss_lookup (&nip
, SETFUNC_NAME_STRING
,
284 status
= DL_CALL_FCT (sfct
, (STAYOPEN_TMPVAR
));
286 status
= NSS_STATUS_NOTFOUND
;
289 while (! no_more
&& status
!= NSS_STATUS_SUCCESS
);
292 __libc_lock_unlock (lock
);
294 *result
= status
== NSS_STATUS_SUCCESS
? resbuf
: NULL
;
295 return status
== NSS_STATUS_SUCCESS
? 0 : errno
;
299 #include <shlib-compat.h>
300 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1_2)
301 #define OLD(name) OLD1 (name)
302 #define OLD1(name) __old_##name
305 OLD (REENTRANT_GETNAME
) (LOOKUP_TYPE
*resbuf
, char *buffer
, size_t buflen
,
306 LOOKUP_TYPE
**result H_ERRNO_PARM
)
308 int ret
= INTERNAL (REENTRANT_GETNAME
) (resbuf
, buffer
, buflen
,
317 #define do_symbol_version(real, name, version) \
318 compat_symbol (libc, real, name, version)
319 do_symbol_version (OLD (REENTRANT_GETNAME
), REENTRANT_GETNAME
, GLIBC_2_0
);
321 #define do_default_symbol_version(real, name, version) \
322 versioned_symbol (libc, real, name, version)
323 do_default_symbol_version (INTERNAL (REENTRANT_GETNAME
),
324 REENTRANT_GETNAME
, GLIBC_2_1_2
);
326 #define do_weak_alias(n1, n2) weak_alias (n1, n2)
327 do_weak_alias (INTERNAL (REENTRANT_GETNAME
), REENTRANT_GETNAME
)
This page took 0.063806 seconds and 5 git commands to generate.