mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-08 17:42:12 +03:00
Update.
2000-07-23 Ulrich Drepper <drepper@redhat.com> * nss/nss_files/files-hosts.c: Implement multi handling. * resolv/Versions: Export _res_hconf for GLIBC_2.2 from libc.
This commit is contained in:
@@ -1,3 +1,8 @@
|
|||||||
|
2000-07-23 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* nss/nss_files/files-hosts.c: Implement multi handling.
|
||||||
|
* resolv/Versions: Export _res_hconf for GLIBC_2.2 from libc.
|
||||||
|
|
||||||
2000-07-22 Ulrich Drepper <drepper@redhat.com>
|
2000-07-22 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
* nss/nss_files/files-parse.c: Don't pollute namespace by using
|
* nss/nss_files/files-parse.c: Don't pollute namespace by using
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
Boston, MA 02111-1307, USA. */
|
Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <arpa/nameser.h>
|
#include <arpa/nameser.h>
|
||||||
@@ -26,6 +27,7 @@
|
|||||||
|
|
||||||
/* Get implementation for some internal functions. */
|
/* Get implementation for some internal functions. */
|
||||||
#include "../resolv/mapv4v6addr.h"
|
#include "../resolv/mapv4v6addr.h"
|
||||||
|
#include "../resolv/res_hconf.h"
|
||||||
|
|
||||||
|
|
||||||
#define ENTNAME hostent
|
#define ENTNAME hostent
|
||||||
@@ -74,25 +76,199 @@ LINE_PARSER
|
|||||||
STRING_FIELD (result->h_name, isspace, 1);
|
STRING_FIELD (result->h_name, isspace, 1);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define HOST_DB_LOOKUP(name, keysize, keypattern, break_if_match, proto...) \
|
||||||
|
enum nss_status \
|
||||||
|
_nss_files_get##name##_r (proto, \
|
||||||
|
struct STRUCTURE *result, char *buffer, \
|
||||||
|
size_t buflen, int *errnop H_ERRNO_PROTO) \
|
||||||
|
{ \
|
||||||
|
enum nss_status status; \
|
||||||
|
\
|
||||||
|
__libc_lock_lock (lock); \
|
||||||
|
\
|
||||||
|
/* Reset file pointer to beginning or open file. */ \
|
||||||
|
status = internal_setent (keep_stream); \
|
||||||
|
\
|
||||||
|
if (status == NSS_STATUS_SUCCESS) \
|
||||||
|
{ \
|
||||||
|
/* Tell getent function that we have repositioned the file pointer. */ \
|
||||||
|
last_use = getby; \
|
||||||
|
\
|
||||||
|
while ((status = internal_getent (result, buffer, buflen, errnop \
|
||||||
|
H_ERRNO_ARG EXTRA_ARGS_VALUE)) \
|
||||||
|
== NSS_STATUS_SUCCESS) \
|
||||||
|
{ break_if_match } \
|
||||||
|
\
|
||||||
|
if (status == NSS_STATUS_SUCCESS \
|
||||||
|
&& _res_hconf.flags & HCONF_FLAG_MULTI) \
|
||||||
|
{ \
|
||||||
|
/* We have to get all host entries from the file. */ \
|
||||||
|
const size_t tmp_buflen = MIN (buflen, 4096); \
|
||||||
|
char tmp_buffer[tmp_buflen]; \
|
||||||
|
struct hostent tmp_result_buf; \
|
||||||
|
int naddrs = 1; \
|
||||||
|
int naliases = 0; \
|
||||||
|
char *bufferend; \
|
||||||
|
\
|
||||||
|
while (result->h_aliases[naliases] != NULL) \
|
||||||
|
++naliases; \
|
||||||
|
\
|
||||||
|
bufferend = (char *) &result->h_aliases[naliases + 1]; \
|
||||||
|
\
|
||||||
|
while ((status = internal_getent (&tmp_result_buf, tmp_buffer, \
|
||||||
|
tmp_buflen, errnop H_ERRNO_ARG \
|
||||||
|
EXTRA_ARGS_VALUE)) \
|
||||||
|
== NSS_STATUS_SUCCESS) \
|
||||||
|
{ \
|
||||||
|
int matches = 1; \
|
||||||
|
struct hostent *old_result = result; \
|
||||||
|
result = &tmp_result_buf; \
|
||||||
|
/* The following piece is a bit clumsy but we want to use the \
|
||||||
|
`break_if_match' value. The optimizer should do its \
|
||||||
|
job. */ \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
break_if_match \
|
||||||
|
result = old_result; \
|
||||||
|
} \
|
||||||
|
while ((matches = 0)); \
|
||||||
|
\
|
||||||
|
if (matches) \
|
||||||
|
{ \
|
||||||
|
/* We could be very clever and try to recycle a few bytes \
|
||||||
|
in the buffer instead of generating new arrays. But \
|
||||||
|
we are not doing this here since it's more work than \
|
||||||
|
it's worth. Simply let the user provide a bit bigger \
|
||||||
|
buffer. */ \
|
||||||
|
char **new_h_addr_list; \
|
||||||
|
char **new_h_aliases; \
|
||||||
|
int newaliases = 0; \
|
||||||
|
size_t newstrlen = 0; \
|
||||||
|
int cnt; \
|
||||||
|
\
|
||||||
|
/* Count the new aliases and the length of the strings. */ \
|
||||||
|
while (tmp_result_buf.h_aliases[newaliases] != NULL) \
|
||||||
|
{ \
|
||||||
|
char *cp = tmp_result_buf.h_aliases[newaliases]; \
|
||||||
|
++newaliases; \
|
||||||
|
newstrlen += strlen (cp) + 1; \
|
||||||
|
} \
|
||||||
|
/* If the real name is different add it also to the \
|
||||||
|
aliases. This means that there is a duplication \
|
||||||
|
in the alias list but this is really the users \
|
||||||
|
problem. */ \
|
||||||
|
if (strcmp (old_result->h_name, \
|
||||||
|
tmp_result_buf.h_name) != 0) \
|
||||||
|
{ \
|
||||||
|
++newaliases; \
|
||||||
|
newstrlen += strlen (tmp_result_buf.h_name) + 1; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
/* Now we can check whether the buffer is large enough. */ \
|
||||||
|
if (bufferend + 16 + (naddrs + 2) * sizeof (char *) \
|
||||||
|
+ roundup (newstrlen, sizeof (char *)) \
|
||||||
|
+ (naliases + newaliases + 1) * sizeof (char *) \
|
||||||
|
>= buffer + buflen) \
|
||||||
|
{ \
|
||||||
|
*errnop = ERANGE; \
|
||||||
|
status = NSS_STATUS_TRYAGAIN; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
new_h_addr_list = \
|
||||||
|
(char **) (bufferend \
|
||||||
|
+ roundup (newstrlen, sizeof (char *)) \
|
||||||
|
+ 16); \
|
||||||
|
new_h_aliases = \
|
||||||
|
(char **) ((char *) new_h_addr_list \
|
||||||
|
+ (naddrs + 2) * sizeof (char *)); \
|
||||||
|
\
|
||||||
|
/* Copy the old data in the new arrays. */ \
|
||||||
|
for (cnt = 0; cnt < naddrs; ++cnt) \
|
||||||
|
new_h_addr_list[cnt] = old_result->h_addr_list[cnt]; \
|
||||||
|
\
|
||||||
|
for (cnt = 0; cnt < naliases; ++cnt) \
|
||||||
|
new_h_aliases[cnt] = old_result->h_aliases[cnt]; \
|
||||||
|
\
|
||||||
|
/* Store the new strings. */ \
|
||||||
|
cnt = 0; \
|
||||||
|
while (tmp_result_buf.h_aliases[cnt] != NULL) \
|
||||||
|
{ \
|
||||||
|
new_h_aliases[naliases++] = bufferend; \
|
||||||
|
bufferend = (__stpcpy (bufferend, \
|
||||||
|
tmp_result_buf.h_aliases[cnt]) \
|
||||||
|
+ 1); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
if (cnt < newaliases) \
|
||||||
|
{ \
|
||||||
|
new_h_aliases[naliases++] = bufferend; \
|
||||||
|
bufferend = __stpcpy (bufferend, \
|
||||||
|
tmp_result_buf.h_name) + 1; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
/* Final NULL pointer. */ \
|
||||||
|
new_h_aliases[naliases] = NULL; \
|
||||||
|
\
|
||||||
|
/* Round up the buffer end address. */ \
|
||||||
|
bufferend += (sizeof (char *) \
|
||||||
|
- ((bufferend - (char *) 0) \
|
||||||
|
% sizeof (char *))); \
|
||||||
|
\
|
||||||
|
/* Now the new address. */ \
|
||||||
|
new_h_addr_list[naddrs++] = \
|
||||||
|
memcpy (bufferend, tmp_result_buf.h_addr, \
|
||||||
|
tmp_result_buf.h_length); \
|
||||||
|
\
|
||||||
|
/* Also here a final NULL pointer. */ \
|
||||||
|
new_h_addr_list[naddrs] = NULL; \
|
||||||
|
\
|
||||||
|
/* Store the new array pointers. */ \
|
||||||
|
old_result->h_aliases = new_h_aliases; \
|
||||||
|
old_result->h_addr_list = new_h_addr_list; \
|
||||||
|
\
|
||||||
|
/* Compute the new buffer end. */ \
|
||||||
|
bufferend = (char *) &new_h_aliases[naliases + 1]; \
|
||||||
|
assert (bufferend <= buffer + buflen); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
if (status != NSS_STATUS_TRYAGAIN) \
|
||||||
|
status = NSS_STATUS_SUCCESS; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
\
|
||||||
|
if (! keep_stream) \
|
||||||
|
internal_endent (); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
__libc_lock_unlock (lock); \
|
||||||
|
\
|
||||||
|
return status; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define EXTRA_ARGS_VALUE \
|
#define EXTRA_ARGS_VALUE \
|
||||||
, ((_res.options & RES_USE_INET6) ? AF_INET6 : AF_INET), \
|
, ((_res.options & RES_USE_INET6) ? AF_INET6 : AF_INET), \
|
||||||
((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0)
|
((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0)
|
||||||
#include "files-XXX.c"
|
#include "files-XXX.c"
|
||||||
|
HOST_DB_LOOKUP (hostbyname, ,,
|
||||||
|
{
|
||||||
|
LOOKUP_NAME_CASE (h_name, h_aliases)
|
||||||
|
}, const char *name)
|
||||||
|
|
||||||
DB_LOOKUP (hostbyname, ,,
|
|
||||||
{
|
|
||||||
LOOKUP_NAME_CASE (h_name, h_aliases)
|
|
||||||
}, const char *name)
|
|
||||||
|
|
||||||
#undef EXTRA_ARGS_VALUE
|
#undef EXTRA_ARGS_VALUE
|
||||||
/* XXX Is using _res to determine whether we want to convert IPv4 addresses
|
/* XXX Is using _res to determine whether we want to convert IPv4 addresses
|
||||||
to IPv6 addresses really the right thing to do? */
|
to IPv6 addresses really the right thing to do? */
|
||||||
#define EXTRA_ARGS_VALUE \
|
#define EXTRA_ARGS_VALUE \
|
||||||
, af, ((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0)
|
, af, ((_res.options & RES_USE_INET6) ? AI_V4MAPPED : 0)
|
||||||
DB_LOOKUP (hostbyname2, ,,
|
HOST_DB_LOOKUP (hostbyname2, ,,
|
||||||
{
|
{
|
||||||
LOOKUP_NAME_CASE (h_name, h_aliases)
|
LOOKUP_NAME_CASE (h_name, h_aliases)
|
||||||
}, const char *name, int af)
|
}, const char *name, int af)
|
||||||
|
|
||||||
DB_LOOKUP (hostbyaddr, ,,
|
DB_LOOKUP (hostbyaddr, ,,
|
||||||
{
|
{
|
||||||
@@ -104,7 +280,7 @@ DB_LOOKUP (hostbyaddr, ,,
|
|||||||
#undef EXTRA_ARGS_VALUE
|
#undef EXTRA_ARGS_VALUE
|
||||||
#define EXTRA_ARGS_VALUE \
|
#define EXTRA_ARGS_VALUE \
|
||||||
, af, flags
|
, af, flags
|
||||||
DB_LOOKUP (ipnodebyname, ,,
|
HOST_DB_LOOKUP (ipnodebyname, ,,
|
||||||
{
|
{
|
||||||
LOOKUP_NAME_CASE (h_name, h_aliases)
|
LOOKUP_NAME_CASE (h_name, h_aliases)
|
||||||
}, const char *name, int af, int flags)
|
}, const char *name, int af, int flags)
|
||||||
|
@@ -20,7 +20,7 @@ libc {
|
|||||||
}
|
}
|
||||||
GLIBC_2.2 {
|
GLIBC_2.2 {
|
||||||
# r*
|
# r*
|
||||||
__res_state; __res_init; __res_nclose; __res_ninit;
|
__res_state; __res_init; __res_nclose; __res_ninit; _res_hconf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user