]> git.ipfire.org Git - thirdparty/glibc.git/blame - nss/getXXbyYY_r.c
Update.
[thirdparty/glibc.git] / nss / getXXbyYY_r.c
CommitLineData
261eada2 1/* Copyright (C) 1996-2002, 2003, 2004 Free Software Foundation, Inc.
2303f5fd
UD
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
5f0e6fc7 4
2303f5fd 5 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
5f0e6fc7 9
2303f5fd
UD
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
41bdb6e2 13 Lesser General Public License for more details.
5f0e6fc7 14
41bdb6e2
AJ
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
5f0e6fc7 19
344c67b6 20#include <assert.h>
d71b808a 21#include <errno.h>
b2ab1f5d 22#include <stdbool.h>
5f0e6fc7 23#include "nsswitch.h"
67479a70
UD
24#ifdef USE_NSCD
25# include <nscd/nscd_proto.h>
26#endif
5edb9387
UD
27#ifdef NEED__RES_HCONF
28# include <resolv/res_hconf.h>
29#endif
b43b13ac
UD
30#ifdef NEED__RES
31# include <resolv.h>
32#endif
5f0e6fc7
RM
33/*******************************************************************\
34|* Here we assume several symbols to be defined: *|
fb776f3e 35|* *|
5f0e6fc7 36|* LOOKUP_TYPE - the return type of the function *|
fb776f3e 37|* *|
5f0e6fc7 38|* FUNCTION_NAME - name of the non-reentrant function *|
fb776f3e 39|* *|
5f0e6fc7
RM
40|* DATABASE_NAME - name of the database the function accesses *|
41|* (e.g., host, services, ...) *|
fb776f3e 42|* *|
5f0e6fc7 43|* ADD_PARAMS - additional parameter, can vary in number *|
fb776f3e 44|* *|
5f0e6fc7 45|* ADD_VARIABLES - names of additional parameter *|
fb776f3e 46|* *|
5f0e6fc7 47|* Optionally the following vars can be defined: *|
fb776f3e 48|* *|
5f0e6fc7
RM
49|* NEED_H_ERRNO - an extra parameter will be passed to point to *|
50|* the global `h_errno' variable. *|
fb776f3e 51|* *|
5f0e6fc7 52|* NEED__RES - the global _res variable might be used so we *|
fb776f3e
AJ
53|* will have to initialize it if necessary *|
54|* *|
ae81730f 55|* PREPROCESS - code run before anything else *|
fb776f3e 56|* *|
ae81730f 57|* POSTPROCESS - code run after the lookup *|
fb776f3e 58|* *|
5f0e6fc7
RM
59\*******************************************************************/
60
61/* To make the real sources a bit prettier. */
62#define REENTRANT_NAME APPEND_R (FUNCTION_NAME)
63#define APPEND_R(name) APPEND_R1 (name)
64#define APPEND_R1(name) name##_r
23396375
UD
65#define INTERNAL(name) INTERNAL1 (name)
66#define INTERNAL1(name) __##name
bff334e0
UD
67#define NEW(name) NEW1 (name)
68#define NEW1(name) __new_##name
5f0e6fc7 69
d67281a7
UD
70#ifdef USE_NSCD
71# define NSCD_NAME ADD_NSCD (REENTRANT_NAME)
72# define ADD_NSCD(name) ADD_NSCD1 (name)
73# define ADD_NSCD1(name) __nscd_##name
ac16e905
UD
74# define NOT_USENSCD_NAME ADD_NOT_NSCDUSE (DATABASE_NAME)
75# define ADD_NOT_NSCDUSE(name) ADD_NOT_NSCDUSE1 (name)
76# define ADD_NOT_NSCDUSE1(name) __nss_not_use_nscd_##name
d67281a7
UD
77#endif
78
5f0e6fc7
RM
79#define FUNCTION_NAME_STRING STRINGIZE (FUNCTION_NAME)
80#define REENTRANT_NAME_STRING STRINGIZE (REENTRANT_NAME)
81#define DATABASE_NAME_STRING STRINGIZE (DATABASE_NAME)
82#define STRINGIZE(name) STRINGIZE1 (name)
83#define STRINGIZE1(name) #name
84
77fe0b9c
UD
85#ifndef DB_LOOKUP_FCT
86# define DB_LOOKUP_FCT CONCAT3_1 (__nss_, DATABASE_NAME, _lookup)
87# define CONCAT3_1(Pre, Name, Post) CONCAT3_2 (Pre, Name, Post)
88# define CONCAT3_2(Pre, Name, Post) Pre##Name##Post
89#endif
5f0e6fc7
RM
90
91/* Sometimes we need to store error codes in the `h_errno' variable. */
92#ifdef NEED_H_ERRNO
93# define H_ERRNO_PARM , int *h_errnop
94# define H_ERRNO_VAR , h_errnop
a5fdf99b 95# define H_ERRNO_VAR_P h_errnop
5f0e6fc7
RM
96#else
97# define H_ERRNO_PARM
98# define H_ERRNO_VAR
a5fdf99b 99# define H_ERRNO_VAR_P NULL
5f0e6fc7
RM
100#endif
101
a5fdf99b
UD
102#ifndef HAVE_TYPE
103# define TYPE_VAR_P NULL
104# define FLAGS_VAR 0
105#endif
106
107#ifdef HAVE_AF
108# define AF_VAR_P &af
109#else
110# define AF_VAR_P NULL
111#endif
5f0e6fc7
RM
112
113/* Type of the lookup function we need here. */
899d423e
UD
114typedef enum nss_status (*lookup_function) (ADD_PARAMS, LOOKUP_TYPE *, char *,
115 size_t, int * H_ERRNO_PARM);
5f0e6fc7 116
5f0e6fc7 117/* The lookup function for the first entry of this service. */
dff07c4b 118extern int DB_LOOKUP_FCT (service_user **nip, const char *name, void **fctp)
37ba7d66
UD
119 internal_function;
120libc_hidden_proto (DB_LOOKUP_FCT)
5f0e6fc7 121
ea278354
UD
122/* Interval in which we transfer retry to contact the NSCD. */
123#define NSS_NSCD_RETRY 100
5f0e6fc7
RM
124
125
ba1ffaa1
UD
126int
127INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
128 size_t buflen, LOOKUP_TYPE **result H_ERRNO_PARM)
5f0e6fc7 129{
c4563d2d 130 static service_user *startp;
5f0e6fc7
RM
131 static lookup_function start_fct;
132 service_user *nip;
fb776f3e
AJ
133 union
134 {
135 lookup_function l;
136 void *ptr;
137 } fct;
138
5f0e6fc7
RM
139 int no_more;
140 enum nss_status status = NSS_STATUS_UNAVAIL;
d67281a7
UD
141#ifdef USE_NSCD
142 int nscd_status;
143#endif
b2ab1f5d
UD
144#ifdef NEED_H_ERRNO
145 bool any_service = false;
146#endif
5f0e6fc7 147
ae81730f
UD
148#ifdef PREPROCESS
149 PREPROCESS;
150#endif
151
61c162b5 152#ifdef HANDLE_DIGITS_DOTS
a5fdf99b
UD
153 switch (__nss_hostname_digits_dots (name, resbuf, &buffer, NULL,
154 buflen, result, &status,
155 TYPE_VAR_P, FLAGS_VAR, AF_VAR_P,
156 H_ERRNO_VAR_P))
d17a729b 157 {
a5fdf99b 158 case -1:
1670698f 159 return errno;
a5fdf99b
UD
160 case 1:
161 goto done;
d17a729b 162 }
61c162b5
UD
163#endif
164
d67281a7 165#ifdef USE_NSCD
ef4d5b32 166 if (NOT_USENSCD_NAME > 0 && ++NOT_USENSCD_NAME > NSS_NSCD_RETRY)
ac16e905 167 NOT_USENSCD_NAME = 0;
ea278354 168
ac16e905 169 if (!NOT_USENSCD_NAME)
d67281a7 170 {
261eada2 171 nscd_status = NSCD_NAME (ADD_VARIABLES, resbuf, buffer, buflen, result
ea278354 172 H_ERRNO_VAR);
1670698f 173 if (nscd_status >= 0)
261eada2 174 return nscd_status;
d67281a7
UD
175 }
176#endif
177
5f0e6fc7
RM
178 if (startp == NULL)
179 {
fb776f3e 180 no_more = DB_LOOKUP_FCT (&nip, REENTRANT_NAME_STRING, &fct.ptr);
5f0e6fc7 181 if (no_more)
8a523922 182 startp = (service_user *) -1l;
5f0e6fc7
RM
183 else
184 {
185 startp = nip;
fb776f3e 186 start_fct = fct.l;
5f0e6fc7
RM
187
188#ifdef NEED__RES
189 /* The resolver code will really be used so we have to
190 initialize it. */
b43b13ac 191 if ((_res.options & RES_INIT) == 0 && __res_ninit (&_res) == -1)
5f0e6fc7 192 {
adc6ff7f 193 *h_errnop = NETDB_INTERNAL;
afd4eb37 194 *result = NULL;
1670698f 195 return errno;
5f0e6fc7
RM
196 }
197#endif /* need _res */
5edb9387
UD
198#ifdef NEED__RES_HCONF
199 if (!_res_hconf.initialized)
200 _res_hconf_init ();
201#endif /* need _res_hconf */
5f0e6fc7
RM
202 }
203 }
204 else
205 {
fb776f3e 206 fct.l = start_fct;
8a523922 207 no_more = (nip = startp) == (service_user *) -1l;
5f0e6fc7
RM
208 }
209
210 while (no_more == 0)
211 {
b2ab1f5d
UD
212#ifdef NEED_H_ERRNO
213 any_service = true;
214#endif
215
fb776f3e
AJ
216 status = DL_CALL_FCT (fct.l, (ADD_VARIABLES, resbuf, buffer, buflen,
217 &errno H_ERRNO_VAR));
5f0e6fc7 218
ea278354 219 /* The status is NSS_STATUS_TRYAGAIN and errno is ERANGE the
566efee2
UD
220 provided buffer is too small. In this case we should give
221 the user the possibility to enlarge the buffer and we should
222 not simply go on with the next service (even if the TRYAGAIN
223 action tells us so). */
224 if (status == NSS_STATUS_TRYAGAIN
225#ifdef NEED_H_ERRNO
226 && *h_errnop == NETDB_INTERNAL
227#endif
228 && errno == ERANGE)
229 break;
230
503054c0 231 no_more = __nss_next (&nip, REENTRANT_NAME_STRING,
fb776f3e 232 &fct.ptr, status, 0);
5f0e6fc7
RM
233 }
234
61c162b5
UD
235#ifdef HANDLE_DIGITS_DOTS
236done:
237#endif
ba1ffaa1 238 *result = status == NSS_STATUS_SUCCESS ? resbuf : NULL;
b2ab1f5d
UD
239#ifdef NEED_H_ERRNO
240 if (status != NSS_STATUS_SUCCESS && ! any_service)
241 /* We were not able to use any service. */
242 *h_errnop = NO_RECOVERY;
243#endif
5edb9387
UD
244#ifdef POSTPROCESS
245 POSTPROCESS;
246#endif
35504a6f 247
a452e4e6 248 int res;
35504a6f 249 if (status == NSS_STATUS_SUCCESS)
a452e4e6 250 res = 0;
35504a6f
UD
251 /* Don't pass back ERANGE if this is not for a too-small buffer. */
252 else if (errno == ERANGE && status != NSS_STATUS_TRYAGAIN)
a452e4e6 253 res = EINVAL;
9bfce4bf 254#ifdef NEED_H_ERRNO
a452e4e6
UD
255 /* These functions only set errno if h_errno is NETDB_INTERNAL. */
256 else if (status == NSS_STATUS_TRYAGAIN && *h_errnop != NETDB_INTERNAL)
257 res = EAGAIN;
9bfce4bf 258#endif
35504a6f
UD
259 else
260 return errno;
261
a452e4e6
UD
262 __set_errno (res);
263 return res;
5f0e6fc7 264}
23396375 265
16710d58
RM
266
267#include <shlib-compat.h>
268#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1_2)
c2fa5b5a
UD
269#define OLD(name) OLD1 (name)
270#define OLD1(name) __old_##name
271
272int
4a381a81 273attribute_compat_text_section
c2fa5b5a
UD
274OLD (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
275 size_t buflen, LOOKUP_TYPE **result H_ERRNO_PARM)
276{
277 int ret = INTERNAL (REENTRANT_NAME) (ADD_VARIABLES, resbuf, buffer,
fb776f3e 278 buflen, result H_ERRNO_VAR);
c2fa5b5a 279
2cfe49db 280 if (ret != 0 || result == NULL)
c2fa5b5a
UD
281 ret = -1;
282
283 return ret;
284}
285
286#define do_symbol_version(real, name, version) \
16710d58 287 compat_symbol (libc, real, name, version)
47963d10 288do_symbol_version (OLD (REENTRANT_NAME), REENTRANT_NAME, GLIBC_2_0);
deb7f0b4 289#endif
c2fa5b5a 290
bff334e0
UD
291/* As INTERNAL (REENTRANT_NAME) may be hidden, we need an alias
292 in between so that the REENTRANT_NAME@@GLIBC_2.1.2 is not
293 hidden too. */
294strong_alias (INTERNAL (REENTRANT_NAME), NEW (REENTRANT_NAME));
295
c2fa5b5a 296#define do_default_symbol_version(real, name, version) \
16710d58 297 versioned_symbol (libc, real, name, version)
bff334e0 298do_default_symbol_version (NEW (REENTRANT_NAME),
16710d58 299 REENTRANT_NAME, GLIBC_2_1_2);
2f7f7bc6
UD
300
301static_link_warning (REENTRANT_NAME)