mirror of
git://sourceware.org/git/glibc.git
synced 2026-09-09 05:59:27 +08:00
Compare commits
34
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1750fb9c6 | ||
|
|
efaf80c5d0 | ||
|
|
959f4c0547 | ||
|
|
627cc92643 | ||
|
|
1b16f19afc | ||
|
|
037c97bbc9 | ||
|
|
bd7c3bed54 | ||
|
|
338cc5101b | ||
|
|
04a9e7f251 | ||
|
|
fd8e1ac720 | ||
|
|
b402c96065 | ||
|
|
5ab387d33b | ||
|
|
ff9e0dc823 | ||
|
|
5d44b2ea72 | ||
|
|
1547e88a9a | ||
|
|
1a19a35223 | ||
|
|
237910315c | ||
|
|
a0d24ebc12 | ||
|
|
1e96287768 | ||
|
|
a1711aa2c9 | ||
|
|
996d168e57 | ||
|
|
05bb11efb2 | ||
|
|
0847bc6ef9 | ||
|
|
f66e5db9b0 | ||
|
|
dc60a4e495 | ||
|
|
c699a3bdd7 | ||
|
|
aaadc59ce1 | ||
|
|
a343cb0f24 | ||
|
|
b9bdb95c3f | ||
|
|
f67c6d9684 | ||
|
|
3cd7504450 | ||
|
|
59ae4124b7 | ||
|
|
ee414d57cf | ||
|
|
b5707b44d2 |
@@ -1,3 +1,185 @@
|
||||
2004-09-26 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* sysdeps/alpha/alphaev6/memcpy.S: Mark .prologue.
|
||||
* sysdeps/unix/alpha/sysdep.h (LEAF, ENTRY): Align entry points
|
||||
to 16 byte boundaries.
|
||||
|
||||
2004-09-26 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* elf/readlib.c (process_file): Before complaining about too-short
|
||||
file, check that it potentially be an ELF file. Also complain about
|
||||
empty files. [BZ #151].
|
||||
|
||||
* scripts/test-installation.pl: Fix ld.so recognition for new
|
||||
LD_TRACE_LOADED_OBJECTS output format.
|
||||
Patch by <jsberg04+computing.glibc@ftml.net> [BZ #407].
|
||||
|
||||
* elf/dl-support.c (_dl_non_dynamic_init): Fix cleaning of
|
||||
environment. [BZ #384]
|
||||
|
||||
* sunrpc/clnt_udp.c (is_network_up): Use getifaddrs instead of ioctl.
|
||||
* sunrpc/get_myaddr.c (get_myaddress): Likewise.
|
||||
* sunrpc/pmap_clnt.c (__get_myaddress): Likewise.
|
||||
* sunrpc/pmap_rmt.c (getbroadcastnets): Likewise. Change interface
|
||||
to avoid buffer overrun and remove now useless parameters.
|
||||
(clnt_broadcast): Adjust caller. [BZ #381].
|
||||
|
||||
* sysdeps/generic/s_fdim.c: Handle +inf/+inf
|
||||
* sysdeps/generic/s_fdimf.c: Likewise.
|
||||
* sysdeps/generic/s_fdiml.c: Likewise.
|
||||
* sysdeps/i386/i686/fpu/s_fdim.S: Likewise.
|
||||
* sysdeps/i386/i686/fpu/s_fdimf.S: Likewise.
|
||||
* sysdeps/i386/i686/fpu/s_fdiml.S: Likewise.
|
||||
* sysdeps/powerpc/fpu/s_fdim.c: Likewise.
|
||||
* sysdeps/powerpc/fpu/s_fdimf.c: Likewise.
|
||||
* sysdeps/x86_64/fpu/s_fdiml.S: Likewise.
|
||||
* math/libm-test.inc (fdim_test): Add test case. [BZ #376].
|
||||
|
||||
* sysdeps/generic/bits/types.h: Fix __SQUAD_TYPE and __UQUAD_TYPE
|
||||
for compilers without __GLIBC_HAVE_LONG_LONG. [BZ #362]
|
||||
|
||||
* sysdeps/posix/getaddrinfo.c (getaddrinfo): Remove incorrect
|
||||
requirement on socktype and protocol.
|
||||
(gaih_inet): If numeric port number is given, return records for all
|
||||
possible socket types.
|
||||
* posix/tst-getaddrinfo2.c: New file.
|
||||
* posix/Makefile (tests): Add tst-getaddrinfo2. [BZ #358]
|
||||
|
||||
2004-09-25 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* locale/loadlocale.c (_nl_intern_locale_data): Recognize LC_CTYPE
|
||||
data where _nl_value_type_LC_CTYPE does not contain the type
|
||||
information. Add range checks.
|
||||
Reported by John Lumby <johnlumby@hotmail.com> [BZ #356].
|
||||
|
||||
* libio/vasprintf.c (_IO_vasprintf): Fix condition to decide
|
||||
whether to realloc or not.
|
||||
Reported by Pavel Kankovsky <peak@argo.troja.mff.cuni.cz> [BZ #346].
|
||||
|
||||
* intl/dcigettext.c (DCIGETTEXT): Protect tfind/tsearch calls.
|
||||
* intl/dcigettext.c (_nl_find_msg): Call _nl_load_domain also if
|
||||
decided < 0.
|
||||
* intl/finddomain.c (_nl_find_domain): Likewise.
|
||||
* intl/loadmsgcat.c (_nl_load_domain): Set decided to 1 only once we
|
||||
are done. First set to -1 to signal initialization is ongoing.
|
||||
Protect against concurrent callers with recursive lock.
|
||||
* intl/finddomain.c (_nl_find_domain): Protect calls to
|
||||
_nl_make_l10nflist. [BZ #322]
|
||||
|
||||
* sysdeps/posix/getaddrinfo.c (getaddrinfo): If determinination of
|
||||
source address fails, initialized source_addr_len field so that
|
||||
duplicate address recognition does not copy junk.
|
||||
|
||||
2004-09-25 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/i386/setuid.c (__setuid): Remove second
|
||||
result declaration.
|
||||
|
||||
2004-09-22 Andreas Schwab <schwab@suse.de>
|
||||
|
||||
* sysdeps/unix/sysv/linux/ia64/sysdep.h: Adjust whitespace.
|
||||
|
||||
2004-09-24 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* misc/daemon.c (daemon): Don't succeed if /dev/null cannot be
|
||||
opened.
|
||||
|
||||
* nis/ypclnt.c (do_ypcall): Add one missing unlock. Simplify the
|
||||
code a bit.
|
||||
|
||||
* misc/daemon.c (daemon): Define errno in case /dev/null is not
|
||||
the correct device.
|
||||
|
||||
* nis/ypclnt.c (yp_bind_file): Optimize a bit. Minimal cleanups.
|
||||
|
||||
2004-09-23 Andreas Jaeger <aj@suse.de>
|
||||
|
||||
* locale/weight.h (findidx): Remove static, it's not supported
|
||||
anymore with GCC 4.0 in a block scope.
|
||||
* locale/weightwc.h (findidx): Likewise.
|
||||
* posix/regcomp.c (seek_collating_symbol_entry): Likewise.
|
||||
(lookup_collation_sequence_value): Likewise.
|
||||
(build_range_exp): Likewise.
|
||||
(build_collating_symbol): Likewise.
|
||||
* iconv/iconvconfig.c (write_output): Likewise.
|
||||
* elf/do-rel.h (elf_dynamic_do_rel): Likewise.
|
||||
|
||||
* sysdeps/x86_64/dl-machine.h (elf_machine_rela_relative): Remove
|
||||
static, add always_inline attribute.
|
||||
(elf_machine_rela): Likewise.
|
||||
(elf_machine_lazy_rel): Likewise.
|
||||
|
||||
* elf/dynamic-link.h (elf_get_dynamic_info): Make static dependend
|
||||
on !RESOLVE so that it's not defined in local scope.
|
||||
|
||||
2004-09-23 Kaz Kojima <kkojima@rr.iij4u.or.jp>
|
||||
|
||||
* sysdeps/unix/sysv/linux/sh/sysdep.h (INTERNAL_SYSCALL_NCS): Define.
|
||||
|
||||
2004-09-23 Thorsten Kukuk <kukuk@suse.de>
|
||||
|
||||
* sysdeps/unix/sysv/linux/sys/mount.h: Sync MS_RMT_MASK flag
|
||||
and BLK* ioctls with linux kernel headers.
|
||||
|
||||
2004-09-23 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* sysdeps/generic/bits/dlfcn.h: Add RTLD_DEEPBIND.
|
||||
* elf/dl-object.c (_dl_new_object): Add new parameter mode. If mode
|
||||
has RTLD_DEEPBIND set add local searchlist before global scope.
|
||||
* sysdeps/generic/ldsodefs.h (_dl_new_object): Adjust prototype.
|
||||
* elf/rtld.c: Adjust callers of _dl_new_object.
|
||||
* elf/dl-load.c: Likewise.
|
||||
(_dl_map_object_from_fd): If RTLD_DEEPBIND is used, don't do anything
|
||||
for DF_SYMBOLIC.
|
||||
* elf/dl-open.c (dl_open_writer): Pass RTLD_DEEPBIND flag on to
|
||||
_dl_map_object_deps.
|
||||
* elf/tst-deep1.c: New file.
|
||||
* elf/tst-deep1mod1.c: New file.
|
||||
* elf/tst-deep1mod2.c: New file.
|
||||
* elf/tst-deep1mod3.c: New file.
|
||||
* elf/Makefile: Add rules to build and run new tests.
|
||||
|
||||
* elf/dl-deps.c: Pretty printing.
|
||||
|
||||
2004-09-23 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/unix/alpha/sysdep.h (inline_syscall[0-6]): Change name
|
||||
argument to numbers from syscall names.
|
||||
(INLINE_SYSCALL1): Pass __NR_##name to inline_syscall##nr.
|
||||
(INTERNAL_SYSCALL_NCS): Renamed from...
|
||||
(INTERNAL_SYSCALL_1): ... this. Use INTERNAL_SYSCALL_NCS.
|
||||
* sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h
|
||||
(INTERNAL_SYSCALL_NCS): Define.
|
||||
* sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h
|
||||
(INTERNAL_SYSCALL_NCS): Likewise.
|
||||
* sysdeps/unix/sysv/linux/sparc/sysdep.h (inline_syscall[0-6]):
|
||||
Change name argument to numbers from syscall names.
|
||||
(INLINE_SYSCALL, INTERNAL_SYSCALL): Adjust.
|
||||
(INTERNAL_SYSCALL_NCS): Define.
|
||||
|
||||
2004-09-22 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* malloc/malloc.c (malloc_printerr): Use syslog if writev failed.
|
||||
|
||||
* string/string.h: Add __nonnull annotations.
|
||||
* stdlib/stdlib.h: Likewise.
|
||||
|
||||
2004-09-20 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/unix/alpha/sysdep.h (inline_syscall[0-6]): Change name
|
||||
argument to numbers from syscall names.
|
||||
(INLINE_SYSCALL1): Pass __NR_##name to inline_syscall##nr.
|
||||
(INTERNAL_SYSCALL_NCS): Renamed from...
|
||||
(INTERNAL_SYSCALL_1): ... this. Use INTERNAL_SYSCALL_NCS.
|
||||
* sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h
|
||||
(INTERNAL_SYSCALL_NCS): Define.
|
||||
* sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h
|
||||
(INTERNAL_SYSCALL_NCS): Likewise.
|
||||
* sysdeps/unix/sysv/linux/sparc/sysdep.h (inline_syscall[0-6]):
|
||||
Change name argument to numbers from syscall names.
|
||||
(INLINE_SYSCALL, INTERNAL_SYSCALL): Adjust.
|
||||
(INTERNAL_SYSCALL_NCS): Define.
|
||||
|
||||
2004-09-20 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/ia64/sysdep.h (DO_INLINE_SYSCALL):
|
||||
@@ -727,6 +909,23 @@
|
||||
before return type.
|
||||
* locale/localename.c (__current_locale_name): Likewise.
|
||||
|
||||
2004-08-31 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* elf/ldconfig.c (parse_conf): Add prefix argument, prepend it
|
||||
before arguments to add_dir and pass to parse_conf_include.
|
||||
(parse_conf_include): Add prefix argument, pass it down to
|
||||
parse_conf.
|
||||
(main): Call arch_startup. Adjust parse_conf caller.
|
||||
Call add_arch_dirs.
|
||||
* sysdeps/generic/dl-cache.h (arch_startup, add_arch_dirs): Define.
|
||||
* sysdeps/unix/sysv/linux/i386/dl-cache.h: New file.
|
||||
* sysdeps/unix/sysv/linux/ia64/dl-cache.h (EMUL_HACK, arch_startup,
|
||||
add_arch_dirs): Define.
|
||||
* sysdeps/unix/sysv/linux/ia64/ldd-rewrite.sed: Prepend
|
||||
/emul/ia32-linux before the 32-bit ld.so pathname.
|
||||
* sysdeps/unix/sysv/linux/ia64/dl-procinfo.c: New file.
|
||||
* sysdeps/unix/sysv/linux/ia64/dl-procinfo.h: New file.
|
||||
|
||||
2004-08-30 Roland McGrath <roland@frob.com>
|
||||
|
||||
* scripts/extract-abilist.awk: If `lastversion' variable defined, omit
|
||||
@@ -883,6 +1082,22 @@
|
||||
* resolv/nss_dns/dns-canon.c (_nss_dns_getcanonname_r): Initialize
|
||||
status to NSS_STATUS_UNAVAIL.
|
||||
|
||||
2004-08-19 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/powerpc/powerpc64/configure.in: New file.
|
||||
* sysdeps/powerpc/powerpc64/configure: Rebuilt.
|
||||
* config.h.in (USE_PPC64_OVERLAPPING_OPD): Add.
|
||||
* configure.in (HAVE_ASM_GLOBAL_DOT_NAME): Remove.
|
||||
* configure: Rebuilt.
|
||||
* sysdeps/powerpc/powerpc64/sysdep.h: Formatting.
|
||||
(OPD_ENT, BODY_LABEL, ENTRY_1, ENTRY_2, END_2, DOT_PREFIX,
|
||||
BODY_PREFIX): Define.
|
||||
(ENTRY, DOT_LABEL, END, TRACEBACK, END_GEN_TB, EALIGN): Support
|
||||
HAVE_ASM_GLOBAL_DOT_NAME or no dot symbols,
|
||||
USE_PPC64_OVERLAPPING_OPD or never overlapping .opd entries.
|
||||
* sysdeps/powerpc/powerpc64/dl-machine.h: Include sysdep.h.
|
||||
(TRAMPOLINE_TEMPLATE, RTLD_START): Use the new sysdep.h macros.
|
||||
|
||||
2004-08-19 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* sysdeps/posix/getaddrinfo.c (gaih_inet): Use h->h_name in the
|
||||
@@ -1187,6 +1402,12 @@
|
||||
|
||||
* iconvdata/testdata/ISO-2022-JP-3: Regenerated.
|
||||
|
||||
2004-07-23 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
[BZ #284]
|
||||
* include/features.h (_POSIX_SOURCE, _POSIX_C_SOURCE): Define
|
||||
if _XOPEN_SOURCE >= 500 even if __STRICT_ANSI__ is defined.
|
||||
|
||||
2004-08-10 Alfred M. Szmidt <ams@kemisten.nu>
|
||||
|
||||
* sysdeps/generic/bits/in.h (struct ip_mreq): Remove definition.
|
||||
|
||||
@@ -1352,6 +1352,11 @@
|
||||
* sysdeps/unix/sysv/linux/mips/sys/tas.h: Add missing .mips0 at the
|
||||
end of inline assembler code.
|
||||
|
||||
2000-10-02 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sunrpc/svc_udp.c (svcudp_recv): Set msg_controllen to all
|
||||
remaining xp_pad space.
|
||||
|
||||
2000-10-02 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* include/features.h [__USE_FILE_OFFSET && !__REDIRECT]: Define
|
||||
@@ -9280,6 +9285,12 @@
|
||||
syscall.
|
||||
* sysdeps/unix/sysv/linux/mips/truncate64.c: Likewise.
|
||||
|
||||
2000-05-30 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* resolv/res_query.c (res_nsearch): Remove unused variable
|
||||
root_on_list. If dots >= statp->ndots and as is querydomain
|
||||
fails, keep searching.
|
||||
|
||||
2000-05-30 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/alpha/oldglob.c (__old_glob): Loose __P.
|
||||
@@ -9480,6 +9491,11 @@
|
||||
* sysdeps/i386/fpu/bits/mathinline.h: Define expm1 inline only if
|
||||
__FAST_MATH__ is defined.
|
||||
|
||||
2000-05-22 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/i386/fpu/bits/mathinline.h (__expm1_code): Avoid using ?:
|
||||
with omitted middle operand.
|
||||
|
||||
2000-05-22 Andreas Jaeger <aj@suse.de>
|
||||
|
||||
* math/Makefile: Add -D__FAST_MATH__ to CFLAGS-test-ifloat.c,
|
||||
@@ -9718,6 +9734,11 @@
|
||||
* manual/arith.texi (Parsing of Integers): Fix typo.
|
||||
Closes PR libc/1744, reported by blp@gnu.org.
|
||||
|
||||
2000-05-17 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* inet/rcmd.c (rcmd_af): If *ahost cannot be resolved, include
|
||||
unresolved hostname in the message.
|
||||
|
||||
2000-05-17 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/arm/bits/huge_val.h (HUGE_VAL, HUGE_VALF): Add
|
||||
|
||||
@@ -7729,6 +7729,13 @@
|
||||
|
||||
* Versions.def [ld]: Add GLIBC_2.2.1.
|
||||
|
||||
2001-01-10 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* malloc/memusage.c (me): If not SUID/SGID, allow creating new
|
||||
$MEMUSAGE_OUTPUT file.
|
||||
* sysdeps/generic/segfault.c (segfault.c): If not SUID/SGID, allow
|
||||
creating new $SEGFAULT_OUTPUT_NAME file.
|
||||
|
||||
2001-01-10 H.J. Lu <hjl@gnu.org>
|
||||
|
||||
* elf/dl-libc.c (do_dlopen): Call DL_STATIC_INIT for static binaries.
|
||||
@@ -8130,6 +8137,11 @@
|
||||
* sysdeps/powerpc/soft-fp/Versions: Likewise.
|
||||
* sysdeps/sparc/sparc64/soft-fp/Versions: Likewise.
|
||||
|
||||
2001-01-02 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* locale/setlocale.c (setlocale): Don't allocate/free category name
|
||||
unnecessarily.
|
||||
|
||||
2001-01-02 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
|
||||
|
||||
* sysdeps/powerpc/dl-machine.c (__process_machine_rela): Fix typo.
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
/* Macros to swap the order of bytes in integer values.
|
||||
Copyright (C) 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#if !defined _BYTESWAP_H && !defined _NETINET_IN_H
|
||||
# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
|
||||
#endif
|
||||
|
||||
#ifndef _BITS_BYTESWAP_H
|
||||
#define _BITS_BYTESWAP_H 1
|
||||
|
||||
/* Swap bytes in 16 bit value. */
|
||||
#ifdef __GNUC__
|
||||
# define __bswap_16(x) \
|
||||
(__extension__ \
|
||||
({ unsigned short int __bsx = (x); \
|
||||
((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8)); }))
|
||||
#else
|
||||
static __inline unsigned short int
|
||||
__bswap_16 (unsigned short int __bsx)
|
||||
{
|
||||
return ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Swap bytes in 32 bit value. */
|
||||
#ifdef __GNUC__
|
||||
# define __bswap_32(x) \
|
||||
(__extension__ \
|
||||
({ unsigned int __bsx = (x); \
|
||||
((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >> 8) | \
|
||||
(((__bsx) & 0x0000ff00) << 8) | (((__bsx) & 0x000000ff) << 24)); }))
|
||||
#else
|
||||
static __inline unsigned int
|
||||
__bswap_32 (unsigned int __bsx)
|
||||
{
|
||||
return ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >> 8) |
|
||||
(((__bsx) & 0x0000ff00) << 8) | (((__bsx) & 0x000000ff) << 24));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined __GNUC__ && __GNUC__ >= 2
|
||||
/* Swap bytes in 64 bit value. */
|
||||
# define __bswap_constant_64(x) \
|
||||
((((x) & 0xff00000000000000ull) >> 56) \
|
||||
| (((x) & 0x00ff000000000000ull) >> 40) \
|
||||
| (((x) & 0x0000ff0000000000ull) >> 24) \
|
||||
| (((x) & 0x000000ff00000000ull) >> 8) \
|
||||
| (((x) & 0x00000000ff000000ull) << 8) \
|
||||
| (((x) & 0x0000000000ff0000ull) << 24) \
|
||||
| (((x) & 0x000000000000ff00ull) << 40) \
|
||||
| (((x) & 0x00000000000000ffull) << 56))
|
||||
|
||||
# define __bswap_64(x) \
|
||||
(__extension__ \
|
||||
({ union { __extension__ unsigned long long int __ll; \
|
||||
unsigned int __l[2]; } __w, __r; \
|
||||
if (__builtin_constant_p (x)) \
|
||||
__r.__ll = __bswap_constant_64 (x); \
|
||||
else \
|
||||
{ \
|
||||
__w.__ll = (x); \
|
||||
__r.__l[0] = __bswap_32 (__w.__l[1]); \
|
||||
__r.__l[1] = __bswap_32 (__w.__l[0]); \
|
||||
} \
|
||||
__r.__ll; }))
|
||||
#endif
|
||||
|
||||
#endif /* _BITS_BYTESWAP_H */
|
||||
-596
@@ -1,596 +0,0 @@
|
||||
/* `sysconf', `pathconf', and `confstr' NAME values. Generic version.
|
||||
Copyright (C) 1993,1995-1998,2000,2001,2003,2004
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _UNISTD_H
|
||||
# error "Never use <bits/confname.h> directly; include <unistd.h> instead."
|
||||
#endif
|
||||
|
||||
/* Values for the NAME argument to `pathconf' and `fpathconf'. */
|
||||
enum
|
||||
{
|
||||
_PC_LINK_MAX,
|
||||
#define _PC_LINK_MAX _PC_LINK_MAX
|
||||
_PC_MAX_CANON,
|
||||
#define _PC_MAX_CANON _PC_MAX_CANON
|
||||
_PC_MAX_INPUT,
|
||||
#define _PC_MAX_INPUT _PC_MAX_INPUT
|
||||
_PC_NAME_MAX,
|
||||
#define _PC_NAME_MAX _PC_NAME_MAX
|
||||
_PC_PATH_MAX,
|
||||
#define _PC_PATH_MAX _PC_PATH_MAX
|
||||
_PC_PIPE_BUF,
|
||||
#define _PC_PIPE_BUF _PC_PIPE_BUF
|
||||
_PC_CHOWN_RESTRICTED,
|
||||
#define _PC_CHOWN_RESTRICTED _PC_CHOWN_RESTRICTED
|
||||
_PC_NO_TRUNC,
|
||||
#define _PC_NO_TRUNC _PC_NO_TRUNC
|
||||
_PC_VDISABLE,
|
||||
#define _PC_VDISABLE _PC_VDISABLE
|
||||
_PC_SYNC_IO,
|
||||
#define _PC_SYNC_IO _PC_SYNC_IO
|
||||
_PC_ASYNC_IO,
|
||||
#define _PC_ASYNC_IO _PC_ASYNC_IO
|
||||
_PC_PRIO_IO,
|
||||
#define _PC_PRIO_IO _PC_PRIO_IO
|
||||
_PC_SOCK_MAXBUF,
|
||||
#define _PC_SOCK_MAXBUF _PC_SOCK_MAXBUF
|
||||
_PC_FILESIZEBITS,
|
||||
#define _PC_FILESIZEBITS _PC_FILESIZEBITS
|
||||
_PC_REC_INCR_XFER_SIZE,
|
||||
#define _PC_REC_INCR_XFER_SIZE _PC_REC_INCR_XFER_SIZE
|
||||
_PC_REC_MAX_XFER_SIZE,
|
||||
#define _PC_REC_MAX_XFER_SIZE _PC_REC_MAX_XFER_SIZE
|
||||
_PC_REC_MIN_XFER_SIZE,
|
||||
#define _PC_REC_MIN_XFER_SIZE _PC_REC_MIN_XFER_SIZE
|
||||
_PC_REC_XFER_ALIGN,
|
||||
#define _PC_REC_XFER_ALIGN _PC_REC_XFER_ALIGN
|
||||
_PC_ALLOC_SIZE_MIN,
|
||||
#define _PC_ALLOC_SIZE_MIN _PC_ALLOC_SIZE_MIN
|
||||
_PC_SYMLINK_MAX,
|
||||
#define _PC_SYMLINK_MAX _PC_SYMLINK_MAX
|
||||
_PC_2_SYMLINKS
|
||||
#define _PC_2_SYMLINKS _PC_2_SYMLINKS
|
||||
};
|
||||
|
||||
/* Values for the argument to `sysconf'. */
|
||||
enum
|
||||
{
|
||||
_SC_ARG_MAX,
|
||||
#define _SC_ARG_MAX _SC_ARG_MAX
|
||||
_SC_CHILD_MAX,
|
||||
#define _SC_CHILD_MAX _SC_CHILD_MAX
|
||||
_SC_CLK_TCK,
|
||||
#define _SC_CLK_TCK _SC_CLK_TCK
|
||||
_SC_NGROUPS_MAX,
|
||||
#define _SC_NGROUPS_MAX _SC_NGROUPS_MAX
|
||||
_SC_OPEN_MAX,
|
||||
#define _SC_OPEN_MAX _SC_OPEN_MAX
|
||||
_SC_STREAM_MAX,
|
||||
#define _SC_STREAM_MAX _SC_STREAM_MAX
|
||||
_SC_TZNAME_MAX,
|
||||
#define _SC_TZNAME_MAX _SC_TZNAME_MAX
|
||||
_SC_JOB_CONTROL,
|
||||
#define _SC_JOB_CONTROL _SC_JOB_CONTROL
|
||||
_SC_SAVED_IDS,
|
||||
#define _SC_SAVED_IDS _SC_SAVED_IDS
|
||||
_SC_REALTIME_SIGNALS,
|
||||
#define _SC_REALTIME_SIGNALS _SC_REALTIME_SIGNALS
|
||||
_SC_PRIORITY_SCHEDULING,
|
||||
#define _SC_PRIORITY_SCHEDULING _SC_PRIORITY_SCHEDULING
|
||||
_SC_TIMERS,
|
||||
#define _SC_TIMERS _SC_TIMERS
|
||||
_SC_ASYNCHRONOUS_IO,
|
||||
#define _SC_ASYNCHRONOUS_IO _SC_ASYNCHRONOUS_IO
|
||||
_SC_PRIORITIZED_IO,
|
||||
#define _SC_PRIORITIZED_IO _SC_PRIORITIZED_IO
|
||||
_SC_SYNCHRONIZED_IO,
|
||||
#define _SC_SYNCHRONIZED_IO _SC_SYNCHRONIZED_IO
|
||||
_SC_FSYNC,
|
||||
#define _SC_FSYNC _SC_FSYNC
|
||||
_SC_MAPPED_FILES,
|
||||
#define _SC_MAPPED_FILES _SC_MAPPED_FILES
|
||||
_SC_MEMLOCK,
|
||||
#define _SC_MEMLOCK _SC_MEMLOCK
|
||||
_SC_MEMLOCK_RANGE,
|
||||
#define _SC_MEMLOCK_RANGE _SC_MEMLOCK_RANGE
|
||||
_SC_MEMORY_PROTECTION,
|
||||
#define _SC_MEMORY_PROTECTION _SC_MEMORY_PROTECTION
|
||||
_SC_MESSAGE_PASSING,
|
||||
#define _SC_MESSAGE_PASSING _SC_MESSAGE_PASSING
|
||||
_SC_SEMAPHORES,
|
||||
#define _SC_SEMAPHORES _SC_SEMAPHORES
|
||||
_SC_SHARED_MEMORY_OBJECTS,
|
||||
#define _SC_SHARED_MEMORY_OBJECTS _SC_SHARED_MEMORY_OBJECTS
|
||||
_SC_AIO_LISTIO_MAX,
|
||||
#define _SC_AIO_LISTIO_MAX _SC_AIO_LISTIO_MAX
|
||||
_SC_AIO_MAX,
|
||||
#define _SC_AIO_MAX _SC_AIO_MAX
|
||||
_SC_AIO_PRIO_DELTA_MAX,
|
||||
#define _SC_AIO_PRIO_DELTA_MAX _SC_AIO_PRIO_DELTA_MAX
|
||||
_SC_DELAYTIMER_MAX,
|
||||
#define _SC_DELAYTIMER_MAX _SC_DELAYTIMER_MAX
|
||||
_SC_MQ_OPEN_MAX,
|
||||
#define _SC_MQ_OPEN_MAX _SC_MQ_OPEN_MAX
|
||||
_SC_MQ_PRIO_MAX,
|
||||
#define _SC_MQ_PRIO_MAX _SC_MQ_PRIO_MAX
|
||||
_SC_VERSION,
|
||||
#define _SC_VERSION _SC_VERSION
|
||||
_SC_PAGESIZE,
|
||||
#define _SC_PAGESIZE _SC_PAGESIZE
|
||||
#define _SC_PAGE_SIZE _SC_PAGESIZE
|
||||
_SC_RTSIG_MAX,
|
||||
#define _SC_RTSIG_MAX _SC_RTSIG_MAX
|
||||
_SC_SEM_NSEMS_MAX,
|
||||
#define _SC_SEM_NSEMS_MAX _SC_SEM_NSEMS_MAX
|
||||
_SC_SEM_VALUE_MAX,
|
||||
#define _SC_SEM_VALUE_MAX _SC_SEM_VALUE_MAX
|
||||
_SC_SIGQUEUE_MAX,
|
||||
#define _SC_SIGQUEUE_MAX _SC_SIGQUEUE_MAX
|
||||
_SC_TIMER_MAX,
|
||||
#define _SC_TIMER_MAX _SC_TIMER_MAX
|
||||
|
||||
/* Values for the argument to `sysconf'
|
||||
corresponding to _POSIX2_* symbols. */
|
||||
_SC_BC_BASE_MAX,
|
||||
#define _SC_BC_BASE_MAX _SC_BC_BASE_MAX
|
||||
_SC_BC_DIM_MAX,
|
||||
#define _SC_BC_DIM_MAX _SC_BC_DIM_MAX
|
||||
_SC_BC_SCALE_MAX,
|
||||
#define _SC_BC_SCALE_MAX _SC_BC_SCALE_MAX
|
||||
_SC_BC_STRING_MAX,
|
||||
#define _SC_BC_STRING_MAX _SC_BC_STRING_MAX
|
||||
_SC_COLL_WEIGHTS_MAX,
|
||||
#define _SC_COLL_WEIGHTS_MAX _SC_COLL_WEIGHTS_MAX
|
||||
_SC_EQUIV_CLASS_MAX,
|
||||
#define _SC_EQUIV_CLASS_MAX _SC_EQUIV_CLASS_MAX
|
||||
_SC_EXPR_NEST_MAX,
|
||||
#define _SC_EXPR_NEST_MAX _SC_EXPR_NEST_MAX
|
||||
_SC_LINE_MAX,
|
||||
#define _SC_LINE_MAX _SC_LINE_MAX
|
||||
_SC_RE_DUP_MAX,
|
||||
#define _SC_RE_DUP_MAX _SC_RE_DUP_MAX
|
||||
_SC_CHARCLASS_NAME_MAX,
|
||||
#define _SC_CHARCLASS_NAME_MAX _SC_CHARCLASS_NAME_MAX
|
||||
|
||||
_SC_2_VERSION,
|
||||
#define _SC_2_VERSION _SC_2_VERSION
|
||||
_SC_2_C_BIND,
|
||||
#define _SC_2_C_BIND _SC_2_C_BIND
|
||||
_SC_2_C_DEV,
|
||||
#define _SC_2_C_DEV _SC_2_C_DEV
|
||||
_SC_2_FORT_DEV,
|
||||
#define _SC_2_FORT_DEV _SC_2_FORT_DEV
|
||||
_SC_2_FORT_RUN,
|
||||
#define _SC_2_FORT_RUN _SC_2_FORT_RUN
|
||||
_SC_2_SW_DEV,
|
||||
#define _SC_2_SW_DEV _SC_2_SW_DEV
|
||||
_SC_2_LOCALEDEF,
|
||||
#define _SC_2_LOCALEDEF _SC_2_LOCALEDEF
|
||||
|
||||
_SC_PII,
|
||||
#define _SC_PII _SC_PII
|
||||
_SC_PII_XTI,
|
||||
#define _SC_PII_XTI _SC_PII_XTI
|
||||
_SC_PII_SOCKET,
|
||||
#define _SC_PII_SOCKET _SC_PII_SOCKET
|
||||
_SC_PII_INTERNET,
|
||||
#define _SC_PII_INTERNET _SC_PII_INTERNET
|
||||
_SC_PII_OSI,
|
||||
#define _SC_PII_OSI _SC_PII_OSI
|
||||
_SC_POLL,
|
||||
#define _SC_POLL _SC_POLL
|
||||
_SC_SELECT,
|
||||
#define _SC_SELECT _SC_SELECT
|
||||
_SC_UIO_MAXIOV,
|
||||
#define _SC_UIO_MAXIOV _SC_UIO_MAXIOV
|
||||
_SC_IOV_MAX = _SC_UIO_MAXIOV,
|
||||
#define _SC_IOV_MAX _SC_IOV_MAX
|
||||
_SC_PII_INTERNET_STREAM,
|
||||
#define _SC_PII_INTERNET_STREAM _SC_PII_INTERNET_STREAM
|
||||
_SC_PII_INTERNET_DGRAM,
|
||||
#define _SC_PII_INTERNET_DGRAM _SC_PII_INTERNET_DGRAM
|
||||
_SC_PII_OSI_COTS,
|
||||
#define _SC_PII_OSI_COTS _SC_PII_OSI_COTS
|
||||
_SC_PII_OSI_CLTS,
|
||||
#define _SC_PII_OSI_CLTS _SC_PII_OSI_CLTS
|
||||
_SC_PII_OSI_M,
|
||||
#define _SC_PII_OSI_M _SC_PII_OSI_M
|
||||
_SC_T_IOV_MAX,
|
||||
#define _SC_T_IOV_MAX _SC_T_IOV_MAX
|
||||
|
||||
/* Values according to POSIX 1003.1c (POSIX threads). */
|
||||
_SC_THREADS,
|
||||
#define _SC_THREADS _SC_THREADS
|
||||
_SC_THREAD_SAFE_FUNCTIONS,
|
||||
#define _SC_THREAD_SAFE_FUNCTIONS _SC_THREAD_SAFE_FUNCTIONS
|
||||
_SC_GETGR_R_SIZE_MAX,
|
||||
#define _SC_GETGR_R_SIZE_MAX _SC_GETGR_R_SIZE_MAX
|
||||
_SC_GETPW_R_SIZE_MAX,
|
||||
#define _SC_GETPW_R_SIZE_MAX _SC_GETPW_R_SIZE_MAX
|
||||
_SC_LOGIN_NAME_MAX,
|
||||
#define _SC_LOGIN_NAME_MAX _SC_LOGIN_NAME_MAX
|
||||
_SC_TTY_NAME_MAX,
|
||||
#define _SC_TTY_NAME_MAX _SC_TTY_NAME_MAX
|
||||
_SC_THREAD_DESTRUCTOR_ITERATIONS,
|
||||
#define _SC_THREAD_DESTRUCTOR_ITERATIONS _SC_THREAD_DESTRUCTOR_ITERATIONS
|
||||
_SC_THREAD_KEYS_MAX,
|
||||
#define _SC_THREAD_KEYS_MAX _SC_THREAD_KEYS_MAX
|
||||
_SC_THREAD_STACK_MIN,
|
||||
#define _SC_THREAD_STACK_MIN _SC_THREAD_STACK_MIN
|
||||
_SC_THREAD_THREADS_MAX,
|
||||
#define _SC_THREAD_THREADS_MAX _SC_THREAD_THREADS_MAX
|
||||
_SC_THREAD_ATTR_STACKADDR,
|
||||
#define _SC_THREAD_ATTR_STACKADDR _SC_THREAD_ATTR_STACKADDR
|
||||
_SC_THREAD_ATTR_STACKSIZE,
|
||||
#define _SC_THREAD_ATTR_STACKSIZE _SC_THREAD_ATTR_STACKSIZE
|
||||
_SC_THREAD_PRIORITY_SCHEDULING,
|
||||
#define _SC_THREAD_PRIORITY_SCHEDULING _SC_THREAD_PRIORITY_SCHEDULING
|
||||
_SC_THREAD_PRIO_INHERIT,
|
||||
#define _SC_THREAD_PRIO_INHERIT _SC_THREAD_PRIO_INHERIT
|
||||
_SC_THREAD_PRIO_PROTECT,
|
||||
#define _SC_THREAD_PRIO_PROTECT _SC_THREAD_PRIO_PROTECT
|
||||
_SC_THREAD_PROCESS_SHARED,
|
||||
#define _SC_THREAD_PROCESS_SHARED _SC_THREAD_PROCESS_SHARED
|
||||
|
||||
_SC_NPROCESSORS_CONF,
|
||||
#define _SC_NPROCESSORS_CONF _SC_NPROCESSORS_CONF
|
||||
_SC_NPROCESSORS_ONLN,
|
||||
#define _SC_NPROCESSORS_ONLN _SC_NPROCESSORS_ONLN
|
||||
_SC_PHYS_PAGES,
|
||||
#define _SC_PHYS_PAGES _SC_PHYS_PAGES
|
||||
_SC_AVPHYS_PAGES,
|
||||
#define _SC_AVPHYS_PAGES _SC_AVPHYS_PAGES
|
||||
_SC_ATEXIT_MAX,
|
||||
#define _SC_ATEXIT_MAX _SC_ATEXIT_MAX
|
||||
_SC_PASS_MAX,
|
||||
#define _SC_PASS_MAX _SC_PASS_MAX
|
||||
|
||||
_SC_XOPEN_VERSION,
|
||||
#define _SC_XOPEN_VERSION _SC_XOPEN_VERSION
|
||||
_SC_XOPEN_XCU_VERSION,
|
||||
#define _SC_XOPEN_XCU_VERSION _SC_XOPEN_XCU_VERSION
|
||||
_SC_XOPEN_UNIX,
|
||||
#define _SC_XOPEN_UNIX _SC_XOPEN_UNIX
|
||||
_SC_XOPEN_CRYPT,
|
||||
#define _SC_XOPEN_CRYPT _SC_XOPEN_CRYPT
|
||||
_SC_XOPEN_ENH_I18N,
|
||||
#define _SC_XOPEN_ENH_I18N _SC_XOPEN_ENH_I18N
|
||||
_SC_XOPEN_SHM,
|
||||
#define _SC_XOPEN_SHM _SC_XOPEN_SHM
|
||||
|
||||
_SC_2_CHAR_TERM,
|
||||
#define _SC_2_CHAR_TERM _SC_2_CHAR_TERM
|
||||
_SC_2_C_VERSION,
|
||||
#define _SC_2_C_VERSION _SC_2_C_VERSION
|
||||
_SC_2_UPE,
|
||||
#define _SC_2_UPE _SC_2_UPE
|
||||
|
||||
_SC_XOPEN_XPG2,
|
||||
#define _SC_XOPEN_XPG2 _SC_XOPEN_XPG2
|
||||
_SC_XOPEN_XPG3,
|
||||
#define _SC_XOPEN_XPG3 _SC_XOPEN_XPG3
|
||||
_SC_XOPEN_XPG4,
|
||||
#define _SC_XOPEN_XPG4 _SC_XOPEN_XPG4
|
||||
|
||||
_SC_CHAR_BIT,
|
||||
#define _SC_CHAR_BIT _SC_CHAR_BIT
|
||||
_SC_CHAR_MAX,
|
||||
#define _SC_CHAR_MAX _SC_CHAR_MAX
|
||||
_SC_CHAR_MIN,
|
||||
#define _SC_CHAR_MIN _SC_CHAR_MIN
|
||||
_SC_INT_MAX,
|
||||
#define _SC_INT_MAX _SC_INT_MAX
|
||||
_SC_INT_MIN,
|
||||
#define _SC_INT_MIN _SC_INT_MIN
|
||||
_SC_LONG_BIT,
|
||||
#define _SC_LONG_BIT _SC_LONG_BIT
|
||||
_SC_WORD_BIT,
|
||||
#define _SC_WORD_BIT _SC_WORD_BIT
|
||||
_SC_MB_LEN_MAX,
|
||||
#define _SC_MB_LEN_MAX _SC_MB_LEN_MAX
|
||||
_SC_NZERO,
|
||||
#define _SC_NZERO _SC_NZERO
|
||||
_SC_SSIZE_MAX,
|
||||
#define _SC_SSIZE_MAX _SC_SSIZE_MAX
|
||||
_SC_SCHAR_MAX,
|
||||
#define _SC_SCHAR_MAX _SC_SCHAR_MAX
|
||||
_SC_SCHAR_MIN,
|
||||
#define _SC_SCHAR_MIN _SC_SCHAR_MIN
|
||||
_SC_SHRT_MAX,
|
||||
#define _SC_SHRT_MAX _SC_SHRT_MAX
|
||||
_SC_SHRT_MIN,
|
||||
#define _SC_SHRT_MIN _SC_SHRT_MIN
|
||||
_SC_UCHAR_MAX,
|
||||
#define _SC_UCHAR_MAX _SC_UCHAR_MAX
|
||||
_SC_UINT_MAX,
|
||||
#define _SC_UINT_MAX _SC_UINT_MAX
|
||||
_SC_ULONG_MAX,
|
||||
#define _SC_ULONG_MAX _SC_ULONG_MAX
|
||||
_SC_USHRT_MAX,
|
||||
#define _SC_USHRT_MAX _SC_USHRT_MAX
|
||||
|
||||
_SC_NL_ARGMAX,
|
||||
#define _SC_NL_ARGMAX _SC_NL_ARGMAX
|
||||
_SC_NL_LANGMAX,
|
||||
#define _SC_NL_LANGMAX _SC_NL_LANGMAX
|
||||
_SC_NL_MSGMAX,
|
||||
#define _SC_NL_MSGMAX _SC_NL_MSGMAX
|
||||
_SC_NL_NMAX,
|
||||
#define _SC_NL_NMAX _SC_NL_NMAX
|
||||
_SC_NL_SETMAX,
|
||||
#define _SC_NL_SETMAX _SC_NL_SETMAX
|
||||
_SC_NL_TEXTMAX,
|
||||
#define _SC_NL_TEXTMAX _SC_NL_TEXTMAX
|
||||
|
||||
_SC_XBS5_ILP32_OFF32,
|
||||
#define _SC_XBS5_ILP32_OFF32 _SC_XBS5_ILP32_OFF32
|
||||
_SC_XBS5_ILP32_OFFBIG,
|
||||
#define _SC_XBS5_ILP32_OFFBIG _SC_XBS5_ILP32_OFFBIG
|
||||
_SC_XBS5_LP64_OFF64,
|
||||
#define _SC_XBS5_LP64_OFF64 _SC_XBS5_LP64_OFF64
|
||||
_SC_XBS5_LPBIG_OFFBIG,
|
||||
#define _SC_XBS5_LPBIG_OFFBIG _SC_XBS5_LPBIG_OFFBIG
|
||||
|
||||
_SC_XOPEN_LEGACY,
|
||||
#define _SC_XOPEN_LEGACY _SC_XOPEN_LEGACY
|
||||
_SC_XOPEN_REALTIME,
|
||||
#define _SC_XOPEN_REALTIME _SC_XOPEN_REALTIME
|
||||
_SC_XOPEN_REALTIME_THREADS,
|
||||
#define _SC_XOPEN_REALTIME_THREADS _SC_XOPEN_REALTIME_THREADS
|
||||
|
||||
_SC_ADVISORY_INFO,
|
||||
#define _SC_ADVISORY_INFO _SC_ADVISORY_INFO
|
||||
_SC_BARRIERS,
|
||||
#define _SC_BARRIERS _SC_BARRIERS
|
||||
_SC_BASE,
|
||||
#define _SC_BASE _SC_BASE
|
||||
_SC_C_LANG_SUPPORT,
|
||||
#define _SC_C_LANG_SUPPORT _SC_C_LANG_SUPPORT
|
||||
_SC_C_LANG_SUPPORT_R,
|
||||
#define _SC_C_LANG_SUPPORT_R _SC_C_LANG_SUPPORT_R
|
||||
_SC_CLOCK_SELECTION,
|
||||
#define _SC_CLOCK_SELECTION _SC_CLOCK_SELECTION
|
||||
_SC_CPUTIME,
|
||||
#define _SC_CPUTIME _SC_CPUTIME
|
||||
_SC_THREAD_CPUTIME,
|
||||
#define _SC_THREAD_CPUTIME _SC_THREAD_CPUTIME
|
||||
_SC_DEVICE_IO,
|
||||
#define _SC_DEVICE_IO _SC_DEVICE_IO
|
||||
_SC_DEVICE_SPECIFIC,
|
||||
#define _SC_DEVICE_SPECIFIC _SC_DEVICE_SPECIFIC
|
||||
_SC_DEVICE_SPECIFIC_R,
|
||||
#define _SC_DEVICE_SPECIFIC_R _SC_DEVICE_SPECIFIC_R
|
||||
_SC_FD_MGMT,
|
||||
#define _SC_FD_MGMT _SC_FD_MGMT
|
||||
_SC_FIFO,
|
||||
#define _SC_FIFO _SC_FIFO
|
||||
_SC_PIPE,
|
||||
#define _SC_PIPE _SC_PIPE
|
||||
_SC_FILE_ATTRIBUTES,
|
||||
#define _SC_FILE_ATTRIBUTES _SC_FILE_ATTRIBUTES
|
||||
_SC_FILE_LOCKING,
|
||||
#define _SC_FILE_LOCKING _SC_FILE_LOCKING
|
||||
_SC_FILE_SYSTEM,
|
||||
#define _SC_FILE_SYSTEM _SC_FILE_SYSTEM
|
||||
_SC_MONOTONIC_CLOCK,
|
||||
#define _SC_MONOTONIC_CLOCK _SC_MONOTONIC_CLOCK
|
||||
_SC_MULTI_PROCESS,
|
||||
#define _SC_MULTI_PROCESS _SC_MULTI_PROCESS
|
||||
_SC_SINGLE_PROCESS,
|
||||
#define _SC_SINGLE_PROCESS _SC_SINGLE_PROCESS
|
||||
_SC_NETWORKING,
|
||||
#define _SC_NETWORKING _SC_NETWORKING
|
||||
_SC_READER_WRITER_LOCKS,
|
||||
#define _SC_READER_WRITER_LOCKS _SC_READER_WRITER_LOCKS
|
||||
_SC_SPIN_LOCKS,
|
||||
#define _SC_SPIN_LOCKS _SC_SPIN_LOCKS
|
||||
_SC_REGEXP,
|
||||
#define _SC_REGEXP _SC_REGEXP
|
||||
_SC_REGEX_VERSION,
|
||||
#define _SC_REGEX_VERSION _SC_REGEX_VERSION
|
||||
_SC_SHELL,
|
||||
#define _SC_SHELL _SC_SHELL
|
||||
_SC_SIGNALS,
|
||||
#define _SC_SIGNALS _SC_SIGNALS
|
||||
_SC_SPAWN,
|
||||
#define _SC_SPAWN _SC_SPAWN
|
||||
_SC_SPORADIC_SERVER,
|
||||
#define _SC_SPORADIC_SERVER _SC_SPORADIC_SERVER
|
||||
_SC_THREAD_SPORADIC_SERVER,
|
||||
#define _SC_THREAD_SPORADIC_SERVER _SC_THREAD_SPORADIC_SERVER
|
||||
_SC_SYSTEM_DATABASE,
|
||||
#define _SC_SYSTEM_DATABASE _SC_SYSTEM_DATABASE
|
||||
_SC_SYSTEM_DATABASE_R,
|
||||
#define _SC_SYSTEM_DATABASE_R _SC_SYSTEM_DATABASE_R
|
||||
_SC_TIMEOUTS,
|
||||
#define _SC_TIMEOUTS _SC_TIMEOUTS
|
||||
_SC_TYPED_MEMORY_OBJECTS,
|
||||
#define _SC_TYPED_MEMORY_OBJECTS _SC_TYPED_MEMORY_OBJECTS
|
||||
_SC_USER_GROUPS,
|
||||
#define _SC_USER_GROUPS _SC_USER_GROUPS
|
||||
_SC_USER_GROUPS_R,
|
||||
#define _SC_USER_GROUPS_R _SC_USER_GROUPS_R
|
||||
_SC_2_PBS,
|
||||
#define _SC_2_PBS _SC_2_PBS
|
||||
_SC_2_PBS_ACCOUNTING,
|
||||
#define _SC_2_PBS_ACCOUNTING _SC_2_PBS_ACCOUNTING
|
||||
_SC_2_PBS_LOCATE,
|
||||
#define _SC_2_PBS_LOCATE _SC_2_PBS_LOCATE
|
||||
_SC_2_PBS_MESSAGE,
|
||||
#define _SC_2_PBS_MESSAGE _SC_2_PBS_MESSAGE
|
||||
_SC_2_PBS_TRACK,
|
||||
#define _SC_2_PBS_TRACK _SC_2_PBS_TRACK
|
||||
_SC_SYMLOOP_MAX,
|
||||
#define _SC_SYMLOOP_MAX _SC_SYMLOOP_MAX
|
||||
_SC_STREAMS,
|
||||
#define _SC_STREAMS _SC_STREAMS
|
||||
_SC_2_PBS_CHECKPOINT,
|
||||
#define _SC_2_PBS_CHECKPOINT _SC_2_PBS_CHECKPOINT
|
||||
|
||||
_SC_V6_ILP32_OFF32,
|
||||
#define _SC_V6_ILP32_OFF32 _SC_V6_ILP32_OFF32
|
||||
_SC_V6_ILP32_OFFBIG,
|
||||
#define _SC_V6_ILP32_OFFBIG _SC_V6_ILP32_OFFBIG
|
||||
_SC_V6_LP64_OFF64,
|
||||
#define _SC_V6_LP64_OFF64 _SC_V6_LP64_OFF64
|
||||
_SC_V6_LPBIG_OFFBIG,
|
||||
#define _SC_V6_LPBIG_OFFBIG _SC_V6_LPBIG_OFFBIG
|
||||
|
||||
_SC_HOST_NAME_MAX,
|
||||
#define _SC_HOST_NAME_MAX _SC_HOST_NAME_MAX
|
||||
_SC_TRACE,
|
||||
#define _SC_TRACE _SC_TRACE
|
||||
_SC_TRACE_EVENT_FILTER,
|
||||
#define _SC_TRACE_EVENT_FILTER _SC_TRACE_EVENT_FILTER
|
||||
_SC_TRACE_INHERIT,
|
||||
#define _SC_TRACE_INHERIT _SC_TRACE_INHERIT
|
||||
_SC_TRACE_LOG,
|
||||
#define _SC_TRACE_LOG _SC_TRACE_LOG
|
||||
|
||||
_SC_LEVEL1_ICACHE_SIZE,
|
||||
#define _SC_LEVEL1_ICACHE_SIZE _SC_LEVEL1_ICACHE_SIZE
|
||||
_SC_LEVEL1_ICACHE_ASSOC,
|
||||
#define _SC_LEVEL1_ICACHE_ASSOC _SC_LEVEL1_ICACHE_ASSOC
|
||||
_SC_LEVEL1_ICACHE_LINESIZE,
|
||||
#define _SC_LEVEL1_ICACHE_LINESIZE _SC_LEVEL1_ICACHE_LINESIZE
|
||||
_SC_LEVEL1_DCACHE_SIZE,
|
||||
#define _SC_LEVEL1_DCACHE_SIZE _SC_LEVEL1_DCACHE_SIZE
|
||||
_SC_LEVEL1_DCACHE_ASSOC,
|
||||
#define _SC_LEVEL1_DCACHE_ASSOC _SC_LEVEL1_DCACHE_ASSOC
|
||||
_SC_LEVEL1_DCACHE_LINESIZE,
|
||||
#define _SC_LEVEL1_DCACHE_LINESIZE _SC_LEVEL1_DCACHE_LINESIZE
|
||||
_SC_LEVEL2_CACHE_SIZE,
|
||||
#define _SC_LEVEL2_CACHE_SIZE _SC_LEVEL2_CACHE_SIZE
|
||||
_SC_LEVEL2_CACHE_ASSOC,
|
||||
#define _SC_LEVEL2_CACHE_ASSOC _SC_LEVEL2_CACHE_ASSOC
|
||||
_SC_LEVEL2_CACHE_LINESIZE,
|
||||
#define _SC_LEVEL2_CACHE_LINESIZE _SC_LEVEL2_CACHE_LINESIZE
|
||||
_SC_LEVEL3_CACHE_SIZE,
|
||||
#define _SC_LEVEL3_CACHE_SIZE _SC_LEVEL3_CACHE_SIZE
|
||||
_SC_LEVEL3_CACHE_ASSOC,
|
||||
#define _SC_LEVEL3_CACHE_ASSOC _SC_LEVEL3_CACHE_ASSOC
|
||||
_SC_LEVEL3_CACHE_LINESIZE,
|
||||
#define _SC_LEVEL3_CACHE_LINESIZE _SC_LEVEL3_CACHE_LINESIZE
|
||||
_SC_LEVEL4_CACHE_SIZE,
|
||||
#define _SC_LEVEL4_CACHE_SIZE _SC_LEVEL4_CACHE_SIZE
|
||||
_SC_LEVEL4_CACHE_ASSOC,
|
||||
#define _SC_LEVEL4_CACHE_ASSOC _SC_LEVEL4_CACHE_ASSOC
|
||||
_SC_LEVEL4_CACHE_LINESIZE
|
||||
#define _SC_LEVEL4_CACHE_LINESIZE _SC_LEVEL4_CACHE_LINESIZE
|
||||
/* Leave room here, maybe we need a few more cache levels some day. */
|
||||
};
|
||||
|
||||
/* Values for the NAME argument to `confstr'. */
|
||||
enum
|
||||
{
|
||||
_CS_PATH, /* The default search path. */
|
||||
#define _CS_PATH _CS_PATH
|
||||
|
||||
_CS_V6_WIDTH_RESTRICTED_ENVS,
|
||||
# define _CS_V6_WIDTH_RESTRICTED_ENVS _CS_V6_WIDTH_RESTRICTED_ENVS
|
||||
|
||||
_CS_GNU_LIBC_VERSION,
|
||||
#define _CS_GNU_LIBC_VERSION _CS_GNU_LIBC_VERSION
|
||||
_CS_GNU_LIBPTHREAD_VERSION,
|
||||
#define _CS_GNU_LIBPTHREAD_VERSION _CS_GNU_LIBPTHREAD_VERSION
|
||||
|
||||
_CS_LFS_CFLAGS = 1000,
|
||||
#define _CS_LFS_CFLAGS _CS_LFS_CFLAGS
|
||||
_CS_LFS_LDFLAGS,
|
||||
#define _CS_LFS_LDFLAGS _CS_LFS_LDFLAGS
|
||||
_CS_LFS_LIBS,
|
||||
#define _CS_LFS_LIBS _CS_LFS_LIBS
|
||||
_CS_LFS_LINTFLAGS,
|
||||
#define _CS_LFS_LINTFLAGS _CS_LFS_LINTFLAGS
|
||||
_CS_LFS64_CFLAGS,
|
||||
#define _CS_LFS64_CFLAGS _CS_LFS64_CFLAGS
|
||||
_CS_LFS64_LDFLAGS,
|
||||
#define _CS_LFS64_LDFLAGS _CS_LFS64_LDFLAGS
|
||||
_CS_LFS64_LIBS,
|
||||
#define _CS_LFS64_LIBS _CS_LFS64_LIBS
|
||||
_CS_LFS64_LINTFLAGS,
|
||||
#define _CS_LFS64_LINTFLAGS _CS_LFS64_LINTFLAGS
|
||||
|
||||
_CS_XBS5_ILP32_OFF32_CFLAGS = 1100,
|
||||
#define _CS_XBS5_ILP32_OFF32_CFLAGS _CS_XBS5_ILP32_OFF32_CFLAGS
|
||||
_CS_XBS5_ILP32_OFF32_LDFLAGS,
|
||||
#define _CS_XBS5_ILP32_OFF32_LDFLAGS _CS_XBS5_ILP32_OFF32_LDFLAGS
|
||||
_CS_XBS5_ILP32_OFF32_LIBS,
|
||||
#define _CS_XBS5_ILP32_OFF32_LIBS _CS_XBS5_ILP32_OFF32_LIBS
|
||||
_CS_XBS5_ILP32_OFF32_LINTFLAGS,
|
||||
#define _CS_XBS5_ILP32_OFF32_LINTFLAGS _CS_XBS5_ILP32_OFF32_LINTFLAGS
|
||||
_CS_XBS5_ILP32_OFFBIG_CFLAGS,
|
||||
#define _CS_XBS5_ILP32_OFFBIG_CFLAGS _CS_XBS5_ILP32_OFFBIG_CFLAGS
|
||||
_CS_XBS5_ILP32_OFFBIG_LDFLAGS,
|
||||
#define _CS_XBS5_ILP32_OFFBIG_LDFLAGS _CS_XBS5_ILP32_OFFBIG_LDFLAGS
|
||||
_CS_XBS5_ILP32_OFFBIG_LIBS,
|
||||
#define _CS_XBS5_ILP32_OFFBIG_LIBS _CS_XBS5_ILP32_OFFBIG_LIBS
|
||||
_CS_XBS5_ILP32_OFFBIG_LINTFLAGS,
|
||||
#define _CS_XBS5_ILP32_OFFBIG_LINTFLAGS _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
|
||||
_CS_XBS5_LP64_OFF64_CFLAGS,
|
||||
#define _CS_XBS5_LP64_OFF64_CFLAGS _CS_XBS5_LP64_OFF64_CFLAGS
|
||||
_CS_XBS5_LP64_OFF64_LDFLAGS,
|
||||
#define _CS_XBS5_LP64_OFF64_LDFLAGS _CS_XBS5_LP64_OFF64_LDFLAGS
|
||||
_CS_XBS5_LP64_OFF64_LIBS,
|
||||
#define _CS_XBS5_LP64_OFF64_LIBS _CS_XBS5_LP64_OFF64_LIBS
|
||||
_CS_XBS5_LP64_OFF64_LINTFLAGS,
|
||||
#define _CS_XBS5_LP64_OFF64_LINTFLAGS _CS_XBS5_LP64_OFF64_LINTFLAGS
|
||||
_CS_XBS5_LPBIG_OFFBIG_CFLAGS,
|
||||
#define _CS_XBS5_LPBIG_OFFBIG_CFLAGS _CS_XBS5_LPBIG_OFFBIG_CFLAGS
|
||||
_CS_XBS5_LPBIG_OFFBIG_LDFLAGS,
|
||||
#define _CS_XBS5_LPBIG_OFFBIG_LDFLAGS _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
|
||||
_CS_XBS5_LPBIG_OFFBIG_LIBS,
|
||||
#define _CS_XBS5_LPBIG_OFFBIG_LIBS _CS_XBS5_LPBIG_OFFBIG_LIBS
|
||||
_CS_XBS5_LPBIG_OFFBIG_LINTFLAGS,
|
||||
#define _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
|
||||
|
||||
_CS_POSIX_V6_ILP32_OFF32_CFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFF32_CFLAGS _CS_POSIX_V6_ILP32_OFF32_CFLAGS
|
||||
_CS_POSIX_V6_ILP32_OFF32_LDFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFF32_LDFLAGS _CS_POSIX_V6_ILP32_OFF32_LDFLAGS
|
||||
_CS_POSIX_V6_ILP32_OFF32_LIBS,
|
||||
#define _CS_POSIX_V6_ILP32_OFF32_LIBS _CS_POSIX_V6_ILP32_OFF32_LIBS
|
||||
_CS_POSIX_V6_ILP32_OFF32_LINTFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS _CS_POSIX_V6_ILP32_OFF32_LINTFLAGS
|
||||
_CS_POSIX_V6_ILP32_OFFBIG_CFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS _CS_POSIX_V6_ILP32_OFFBIG_CFLAGS
|
||||
_CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS _CS_POSIX_V6_ILP32_OFFBIG_LDFLAGS
|
||||
_CS_POSIX_V6_ILP32_OFFBIG_LIBS,
|
||||
#define _CS_POSIX_V6_ILP32_OFFBIG_LIBS _CS_POSIX_V6_ILP32_OFFBIG_LIBS
|
||||
_CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS,
|
||||
#define _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS _CS_POSIX_V6_ILP32_OFFBIG_LINTFLAGS
|
||||
_CS_POSIX_V6_LP64_OFF64_CFLAGS,
|
||||
#define _CS_POSIX_V6_LP64_OFF64_CFLAGS _CS_POSIX_V6_LP64_OFF64_CFLAGS
|
||||
_CS_POSIX_V6_LP64_OFF64_LDFLAGS,
|
||||
#define _CS_POSIX_V6_LP64_OFF64_LDFLAGS _CS_POSIX_V6_LP64_OFF64_LDFLAGS
|
||||
_CS_POSIX_V6_LP64_OFF64_LIBS,
|
||||
#define _CS_POSIX_V6_LP64_OFF64_LIBS _CS_POSIX_V6_LP64_OFF64_LIBS
|
||||
_CS_POSIX_V6_LP64_OFF64_LINTFLAGS,
|
||||
#define _CS_POSIX_V6_LP64_OFF64_LINTFLAGS _CS_POSIX_V6_LP64_OFF64_LINTFLAGS
|
||||
_CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS,
|
||||
#define _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS _CS_POSIX_V6_LPBIG_OFFBIG_CFLAGS
|
||||
_CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS,
|
||||
#define _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS _CS_POSIX_V6_LPBIG_OFFBIG_LDFLAGS
|
||||
_CS_POSIX_V6_LPBIG_OFFBIG_LIBS,
|
||||
#define _CS_POSIX_V6_LPBIG_OFFBIG_LIBS _CS_POSIX_V6_LPBIG_OFFBIG_LIBS
|
||||
_CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS
|
||||
#define _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS _CS_POSIX_V6_LPBIG_OFFBIG_LINTFLAGS
|
||||
};
|
||||
@@ -1,64 +0,0 @@
|
||||
/* System dependent definitions for run-time dynamic loading.
|
||||
Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _DLFCN_H
|
||||
# error "Never use <bits/dlfcn.h> directly; include <dlfcn.h> instead."
|
||||
#endif
|
||||
|
||||
/* The MODE argument to `dlopen' contains one of the following: */
|
||||
#define RTLD_LAZY 0x00001 /* Lazy function call binding. */
|
||||
#define RTLD_NOW 0x00002 /* Immediate function call binding. */
|
||||
#define RTLD_BINDING_MASK 0x3 /* Mask of binding time value. */
|
||||
#define RTLD_NOLOAD 0x00004 /* Do not load the object. */
|
||||
|
||||
/* If the following bit is set in the MODE argument to `dlopen',
|
||||
the symbols of the loaded object and its dependencies are made
|
||||
visible as if the object were linked directly into the program. */
|
||||
#define RTLD_GLOBAL 0x00100
|
||||
|
||||
/* Unix98 demands the following flag which is the inverse to RTLD_GLOBAL.
|
||||
The implementation does this by default and so we can define the
|
||||
value to zero. */
|
||||
#define RTLD_LOCAL 0
|
||||
|
||||
/* Do not delete object when closed. */
|
||||
#define RTLD_NODELETE 0x01000
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* To support profiling of shared objects it is a good idea to call
|
||||
the function found using `dlsym' using the following macro since
|
||||
these calls do not use the PLT. But this would mean the dynamic
|
||||
loader has no chance to find out when the function is called. The
|
||||
macro applies the necessary magic so that profiling is possible.
|
||||
Rewrite
|
||||
foo = (*fctp) (arg1, arg2);
|
||||
into
|
||||
foo = DL_CALL_FCT (fctp, (arg1, arg2));
|
||||
*/
|
||||
# define DL_CALL_FCT(fctp, args) \
|
||||
(_dl_mcount_wrapper_check ((void *) (fctp)), (*(fctp)) args)
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/* This function calls the profiling functions. */
|
||||
extern void _dl_mcount_wrapper_check (void *__selfpc) __THROW;
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
||||
@@ -1,75 +0,0 @@
|
||||
/* Copyright (C) 1999, 2001 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifndef _UNISTD_H
|
||||
# error "Never include this file directly. Use <unistd.h> instead"
|
||||
#endif
|
||||
|
||||
#include <bits/wordsize.h>
|
||||
|
||||
/* This header should define the following symbols under the described
|
||||
situations. A value `1' means that the model is always supported,
|
||||
`-1' means it is never supported. Undefined means it cannot be
|
||||
statically decided.
|
||||
|
||||
_POSIX_V6_ILP32_OFF32 32bit int, long, pointers, and off_t type
|
||||
_POSIX_V6_ILP32_OFFBIG 32bit int, long, and pointers and larger off_t type
|
||||
|
||||
_POSIX_V6_LP64_OFF32 64bit long and pointers and 32bit off_t type
|
||||
_POSIX_V6_LPBIG_OFFBIG 64bit long and pointers and large off_t type
|
||||
|
||||
The macros _XBS5_ILP32_OFF32, _XBS5_ILP32_OFFBIG, _XBS5_LP64_OFF32, and
|
||||
_XBS5_LPBIG_OFFBIG were used in previous versions of the Unix standard
|
||||
and are available only for compatibility.
|
||||
*/
|
||||
|
||||
#if __WORDSIZE == 64
|
||||
|
||||
/* We can never provide environments with 32-bit wide pointers. */
|
||||
# define _POSIX_V6_ILP32_OFF32 -1
|
||||
# define _POSIX_V6_ILP32_OFFBIG -1
|
||||
# define _XBS5_ILP32_OFF32 -1
|
||||
# define _XBS5_ILP32_OFFBIG -1
|
||||
/* We also have no use (for now) for an environment with bigger pointers
|
||||
and offsets. */
|
||||
# define _POSIX_V6_LPBIG_OFFBIG -1
|
||||
# define _XBS5_LPBIG_OFFBIG -1
|
||||
|
||||
/* By default we have 64-bit wide `long int', pointers and `off_t'. */
|
||||
# define _POSIX_V6_LP64_OFF64 1
|
||||
# define _XBS5_LP64_OFF64 1
|
||||
|
||||
#else /* __WORDSIZE == 32 */
|
||||
|
||||
/* By default we have 32-bit wide `int', `long int', pointers and `off_t'
|
||||
and all platforms support LFS. */
|
||||
# define _POSIX_V6_ILP32_OFF32 1
|
||||
# define _POSIX_V6_ILP32_OFFBIG 1
|
||||
# define _XBS5_ILP32_OFF32 1
|
||||
# define _XBS5_ILP32_OFFBIG 1
|
||||
|
||||
/* We optionally provide an environment with the above size but an 64-bit
|
||||
side `off_t'. Therefore we don't define _XBS5_ILP32_OFFBIG. */
|
||||
|
||||
/* We can never provide environments with 64-bit wide pointers. */
|
||||
# define _POSIX_V6_LP64_OFF64 -1
|
||||
# define _POSIX_V6_LPBIG_OFFBIG -1
|
||||
# define _XBS5_LP64_OFF64 -1
|
||||
# define _XBS5_LPBIG_OFFBIG -1
|
||||
|
||||
#endif /* __WORDSIZE == 32 */
|
||||
@@ -1,4 +0,0 @@
|
||||
struct link_map_machine
|
||||
{
|
||||
/* empty by default */
|
||||
};
|
||||
-91
@@ -1,91 +0,0 @@
|
||||
/* Definitions for BSD-style memory management.
|
||||
Copyright (C) 1994-1998,2000,01,02 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/* These are the bits used by 4.4 BSD and its derivatives. On systems
|
||||
(such as GNU) where these facilities are not system services but can be
|
||||
emulated in the C library, these are the definitions we emulate. */
|
||||
|
||||
#ifndef _SYS_MMAN_H
|
||||
# error "Never use <bits/mman.h> directly; include <sys/mman.h> instead."
|
||||
#endif
|
||||
|
||||
/* Protections are chosen from these bits, OR'd together. The
|
||||
implementation does not necessarily support PROT_EXEC or PROT_WRITE
|
||||
without PROT_READ. The only guarantees are that no writing will be
|
||||
allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
|
||||
|
||||
#define PROT_NONE 0x00 /* No access. */
|
||||
#define PROT_READ 0x04 /* Pages can be read. */
|
||||
#define PROT_WRITE 0x02 /* Pages can be written. */
|
||||
#define PROT_EXEC 0x01 /* Pages can be executed. */
|
||||
|
||||
/* Flags contain mapping type, sharing type and options. */
|
||||
|
||||
/* Mapping type (must choose one and only one of these). */
|
||||
#ifdef __USE_BSD
|
||||
# define MAP_FILE 0x0001 /* Mapped from a file or device. */
|
||||
# define MAP_ANON 0x0002 /* Allocated from anonymous virtual memory. */
|
||||
# define MAP_TYPE 0x000f /* Mask for type field. */
|
||||
# ifdef __USE_MISC
|
||||
# define MAP_ANONYMOUS MAP_ANON /* Linux name. */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Sharing types (must choose one and only one of these). */
|
||||
#ifdef __USE_BSD
|
||||
# define MAP_COPY 0x0020 /* Virtual copy of region at mapping time. */
|
||||
#endif
|
||||
#define MAP_SHARED 0x0010 /* Share changes. */
|
||||
#define MAP_PRIVATE 0x0000 /* Changes private; copy pages on write. */
|
||||
|
||||
/* Other flags. */
|
||||
#define MAP_FIXED 0x0100 /* Map address must be exactly as requested. */
|
||||
#ifdef __USE_BSD
|
||||
# define MAP_NOEXTEND 0x0200 /* For MAP_FILE, don't change file size. */
|
||||
# define MAP_HASSEMPHORE 0x0400 /* Region may contain semaphores. */
|
||||
# define MAP_INHERIT 0x0800 /* Region is retained after exec. */
|
||||
#endif
|
||||
|
||||
/* Advice to `madvise'. */
|
||||
#ifdef __USE_BSD
|
||||
# define MADV_NORMAL 0 /* No further special treatment. */
|
||||
# define MADV_RANDOM 1 /* Expect random page references. */
|
||||
# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
|
||||
# define MADV_WILLNEED 3 /* Will need these pages. */
|
||||
# define MADV_DONTNEED 4 /* Don't need these pages. */
|
||||
#endif
|
||||
|
||||
/* The POSIX people had to invent similar names for the same things. */
|
||||
#ifdef __USE_XOPEN2K
|
||||
# define POSIX_MADV_NORMAL 0 /* No further special treatment. */
|
||||
# define POSIX_MADV_RANDOM 1 /* Expect random page references. */
|
||||
# define POSIX_MADV_SEQUENTIAL 2 /* Expect sequential page references. */
|
||||
# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
|
||||
# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
|
||||
#endif
|
||||
|
||||
/* Flags to `msync'. */
|
||||
#define MS_ASYNC 1 /* Sync memory asynchronously. */
|
||||
#define MS_SYNC 0 /* Synchronous memory sync. */
|
||||
#define MS_INVALIDATE 2 /* Invalidate the caches. */
|
||||
|
||||
/* Flags for `mlockall' (can be OR'd together). */
|
||||
#define MCL_CURRENT 1 /* Lock all currently mapped pages. */
|
||||
#define MCL_FUTURE 2 /* Lock all additions to address
|
||||
space. */
|
||||
-199
@@ -1,199 +0,0 @@
|
||||
/* bits/types.h -- definitions of __*_t types underlying *_t types.
|
||||
Copyright (C) 2002, 2003 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
/*
|
||||
* Never include this file directly; use <sys/types.h> instead.
|
||||
*/
|
||||
|
||||
#ifndef _BITS_TYPES_H
|
||||
#define _BITS_TYPES_H 1
|
||||
|
||||
#include <features.h>
|
||||
#include <bits/wordsize.h>
|
||||
|
||||
#define __need_size_t
|
||||
#include <stddef.h>
|
||||
|
||||
/* Convenience types. */
|
||||
typedef unsigned char __u_char;
|
||||
typedef unsigned short int __u_short;
|
||||
typedef unsigned int __u_int;
|
||||
typedef unsigned long int __u_long;
|
||||
|
||||
/* Fixed-size types, underlying types depend on word size and compiler. */
|
||||
typedef signed char __int8_t;
|
||||
typedef unsigned char __uint8_t;
|
||||
typedef signed short int __int16_t;
|
||||
typedef unsigned short int __uint16_t;
|
||||
typedef signed int __int32_t;
|
||||
typedef unsigned int __uint32_t;
|
||||
#if __WORDSIZE == 64
|
||||
typedef signed long int __int64_t;
|
||||
typedef unsigned long int __uint64_t;
|
||||
#elif defined __GLIBC_HAVE_LONG_LONG
|
||||
__extension__ typedef signed long long int __int64_t;
|
||||
__extension__ typedef unsigned long long int __uint64_t;
|
||||
#endif
|
||||
|
||||
/* quad_t is also 64 bits. */
|
||||
#if __WORDSIZE == 64
|
||||
typedef long int __quad_t;
|
||||
typedef unsigned long int __u_quad_t;
|
||||
#elif defined __GLIBC_HAVE_LONG_LONG
|
||||
__extension__ typedef long long int __quad_t;
|
||||
__extension__ typedef unsigned long long int __u_quad_t;
|
||||
#else
|
||||
typedef struct
|
||||
{
|
||||
long __val[2];
|
||||
} __quad_t;
|
||||
typedef struct
|
||||
{
|
||||
__u_long __val[2];
|
||||
} __u_quad_t;
|
||||
#endif
|
||||
|
||||
|
||||
/* The machine-dependent file <bits/typesizes.h> defines __*_T_TYPE
|
||||
macros for each of the OS types we define below. The definitions
|
||||
of those macros must use the following macros for underlying types.
|
||||
We define __S<SIZE>_TYPE and __U<SIZE>_TYPE for the signed and unsigned
|
||||
variants of each of the following integer types on this machine.
|
||||
|
||||
16 -- "natural" 16-bit type (always short)
|
||||
32 -- "natural" 32-bit type (always int)
|
||||
64 -- "natural" 64-bit type (long or long long)
|
||||
LONG32 -- 32-bit type, traditionally long
|
||||
QUAD -- 64-bit type, always long long
|
||||
WORD -- natural type of __WORDSIZE bits (int or long)
|
||||
LONGWORD -- type of __WORDSIZE bits, traditionally long
|
||||
|
||||
We distinguish WORD/LONGWORD, 32/LONG32, and 64/QUAD so that the
|
||||
conventional uses of `long' or `long long' type modifiers match the
|
||||
types we define, even when a less-adorned type would be the same size.
|
||||
This matters for (somewhat) portably writing printf/scanf formats for
|
||||
these types, where using the appropriate l or ll format modifiers can
|
||||
make the typedefs and the formats match up across all GNU platforms. If
|
||||
we used `long' when it's 64 bits where `long long' is expected, then the
|
||||
compiler would warn about the formats not matching the argument types,
|
||||
and the programmer changing them to shut up the compiler would break the
|
||||
program's portability.
|
||||
|
||||
Here we assume what is presently the case in all the GCC configurations
|
||||
we support: long long is always 64 bits, long is always word/address size,
|
||||
and int is always 32 bits. */
|
||||
|
||||
#define __S16_TYPE short int
|
||||
#define __U16_TYPE unsigned short int
|
||||
#define __S32_TYPE int
|
||||
#define __U32_TYPE unsigned int
|
||||
#define __SLONGWORD_TYPE long int
|
||||
#define __ULONGWORD_TYPE unsigned long int
|
||||
#if __WORDSIZE == 32
|
||||
# define __SQUAD_TYPE long long int
|
||||
# define __UQUAD_TYPE unsigned long long int
|
||||
# define __SWORD_TYPE int
|
||||
# define __UWORD_TYPE unsigned int
|
||||
# define __SLONG32_TYPE long int
|
||||
# define __ULONG32_TYPE unsigned long int
|
||||
# define __S64_TYPE __quad_t
|
||||
# define __U64_TYPE __u_quad_t
|
||||
#elif __WORDSIZE == 64
|
||||
# define __SQUAD_TYPE long int
|
||||
# define __UQUAD_TYPE unsigned long int
|
||||
# define __SWORD_TYPE long int
|
||||
# define __UWORD_TYPE unsigned long int
|
||||
# define __SLONG32_TYPE int
|
||||
# define __ULONG32_TYPE unsigned int
|
||||
# define __S64_TYPE long int
|
||||
# define __U64_TYPE unsigned long int
|
||||
#else
|
||||
# error
|
||||
#endif
|
||||
#include <bits/typesizes.h> /* Defines __*_T_TYPE macros. */
|
||||
|
||||
/* We want __extension__ before typedef's that use nonstandard base types
|
||||
such as `long long' in C89 mode. */
|
||||
#define __STD_TYPE __extension__ typedef
|
||||
|
||||
|
||||
__STD_TYPE __DEV_T_TYPE __dev_t; /* Type of device numbers. */
|
||||
__STD_TYPE __UID_T_TYPE __uid_t; /* Type of user identifications. */
|
||||
__STD_TYPE __GID_T_TYPE __gid_t; /* Type of group identifications. */
|
||||
__STD_TYPE __INO_T_TYPE __ino_t; /* Type of file serial numbers. */
|
||||
__STD_TYPE __INO64_T_TYPE __ino64_t; /* Type of file serial numbers (LFS).*/
|
||||
__STD_TYPE __MODE_T_TYPE __mode_t; /* Type of file attribute bitmasks. */
|
||||
__STD_TYPE __NLINK_T_TYPE __nlink_t; /* Type of file link counts. */
|
||||
__STD_TYPE __OFF_T_TYPE __off_t; /* Type of file sizes and offsets. */
|
||||
__STD_TYPE __OFF64_T_TYPE __off64_t; /* Type of file sizes and offsets (LFS). */
|
||||
__STD_TYPE __PID_T_TYPE __pid_t; /* Type of process identifications. */
|
||||
__STD_TYPE __FSID_T_TYPE __fsid_t; /* Type of file system IDs. */
|
||||
__STD_TYPE __CLOCK_T_TYPE __clock_t; /* Type of CPU usage counts. */
|
||||
__STD_TYPE __RLIM_T_TYPE __rlim_t; /* Type for resource measurement. */
|
||||
__STD_TYPE __RLIM64_T_TYPE __rlim64_t; /* Type for resource measurement (LFS). */
|
||||
__STD_TYPE __ID_T_TYPE __id_t; /* General type for IDs. */
|
||||
__STD_TYPE __TIME_T_TYPE __time_t; /* Seconds since the Epoch. */
|
||||
__STD_TYPE __USECONDS_T_TYPE __useconds_t; /* Count of microseconds. */
|
||||
__STD_TYPE __SUSECONDS_T_TYPE __suseconds_t; /* Signed count of microseconds. */
|
||||
|
||||
__STD_TYPE __DADDR_T_TYPE __daddr_t; /* The type of a disk address. */
|
||||
__STD_TYPE __SWBLK_T_TYPE __swblk_t; /* Type of a swap block maybe? */
|
||||
__STD_TYPE __KEY_T_TYPE __key_t; /* Type of an IPC key. */
|
||||
|
||||
/* Clock ID used in clock and timer functions. */
|
||||
__STD_TYPE __CLOCKID_T_TYPE __clockid_t;
|
||||
|
||||
/* Timer ID returned by `timer_create'. */
|
||||
__STD_TYPE __TIMER_T_TYPE __timer_t;
|
||||
|
||||
/* Type to represent block size. */
|
||||
__STD_TYPE __BLKSIZE_T_TYPE __blksize_t;
|
||||
|
||||
/* Types from the Large File Support interface. */
|
||||
|
||||
/* Type to count number of disk blocks. */
|
||||
__STD_TYPE __BLKCNT_T_TYPE __blkcnt_t;
|
||||
__STD_TYPE __BLKCNT64_T_TYPE __blkcnt64_t;
|
||||
|
||||
/* Type to count file system blocks. */
|
||||
__STD_TYPE __FSBLKCNT_T_TYPE __fsblkcnt_t;
|
||||
__STD_TYPE __FSBLKCNT64_T_TYPE __fsblkcnt64_t;
|
||||
|
||||
/* Type to count file system nodes. */
|
||||
__STD_TYPE __FSFILCNT_T_TYPE __fsfilcnt_t;
|
||||
__STD_TYPE __FSFILCNT64_T_TYPE __fsfilcnt64_t;
|
||||
|
||||
__STD_TYPE __SSIZE_T_TYPE __ssize_t; /* Type of a byte count, or error. */
|
||||
|
||||
/* These few don't really vary by system, they always correspond
|
||||
to one of the other defined types. */
|
||||
typedef __off64_t __loff_t; /* Type of file sizes and offsets (LFS). */
|
||||
typedef __quad_t *__qaddr_t;
|
||||
typedef char *__caddr_t;
|
||||
|
||||
/* Duplicates info from stdint.h but this is used in unistd.h. */
|
||||
__STD_TYPE __SWORD_TYPE __intptr_t;
|
||||
|
||||
/* Duplicate info from sys/socket.h. */
|
||||
__STD_TYPE __U32_TYPE __socklen_t;
|
||||
|
||||
|
||||
#undef __STD_TYPE
|
||||
|
||||
#endif /* bits/types.h */
|
||||
@@ -1,104 +0,0 @@
|
||||
/* Definitions of status bits for `wait' et al.
|
||||
Copyright (C) 1992, 1994, 1996, 1997, 2000 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#if !defined _SYS_WAIT_H && !defined _STDLIB_H
|
||||
# error "Never include <bits/waitstatus.h> directly; use <sys/wait.h> instead."
|
||||
#endif
|
||||
|
||||
|
||||
/* Everything extant so far uses these same bits. */
|
||||
|
||||
|
||||
/* If WIFEXITED(STATUS), the low-order 8 bits of the status. */
|
||||
#define __WEXITSTATUS(status) (((status) & 0xff00) >> 8)
|
||||
|
||||
/* If WIFSIGNALED(STATUS), the terminating signal. */
|
||||
#define __WTERMSIG(status) ((status) & 0x7f)
|
||||
|
||||
/* If WIFSTOPPED(STATUS), the signal that stopped the child. */
|
||||
#define __WSTOPSIG(status) __WEXITSTATUS(status)
|
||||
|
||||
/* Nonzero if STATUS indicates normal termination. */
|
||||
#define __WIFEXITED(status) (__WTERMSIG(status) == 0)
|
||||
|
||||
/* Nonzero if STATUS indicates termination by a signal. */
|
||||
#ifdef __GNUC__
|
||||
# define __WIFSIGNALED(status) \
|
||||
(__extension__ ({ int __status = (status); \
|
||||
!__WIFSTOPPED(__status) && !__WIFEXITED(__status); }))
|
||||
#else /* Not GCC. */
|
||||
# define __WIFSIGNALED(status) (!__WIFSTOPPED(status) && !__WIFEXITED(status))
|
||||
#endif /* GCC. */
|
||||
|
||||
/* Nonzero if STATUS indicates the child is stopped. */
|
||||
#define __WIFSTOPPED(status) (((status) & 0xff) == 0x7f)
|
||||
|
||||
/* Nonzero if STATUS indicates the child dumped core. */
|
||||
#define __WCOREDUMP(status) ((status) & __WCOREFLAG)
|
||||
|
||||
/* Macros for constructing status values. */
|
||||
#define __W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
|
||||
#define __W_STOPCODE(sig) ((sig) << 8 | 0x7f)
|
||||
#define __WCOREFLAG 0x80
|
||||
|
||||
|
||||
#ifdef __USE_BSD
|
||||
|
||||
# include <endian.h>
|
||||
|
||||
union wait
|
||||
{
|
||||
int w_status;
|
||||
struct
|
||||
{
|
||||
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned int __w_termsig:7; /* Terminating signal. */
|
||||
unsigned int __w_coredump:1; /* Set if dumped core. */
|
||||
unsigned int __w_retcode:8; /* Return code if exited normally. */
|
||||
unsigned int:16;
|
||||
# endif /* Little endian. */
|
||||
# if __BYTE_ORDER == __BIG_ENDIAN
|
||||
unsigned int:16;
|
||||
unsigned int __w_retcode:8;
|
||||
unsigned int __w_coredump:1;
|
||||
unsigned int __w_termsig:7;
|
||||
# endif /* Big endian. */
|
||||
} __wait_terminated;
|
||||
struct
|
||||
{
|
||||
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned int __w_stopval:8; /* W_STOPPED if stopped. */
|
||||
unsigned int __w_stopsig:8; /* Stopping signal. */
|
||||
unsigned int:16;
|
||||
# endif /* Little endian. */
|
||||
# if __BYTE_ORDER == __BIG_ENDIAN
|
||||
unsigned int:16;
|
||||
unsigned int __w_stopsig:8; /* Stopping signal. */
|
||||
unsigned int __w_stopval:8; /* W_STOPPED if stopped. */
|
||||
# endif /* Big endian. */
|
||||
} __wait_stopped;
|
||||
};
|
||||
|
||||
# define w_termsig __wait_terminated.__w_termsig
|
||||
# define w_coredump __wait_terminated.__w_coredump
|
||||
# define w_retcode __wait_terminated.__w_retcode
|
||||
# define w_stopsig __wait_stopped.__w_stopsig
|
||||
# define w_stopval __wait_stopped.__w_stopval
|
||||
|
||||
#endif /* Use BSD. */
|
||||
@@ -0,0 +1 @@
|
||||
The C stubs add-on version 2.1.2.
|
||||
@@ -0,0 +1,482 @@
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the library GPL. It is
|
||||
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Library General Public License, applies to some
|
||||
specially designated Free Software Foundation software, and to any
|
||||
other libraries whose authors decide to use it. You can use it for
|
||||
your libraries, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if
|
||||
you distribute copies of the library, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link a program with the library, you must provide
|
||||
complete object files to the recipients so that they can relink them
|
||||
with the library, after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
Our method of protecting your rights has two steps: (1) copyright
|
||||
the library, and (2) offer you this license which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
Also, for each distributor's protection, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
library. If the library is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original
|
||||
version, so that any problems introduced by others will not reflect on
|
||||
the original authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that companies distributing free
|
||||
software will individually obtain patent licenses, thus in effect
|
||||
transforming the program into proprietary software. To prevent this,
|
||||
we have made it clear that any patent must be licensed for everyone's
|
||||
free use or not licensed at all.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the ordinary
|
||||
GNU General Public License, which was designed for utility programs. This
|
||||
license, the GNU Library General Public License, applies to certain
|
||||
designated libraries. This license is quite different from the ordinary
|
||||
one; be sure to read it in full, and don't assume that anything in it is
|
||||
the same as in the ordinary license.
|
||||
|
||||
The reason we have a separate public license for some libraries is that
|
||||
they blur the distinction we usually make between modifying or adding to a
|
||||
program and simply using it. Linking a program with a library, without
|
||||
changing the library, is in some sense simply using the library, and is
|
||||
analogous to running a utility program or application program. However, in
|
||||
a textual and legal sense, the linked executable is a combined work, a
|
||||
derivative of the original library, and the ordinary General Public License
|
||||
treats it as such.
|
||||
|
||||
Because of this blurred distinction, using the ordinary General
|
||||
Public License for libraries did not effectively promote software
|
||||
sharing, because most developers did not use the libraries. We
|
||||
concluded that weaker conditions might promote sharing better.
|
||||
|
||||
However, unrestricted linking of non-free programs would deprive the
|
||||
users of those programs of all benefit from the free status of the
|
||||
libraries themselves. This Library General Public License is intended to
|
||||
permit developers of non-free programs to use free libraries, while
|
||||
preserving your freedom as a user of such programs to change the free
|
||||
libraries that are incorporated in them. (We have not seen how to achieve
|
||||
this as regards changes in header files, but we have achieved it as regards
|
||||
changes in the actual functions of the Library.) The hope is that this
|
||||
will lead to faster development of free libraries.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, while the latter only
|
||||
works together with the library.
|
||||
|
||||
Note that it is possible for a library to be covered by the ordinary
|
||||
General Public License rather than by this special one.
|
||||
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library which
|
||||
contains a notice placed by the copyright holder or other authorized
|
||||
party saying it may be distributed under the terms of this Library
|
||||
General Public License (also called "this License"). Each licensee is
|
||||
addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also compile or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
c) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
d) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the source code distributed need not include anything that is normally
|
||||
distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Library General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
@@ -0,0 +1,42 @@
|
||||
2001-08-07 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* gconv_stubs.c (__gconv_lookup_alias): Remove.
|
||||
(__gconv_NOOP, __gconv_compare_alias, __gconv_release_cache,
|
||||
__gconv_release_step): New.
|
||||
|
||||
2001-06-07 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* gconv_stubs.c (__gconv_lookup_alias): New.
|
||||
|
||||
2000-02-27 Cristian Gafton <gafton@redhat.com>
|
||||
|
||||
* gconv_stubs.c: Return __gconv_OK for:
|
||||
__gconv_transform_ascii_internal
|
||||
__gconv_transform_ucs2little_internal
|
||||
__gconv_transform_utf16_internal
|
||||
__gconv_transform_utf8_internal
|
||||
__gconv_transform_ucs2_internal
|
||||
|
||||
2000-02-25 Cristian Gafton <gafton@redhat.com>
|
||||
|
||||
* gconv_stubs.c: add __c_stubs_is_compiled_in so we can detect when
|
||||
the library is linked in.
|
||||
|
||||
Wed Dec 8 13:47:25 1999 Ivan Brunello <ivan.brunello@tiscalinet.it>
|
||||
|
||||
* Makefile (extra-objs): Changed stubs.o to gconv_stubs.o.
|
||||
|
||||
Sun Dec 5 11:32:17 1999 H.J. Lu <hjl@gnu.org>
|
||||
|
||||
* gconv_stubs.c: Renamed from stubs.c.
|
||||
Support glibc 2.1.x.
|
||||
|
||||
Mon Aug 23 16:42:05 1999 H.J. Lu <hjl@gnu.org>
|
||||
|
||||
* Banner: New.
|
||||
* COPYING.LIB: Likewise.
|
||||
* Makefile: Likewise.
|
||||
* README: Likewise.
|
||||
* configure: Likewise.
|
||||
* stubs.c: Likewise.
|
||||
* test-stdio.c: Likewise.
|
||||
@@ -0,0 +1,46 @@
|
||||
# Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
# This file is part of the GNU C Library.
|
||||
|
||||
# The GNU C Library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Library General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of the
|
||||
# License, or (at your option) any later version.
|
||||
|
||||
# The GNU C Library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Library General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
#
|
||||
# Sub-makefile for the C stub add-on library.
|
||||
#
|
||||
subdir := c_stubs
|
||||
|
||||
tests-static := test-stdio
|
||||
tests := $(tests-static)
|
||||
|
||||
libc_stubs-objs := gconv_stubs.o
|
||||
|
||||
install-lib := libc_stubs.a
|
||||
non-lib.a := libc_stubs.a
|
||||
|
||||
extra-objs := gconv_stubs.o libc_stubs.a
|
||||
|
||||
include ../Makeconfig
|
||||
|
||||
CPPFLAGS += -I../iconv
|
||||
|
||||
include ../Rules
|
||||
|
||||
$(objpfx)libc_stubs.a: $(addprefix $(objpfx), $(libc_stubs-objs))
|
||||
-rm -f $@
|
||||
$(CC) -nostdlib -nostartfiles -r -o $@ $^
|
||||
|
||||
lib: $(objpfx)libc_stubs.a
|
||||
|
||||
$(objpfx)test-stdio: $(objpfx)libc_stubs.a
|
||||
@@ -0,0 +1,8 @@
|
||||
This is a stub add-on library for the GNU C library version 2.1.2 and
|
||||
above. It is used to create the smaller static binaries by stubbing
|
||||
out the gconv related functions. The resulting binaries may not have
|
||||
all the functionalities.
|
||||
|
||||
H.J. Lu
|
||||
hjl@gnu.org
|
||||
12/05/1999
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
# This is only to keep the GNU C library configure mechanism happy.
|
||||
# This is a shell script fragment sourced by the main configure script.
|
||||
# We have nothing we need to add here.
|
||||
@@ -0,0 +1,126 @@
|
||||
/* Provide gconv stub functions for the minimum static binaries.
|
||||
Copyright (C) 1999, 2001, 2003, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <features.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#if __GNUC_PREREQ(3, 3)
|
||||
# include <gconv_int.h>
|
||||
#else
|
||||
# include <gconv.h>
|
||||
#endif
|
||||
|
||||
__libc_lock_define_initialized (, __gconv_lock)
|
||||
|
||||
/* hack for self identification */
|
||||
int __c_stubs_is_compiled_in;
|
||||
|
||||
/* Don't drag in the dynamic linker. */
|
||||
void *__libc_stack_end;
|
||||
|
||||
int attribute_hidden
|
||||
__gconv_OK (void)
|
||||
{
|
||||
#if __GLIBC__ > 2 || __GLIBC_MINOR__ > 1
|
||||
return __GCONV_OK;
|
||||
#else
|
||||
return GCONV_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
int attribute_hidden
|
||||
__gconv_NOCONV (void)
|
||||
{
|
||||
#if __GLIBC__ > 2 || __GLIBC_MINOR__ > 1
|
||||
return __GCONV_NOCONV;
|
||||
#else
|
||||
return GCONV_NOCONV;
|
||||
#endif
|
||||
}
|
||||
|
||||
void attribute_hidden
|
||||
__gconv_NOOP (void)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
internal_function
|
||||
__gconv_compare_alias (const char *name1, const char *name2)
|
||||
{
|
||||
return strcmp (name1, name2);
|
||||
}
|
||||
|
||||
wint_t
|
||||
__gconv_btwoc_ascii (struct __gconv_step *step, unsigned char c)
|
||||
{
|
||||
if (c < 0x80)
|
||||
return c;
|
||||
else
|
||||
return WEOF;
|
||||
}
|
||||
|
||||
|
||||
#if __GNUC_PREREQ(3, 3)
|
||||
# undef strong_alias
|
||||
# define strong_alias(impl, name) \
|
||||
__typeof (name) name __attribute__ ((alias (#impl)))
|
||||
#endif
|
||||
|
||||
strong_alias (__gconv_OK,
|
||||
__gconv_close_transform);
|
||||
strong_alias (__gconv_OK,
|
||||
__gconv_close);
|
||||
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv);
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_find_transform);
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_open);
|
||||
|
||||
/* These transformations should not fail in normal conditions */
|
||||
strong_alias (__gconv_OK,
|
||||
__gconv_transform_ascii_internal);
|
||||
strong_alias (__gconv_OK,
|
||||
__gconv_transform_utf16_internal);
|
||||
strong_alias (__gconv_OK,
|
||||
__gconv_transform_utf8_internal);
|
||||
strong_alias (__gconv_OK,
|
||||
__gconv_transform_ucs2_internal);
|
||||
|
||||
/* We can assume no conversion for these ones */
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_transform_internal_ascii);
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_transform_internal_ucs2);
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_transform_internal_ucs4);
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_transform_internal_utf16);
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_transform_internal_utf8);
|
||||
|
||||
strong_alias (__gconv_NOCONV,
|
||||
__gconv_transliterate);
|
||||
|
||||
strong_alias (__gconv_NOOP,
|
||||
__gconv_release_cache);
|
||||
strong_alias (__gconv_NOOP,
|
||||
__gconv_release_step);
|
||||
@@ -0,0 +1,8 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
printf ("Hello world\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -6842,15 +6842,10 @@ rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
echo "${ECHO_T}$have_selinux" >&6
|
||||
fi
|
||||
|
||||
if test x$with_selinux = xauto ; then
|
||||
if test x$with_selinux = xyes ; then
|
||||
if test x$have_selinux = xno ; then
|
||||
{ echo "$as_me:$LINENO: WARNING: Sufficiently new SELinux library not found" >&5
|
||||
echo "$as_me: WARNING: Sufficiently new SELinux library not found" >&2;}
|
||||
fi
|
||||
else
|
||||
if test x$have_selinux = xno ; then
|
||||
{ { echo "$as_me:$LINENO: error: SELinux explicitly required, and SELinux library not found" >&5
|
||||
echo "$as_me: error: SELinux explicitly required, and SELinux library not found" >&2;}
|
||||
{ { echo "$as_me:$LINENO: error: SELinux explicitly required, but sufficiently recent SELinux library not found" >&5
|
||||
echo "$as_me: error: SELinux explicitly required, but sufficiently recent SELinux library not found" >&2;}
|
||||
{ (exit 1); exit 1; }; }
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -44,6 +44,24 @@ extern void (*__init_array_start []) (void) attribute_hidden;
|
||||
extern void (*__init_array_end []) (void) attribute_hidden;
|
||||
extern void (*__fini_array_start []) (void) attribute_hidden;
|
||||
extern void (*__fini_array_end []) (void) attribute_hidden;
|
||||
|
||||
# if defined HAVE_VISIBILITY_ATTRIBUTE \
|
||||
&& (defined SHARED || defined LIBC_NONSHARED)
|
||||
# define hidden_undef_2(x) #x
|
||||
# define hidden_undef_1(x) hidden_undef_2 (x)
|
||||
# define hidden_undef(x) \
|
||||
__asm (hidden_undef_1 (ASM_GLOBAL_DIRECTIVE) " " #x); \
|
||||
__asm (".hidden " #x);
|
||||
# else
|
||||
# define hidden_undef(x)
|
||||
# endif
|
||||
|
||||
hidden_undef (__preinit_array_start)
|
||||
hidden_undef (__preinit_array_end)
|
||||
hidden_undef (__init_array_start)
|
||||
hidden_undef (__init_array_end)
|
||||
hidden_undef (__fini_array_start)
|
||||
hidden_undef (__fini_array_end)
|
||||
#endif
|
||||
|
||||
/* These function symbols are provided for the .init/.fini section entry
|
||||
|
||||
+11
-3
@@ -82,7 +82,8 @@ distribute := rtld-Rules \
|
||||
tst-array1.exp tst-array2.exp tst-array4.exp \
|
||||
tst-array2dep.c tst-piemod1.c \
|
||||
tst-execstack-mod.c tst-dlmodcount.c \
|
||||
check-textrel.c dl-sysdep.h test-dlopenrpathmod.c
|
||||
check-textrel.c dl-sysdep.h test-dlopenrpathmod.c \
|
||||
tst-deep1mod1.c tst-deep1mod2.c tst-deep1mod3.c
|
||||
|
||||
CFLAGS-dl-runtime.c = -fexceptions -fasynchronous-unwind-tables
|
||||
CFLAGS-dl-lookup.c = -fexceptions -fasynchronous-unwind-tables
|
||||
@@ -152,7 +153,8 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
|
||||
restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \
|
||||
circleload1 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 \
|
||||
tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-align \
|
||||
$(tests-execstack-$(have-z-execstack)) tst-dlmodcount tst-dlopenrpath
|
||||
$(tests-execstack-$(have-z-execstack)) tst-dlmodcount \
|
||||
tst-dlopenrpath tst-deep1
|
||||
# reldep9
|
||||
test-srcs = tst-pathopt
|
||||
tests-vis-yes = vismain
|
||||
@@ -185,7 +187,7 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
|
||||
reldep8mod1 reldep8mod2 reldep8mod3 \
|
||||
reldep9mod1 reldep9mod2 reldep9mod3 \
|
||||
tst-alignmod $(modules-execstack-$(have-z-execstack)) \
|
||||
tst-dlopenrpathmod
|
||||
tst-dlopenrpathmod tst-deep1mod1 tst-deep1mod2 tst-deep1mod3
|
||||
ifeq (yes,$(have-initfini-array))
|
||||
modules-names += tst-array2dep
|
||||
endif
|
||||
@@ -754,3 +756,9 @@ $(objpfx)tst-dlopenrpath: $(objpfx)tst-dlopenrpathmod.so $(libdl)
|
||||
CFLAGS-tst-dlopenrpath.c += -DPFX=\"$(objpfx)\"
|
||||
LDFLAGS-tst-dlopenrpathmod.so += -Wl,-rpath,\$$ORIGIN/test-subdir
|
||||
$(objpfx)tst-dlopenrpath.out: $(objpfx)firstobj.so
|
||||
|
||||
$(objpfx)tst-deep1mod2.so: $(objpfx)tst-deep1mod3.so
|
||||
$(objpfx)tst-deep1: $(libdl) $(objpfx)tst-deep1mod1.so
|
||||
$(objpfx)tst-deep1.out: $(objpfx)tst-deep1mod2.so
|
||||
LDFLAGS-tst-deep1 += -rdynamic
|
||||
tst-deep1mod3.so-no-z-defs = yes
|
||||
|
||||
+1
-1
@@ -509,7 +509,7 @@ _dl_map_object_deps (struct link_map *map,
|
||||
runp->map->l_reserved = 0;
|
||||
}
|
||||
|
||||
if (__builtin_expect(GLRO(dl_debug_mask) & DL_DEBUG_PRELINK, 0) != 0
|
||||
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK, 0) != 0
|
||||
&& map == GL(dl_loaded))
|
||||
{
|
||||
/* If we are to compute conflicts, we have to build local scope
|
||||
|
||||
+6
-8
@@ -881,7 +881,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
|
||||
#endif
|
||||
|
||||
/* Enter the new object in the list of loaded objects. */
|
||||
l = _dl_new_object (realname, name, l_type, loader);
|
||||
l = _dl_new_object (realname, name, l_type, loader, mode);
|
||||
if (__builtin_expect (! l, 0))
|
||||
{
|
||||
errstring = N_("cannot create shared object descriptor");
|
||||
@@ -1355,15 +1355,12 @@ cannot enable executable stack as shared object requires");
|
||||
|
||||
/* If this object has DT_SYMBOLIC set modify now its scope. We don't
|
||||
have to do this for the main map. */
|
||||
if (__builtin_expect (l->l_info[DT_SYMBOLIC] != NULL, 0)
|
||||
if ((mode & RTLD_DEEPBIND) == 0
|
||||
&& __builtin_expect (l->l_info[DT_SYMBOLIC] != NULL, 0)
|
||||
&& &l->l_searchlist != l->l_scope[0])
|
||||
{
|
||||
/* Create an appropriate searchlist. It contains only this map.
|
||||
|
||||
XXX This is the definition of DT_SYMBOLIC in SysVr4. The old
|
||||
GNU ld.so implementation had a different interpretation which
|
||||
is more reasonable. We are prepared to add this possibility
|
||||
back as part of a GNU extension of the ELF format. */
|
||||
This is the definition of DT_SYMBOLIC in SysVr4. */
|
||||
l->l_symbolic_searchlist.r_list =
|
||||
(struct link_map **) malloc (sizeof (struct link_map *));
|
||||
|
||||
@@ -1968,7 +1965,8 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded,
|
||||
|
||||
/* Enter the new object in the list of loaded objects. */
|
||||
if ((name_copy = local_strdup (name)) == NULL
|
||||
|| (l = _dl_new_object (name_copy, name, type, loader)) == NULL)
|
||||
|| (l = _dl_new_object (name_copy, name, type, loader,
|
||||
mode)) == NULL)
|
||||
_dl_signal_error (ENOMEM, name, NULL,
|
||||
N_("cannot create shared object descriptor"));
|
||||
/* Signal that this is a faked entry. */
|
||||
|
||||
+10
-2
@@ -32,7 +32,7 @@
|
||||
struct link_map *
|
||||
internal_function
|
||||
_dl_new_object (char *realname, const char *libname, int type,
|
||||
struct link_map *loader)
|
||||
struct link_map *loader, int mode)
|
||||
{
|
||||
struct link_map *l;
|
||||
int idx;
|
||||
@@ -95,7 +95,15 @@ _dl_new_object (char *realname, const char *libname, int type,
|
||||
|
||||
/* Insert the scope if it isn't the global scope we already added. */
|
||||
if (idx == 0 || &loader->l_searchlist != new->l_scope[0])
|
||||
new->l_scope[idx] = &loader->l_searchlist;
|
||||
{
|
||||
if ((mode & RTLD_DEEPBIND) != 0 && idx != 0)
|
||||
{
|
||||
new->l_scope[1] = new->l_scope[0];
|
||||
idx = 0;
|
||||
}
|
||||
|
||||
new->l_scope[idx] = &loader->l_searchlist;
|
||||
}
|
||||
|
||||
new->l_local_scope[0] = &new->l_searchlist;
|
||||
|
||||
|
||||
+2
-1
@@ -272,7 +272,8 @@ dl_open_worker (void *a)
|
||||
}
|
||||
|
||||
/* Load that object's dependencies. */
|
||||
GLRO(dl_map_object_deps) (new, NULL, 0, 0, mode & __RTLD_DLOPEN);
|
||||
GLRO(dl_map_object_deps) (new, NULL, 0, 0,
|
||||
mode & (__RTLD_DLOPEN | RTLD_DEEPBIND));
|
||||
|
||||
/* So far, so good. Now check the versions. */
|
||||
for (i = 0; i < new->l_searchlist.r_nlist; ++i)
|
||||
|
||||
+15
-10
@@ -257,22 +257,22 @@ _dl_non_dynamic_init (void)
|
||||
|
||||
if (__libc_enable_secure)
|
||||
{
|
||||
static const char *unsecure_envvars[] =
|
||||
{
|
||||
UNSECURE_ENVVARS,
|
||||
static const char unsecure_envvars[] =
|
||||
UNSECURE_ENVVARS
|
||||
#ifdef EXTRA_UNSECURE_ENVVARS
|
||||
EXTRA_UNSECURE_ENVVARS
|
||||
#endif
|
||||
};
|
||||
size_t cnt;
|
||||
;
|
||||
const char *cp = unsecure_envvars;
|
||||
|
||||
for (cnt = 0;
|
||||
cnt < sizeof (unsecure_envvars) / sizeof (unsecure_envvars[0]);
|
||||
++cnt)
|
||||
unsetenv (unsecure_envvars[cnt]);
|
||||
while (cp < unsecure_envvars + sizeof (unsecure_envvars))
|
||||
{
|
||||
__unsetenv (cp);
|
||||
cp = (const char *) __rawmemchr (cp, '\0') + 1;
|
||||
}
|
||||
|
||||
if (__access ("/etc/suid-debug", F_OK) != 0)
|
||||
unsetenv ("MALLOC_CHECK_");
|
||||
__unsetenv ("MALLOC_CHECK_");
|
||||
}
|
||||
|
||||
#ifdef DL_PLATFORM_INIT
|
||||
@@ -287,6 +287,11 @@ _dl_non_dynamic_init (void)
|
||||
if (_dl_platform != NULL)
|
||||
_dl_platformlen = strlen (_dl_platform);
|
||||
|
||||
#if defined (__i386__) && !defined (USE_TLS)
|
||||
/* Load libs not using TLS. */
|
||||
_dl_osversion = 0x20205;
|
||||
#endif
|
||||
|
||||
/* Scan for a program header telling us the stack is nonexecutable. */
|
||||
if (_dl_phdr != NULL)
|
||||
for (uint_fast16_t i = 0; i < _dl_phnum; ++i)
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/* Do relocations for ELF dynamic linking.
|
||||
Copyright (C) 1995-2002, 2003 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995-2003, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@@ -49,7 +49,7 @@
|
||||
relocations; they should be set up to call _dl_runtime_resolve, rather
|
||||
than fully resolved now. */
|
||||
|
||||
static inline void __attribute__ ((always_inline))
|
||||
auto inline void __attribute__ ((always_inline))
|
||||
elf_dynamic_do_rel (struct link_map *map,
|
||||
ElfW(Addr) reladdr, ElfW(Addr) relsize,
|
||||
int lazy)
|
||||
|
||||
+6
-2
@@ -64,8 +64,12 @@ elf_machine_lazy_rel (struct link_map *map,
|
||||
|
||||
|
||||
/* Read the dynamic section at DYN and fill in INFO with indices DT_*. */
|
||||
|
||||
static inline void __attribute__ ((unused, always_inline))
|
||||
#ifndef RESOLVE
|
||||
static
|
||||
#else
|
||||
auto
|
||||
#endif
|
||||
inline void __attribute__ ((unused, always_inline))
|
||||
elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
|
||||
{
|
||||
ElfW(Dyn) *dyn = l->l_ld;
|
||||
|
||||
+19
-6
@@ -944,17 +944,19 @@ search_dirs (void)
|
||||
|
||||
|
||||
static void parse_conf_include (const char *config_file, unsigned int lineno,
|
||||
bool do_chroot, const char *pattern);
|
||||
const char *prefix, bool do_chroot,
|
||||
const char *pattern);
|
||||
|
||||
/* Parse configuration file. */
|
||||
static void
|
||||
parse_conf (const char *filename, bool do_chroot)
|
||||
parse_conf (const char *filename, const char *prefix, bool do_chroot)
|
||||
{
|
||||
FILE *file = NULL;
|
||||
char *line = NULL;
|
||||
const char *canon;
|
||||
size_t len = 0;
|
||||
unsigned int lineno;
|
||||
size_t prefix_len = prefix ? strlen (prefix) : 0;
|
||||
|
||||
if (do_chroot && opt_chroot)
|
||||
{
|
||||
@@ -1015,7 +1017,14 @@ parse_conf (const char *filename, bool do_chroot)
|
||||
cp += 8;
|
||||
while ((dir = strsep (&cp, " \t")) != NULL)
|
||||
if (dir[0] != '\0')
|
||||
parse_conf_include (filename, lineno, do_chroot, dir);
|
||||
parse_conf_include (filename, lineno, prefix, do_chroot, dir);
|
||||
}
|
||||
else if (prefix != NULL)
|
||||
{
|
||||
size_t cp_len = strlen (cp);
|
||||
char new_cp [prefix_len + cp_len + 1];
|
||||
memcpy (mempcpy (new_cp, prefix, prefix_len), cp, cp_len + 1);
|
||||
add_dir (new_cp);
|
||||
}
|
||||
else
|
||||
add_dir (cp);
|
||||
@@ -1031,7 +1040,7 @@ parse_conf (const char *filename, bool do_chroot)
|
||||
config files to read. */
|
||||
static void
|
||||
parse_conf_include (const char *config_file, unsigned int lineno,
|
||||
bool do_chroot, const char *pattern)
|
||||
const char *prefix, bool do_chroot, const char *pattern)
|
||||
{
|
||||
if (opt_chroot && pattern[0] != '/')
|
||||
error (EXIT_FAILURE, 0,
|
||||
@@ -1061,7 +1070,7 @@ parse_conf_include (const char *config_file, unsigned int lineno,
|
||||
{
|
||||
case 0:
|
||||
for (size_t i = 0; i < gl.gl_pathc; ++i)
|
||||
parse_conf (gl.gl_pathv[i], false);
|
||||
parse_conf (gl.gl_pathv[i], prefix, false);
|
||||
globfree64 (&gl);
|
||||
break;
|
||||
|
||||
@@ -1101,6 +1110,8 @@ main (int argc, char **argv)
|
||||
{
|
||||
int remaining;
|
||||
|
||||
arch_startup (argc, argv);
|
||||
|
||||
/* Parse and process arguments. */
|
||||
argp_parse (&argp, argc, argv, 0, &remaining, NULL);
|
||||
|
||||
@@ -1209,12 +1220,14 @@ main (int argc, char **argv)
|
||||
|
||||
if (!opt_only_cline)
|
||||
{
|
||||
parse_conf (config_file, true);
|
||||
parse_conf (config_file, NULL, true);
|
||||
|
||||
/* Always add the standard search paths. */
|
||||
add_system_dir (SLIBDIR);
|
||||
if (strcmp (SLIBDIR, LIBDIR))
|
||||
add_system_dir (LIBDIR);
|
||||
|
||||
add_arch_dirs (config_file);
|
||||
}
|
||||
|
||||
search_dirs ();
|
||||
|
||||
+9
-1
@@ -105,7 +105,15 @@ process_file (const char *real_file_name, const char *file_name,
|
||||
if ((size_t) statbuf.st_size < sizeof (struct exec)
|
||||
|| (size_t) statbuf.st_size < sizeof (ElfW(Ehdr)))
|
||||
{
|
||||
error (0, 0, _("File %s is too small, not checked."), file_name);
|
||||
if (statbuf.st_size == 0)
|
||||
error (0, 0, _("File %s is empty, not checked."), file_name);
|
||||
else
|
||||
{
|
||||
char buf[SELFMAG];
|
||||
size_t n = MIN (statbuf.st_size, SELFMAG);
|
||||
if (fread (buf, n, 1, file) == 1 && memcmp (buf, ELFMAG, n) == 0)
|
||||
error (0, 0, _("File %s is too small, not checked."), file_name);
|
||||
}
|
||||
fclose (file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
+104
-2
@@ -879,7 +879,7 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
{
|
||||
/* Create a link_map for the executable itself.
|
||||
This will be what dlopen on "" returns. */
|
||||
_dl_new_object ((char *) "", "", lt_executable, NULL);
|
||||
_dl_new_object ((char *) "", "", lt_executable, NULL, 0);
|
||||
if (GL(dl_loaded) == NULL)
|
||||
_dl_fatal_printf ("cannot allocate memory for link map\n");
|
||||
GL(dl_loaded)->l_phdr = phdr;
|
||||
@@ -1077,6 +1077,49 @@ of this helper program; chances are you did not intend to run this program.\n\
|
||||
++GL(dl_nloaded);
|
||||
++GL(dl_load_adds);
|
||||
|
||||
#if defined(__i386__)
|
||||
/* Force non-TLS libraries for glibc 2.0 binaries
|
||||
or if a buggy binary references non-TLS errno or h_errno. */
|
||||
if (__builtin_expect (GL(dl_loaded)->l_info[DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED)] == NULL, 0)
|
||||
&& GL(dl_loaded)->l_info[DT_DEBUG])
|
||||
GLRO(dl_osversion) = 0x20205;
|
||||
else if ((__builtin_expect (mode, normal) != normal
|
||||
|| GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_LIBLIST)] == NULL)
|
||||
/* Only binaries have DT_DEBUG dynamic tags... */
|
||||
&& GL(dl_loaded)->l_info[DT_DEBUG])
|
||||
{
|
||||
/* Workaround for buggy binaries. This doesn't handle buggy
|
||||
libraries. */
|
||||
bool buggy = false;
|
||||
const ElfW(Sym) *symtab = (const void *) D_PTR (GL(dl_loaded), l_info[DT_SYMTAB]);
|
||||
const char *strtab = (const void *) D_PTR (GL(dl_loaded), l_info[DT_STRTAB]);
|
||||
Elf_Symndx symidx;
|
||||
for (symidx = GL(dl_loaded)->l_buckets[0x6c994f % GL(dl_loaded)->l_nbuckets];
|
||||
symidx != STN_UNDEF;
|
||||
symidx = GL(dl_loaded)->l_chain[symidx])
|
||||
{
|
||||
if (__builtin_expect (strcmp (strtab + symtab[symidx].st_name,
|
||||
"errno") == 0, 0)
|
||||
&& ELFW(ST_TYPE) (symtab[symidx].st_info) != STT_TLS)
|
||||
buggy = true;
|
||||
}
|
||||
for (symidx = GL(dl_loaded)->l_buckets[0xe5c992f % GL(dl_loaded)->l_nbuckets];
|
||||
symidx != STN_UNDEF;
|
||||
symidx = GL(dl_loaded)->l_chain[symidx])
|
||||
{
|
||||
if (__builtin_expect (strcmp (strtab + symtab[symidx].st_name,
|
||||
"h_errno") == 0, 0)
|
||||
&& ELFW(ST_TYPE) (symtab[symidx].st_info) != STT_TLS)
|
||||
buggy = true;
|
||||
}
|
||||
if (__builtin_expect (buggy, false) && GLRO(dl_osversion) > 0x20401)
|
||||
{
|
||||
GLRO(dl_osversion) = 0x20401;
|
||||
_dl_error_printf ("Incorrectly built binary which accesses errno or h_errno directly. Needs to be fixed.\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If LD_USE_LOAD_BIAS env variable has not been seen, default
|
||||
to not using bias for non-prelinked PIEs and libraries
|
||||
and using it for executables or prelinked PIEs or libraries. */
|
||||
@@ -1247,6 +1290,64 @@ ERROR: ld.so: object '%s' from %s cannot be preloaded: ignored.\n",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(__i386__) || defined(__alpha__) || (defined(__sparc__) && !defined(__arch64__))
|
||||
/*
|
||||
* Modifications by Red Hat Software
|
||||
*
|
||||
* Deal with the broken binaries from the non-versioned ages of glibc.
|
||||
* If a binary does not have version information enabled, we assume that
|
||||
* it is a glibc 2.0 binary and we load a compatibility library to try to
|
||||
* overcome binary incompatibilities.
|
||||
* Blame: gafton@redhat.com
|
||||
*/
|
||||
#define LIB_NOVERSION "/lib/libNoVersion.so.1"
|
||||
|
||||
if (__builtin_expect (GL(dl_loaded)->l_info[DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED)] == NULL, 0)
|
||||
&& (GL(dl_loaded)->l_info[DT_DEBUG] || !(GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)))
|
||||
{
|
||||
struct stat test_st;
|
||||
int test_fd;
|
||||
int can_load;
|
||||
|
||||
HP_TIMING_NOW (start);
|
||||
|
||||
/* _dl_sysdep_message("Loading compatibility library... ", NULL); */
|
||||
|
||||
can_load = 1;
|
||||
test_fd = __open (LIB_NOVERSION, O_RDONLY);
|
||||
if (test_fd < 0) {
|
||||
can_load = 0;
|
||||
/* _dl_sysdep_message(" Can't find " LIB_NOVERSION "\n", NULL); */
|
||||
} else {
|
||||
if (__fxstat (_STAT_VER, test_fd, &test_st) < 0 || test_st.st_size == 0) {
|
||||
can_load = 0;
|
||||
/* _dl_sysdep_message(" Can't stat " LIB_NOVERSION "\n", NULL); */
|
||||
}
|
||||
}
|
||||
|
||||
if (test_fd >= 0) /* open did no fail.. */
|
||||
__close(test_fd); /* avoid fd leaks */
|
||||
|
||||
if (can_load != 0) {
|
||||
struct link_map *new_map;
|
||||
new_map = _dl_map_object (GL(dl_loaded), LIB_NOVERSION,
|
||||
1, lt_library, 0, 0);
|
||||
if (++new_map->l_opencount == 1) {
|
||||
/* It is no duplicate. */
|
||||
++npreloads;
|
||||
/* _dl_sysdep_message(" DONE\n", NULL); */
|
||||
} else {
|
||||
/* _dl_sysdep_message(" FAILED\n", NULL); */
|
||||
}
|
||||
}
|
||||
|
||||
HP_TIMING_NOW (stop);
|
||||
HP_TIMING_DIFF (diff, start, stop);
|
||||
HP_TIMING_ACCUM_NT (load_time, diff);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (__builtin_expect (npreloads, 0) != 0)
|
||||
{
|
||||
/* Set up PRELOADS with a vector of the preloaded libraries. */
|
||||
@@ -1271,7 +1372,8 @@ ERROR: ld.so: object '%s' from %s cannot be preloaded: ignored.\n",
|
||||
better be, since it's read-only and so we couldn't relocate it).
|
||||
We just want our data structures to describe it as if we had just
|
||||
mapped and relocated it normally. */
|
||||
struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL);
|
||||
struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL,
|
||||
0);
|
||||
if (__builtin_expect (l != NULL, 1))
|
||||
{
|
||||
static ElfW(Dyn) dyn_temp[DL_RO_DYN_TEMP_CNT] attribute_relro;
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
xyzzy (void)
|
||||
{
|
||||
printf ("%s:%s\n", __FILE__, __func__);
|
||||
return 21;
|
||||
}
|
||||
|
||||
int
|
||||
back (void)
|
||||
{
|
||||
printf ("%s:%s\n", __FILE__, __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
extern int foo (void);
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
void *p = dlopen ("$ORIGIN/tst-deep1mod2.so", RTLD_LAZY|RTLD_DEEPBIND);
|
||||
|
||||
int (*f) (void) = dlsym (p, "bar");
|
||||
if (f == NULL)
|
||||
{
|
||||
puts (dlerror ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
return foo () + f ();
|
||||
}
|
||||
|
||||
#define TEST_FUNCTION do_test ()
|
||||
#include "../test-skeleton.c"
|
||||
@@ -0,0 +1,14 @@
|
||||
#include <stdio.h>
|
||||
int
|
||||
foo (void)
|
||||
{
|
||||
printf ("%s:%s\n", __FILE__, __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
baz (void)
|
||||
{
|
||||
printf ("%s:%s\n", __FILE__, __func__);
|
||||
return 20;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#include <stdio.h>
|
||||
extern int baz (void);
|
||||
extern int xyzzy (void);
|
||||
int
|
||||
bar (void)
|
||||
{
|
||||
printf ("%s:%s\n", __FILE__, __func__);
|
||||
return baz () + xyzzy ();;
|
||||
}
|
||||
|
||||
int
|
||||
back (void)
|
||||
{
|
||||
printf ("%s:%s\n", __FILE__, __func__);
|
||||
return -1;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#include <stdio.h>
|
||||
|
||||
extern int back (void);
|
||||
|
||||
int
|
||||
baz (void)
|
||||
{
|
||||
printf ("%s:%s\n", __FILE__, __func__);
|
||||
return back ();
|
||||
}
|
||||
|
||||
int
|
||||
xyzzy (void)
|
||||
{
|
||||
printf ("%s:%s\n", __FILE__, __func__);
|
||||
return 0;
|
||||
}
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
#include <tls.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined USE_TLS && defined HAVE___THREAD \
|
||||
&& defined HAVE_TLS_MODEL_ATTRIBUTE
|
||||
#if defined USE_TLS \
|
||||
&& (0 || (defined HAVE___THREAD && defined HAVE_TLS_MODEL_ATTRIBUTE))
|
||||
# define USE_TLS__THREAD
|
||||
|
||||
struct A
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
glibc-*.tar.bz2
|
||||
glibc-*.src.rpm
|
||||
glibc-fedora.patch
|
||||
glibc.spec
|
||||
update.log
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
# Makefile for maintaining glibc fedora-branch and creating Fedora source RPMs.
|
||||
|
||||
glibc.spec: # The default target.
|
||||
|
||||
tag-prefix := fedora-
|
||||
|
||||
.PHONY: update commit-merge commit patch tag archive finish_archive srpm rpm
|
||||
|
||||
snapshot-date-fmt := +'%Y-%m-%d %H:%M %Z'
|
||||
snapshot-name-fmt := +'%Y%m%dT%H%M'
|
||||
|
||||
include branch.mk
|
||||
|
||||
|
||||
on-branch = $(filter-out HEAD,$(glibc-base))
|
||||
|
||||
snapshot-date := $($(glibc-branch)-sync-date)
|
||||
snapshot-name := $(shell date -u -d '$(snapshot-date)' $(snapshot-name-fmt))
|
||||
|
||||
tar-name := glibc$(subst _,.,$(patsubst glibc-%-branch,-%,\
|
||||
$(filter-out HEAD,$(glibc-base))))
|
||||
select-snapshot = -r '$($(glibc-branch)-sync-tag)'
|
||||
snapshot-id = $($(glibc-branch)-sync-tag)
|
||||
|
||||
|
||||
update:
|
||||
now=`date -u $(snapshot-date-fmt)`; \
|
||||
name=`date -u -d "$$now" $(snapshot-name-fmt)`; \
|
||||
new="$(tag-prefix)$(tar-name)-$$name"; \
|
||||
cvs -Q rtag $(if $(on-branch),-r $(glibc-base),-D "$$now") $$new libc;\
|
||||
(echo '# This file is updated automatically by Makefile.'; \
|
||||
echo 'glibc-branch := $(glibc-branch)'; \
|
||||
echo 'glibc-base := $(glibc-base)'; \
|
||||
echo "$(glibc-branch)-sync-date := $$now"; \
|
||||
echo "$(glibc-branch)-sync-tag := $$new"; \
|
||||
) > branch.mk; \
|
||||
cd ..; (set -x; cvs -q update -d -P \
|
||||
-j'$($(glibc-branch)-sync-tag)' -j"$$new") \
|
||||
2>&1 | tee fedora/update.log
|
||||
|
||||
commit-merge:
|
||||
cd ..; cvs -Q commit -m"Updated to $(snapshot-id)"
|
||||
|
||||
glibc.spec: glibc.spec.in ../version.h branch.mk
|
||||
(echo '%define glibcdate $(snapshot-name)'; \
|
||||
sed -n '/VERSION/s/^.*"\([^"]*\)"$$/%define glibcversion \1/p' \
|
||||
../version.h; \
|
||||
cat $<) > $@.new
|
||||
mv -f $@.new $@
|
||||
|
||||
ifeq (,$(wildcard glibc.spec))
|
||||
Makefile: glibc.spec ;
|
||||
else
|
||||
|
||||
spec-nvr := $(shell rpm -q --qf '%{NAME}-%{VERSION}-%{RELEASE}\n' \
|
||||
--specfile glibc.spec | sed 1q)
|
||||
spec-tag = $(subst .,_,$(spec-nvr))
|
||||
|
||||
tag: glibc.spec
|
||||
cd ..; cvs -Q tag -c $(tag-prefix)$(spec-tag)
|
||||
|
||||
$(tar-name)-$(glibc-branch).patch: makepatch.awk glibc.spec \
|
||||
../ChangeLog ../*/ChangeLog
|
||||
(cd ..; cvs -q diff -upN \
|
||||
$(select-snapshot) -r $(tag-prefix)$(spec-tag)) | \
|
||||
awk -v OLDVER=$(tar-name)-$(snapshot-name) \
|
||||
-v NEWVER=$(tar-name)-$(snapshot-name)-$(glibc-branch) \
|
||||
-f $< > patch.tmp
|
||||
mv -f patch.tmp $@
|
||||
|
||||
# makepatch.awk omits these files from the patch; we put them in a tar file.
|
||||
outside-patch = fedora c_stubs rtkaio glibc-compat \
|
||||
localedata/charmaps/GB18030 iconvdata/gb18030.c
|
||||
|
||||
$(tar-name)-$(glibc-branch)-$(snapshot-name).tar.bz2: Makefile branch.mk \
|
||||
../ChangeLog \
|
||||
../*/ChangeLog
|
||||
@rm -rf libc
|
||||
cvs -Q export -r$(tag-prefix)$(spec-tag) \
|
||||
$(addprefix libc/,$(outside-patch))
|
||||
tar cf - -C libc $(outside-patch) | bzip2 -9 > $@.new
|
||||
rm -rf libc
|
||||
mv -f $@.new $@
|
||||
|
||||
$(tar-name)-$(snapshot-name).tar.bz2: Makefile branch.mk
|
||||
@rm -rf $(tar-name)-$(snapshot-name)
|
||||
cvs -Q export -d $(tar-name)-$(snapshot-name) $(select-snapshot) libc
|
||||
tar cf - $(tar-name)-$(snapshot-name) | bzip2 -9 > $@.new
|
||||
rm -rf $(tar-name)-$(snapshot-name)
|
||||
mv -f $@.new $@
|
||||
|
||||
archives = $(tar-name)-$(snapshot-name).tar.bz2 \
|
||||
$(tar-name)-$(glibc-branch)-$(snapshot-name).tar.bz2 \
|
||||
$(tar-name)-$(glibc-branch).patch
|
||||
finish_archive: $(archives)
|
||||
|
||||
archive: glibc.spec
|
||||
$(MAKE) tag finish_archive
|
||||
|
||||
rpm srpm: $(spec-nvr).src.rpm
|
||||
$(spec-nvr).src.rpm: glibc.spec $(archives)
|
||||
rpmbuild --define "_sourcedir `pwd`" \
|
||||
--define "_specdir `pwd`" \
|
||||
--define "_srcrpmdir `pwd`" \
|
||||
--nodeps -bs $<
|
||||
|
||||
endif
|
||||
@@ -0,0 +1,5 @@
|
||||
# This file is updated automatically by Makefile.
|
||||
glibc-branch := fedora
|
||||
glibc-base := HEAD
|
||||
fedora-sync-date := 2004-09-27 06:11 UTC
|
||||
fedora-sync-tag := fedora-glibc-20040927T0611
|
||||
@@ -0,0 +1,160 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include "../locale/hashval.h"
|
||||
|
||||
const char *alias_file = DATADIR "/locale/locale.alias";
|
||||
const char *locar_file = PREFIX "/lib/locale/locale-archive";
|
||||
const char *loc_path = PREFIX "/lib/locale/";
|
||||
int be_quiet = 1;
|
||||
int verbose = 0;
|
||||
int max_locarchive_open_retry = 10;
|
||||
const char *output_prefix;
|
||||
|
||||
static int
|
||||
is_prime (unsigned long candidate)
|
||||
{
|
||||
/* No even number and none less than 10 will be passed here. */
|
||||
unsigned long int divn = 3;
|
||||
unsigned long int sq = divn * divn;
|
||||
|
||||
while (sq < candidate && candidate % divn != 0)
|
||||
{
|
||||
++divn;
|
||||
sq += 4 * divn;
|
||||
++divn;
|
||||
}
|
||||
|
||||
return candidate % divn != 0;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
next_prime (unsigned long seed)
|
||||
{
|
||||
/* Make it definitely odd. */
|
||||
seed |= 1;
|
||||
|
||||
while (!is_prime (seed))
|
||||
seed += 2;
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
||||
/* xmalloc is only used by show_archive_content. */
|
||||
void *
|
||||
xmalloc (size_t size)
|
||||
{
|
||||
exit (255);
|
||||
}
|
||||
|
||||
void
|
||||
error (int status, int errnum, const char *message, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start (args, message);
|
||||
fflush (stdout);
|
||||
fprintf (stderr, "%s: ", program_invocation_name);
|
||||
vfprintf (stderr, message, args);
|
||||
va_end (args);
|
||||
if (errnum)
|
||||
fprintf (stderr, ": %s", strerror (errnum));
|
||||
putc ('\n', stderr);
|
||||
fflush (stderr);
|
||||
if (status)
|
||||
exit (errnum == EROFS ? 0 : status);
|
||||
}
|
||||
|
||||
extern int add_locales_to_archive (size_t nlist, char *list[], bool replace);
|
||||
|
||||
int main ()
|
||||
{
|
||||
char path[4096];
|
||||
DIR *dirp;
|
||||
struct dirent64 *d;
|
||||
struct stat64 st;
|
||||
char *list[16384], *primary;
|
||||
unsigned int cnt = 0;
|
||||
|
||||
unlink (locar_file);
|
||||
dirp = opendir (loc_path);
|
||||
if (dirp == NULL)
|
||||
error (EXIT_FAILURE, errno, "cannot open directory \"%s\"", loc_path);
|
||||
|
||||
primary = getenv ("LC_ALL");
|
||||
if (primary == NULL)
|
||||
primary = getenv ("LANG");
|
||||
if (primary != NULL)
|
||||
{
|
||||
if (strncmp (primary, "ja", 2) != 0
|
||||
&& strncmp (primary, "ko", 2) != 0
|
||||
&& strncmp (primary, "zh", 2) != 0)
|
||||
{
|
||||
char *ptr = malloc (strlen (primary) + strlen (".utf8") + 1), *p, *q;
|
||||
|
||||
if (ptr)
|
||||
{
|
||||
p = ptr;
|
||||
q = primary;
|
||||
while (*q && *q != '.' && *q != '@')
|
||||
*p++ = *q++;
|
||||
if (*q == '.')
|
||||
while (*q && *q != '@')
|
||||
q++;
|
||||
p = stpcpy (p, ".utf8");
|
||||
strcpy (p, q);
|
||||
primary = ptr;
|
||||
}
|
||||
else
|
||||
primary = ".....";
|
||||
}
|
||||
strcpy (stpcpy (path, loc_path), primary);
|
||||
if (stat64 (path, &st) >= 0 && S_ISDIR (st.st_mode))
|
||||
{
|
||||
list[cnt] = strdup (path);
|
||||
if (list[cnt] == NULL)
|
||||
error (0, errno, "cannot add file to list \"%s\"", path);
|
||||
else
|
||||
cnt++;
|
||||
}
|
||||
if (cnt == 0)
|
||||
primary = NULL;
|
||||
}
|
||||
|
||||
while ((d = readdir64 (dirp)) != NULL)
|
||||
{
|
||||
if (strcmp (d->d_name, ".") == 0 || strcmp (d->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
if (primary && strcmp (d->d_name, primary) == 0)
|
||||
continue;
|
||||
|
||||
strcpy (stpcpy (path, loc_path), d->d_name);
|
||||
if (stat64 (path, &st) < 0)
|
||||
{
|
||||
error (0, errno, "cannot stat \"%s\"", path);
|
||||
continue;
|
||||
}
|
||||
if (! S_ISDIR (st.st_mode))
|
||||
continue;
|
||||
if (cnt == 16384)
|
||||
error (EXIT_FAILURE, 0, "too many directories in \"%s\"", loc_path);
|
||||
list[cnt] = strdup (path);
|
||||
if (list[cnt] == NULL)
|
||||
{
|
||||
error (0, errno, "cannot add file to list \"%s\"", path);
|
||||
continue;
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
closedir (dirp);
|
||||
add_locales_to_archive (cnt, list, 0);
|
||||
exit (0);
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
2004-05-14 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/configure.in: Use */lib64 even for ia64.
|
||||
* sysdeps/unix/sysv/linux/configure: Rebuilt.
|
||||
* sysdeps/unix/sysv/linux/ia64/dl-procinfo.c: New file.
|
||||
* sysdeps/unix/sysv/linux/ia64/dl-procinfo.h: New file.
|
||||
* sysdeps/unix/sysv/linux/ia64/ldd-rewrite.sed: Change /lib64/ld*
|
||||
into /lib/ld*. Add LD_LIBRARY_VERSION.
|
||||
* sysdeps/unix/sysv/linux/ia64/ldconfig.h
|
||||
(SYSDEP_KNOWN_INTERPRETER_NAMES): Add /lib64/ld-linux-ia64.so.2.
|
||||
* sysdeps/unix/sysv/linux/ia64/dl-cache.h: Include sparc-linux
|
||||
dl-cache.h instead of generic dl-cache.h.
|
||||
|
||||
--- libc/sysdeps/unix/sysv/linux/configure.jj 2003-03-23 03:10:04.000000000 +0100
|
||||
+++ libc/sysdeps/unix/sysv/linux/configure 2004-05-14 15:54:35.669802684 +0200
|
||||
@@ -225,7 +225,7 @@ case "$prefix" in
|
||||
# 64-bit libraries on bi-arch platforms go in /lib64 instead of /lib
|
||||
case $machine in
|
||||
sparc/sparc64 | x86_64 | powerpc/powerpc64 | s390/s390-64 | \
|
||||
- mips/mips64/n64/* )
|
||||
+ mips/mips64/n64/* | ia64 )
|
||||
libc_cv_slibdir="/lib64"
|
||||
if test "$libdir" = '${exec_prefix}/lib'; then
|
||||
libdir='${exec_prefix}/lib64';
|
||||
--- libc/sysdeps/unix/sysv/linux/configure.in.jj 2003-03-23 03:10:04.000000000 +0100
|
||||
+++ libc/sysdeps/unix/sysv/linux/configure.in 2004-05-14 15:53:44.355998785 +0200
|
||||
@@ -158,7 +158,7 @@ case "$prefix" in
|
||||
# 64-bit libraries on bi-arch platforms go in /lib64 instead of /lib
|
||||
case $machine in
|
||||
sparc/sparc64 | x86_64 | powerpc/powerpc64 | s390/s390-64 | \
|
||||
- mips/mips64/n64/* )
|
||||
+ mips/mips64/n64/* | ia64 )
|
||||
libc_cv_slibdir="/lib64"
|
||||
if test "$libdir" = '${exec_prefix}/lib'; then
|
||||
libdir='${exec_prefix}/lib64';
|
||||
--- libc/sysdeps/unix/sysv/linux/ia64/dl-procinfo.c.jj 2004-05-14 15:42:09.307560515 +0200
|
||||
+++ libc/sysdeps/unix/sysv/linux/ia64/dl-procinfo.c 2003-09-30 00:23:24.000000000 +0200
|
||||
@@ -0,0 +1,5 @@
|
||||
+#ifdef IS_IN_ldconfig
|
||||
+#include <sysdeps/i386/dl-procinfo.c>
|
||||
+#else
|
||||
+#include <sysdeps/generic/dl-procinfo.c>
|
||||
+#endif
|
||||
--- libc/sysdeps/unix/sysv/linux/ia64/ldd-rewrite.sed.jj 2002-01-17 07:49:28.000000000 +0100
|
||||
+++ libc/sysdeps/unix/sysv/linux/ia64/ldd-rewrite.sed 2004-05-14 16:21:03.041325040 +0200
|
||||
@@ -1 +1,4 @@
|
||||
-s_^\(RTLDLIST=\)\([^ ]*\)-ia64\(\.so\.[0-9.]*\)[ ]*$_\1"\2-ia64\3 \2\3"_
|
||||
+/LD_TRACE_LOADED_OBJECTS=1/a\
|
||||
+add_env="$add_env LD_LIBRARY_VERSION=\\$verify_out"
|
||||
+s_^\(RTLDLIST=\)/lib64/ld\([^ ]*\)-ia64\(\.so\.[0-9.]*\)[ ]*$_\1"/lib/ld\2-ia64\3 /lib/ld\2\3"_
|
||||
+s_^\(RTLDLIST=\)\([^"][^ ]*\)-ia64\(\.so\.[0-9.]*\)[ ]*$_\1"\2-ia64\3 \2\3"_
|
||||
--- libc/sysdeps/unix/sysv/linux/ia64/ldconfig.h.jj 2001-07-06 06:56:17.000000000 +0200
|
||||
+++ libc/sysdeps/unix/sysv/linux/ia64/ldconfig.h 2004-05-14 15:45:40.103783087 +0200
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
+/* Copyright (C) 2001, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@@ -19,7 +19,8 @@
|
||||
#include <sysdeps/generic/ldconfig.h>
|
||||
|
||||
#define SYSDEP_KNOWN_INTERPRETER_NAMES \
|
||||
- { "/lib/ld-linux.so.2", FLAG_ELF_LIBC6 },
|
||||
+ { "/lib/ld-linux.so.2", FLAG_ELF_LIBC6 }, \
|
||||
+ { "/lib64/ld-linux-ia64.so.2", FLAG_ELF_LIBC6 },
|
||||
#define SYSDEP_KNOWN_LIBRARY_NAMES \
|
||||
{ "libc.so.6", FLAG_ELF_LIBC6 }, \
|
||||
{ "libm.so.6", FLAG_ELF_LIBC6 },
|
||||
--- libc/sysdeps/unix/sysv/linux/ia64/dl-cache.h.jj 2001-07-06 06:56:17.000000000 +0200
|
||||
+++ libc/sysdeps/unix/sysv/linux/ia64/dl-cache.h 2004-05-14 15:41:11.658891907 +0200
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Support for reading /etc/ld.so.cache files written by Linux ldconfig.
|
||||
- Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
+ Copyright (C) 2000, 2004 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@@ -22,4 +22,4 @@
|
||||
#define _dl_cache_check_flags(flags) \
|
||||
((flags) == _DL_CACHE_DEFAULT_ID)
|
||||
|
||||
-#include_next <dl-cache.h>
|
||||
+#include <sysdeps/unix/sysv/linux/sparc/dl-cache.h>
|
||||
--- libc/sysdeps/unix/sysv/linux/ia64/dl-procinfo.h.jj 2004-05-14 15:42:13.018895395 +0200
|
||||
+++ libc/sysdeps/unix/sysv/linux/ia64/dl-procinfo.h 2003-07-23 00:06:23.000000000 +0200
|
||||
@@ -0,0 +1,5 @@
|
||||
+#ifdef IS_IN_ldconfig
|
||||
+#include <sysdeps/unix/sysv/linux/i386/dl-procinfo.h>
|
||||
+#else
|
||||
+#include <sysdeps/generic/dl-procinfo.h>
|
||||
+#endif
|
||||
@@ -0,0 +1,48 @@
|
||||
--- libc/sysdeps/unix/sysv/linux/dl-osinfo.h.jj 2002-12-10 09:09:24.000000000 -0500
|
||||
+++ libc/sysdeps/unix/sysv/linux/dl-osinfo.h 2003-05-20 17:05:37.000000000 -0400
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/utsname.h>
|
||||
#include "kernel-features.h"
|
||||
+#include <sysdep.h>
|
||||
|
||||
#ifndef MIN
|
||||
# define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
@@ -37,8 +38,29 @@ dl_fatal (const char *str)
|
||||
_dl_dprintf (2, str);
|
||||
_exit (1);
|
||||
}
|
||||
-#endif
|
||||
|
||||
+static inline void
|
||||
+__attribute__ ((always_inline))
|
||||
+dl_redhat_nptl_check (const char *cp)
|
||||
+{
|
||||
+ cp = strchr (cp, 'n');
|
||||
+ if (__builtin_expect (cp == NULL || cp[1] != 'p'
|
||||
+ || cp[2] != 't' || cp[3] != 'l', 0)
|
||||
+ && GLRO(dl_osversion) < 0x20545
|
||||
+ && GLRO(dl_osversion) > 0x20413)
|
||||
+ {
|
||||
+#ifdef __NR_set_tid_address
|
||||
+ INTERNAL_SYSCALL_DECL (err);
|
||||
+ int ret;
|
||||
+ ret = INTERNAL_SYSCALL (set_tid_address, err, 1, NULL);
|
||||
+ if (INTERNAL_SYSCALL_ERROR_P (ret, err))
|
||||
+#endif
|
||||
+ GLRO(dl_osversion) = 0x20413;
|
||||
+ }
|
||||
+}
|
||||
+#else
|
||||
+#define dl_redhat_nptl_check(cp)
|
||||
+#endif
|
||||
|
||||
#define DL_SYSDEP_OSCHECK(FATAL) \
|
||||
do { \
|
||||
@@ -105,5 +127,6 @@ dl_fatal (const char *str)
|
||||
FATAL ("FATAL: kernel too old\n"); \
|
||||
\
|
||||
GLRO(dl_osversion) = version; \
|
||||
+ dl_redhat_nptl_check (cp); \
|
||||
} \
|
||||
} while (0)
|
||||
@@ -0,0 +1,18 @@
|
||||
--- libc/sysdeps/unix/sysv/linux/powerpc/kernel-features.h.jj 2003-01-30 05:24:37.000000000 -0500
|
||||
+++ libc/sysdeps/unix/sysv/linux/powerpc/kernel-features.h 2003-09-23 18:28:07.000000000 -0400
|
||||
@@ -0,0 +1,15 @@
|
||||
+/* In RHEL3, we can assume the shipped kernel, which is 2.4.21. */
|
||||
+#include_next <kernel-features.h>
|
||||
+
|
||||
+#if !defined __ASSUME_NEW_PRCTL_SYSCALL && defined __powerpc__
|
||||
+# define __ASSUME_NEW_PRCTL_SYSCALL 1
|
||||
+#endif
|
||||
+
|
||||
+#if !defined __ASSUME_FIXED_CLONE_SYSCALL && defined __powerpc__ \
|
||||
+ && !defined __powerpc64__
|
||||
+# define __ASSUME_FIXED_CLONE_SYSCALL 1
|
||||
+#endif
|
||||
+
|
||||
+#if !defined __ASSUME_NEW_RT_SIGRETURN_SYSCALL && defined __powerpc64__
|
||||
+# define __ASSUME_NEW_RT_SIGRETURN_SYSCALL 1
|
||||
+#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,256 @@
|
||||
#if defined __sparc__ && defined __arch64__
|
||||
register void *__thread_self __asm ("g7");
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <dirent.h>
|
||||
#include <stddef.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
pid_t pid;
|
||||
int status, rerun_ldconfig = 0, rerun_cnt = 0;
|
||||
char initpath[256];
|
||||
|
||||
#ifdef __i386__
|
||||
char buffer[4096];
|
||||
struct pref {
|
||||
char *p;
|
||||
int len;
|
||||
} prefix[] = { { "libc-", 5 }, { "libm-", 5 },
|
||||
{ "librt-", 6 }, { "libpthread-", 11 },
|
||||
{ "librtkaio-", 10 }, { "libthread_db-", 13 } };
|
||||
int i, j, fd;
|
||||
off_t base;
|
||||
ssize_t ret;
|
||||
#ifdef ARCH_386
|
||||
const char *remove_dirs[] = { "/lib/i686", "/lib/tls" };
|
||||
#else
|
||||
const char *remove_dirs[] = { "/lib/tls/i686" };
|
||||
#endif
|
||||
for (j = 0; j < sizeof (remove_dirs) / sizeof (remove_dirs[0]); ++j)
|
||||
{
|
||||
size_t rmlen = strlen (remove_dirs[j]);
|
||||
fd = open (remove_dirs[j], O_RDONLY);
|
||||
if (fd >= 0
|
||||
&& (ret = getdirentries (fd, buffer, sizeof (buffer), &base))
|
||||
>= (ssize_t) offsetof (struct dirent, d_name))
|
||||
{
|
||||
for (base = 0; base + offsetof (struct dirent, d_name) < ret; )
|
||||
{
|
||||
struct dirent *d = (struct dirent *) (buffer + base);
|
||||
|
||||
for (i = 0; i < sizeof (prefix) / sizeof (prefix[0]); i++)
|
||||
if (! strncmp (d->d_name, prefix[i].p, prefix[i].len))
|
||||
{
|
||||
char *p = d->d_name + prefix[i].len;
|
||||
|
||||
while (*p == '.' || (*p >= '0' && *p <= '9')) p++;
|
||||
if (p[0] == 's' && p[1] == 'o' && p[2] == '\0'
|
||||
&& p + 3 - d->d_name
|
||||
< sizeof (initpath) - rmlen - 1)
|
||||
{
|
||||
memcpy (initpath, remove_dirs[j], rmlen);
|
||||
initpath[rmlen] = '/';
|
||||
strcpy (initpath + rmlen + 1, d->d_name);
|
||||
unlink (initpath);
|
||||
break;
|
||||
}
|
||||
}
|
||||
base += d->d_reclen;
|
||||
}
|
||||
close (fd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int ldsocfd = open (LD_SO_CONF, O_RDONLY);
|
||||
struct stat ldsocst;
|
||||
if (ldsocfd >= 0 && fstat (ldsocfd, &ldsocst) >= 0)
|
||||
{
|
||||
char p[ldsocst.st_size + 1];
|
||||
if (read (ldsocfd, p, ldsocst.st_size) == ldsocst.st_size)
|
||||
{
|
||||
p[ldsocst.st_size] = '\0';
|
||||
if (strstr (p, "include ld.so.conf.d/*.conf") == NULL)
|
||||
{
|
||||
close (ldsocfd);
|
||||
ldsocfd = open (LD_SO_CONF, O_WRONLY | O_TRUNC);
|
||||
if (ldsocfd >= 0)
|
||||
{
|
||||
size_t slen = strlen ("include ld.so.conf.d/*.conf\n");
|
||||
if (write (ldsocfd, "include ld.so.conf.d/*.conf\n", slen)
|
||||
!= slen
|
||||
|| write (ldsocfd, p, ldsocst.st_size) != ldsocst.st_size)
|
||||
_exit (109);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ldsocfd >= 0)
|
||||
close (ldsocfd);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
char linkbuf[64], *linkp;
|
||||
int linklen;
|
||||
|
||||
pid = vfork ();
|
||||
if (pid == 0)
|
||||
{
|
||||
execl ("/sbin/ldconfig", "/sbin/ldconfig", NULL);
|
||||
_exit (110);
|
||||
}
|
||||
else if (pid < 0)
|
||||
_exit (111);
|
||||
if (waitpid (0, &status, 0) != pid || !WIFEXITED (status))
|
||||
_exit (112);
|
||||
if (WEXITSTATUS (status))
|
||||
_exit (WEXITSTATUS (status));
|
||||
|
||||
rerun_ldconfig = 0;
|
||||
#ifdef LIBTLS
|
||||
linkp = linkbuf + strlen (LIBTLS);
|
||||
linklen = readlink (LIBTLS "librt.so.1", linkp,
|
||||
sizeof (linkbuf) - 1 - strlen (LIBTLS));
|
||||
if (linklen == strlen ("librtkaio-2.3.X.so")
|
||||
&& memcmp (linkp, "librtkaio-2.3.", 14) == 0
|
||||
&& strchr ("23", linkp[14])
|
||||
&& memcmp (linkp + 15, ".so", 4) == 0)
|
||||
{
|
||||
memcpy (linkbuf, LIBTLS, strlen (LIBTLS));
|
||||
unlink (linkbuf);
|
||||
rerun_ldconfig = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __i386__
|
||||
linkp = linkbuf + strlen ("/lib/i686/");
|
||||
linklen = readlink ("/lib/i686/librt.so.1", linkp,
|
||||
sizeof (linkbuf) - 1 - strlen ("/lib/i686/"));
|
||||
if (linklen == strlen ("librtkaio-2.3.X.so")
|
||||
&& memcmp (linkp, "librtkaio-2.3.", 14) == 0
|
||||
&& strchr ("23", linkp[14])
|
||||
&& memcmp (linkp + 15, ".so", 4) == 0)
|
||||
{
|
||||
memcpy (linkbuf, "/lib/i686/", strlen ("/lib/i686/"));
|
||||
unlink (linkbuf);
|
||||
rerun_ldconfig = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
while (rerun_ldconfig && ++rerun_cnt < 2);
|
||||
|
||||
if (! utimes (GCONV_MODULES_CACHE, NULL))
|
||||
{
|
||||
pid = vfork ();
|
||||
if (pid == 0)
|
||||
{
|
||||
execl ("/usr/sbin/iconvconfig", "/usr/sbin/iconvconfig", NULL);
|
||||
_exit (113);
|
||||
}
|
||||
else if (pid < 0)
|
||||
_exit (114);
|
||||
if (waitpid (0, &status, 0) != pid || !WIFEXITED (status))
|
||||
_exit (115);
|
||||
if (WEXITSTATUS (status))
|
||||
_exit (WEXITSTATUS (status));
|
||||
}
|
||||
|
||||
/* Check if telinit is available and the init fifo as well. */
|
||||
if (access ("/sbin/telinit", X_OK) || access ("/dev/initctl", F_OK))
|
||||
_exit (0);
|
||||
/* Check if we are not inside of some chroot, because we'd just
|
||||
timeout and leave /etc/initrunlvl. */
|
||||
if (readlink ("/proc/1/exe", initpath, 256) <= 0 ||
|
||||
readlink ("/proc/1/root", initpath, 256) <= 0)
|
||||
_exit (0);
|
||||
|
||||
pid = vfork ();
|
||||
if (pid == 0)
|
||||
{
|
||||
execl ("/sbin/telinit", "/sbin/telinit", "u", NULL);
|
||||
_exit (116);
|
||||
}
|
||||
else if (pid < 0)
|
||||
_exit (117);
|
||||
if (waitpid (0, &status, 0) != pid || !WIFEXITED (status))
|
||||
_exit (118);
|
||||
|
||||
/* Check if we can safely condrestart sshd. */
|
||||
if (access ("/sbin/service", X_OK) == 0
|
||||
&& access ("/usr/sbin/sshd", X_OK) == 0
|
||||
&& access ("/bin/bash", X_OK) == 0)
|
||||
{
|
||||
pid = vfork ();
|
||||
if (pid == 0)
|
||||
{
|
||||
execl ("/sbin/service", "/sbin/service", "sshd", "condrestart", NULL);
|
||||
_exit (119);
|
||||
}
|
||||
else if (pid < 0)
|
||||
_exit (120);
|
||||
if (waitpid (0, &status, 0) != pid || !WIFEXITED (status))
|
||||
_exit (121);
|
||||
}
|
||||
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
int __libc_multiple_threads __attribute__((nocommon));
|
||||
int __libc_enable_asynccancel (void) { return 0; }
|
||||
void __libc_disable_asynccancel (int x) { }
|
||||
void __libc_csu_init (void) { }
|
||||
void __libc_csu_fini (void) { }
|
||||
pid_t __fork (void) { return -1; }
|
||||
char thr_buf[65536];
|
||||
|
||||
#ifndef __powerpc__
|
||||
int __libc_start_main (int (*main) (void), int argc, char **argv,
|
||||
void (*init) (void), void (*fini) (void),
|
||||
void (*rtld_fini) (void), void * stack_end)
|
||||
#else
|
||||
struct startup_info
|
||||
{
|
||||
void *sda_base;
|
||||
int (*main) (int, char **, char **, void *);
|
||||
int (*init) (int, char **, char **, void *);
|
||||
void (*fini) (void);
|
||||
};
|
||||
|
||||
int __libc_start_main (int argc, char **ubp_av,
|
||||
char **ubp_ev,
|
||||
void *auxvec, void (*rtld_fini) (void),
|
||||
struct startup_info *stinfo,
|
||||
char **stack_on_entry)
|
||||
#endif
|
||||
{
|
||||
#if defined __ia64__ || defined __powerpc64__
|
||||
register void *r13 __asm ("r13") = thr_buf + 32768;
|
||||
__asm ("" : : "r" (r13));
|
||||
#elif defined __sparc__
|
||||
register void *g6 __asm ("g6") = thr_buf + 32768;
|
||||
# ifdef __arch64__
|
||||
__thread_self = thr_buf + 32768;
|
||||
# else
|
||||
register void *__thread_self __asm ("g7") = thr_buf + 32768;
|
||||
# endif
|
||||
__asm ("" : : "r" (g6), "r" (__thread_self));
|
||||
#elif defined __s390__ && !defined __s390x__
|
||||
__asm ("sar %%a0,%0" : : "d" (thr_buf + 32768));
|
||||
#elif defined __s390x__
|
||||
__asm ("sar %%a1,%0; srlg 0,%0,32; sar %%a0,0" : : "d" (thr_buf + 32768) : "0");
|
||||
#elif defined __powerpc__ && !defined __powerpc64__
|
||||
register void *r2 __asm ("r2") = thr_buf + 32768;
|
||||
__asm ("" : : "r" (r2));
|
||||
#endif
|
||||
main();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,344 @@
|
||||
/* Copyright (C) 2001 Red Hat, Inc.
|
||||
|
||||
Written by Jakub Jelinek <jakub@redhat.com>.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with this program; see the file COPYING. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Changes by Rémy Card to use constants and add option -n. */
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define NHASH 131072 /* Must be a power of 2! */
|
||||
#define NAMELEN 4096
|
||||
#define NBUF 64
|
||||
|
||||
struct _f;
|
||||
typedef struct _h {
|
||||
struct _h *next;
|
||||
struct _f *chain;
|
||||
off_t size;
|
||||
time_t mtime;
|
||||
} h;
|
||||
|
||||
typedef struct _d {
|
||||
struct _d *next;
|
||||
char name[0];
|
||||
} d;
|
||||
|
||||
d *dirs;
|
||||
|
||||
h *hps[NHASH];
|
||||
|
||||
int no_link = 0;
|
||||
int verbose = 0;
|
||||
int content_only = 0;
|
||||
|
||||
typedef struct _f {
|
||||
struct _f *next;
|
||||
ino_t ino;
|
||||
dev_t dev;
|
||||
unsigned int cksum;
|
||||
char name[0];
|
||||
} f;
|
||||
|
||||
inline unsigned int hash(off_t size, time_t mtime)
|
||||
{
|
||||
return (size ^ mtime) & (NHASH - 1);
|
||||
}
|
||||
|
||||
inline int stcmp(struct stat *st1, struct stat *st2, int content_only)
|
||||
{
|
||||
if (content_only)
|
||||
return st1->st_size != st2->st_size;
|
||||
return st1->st_mode != st2->st_mode || st1->st_uid != st2->st_uid ||
|
||||
st1->st_gid != st2->st_gid || st1->st_size != st2->st_size ||
|
||||
st1->st_mtime != st2->st_mtime;
|
||||
}
|
||||
|
||||
long long ndirs, nobjects, nregfiles, nmmap, ncomp, nlinks, nsaved;
|
||||
|
||||
void doexit(int i)
|
||||
{
|
||||
if (verbose) {
|
||||
fprintf(stderr, "\n\n");
|
||||
fprintf(stderr, "Directories %lld\n", ndirs);
|
||||
fprintf(stderr, "Objects %lld\n", nobjects);
|
||||
fprintf(stderr, "IFREG %lld\n", nregfiles);
|
||||
fprintf(stderr, "Mmaps %lld\n", nmmap);
|
||||
fprintf(stderr, "Comparisons %lld\n", ncomp);
|
||||
fprintf(stderr, "%s %lld\n", (no_link ? "Would link" : "Linked"), nlinks);
|
||||
fprintf(stderr, "%s %lld\n", (no_link ? "Would save" : "saved"), nsaved);
|
||||
}
|
||||
exit(i);
|
||||
}
|
||||
|
||||
void usage(prog)
|
||||
{
|
||||
fprintf (stderr, "Usage: %s [-cnv] directories...\n", prog);
|
||||
exit(255);
|
||||
}
|
||||
|
||||
unsigned int buf[NBUF];
|
||||
char nambuf1[NAMELEN], nambuf2[NAMELEN];
|
||||
|
||||
void rf (char *name)
|
||||
{
|
||||
struct stat st, st2, st3;
|
||||
nobjects++;
|
||||
if (lstat (name, &st))
|
||||
return;
|
||||
if (S_ISDIR (st.st_mode)) {
|
||||
d * dp = malloc(sizeof(d) + 1 + strlen (name));
|
||||
if (!dp) {
|
||||
fprintf(stderr, "\nOut of memory 3\n");
|
||||
doexit(3);
|
||||
}
|
||||
strcpy (dp->name, name);
|
||||
dp->next = dirs;
|
||||
dirs = dp;
|
||||
} else if (S_ISREG (st.st_mode)) {
|
||||
int fd, i;
|
||||
f * fp, * fp2;
|
||||
h * hp;
|
||||
char *p, *q;
|
||||
char *n1, *n2;
|
||||
int cksumsize = sizeof(buf);
|
||||
unsigned int cksum;
|
||||
time_t mtime = content_only ? 0 : st.st_mtime;
|
||||
unsigned int hsh = hash (st.st_size, mtime);
|
||||
nregfiles++;
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, " %s", name);
|
||||
fd = open (name, O_RDONLY);
|
||||
if (fd < 0) return;
|
||||
if (st.st_size < sizeof(buf)) {
|
||||
cksumsize = st.st_size;
|
||||
memset (((char *)buf) + cksumsize, 0, (sizeof(buf) - cksumsize) % sizeof(buf[0]));
|
||||
}
|
||||
if (read (fd, buf, cksumsize) != cksumsize) {
|
||||
close(fd);
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "\r%*s\r", (int)strlen(name)+2, "");
|
||||
return;
|
||||
}
|
||||
cksumsize = (cksumsize + sizeof(buf[0]) - 1) / sizeof(buf[0]);
|
||||
for (i = 0, cksum = 0; i < cksumsize; i++) {
|
||||
if (cksum + buf[i] < cksum)
|
||||
cksum += buf[i] + 1;
|
||||
else
|
||||
cksum += buf[i];
|
||||
}
|
||||
for (hp = hps[hsh]; hp; hp = hp->next)
|
||||
if (hp->size == st.st_size && hp->mtime == mtime)
|
||||
break;
|
||||
if (!hp) {
|
||||
hp = malloc(sizeof(h));
|
||||
if (!hp) {
|
||||
fprintf(stderr, "\nOut of memory 1\n");
|
||||
doexit(1);
|
||||
}
|
||||
hp->size = st.st_size;
|
||||
hp->mtime = mtime;
|
||||
hp->chain = NULL;
|
||||
hp->next = hps[hsh];
|
||||
hps[hsh] = hp;
|
||||
}
|
||||
for (fp = hp->chain; fp; fp = fp->next)
|
||||
if (fp->cksum == cksum)
|
||||
break;
|
||||
for (fp2 = fp; fp2 && fp2->cksum == cksum; fp2 = fp2->next)
|
||||
if (fp2->ino == st.st_ino && fp2->dev == st.st_dev) {
|
||||
close(fd);
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "\r%*s\r", (int)strlen(name)+2, "");
|
||||
return;
|
||||
}
|
||||
if (fp) {
|
||||
p = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
nmmap++;
|
||||
if (p == (void *)-1) {
|
||||
close(fd);
|
||||
fprintf(stderr, "\nFailed to mmap %s\n", name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (fp2 = fp; fp2 && fp2->cksum == cksum; fp2 = fp2->next)
|
||||
if (!lstat (fp2->name, &st2) && S_ISREG (st2.st_mode) &&
|
||||
!stcmp (&st, &st2, content_only) &&
|
||||
st2.st_ino != st.st_ino &&
|
||||
st2.st_dev == st.st_dev) {
|
||||
int fd2 = open (fp2->name, O_RDONLY);
|
||||
if (fd2 < 0) continue;
|
||||
if (fstat (fd2, &st2) || !S_ISREG (st2.st_mode)) {
|
||||
close (fd2);
|
||||
continue;
|
||||
}
|
||||
ncomp++;
|
||||
q = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd2, 0);
|
||||
if (q == (void *)-1) {
|
||||
close(fd2);
|
||||
fprintf(stderr, "\nFailed to mmap %s\n", fp2->name);
|
||||
continue;
|
||||
}
|
||||
if (memcmp (p, q, st.st_size)) {
|
||||
munmap (q, st.st_size);
|
||||
close(fd2);
|
||||
continue;
|
||||
}
|
||||
munmap (q, st.st_size);
|
||||
close(fd2);
|
||||
if (lstat (name, &st3)) {
|
||||
fprintf(stderr, "\nCould not stat %s again\n", name);
|
||||
munmap (p, st.st_size);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
st3.st_atime = st.st_atime;
|
||||
if (stcmp (&st, &st3, 0)) {
|
||||
fprintf(stderr, "\nFile %s changed underneath us\n", name);
|
||||
munmap (p, st.st_size);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
n1 = fp2->name;
|
||||
n2 = name;
|
||||
if (!no_link) {
|
||||
strcpy (stpcpy (nambuf2, n2), ".$$$___cleanit___$$$");
|
||||
if (rename (n2, nambuf2)) {
|
||||
fprintf(stderr, "\nFailed to rename %s to %s\n", n2, nambuf2);
|
||||
continue;
|
||||
}
|
||||
if (link (n1, n2)) {
|
||||
fprintf(stderr, "\nFailed to hardlink %s to %s\n", n1, n2);
|
||||
if (rename (nambuf2, n2)) {
|
||||
fprintf(stderr, "\nBad bad - failed to rename back %s to %s\n", nambuf2, n2);
|
||||
}
|
||||
munmap (p, st.st_size);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
unlink (nambuf2);
|
||||
}
|
||||
nlinks++;
|
||||
if (st3.st_nlink > 1) {
|
||||
/* We actually did not save anything this time, since the link second argument
|
||||
had some other links as well. */
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "\r%*s\r%s %s to %s\n", (int)strlen(name)+2, "", (no_link ? "Would link" : "Linked"), n1, n2);
|
||||
} else {
|
||||
nsaved+=st.st_size;
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "\r%*s\r%s %s to %s, %s %ld\n", (int)strlen(name)+2, "", (no_link ? "Would link" : "Linked"), n1, n2, (no_link ? "would save" : "saved"), st.st_size);
|
||||
}
|
||||
munmap (p, st.st_size);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
if (fp)
|
||||
munmap (p, st.st_size);
|
||||
fp2 = malloc(sizeof(f) + 1 + strlen (name));
|
||||
if (!fp2) {
|
||||
fprintf(stderr, "\nOut of memory 2\n");
|
||||
doexit(2);
|
||||
}
|
||||
close(fd);
|
||||
fp2->ino = st.st_ino;
|
||||
fp2->dev = st.st_dev;
|
||||
fp2->cksum = cksum;
|
||||
strcpy(fp2->name, name);
|
||||
if (fp) {
|
||||
fp2->next = fp->next;
|
||||
fp->next = fp2;
|
||||
} else {
|
||||
fp2->next = hp->chain;
|
||||
hp->chain = fp2;
|
||||
}
|
||||
if (verbose > 1)
|
||||
fprintf(stderr, "\r%*s\r", (int)strlen(name)+2, "");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ch;
|
||||
int i;
|
||||
char *p;
|
||||
d * dp;
|
||||
DIR *dh;
|
||||
struct dirent *di;
|
||||
while ((ch = getopt (argc, argv, "cnv")) != -1) {
|
||||
switch (ch) {
|
||||
case 'n':
|
||||
no_link++;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'c':
|
||||
content_only++;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
if (optind >= argc)
|
||||
usage(argv[0]);
|
||||
for (i = optind; i < argc; i++)
|
||||
rf(argv[i]);
|
||||
while (dirs) {
|
||||
dp = dirs;
|
||||
dirs = dp->next;
|
||||
strcpy (nambuf1, dp->name);
|
||||
free (dp);
|
||||
strcat (nambuf1, "/");
|
||||
p = strchr (nambuf1, 0);
|
||||
dh = opendir (nambuf1);
|
||||
if (dh == NULL)
|
||||
continue;
|
||||
ndirs++;
|
||||
while ((di = readdir (dh)) != NULL) {
|
||||
if (!di->d_name[0])
|
||||
continue;
|
||||
if (di->d_name[0] == '.') {
|
||||
char *q;
|
||||
if (!di->d_name[1] || !strcmp (di->d_name, "..") || !strncmp (di->d_name, ".in.", 4))
|
||||
continue;
|
||||
q = strrchr (di->d_name, '.');
|
||||
if (q && strlen (q) == 7 && q != di->d_name) {
|
||||
*p = 0;
|
||||
if (verbose)
|
||||
fprintf(stderr, "Skipping %s%s\n", nambuf1, di->d_name);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
strcpy (p, di->d_name);
|
||||
rf(nambuf1);
|
||||
}
|
||||
closedir(dh);
|
||||
}
|
||||
doexit(0);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
#!/bin/awk -f
|
||||
/^cvs (diff|server): tag.*is not in file/ {
|
||||
print
|
||||
next
|
||||
}
|
||||
/^cvs (diff|server): Diffing/ {
|
||||
next
|
||||
}
|
||||
/^\? / {
|
||||
next
|
||||
}
|
||||
/^Index:/ {
|
||||
file=$2
|
||||
next
|
||||
}
|
||||
/^===============/ {
|
||||
next
|
||||
}
|
||||
/^RCS/ {
|
||||
next
|
||||
}
|
||||
/^retrieving/ {
|
||||
next
|
||||
}
|
||||
/^diff/ {
|
||||
next
|
||||
}
|
||||
/^---/ {
|
||||
if ($2 ~ /^\/dev\/null/ ||
|
||||
$2 ~ /^\/tmp\//)
|
||||
$2=file
|
||||
if ($2 ~ /.cvsignore$/ ||
|
||||
$2 ~ /^c_stubs/ ||
|
||||
$2 ~ /^rtkaio/ ||
|
||||
$2 ~ /^fedora/ ||
|
||||
$2 ~ /^localedata\/charmaps\/GB18030/ ||
|
||||
$2 ~ /^iconvdata\/gb18030\.c/ ||
|
||||
$2 ~ /^glibc-compat/) {
|
||||
hide = 1
|
||||
next
|
||||
} else {
|
||||
hide = 0
|
||||
}
|
||||
sub(/^---[ ]*/,"--- " OLDVER "/")
|
||||
}
|
||||
/^\+\+\+/ {
|
||||
if (hide)
|
||||
next
|
||||
if ($2 ~ /^\/dev\/null/ ||
|
||||
$2 ~ /^\/tmp\//)
|
||||
$2=file
|
||||
sub(/^\+\+\+[ ]*/,"+++ " NEWVER "/")
|
||||
}
|
||||
{
|
||||
if (hide)
|
||||
next
|
||||
print
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
#
|
||||
# /etc/nsswitch.conf
|
||||
#
|
||||
# An example Name Service Switch config file. This file should be
|
||||
# sorted with the most-used services at the beginning.
|
||||
#
|
||||
# The entry '[NOTFOUND=return]' means that the search for an
|
||||
# entry should stop if the search in the previous entry turned
|
||||
# up nothing. Note that if the search failed due to some other reason
|
||||
# (like no NIS server responding) then the search continues with the
|
||||
# next entry.
|
||||
#
|
||||
# Legal entries are:
|
||||
#
|
||||
# nisplus or nis+ Use NIS+ (NIS version 3)
|
||||
# nis or yp Use NIS (NIS version 2), also called YP
|
||||
# dns Use DNS (Domain Name Service)
|
||||
# files Use the local files
|
||||
# db Use the local database (.db) files
|
||||
# compat Use NIS on compat mode
|
||||
# hesiod Use Hesiod for user lookups
|
||||
# [NOTFOUND=return] Stop searching if not found so far
|
||||
#
|
||||
|
||||
# To use db, put the "db" in front of "files" for entries you want to be
|
||||
# looked up first in the databases
|
||||
#
|
||||
# Example:
|
||||
#passwd: db files nisplus nis
|
||||
#shadow: db files nisplus nis
|
||||
#group: db files nisplus nis
|
||||
|
||||
passwd: files
|
||||
shadow: files
|
||||
group: files
|
||||
|
||||
#hosts: db files nisplus nis dns
|
||||
hosts: files dns
|
||||
|
||||
# Example - obey only what nisplus tells us...
|
||||
#services: nisplus [NOTFOUND=return] files
|
||||
#networks: nisplus [NOTFOUND=return] files
|
||||
#protocols: nisplus [NOTFOUND=return] files
|
||||
#rpc: nisplus [NOTFOUND=return] files
|
||||
#ethers: nisplus [NOTFOUND=return] files
|
||||
#netmasks: nisplus [NOTFOUND=return] files
|
||||
|
||||
bootparams: nisplus [NOTFOUND=return] files
|
||||
|
||||
ethers: files
|
||||
netmasks: files
|
||||
networks: files
|
||||
protocols: files
|
||||
rpc: files
|
||||
services: files
|
||||
|
||||
netgroup: nisplus
|
||||
|
||||
publickey: nisplus
|
||||
|
||||
automount: files nisplus
|
||||
aliases: files nisplus
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
glibc-compat*.tar.gz
|
||||
@@ -0,0 +1 @@
|
||||
Glibc-2.0 compatibility add-on by Cristian Gafton
|
||||
@@ -0,0 +1,37 @@
|
||||
2000-04-13 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* Makefile (services): revert last change.
|
||||
(libnss1_db-routines): Add db-open.
|
||||
(libnss1_db.so): Remove libdb dependencies, add libdl.
|
||||
* nss_db/db-open.c: New file.
|
||||
* nss_db/dummy-db.h: New file.
|
||||
* nss_db/nss_db.h: New file.
|
||||
* nss_db/db-XXX.c: Update from glibc 2.1.90 nss_db/db-XXX.c,
|
||||
remove errnop passing and EXTRA_ARGS.
|
||||
* nss_db/db-alias.c: Likewise.
|
||||
* nss_db/db-netgrp.c: Likewise.
|
||||
|
||||
2000-01-04 Cristian Gafton <gafton@redhat.com>
|
||||
|
||||
* Makefile (services): disable the compat NSS module for
|
||||
Berkeley DB (nss_db). Berkeley BD is not part of the glibc anymore.
|
||||
|
||||
1999-07-08 Cristian Gafton <gafton@redhat.com>
|
||||
|
||||
* stubs.c (__setfpucw): New function
|
||||
* Makefile: Use -include, not include
|
||||
(archive): New target.
|
||||
|
||||
1999-04-09 Andreas Jaeger <aj@arthur.rhein-neckar.de>
|
||||
* glibc-compat/Makefile: Add rules to link libnss_*.so.1 to libnss1_*.so.2.
|
||||
|
||||
1998-11-18 Cristian Gafton <gafton@redhat.com>
|
||||
|
||||
* shlib-versions: added alpha versions
|
||||
|
||||
* Makefile (services): Added libnss_dns
|
||||
|
||||
1998-11-16 Cristian Gafton <gafton@redhat.com>
|
||||
|
||||
* makedist (archive): remove old tar file just in case
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
resolv
|
||||
nss
|
||||
nis
|
||||
@@ -0,0 +1,150 @@
|
||||
# Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
|
||||
# This is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Library General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of the
|
||||
# License, or (at your option) any later version.
|
||||
|
||||
# The GNU C Library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Library General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
# $Id$
|
||||
|
||||
subdir := glibc-compat
|
||||
|
||||
distribute := nss-nis.h
|
||||
|
||||
# This is the trivial part which goes into libc itself.
|
||||
routines =
|
||||
|
||||
# These are the databases that go through nss dispatch.
|
||||
# Caution: if you add a database here, you must add its real name
|
||||
# in databases.def, too.
|
||||
databases = proto service hosts network grp pwd rpc ethers \
|
||||
spwd netgrp alias
|
||||
|
||||
# Specify rules for the nss_* modules. We have some services.
|
||||
services := files nis compat dns
|
||||
|
||||
extra-libs := $(services:%=libnss1_%) libNoVersion
|
||||
# These libraries will be built in the `others' pass rather than
|
||||
# the `lib' pass, because they depend on libc.so being built already.
|
||||
extra-libs-others = $(extra-libs)
|
||||
|
||||
# The sources are found in the appropriate subdir.
|
||||
subdir-dirs = $(services:%=nss_%)
|
||||
vpath %.c $(subdir-dirs)
|
||||
|
||||
libnss1_files-routines := $(addprefix files-,$(databases))
|
||||
libnss1_compat-routines := $(addprefix compat-,grp pwd spwd)
|
||||
libnss1_nis-routines := $(addprefix nis-,$(databases))
|
||||
libnss1_dns-routines := $(addprefix dns-, host network)
|
||||
|
||||
libcompat-routines := $(addprefix old, fileops iofdopen iopopen stdfiles \
|
||||
iofclose iofopen pclose tmpfile)
|
||||
libNoVersion-routines := stubs
|
||||
|
||||
libnss1_files-inhibit-o = $(filter-out .os,$(object-suffixes))
|
||||
libnss1_compat-inhibit-o = $(filter-out .os,$(object-suffixes))
|
||||
libnss1_nis-inhibit-o = $(filter-out .os,$(object-suffixes))
|
||||
libnss1_dns-inhibit-o = $(filter-out .os,$(object-suffixes))
|
||||
|
||||
-include ../Rules
|
||||
|
||||
# Force the soname to be libnss_*.so.1 for compatibility.
|
||||
LDFLAGS-nss1_files.so = -Wl,-soname=lib$(libprefix)nss_files.so$($(@F)-version)
|
||||
LDFLAGS-nss1_nis.so = -Wl,-soname=lib$(libprefix)nss_nis.so$($(@F)-version)
|
||||
LDFLAGS-nss1_compat.so = -Wl,-soname=lib$(libprefix)nss_compat.so$($(@F)-version)
|
||||
LDFLAGS-nss1_dns.so = -Wl,-soname=lib$(libprefix)nss_dns.so$($(@F)-version)
|
||||
|
||||
-include ../Makeconfig
|
||||
|
||||
ifeq (yes,$(build-shared))
|
||||
install-others += $(inst_slibdir)/libnss_files.so$(libnss1_files.so-version) \
|
||||
$(inst_slibdir)/libnss_nis.so$(libnss1_nis.so-version) \
|
||||
$(inst_slibdir)/libnss_compat.so$(libnss1_compat.so-version) \
|
||||
$(inst_slibdir)/libnss_dns.so$(libnss1_dns.so-version)
|
||||
endif
|
||||
|
||||
$(inst_slibdir)/libnss_files.so$(libnss1_files.so-version): $(inst_slibdir)/libnss1_files-$(version).so $(+force)
|
||||
rm -f $@
|
||||
$(LN_S) $(<F) $@
|
||||
|
||||
$(inst_slibdir)/libnss_nis.so$(libnss1_nis.so-version): $(inst_slibdir)/libnss1_nis-$(version).so $(+force)
|
||||
rm -f $@
|
||||
$(LN_S) $(<F) $@
|
||||
|
||||
$(inst_slibdir)/libnss_compat.so$(libnss1_compat.so-version): $(inst_slibdir)/libnss1_compat-$(version).so $(+force)
|
||||
rm -f $@
|
||||
$(LN_S) $(<F) $@
|
||||
|
||||
$(inst_slibdir)/libnss_dns.so$(libnss1_dns.so-version): $(inst_slibdir)/libnss1_dns-$(version).so $(+force)
|
||||
rm -f $@
|
||||
$(LN_S) $(<F) $@
|
||||
|
||||
|
||||
$(objpfx)libnss1_compat.so: $(common-objpfx)nis/libnsl.so$(libnsl.so-version) \
|
||||
$(objpfx)libnss1_files.so
|
||||
$(objpfx)libnss1_nis.so: $(common-objpfx)nis/libnsl.so$(libnsl.so-version) \
|
||||
$(objpfx)libnss1_files.so
|
||||
|
||||
# The DNS NSS modules needs the resolver.
|
||||
#$(objpfx)libnss1_dns.so: $(filter-out $(common-objpfx)resolv/stamp.os, \
|
||||
# $(wildcard $(common-objpfx)resolv/*.os)) \
|
||||
# $(common-objpfx)libc.so
|
||||
$(objpfx)libnss1_dns.so: $(common-objpfx)resolv/libresolv.so $(common-objpfx)libc.so
|
||||
|
||||
# Depend on libc.so so a DT_NEEDED is generated in the shared objects.
|
||||
# This ensures they will load libc.so for needed symbols if loaded by
|
||||
# a statically-linked program that hasn't already loaded it.
|
||||
$(objpfx)libnss1_compat.so: $(common-objpfx)nis/libnsl.so$(libnsl.so-version) \
|
||||
$(objpfx)libnss1_files.so $(common-objpfx)libc.so
|
||||
$(objpfx)libnss1_dns.so: $(common-objpfx)resolv/libresolv.so \
|
||||
$(common-objpfx)libc.so
|
||||
$(objpfs)libnss1_files.so: $(common-objpfx)libc.so
|
||||
$(objpfx)libnss1_nis.so: $(common-objpfx)nis/libnsl.so$(libnsl.so-version) \
|
||||
$(objpfx)libnss1_files.so $(common-objpfx)libc.so
|
||||
|
||||
check-abi-libNoVersion: $(..)scripts/extract-abilist.awk
|
||||
@:
|
||||
update-abi-libNoVersion: $(..)scripts/merge-abilist.awk
|
||||
@:
|
||||
check-abi-libnss1_compat: $(..)scripts/extract-abilist.awk
|
||||
@:
|
||||
update-abi-libnss1_compat: $(..)scripts/merge-abilist.awk
|
||||
@:
|
||||
check-abi-libnss1_dns: $(..)scripts/extract-abilist.awk
|
||||
@:
|
||||
update-abi-libnss1_dns: $(..)scripts/merge-abilist.awk
|
||||
@:
|
||||
check-abi-libnss1_files: $(..)scripts/extract-abilist.awk
|
||||
@:
|
||||
update-abi-libnss1_files: $(..)scripts/merge-abilist.awk
|
||||
@:
|
||||
check-abi-libnss1_nis: $(..)scripts/extract-abilist.awk
|
||||
@:
|
||||
update-abi-libnss1_nis: $(..)scripts/merge-abilist.awk
|
||||
@:
|
||||
|
||||
#
|
||||
# This is needed to build the separate tarball
|
||||
#
|
||||
pkgNAME = $(subdir)
|
||||
pkgVERSION = 2.1.3
|
||||
pkgCVSTAG = $(pkgNAME)_$(subst .,-,$(pkgVERSION))
|
||||
|
||||
archive:
|
||||
@rm -f *.tar.gz *~
|
||||
cvs tag -F $(pkgCVSTAG) .
|
||||
@rm -rf /tmp/$(pkgNAME)-$(pkgVERSION) /tmp/$(pkgNAME) $(pkgNAME)-$(pkgVERSION).tar.gz
|
||||
@cd /tmp; cvs export -r$(pkgCVSTAG) $(pkgNAME)
|
||||
@pkgDIR=$$PWD; cd /tmp; tar cvzf $$pkgDIR/$(pkgNAME)-$(pkgVERSION).tar.gz $(pkgNAME)
|
||||
@rm -rf /tmp/$(pkgNAME)
|
||||
@echo "The archive is in $(pkgNAME)-$(pkgVERSION).tar.gz"
|
||||
@@ -0,0 +1,106 @@
|
||||
libnss1_db {
|
||||
GLIBC_2.0 {
|
||||
_nss_db_endaliasent; _nss_db_endetherent; _nss_db_endgrent;
|
||||
_nss_db_endnetgrent; _nss_db_endprotoent; _nss_db_endpwent;
|
||||
_nss_db_endrpcent; _nss_db_endservent; _nss_db_endspent;
|
||||
_nss_db_getaliasbyname_r; _nss_db_getaliasent_r; _nss_db_getetherent_r;
|
||||
_nss_db_getgrent_r; _nss_db_getgrgid_r; _nss_db_getgrnam_r;
|
||||
_nss_db_gethostton_r; _nss_db_getnetgrent_r; _nss_db_getntohost_r;
|
||||
_nss_db_getprotobyname_r; _nss_db_getprotobynumber_r;
|
||||
_nss_db_getprotoent_r; _nss_db_getpwent_r; _nss_db_getpwnam_r;
|
||||
_nss_db_getpwuid_r; _nss_db_getrpcbyname_r; _nss_db_getrpcbynumber_r;
|
||||
_nss_db_getrpcent_r; _nss_db_getservbyname_r; _nss_db_getservbyport_r;
|
||||
_nss_db_getservent_r; _nss_db_getspent_r; _nss_db_getspnam_r;
|
||||
_nss_db_setaliasent; _nss_db_setetherent; _nss_db_setgrent;
|
||||
_nss_db_setnetgrent; _nss_db_setprotoent; _nss_db_setpwent;
|
||||
_nss_db_setrpcent; _nss_db_setservent; _nss_db_setspent;
|
||||
}
|
||||
}
|
||||
|
||||
libnss1_dns {
|
||||
GLIBC_2.0 {
|
||||
_nss_dns_gethostbyaddr_r; _nss_dns_gethostbyname2_r;
|
||||
_nss_dns_gethostbyname_r; _nss_dns_getnetbyaddr_r;
|
||||
_nss_dns_getnetbyname_r;
|
||||
}
|
||||
}
|
||||
|
||||
libnss1_files {
|
||||
GLIBC_2.0 {
|
||||
_nss_files_setaliasent; _nss_files_endaliasent;
|
||||
_nss_files_getaliasbyname_r; _nss_files_getaliasent_r;
|
||||
|
||||
_nss_files_setetherent; _nss_files_endetherent;
|
||||
_nss_files_getetherent_r; _nss_files_parse_etherent;
|
||||
|
||||
_nss_files_setgrent; _nss_files_endgrent;
|
||||
_nss_files_getgrent_r; _nss_files_getgrgid_r; _nss_files_getgrnam_r;
|
||||
|
||||
_nss_files_sethostent; _nss_files_endhostent;
|
||||
_nss_files_gethostbyaddr_r; _nss_files_gethostbyname2_r; _nss_files_gethostbyname_r;
|
||||
_nss_files_gethostent_r; _nss_files_gethostton_r;
|
||||
|
||||
_nss_files_setnetent; _nss_files_endnetent;
|
||||
_nss_files_getnetbyaddr_r; _nss_files_getnetbyname_r;
|
||||
_nss_files_getnetent_r; _nss_files_getntohost_r;
|
||||
_nss_files_parse_netent;
|
||||
|
||||
_nss_files_setnetgrent; _nss_files_endnetgrent; _nss_files_getnetgrent_r;
|
||||
|
||||
_nss_files_setprotoent; _nss_files_endprotoent;
|
||||
_nss_files_getprotobyname_r; _nss_files_getprotobynumber_r;
|
||||
_nss_files_getprotoent_r; _nss_files_parse_protoent;
|
||||
|
||||
_nss_files_setpwent; _nss_files_endpwent;
|
||||
_nss_files_getpwent_r; _nss_files_getpwnam_r; _nss_files_getpwuid_r;
|
||||
|
||||
_nss_files_setrpcent; _nss_files_endrpcent;
|
||||
_nss_files_getrpcbyname_r; _nss_files_getrpcbynumber_r;
|
||||
_nss_files_getrpcent_r;
|
||||
_nss_files_parse_rpcent;
|
||||
|
||||
_nss_files_setservent; _nss_files_endservent;
|
||||
_nss_files_getservbyname_r; _nss_files_getservbyport_r;
|
||||
_nss_files_getservent_r;
|
||||
_nss_files_parse_servent;
|
||||
|
||||
_nss_files_setspent; _nss_files_endspent;
|
||||
_nss_files_getspent_r; _nss_files_getspnam_r;
|
||||
|
||||
_nss_netgroup_parseline;
|
||||
}
|
||||
}
|
||||
|
||||
libnss1_compat {
|
||||
GLIBC_2.0 {
|
||||
_nss_compat_endgrent; _nss_compat_endpwent; _nss_compat_endspent;
|
||||
_nss_compat_getgrent_r; _nss_compat_getgrgid_r; _nss_compat_getgrnam_r;
|
||||
_nss_compat_getpwent_r; _nss_compat_getpwnam_r; _nss_compat_getpwuid_r;
|
||||
_nss_compat_getspent_r; _nss_compat_getspnam_r; _nss_compat_initgroups;
|
||||
_nss_compat_setgrent; _nss_compat_setpwent; _nss_compat_setspent;
|
||||
}
|
||||
}
|
||||
|
||||
libnss1_nis {
|
||||
GLIBC_2.0 {
|
||||
_nss_nis_endaliasent; _nss_nis_endetherent; _nss_nis_endgrent;
|
||||
_nss_nis_endhostent; _nss_nis_endnetent; _nss_nis_endnetgrent;
|
||||
_nss_nis_endprotoent; _nss_nis_endpwent; _nss_nis_endrpcent;
|
||||
_nss_nis_endservent; _nss_nis_endspent; _nss_nis_getaliasbyname_r;
|
||||
_nss_nis_getaliasent_r; _nss_nis_getetherent_r; _nss_nis_getgrent_r;
|
||||
_nss_nis_getgrgid_r; _nss_nis_getgrnam_r; _nss_nis_gethostbyaddr_r;
|
||||
_nss_nis_gethostbyname2_r; _nss_nis_gethostbyname_r; _nss_nis_gethostent_r;
|
||||
_nss_nis_gethostton_r; _nss_nis_getnetbyaddr_r; _nss_nis_getnetbyname_r;
|
||||
_nss_nis_getnetent_r; _nss_nis_getnetgrent_r; _nss_nis_getntohost_r;
|
||||
_nss_nis_getprotobyname_r; _nss_nis_getprotobynumber_r;
|
||||
_nss_nis_getprotoent_r; _nss_nis_getpublickey; _nss_nis_getpwent_r;
|
||||
_nss_nis_getpwnam_r; _nss_nis_getpwuid_r; _nss_nis_getrpcbyname_r;
|
||||
_nss_nis_getrpcbynumber_r; _nss_nis_getrpcent_r; _nss_nis_getsecretkey;
|
||||
_nss_nis_getservbyname_r; _nss_nis_getservbyport_r; _nss_nis_getservent_r;
|
||||
_nss_nis_getspent_r; _nss_nis_getspnam_r; _nss_nis_initgroups;
|
||||
_nss_nis_netname2user; _nss_nis_setaliasent; _nss_nis_setetherent;
|
||||
_nss_nis_setgrent; _nss_nis_sethostent; _nss_nis_setnetent;
|
||||
_nss_nis_setnetgrent; _nss_nis_setprotoent; _nss_nis_setpwent;
|
||||
_nss_nis_setrpcent; _nss_nis_setservent; _nss_nis_setspent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
libnss1_files {
|
||||
GLIBC_2.0
|
||||
}
|
||||
libnss1_db {
|
||||
GLIBC_2.0
|
||||
}
|
||||
libnss1_dns {
|
||||
GLIBC_2.0
|
||||
}
|
||||
libnss1_nis {
|
||||
GLIBC_2.0
|
||||
}
|
||||
libnss1_compat {
|
||||
GLIBC_2.0
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
# This is only to keep the GNU C library configure mechanism happy.
|
||||
# This is a shell script fragment sourced by the main configure script.
|
||||
# We have nothing we need to add here.
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef _ALIASES_H
|
||||
#include <inet/aliases.h>
|
||||
|
||||
extern int __getaliasent_r (struct aliasent *__restrict __result_buf,
|
||||
char *__restrict __buffer, size_t __buflen,
|
||||
struct aliasent **__restrict __result);
|
||||
extern int __old_getaliasent_r (struct aliasent *__restrict __result_buf,
|
||||
char *__restrict __buffer, size_t __buflen,
|
||||
struct aliasent **__restrict __result);
|
||||
|
||||
extern int __getaliasbyname_r (__const char *__restrict __name,
|
||||
struct aliasent *__restrict __result_buf,
|
||||
char *__restrict __buffer, size_t __buflen,
|
||||
struct aliasent **__restrict __result);
|
||||
extern int __old_getaliasbyname_r (__const char *__restrict __name,
|
||||
struct aliasent *__restrict __result_buf,
|
||||
char *__restrict __buffer, size_t __buflen,
|
||||
struct aliasent **__restrict __result);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef _GRP_H
|
||||
#include <grp/grp.h>
|
||||
|
||||
/* Now define the internal interfaces. */
|
||||
extern int __getgrent_r (struct group *__resultbuf, char *buffer,
|
||||
size_t __buflen, struct group **__result);
|
||||
extern int __old_getgrent_r (struct group *__resultbuf, char *buffer,
|
||||
size_t __buflen, struct group **__result);
|
||||
extern int __fgetgrent_r (FILE * __stream, struct group *__resultbuf,
|
||||
char *buffer, size_t __buflen,
|
||||
struct group **__result);
|
||||
|
||||
/* Search for an entry with a matching group ID. */
|
||||
extern int __getgrgid_r (__gid_t __gid, struct group *__resultbuf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct group **__result);
|
||||
extern int __old_getgrgid_r (__gid_t __gid, struct group *__resultbuf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct group **__result);
|
||||
|
||||
/* Search for an entry with a matching group name. */
|
||||
extern int __getgrnam_r (__const char *__name, struct group *__resultbuf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct group **__result);
|
||||
extern int __old_getgrnam_r (__const char *__name, struct group *__resultbuf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct group **__result);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,178 @@
|
||||
#ifndef _NETDB_H
|
||||
#include <glibc-compat/include/rpc/netdb.h>
|
||||
#include <resolv/netdb.h>
|
||||
|
||||
/* Macros for accessing h_errno from inside libc. */
|
||||
# ifdef _LIBC_REENTRANT
|
||||
# include <tls.h>
|
||||
# if USE___THREAD
|
||||
# undef h_errno
|
||||
# ifndef NOT_IN_libc
|
||||
# define h_errno __libc_h_errno
|
||||
# else
|
||||
# define h_errno h_errno /* For #ifndef h_errno tests. */
|
||||
# endif
|
||||
extern __thread int h_errno attribute_tls_model_ie;
|
||||
# define __set_h_errno(x) (h_errno = (x))
|
||||
# else
|
||||
static inline int
|
||||
__set_h_errno (int __err)
|
||||
{
|
||||
return *__h_errno_location () = __err;
|
||||
}
|
||||
# endif
|
||||
# else
|
||||
# undef h_errno
|
||||
# define __set_h_errno(x) (h_errno = (x))
|
||||
extern int h_errno;
|
||||
# endif /* _LIBC_REENTRANT */
|
||||
|
||||
/* Document internal interfaces. */
|
||||
extern int __gethostent_r (struct hostent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct hostent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
extern int __old_gethostent_r (struct hostent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct hostent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
|
||||
extern int __gethostbyaddr_r (__const void *__restrict __addr,
|
||||
socklen_t __len, int __type,
|
||||
struct hostent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct hostent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
extern int __old_gethostbyaddr_r (__const void *__restrict __addr,
|
||||
socklen_t __len, int __type,
|
||||
struct hostent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct hostent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
|
||||
extern int __gethostbyname_r (__const char *__restrict __name,
|
||||
struct hostent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct hostent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
extern int __old_gethostbyname_r (__const char *__restrict __name,
|
||||
struct hostent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct hostent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
|
||||
extern int __gethostbyname2_r (__const char *__restrict __name, int __af,
|
||||
struct hostent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct hostent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
extern int __old_gethostbyname2_r (__const char *__restrict __name, int __af,
|
||||
struct hostent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct hostent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
|
||||
extern int __getnetent_r (struct netent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct netent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
extern int __old_getnetent_r (struct netent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct netent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
|
||||
extern int __getnetbyaddr_r (uint32_t __net, int __type,
|
||||
struct netent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct netent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
extern int __old_getnetbyaddr_r (uint32_t __net, int __type,
|
||||
struct netent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct netent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
|
||||
extern int __getnetbyname_r (__const char *__restrict __name,
|
||||
struct netent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct netent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
extern int __old_getnetbyname_r (__const char *__restrict __name,
|
||||
struct netent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct netent **__restrict __result,
|
||||
int *__restrict __h_errnop);
|
||||
|
||||
extern int __getservent_r (struct servent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct servent **__restrict __result);
|
||||
extern int __old_getservent_r (struct servent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct servent **__restrict __result);
|
||||
|
||||
extern int __getservbyname_r (__const char *__restrict __name,
|
||||
__const char *__restrict __proto,
|
||||
struct servent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct servent **__restrict __result);
|
||||
extern int __old_getservbyname_r (__const char *__restrict __name,
|
||||
__const char *__restrict __proto,
|
||||
struct servent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct servent **__restrict __result);
|
||||
|
||||
extern int __getservbyport_r (int __port,
|
||||
__const char *__restrict __proto,
|
||||
struct servent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct servent **__restrict __result);
|
||||
extern int __old_getservbyport_r (int __port,
|
||||
__const char *__restrict __proto,
|
||||
struct servent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct servent **__restrict __result);
|
||||
|
||||
extern int __getprotoent_r (struct protoent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct protoent **__restrict __result);
|
||||
extern int __old_getprotoent_r (struct protoent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct protoent **__restrict __result);
|
||||
|
||||
extern int __getprotobyname_r (__const char *__restrict __name,
|
||||
struct protoent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct protoent **__restrict __result);
|
||||
extern int __old_getprotobyname_r (__const char *__restrict __name,
|
||||
struct protoent *__restrict __result_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct protoent **__restrict __result);
|
||||
|
||||
extern int __getprotobynumber_r (int __proto,
|
||||
struct protoent *__restrict __res_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct protoent **__restrict __result);
|
||||
extern int __old_getprotobynumber_r (int __proto,
|
||||
struct protoent *__restrict __res_buf,
|
||||
char *__restrict __buf, size_t __buflen,
|
||||
struct protoent **__restrict __result);
|
||||
|
||||
extern int __getnetgrent_r (char **__restrict __hostp,
|
||||
char **__restrict __userp,
|
||||
char **__restrict __domainp,
|
||||
char *__restrict __buffer, size_t __buflen);
|
||||
|
||||
extern int ruserpass (const char *host, const char **aname,
|
||||
const char **apass);
|
||||
|
||||
|
||||
/* The following declarations and definitions have been removed from
|
||||
the public header since we don't want people to use them. */
|
||||
|
||||
#define AI_V4MAPPED 0x0008 /* IPv4-mapped addresses are acceptable. */
|
||||
#define AI_ALL 0x0010 /* Return both IPv4 and IPv6 addresses. */
|
||||
#define AI_ADDRCONFIG 0x0020 /* Use configuration of this host to choose
|
||||
returned address type. */
|
||||
#define AI_DEFAULT (AI_V4MAPPED | AI_ADDRCONFIG)
|
||||
|
||||
#endif /* !_NETDB_H */
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef _PWD_H
|
||||
#include <pwd/pwd.h>
|
||||
|
||||
/* Now define the internal interfaces. */
|
||||
extern int __getpwent_r (struct passwd *__resultbuf, char *__buffer,
|
||||
size_t __buflen, struct passwd **__result);
|
||||
extern int __old_getpwent_r (struct passwd *__resultbuf, char *__buffer,
|
||||
size_t __buflen, struct passwd **__result);
|
||||
extern int __getpwuid_r (__uid_t __uid, struct passwd *__resultbuf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct passwd **__result);
|
||||
extern int __old_getpwuid_r (__uid_t __uid, struct passwd *__resultbuf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct passwd **__result);
|
||||
extern int __getpwnam_r (__const char *__name, struct passwd *__resultbuf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct passwd **__result);
|
||||
extern int __old_getpwnam_r (__const char *__name, struct passwd *__resultbuf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct passwd **__result);
|
||||
extern int __fgetpwent_r (FILE * __stream, struct passwd *__resultbuf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct passwd **__result);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef _RPC_NETDB_H
|
||||
#include <sunrpc/rpc/netdb.h>
|
||||
|
||||
extern int __getrpcbyname_r (__const char *__name, struct rpcent *__result_buf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct rpcent **__result);
|
||||
extern int __old_getrpcbyname_r (__const char *__name,
|
||||
struct rpcent *__result_buf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct rpcent **__result);
|
||||
|
||||
extern int __getrpcbynumber_r (int __number, struct rpcent *__result_buf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct rpcent **__result);
|
||||
extern int __old_getrpcbynumber_r (int __number, struct rpcent *__result_buf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct rpcent **__result);
|
||||
|
||||
extern int __getrpcent_r (struct rpcent *__result_buf, char *__buffer,
|
||||
size_t __buflen, struct rpcent **__result);
|
||||
extern int __old_getrpcent_r (struct rpcent *__result_buf, char *__buffer,
|
||||
size_t __buflen, struct rpcent **__result);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef _SHADOW_H
|
||||
#include <shadow/shadow.h>
|
||||
|
||||
/* Now define the internal interfaces. */
|
||||
extern int __getspent_r (struct spwd *__result_buf, char *__buffer,
|
||||
size_t __buflen, struct spwd **__result);
|
||||
extern int __old_getspent_r (struct spwd *__result_buf, char *__buffer,
|
||||
size_t __buflen, struct spwd **__result);
|
||||
extern int __getspnam_r (__const char *__name, struct spwd *__result_buf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct spwd **__result);
|
||||
extern int __old_getspnam_r (__const char *__name, struct spwd *__result_buf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct spwd **__result);
|
||||
extern int __sgetspent_r (__const char *__string,
|
||||
struct spwd *__result_buf, char *__buffer,
|
||||
size_t __buflen, struct spwd **__result);
|
||||
extern int __fgetspent_r (FILE *__stream, struct spwd *__result_buf,
|
||||
char *__buffer, size_t __buflen,
|
||||
struct spwd **__result);
|
||||
extern int __lckpwdf (void);
|
||||
extern int __ulckpwdf (void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,58 @@
|
||||
/* Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _NIS_NSS_NIS_H
|
||||
#define _NIS_NSS_NIS_H 1
|
||||
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include "nsswitch.h"
|
||||
|
||||
|
||||
/* Convert YP error number to NSS error number. */
|
||||
static enum nss_status yperr2nss_tab[] =
|
||||
{
|
||||
[YPERR_SUCCESS] = NSS_STATUS_SUCCESS,
|
||||
[YPERR_BADARGS] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_RPC] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_DOMAIN] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_MAP] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_KEY] = NSS_STATUS_NOTFOUND,
|
||||
[YPERR_YPERR] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_RESRC] = NSS_STATUS_TRYAGAIN,
|
||||
[YPERR_NOMORE] = NSS_STATUS_NOTFOUND,
|
||||
[YPERR_PMAP] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_YPBIND] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_YPSERV] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_NODOM] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_BADDB] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_VERS] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_ACCESS] = NSS_STATUS_UNAVAIL,
|
||||
[YPERR_BUSY] = NSS_STATUS_TRYAGAIN
|
||||
};
|
||||
#define YPERR_COUNT (sizeof (yperr2nss_tab) / sizeof (yperr2nss_tab[0]))
|
||||
|
||||
static inline enum nss_status
|
||||
yperr2nss (int errval)
|
||||
{
|
||||
if ((unsigned int) errval > YPERR_COUNT)
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
return yperr2nss_tab[errval];
|
||||
}
|
||||
|
||||
#endif /* nis/nss-nis.h */
|
||||
@@ -0,0 +1,769 @@
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <nss.h>
|
||||
#include <glibc-compat/include/grp.h>
|
||||
#include <ctype.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include <string.h>
|
||||
#include <rpcsvc/yp.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
#include <nsswitch.h>
|
||||
|
||||
/* Get the declaration of the parser function. */
|
||||
#define ENTNAME grent
|
||||
#define STRUCTURE group
|
||||
#define EXTERN_PARSER
|
||||
#include "../nss_files/files-parse.c"
|
||||
|
||||
/* Structure for remembering -group members ... */
|
||||
#define BLACKLIST_INITIAL_SIZE 512
|
||||
#define BLACKLIST_INCREMENT 256
|
||||
struct blacklist_t
|
||||
{
|
||||
char *data;
|
||||
int current;
|
||||
int size;
|
||||
};
|
||||
|
||||
struct ent_t
|
||||
{
|
||||
bool_t nis;
|
||||
bool_t nis_first;
|
||||
char *oldkey;
|
||||
int oldkeylen;
|
||||
FILE *stream;
|
||||
struct blacklist_t blacklist;
|
||||
};
|
||||
typedef struct ent_t ent_t;
|
||||
|
||||
static ent_t ext_ent = {0, 0, NULL, 0, NULL, {NULL, 0, 0}};
|
||||
|
||||
/* Protect global state against multiple changers. */
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
static void blacklist_store_name (const char *, ent_t *);
|
||||
static int in_blacklist (const char *, int, ent_t *);
|
||||
|
||||
static enum nss_status
|
||||
internal_setgrent (ent_t *ent)
|
||||
{
|
||||
enum nss_status status = NSS_STATUS_SUCCESS;
|
||||
|
||||
ent->nis = ent->nis_first = 0;
|
||||
|
||||
if (ent->oldkey != NULL)
|
||||
{
|
||||
free (ent->oldkey);
|
||||
ent->oldkey = NULL;
|
||||
ent->oldkeylen = 0;
|
||||
}
|
||||
|
||||
if (ent->blacklist.data != NULL)
|
||||
{
|
||||
ent->blacklist.current = 1;
|
||||
ent->blacklist.data[0] = '|';
|
||||
ent->blacklist.data[1] = '\0';
|
||||
}
|
||||
else
|
||||
ent->blacklist.current = 0;
|
||||
|
||||
if (ent->stream == NULL)
|
||||
{
|
||||
ent->stream = fopen ("/etc/group", "r");
|
||||
|
||||
if (ent->stream == NULL)
|
||||
status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
|
||||
else
|
||||
{
|
||||
/* We have to make sure the file is `closed on exec'. */
|
||||
int result, flags;
|
||||
|
||||
result = flags = fcntl (fileno (ent->stream), F_GETFD, 0);
|
||||
if (result >= 0)
|
||||
{
|
||||
flags |= FD_CLOEXEC;
|
||||
result = fcntl (fileno (ent->stream), F_SETFD, flags);
|
||||
}
|
||||
if (result < 0)
|
||||
{
|
||||
/* Something went wrong. Close the stream and return a
|
||||
failure. */
|
||||
fclose (ent->stream);
|
||||
ent->stream = NULL;
|
||||
status = NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
rewind (ent->stream);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_compat_setgrent (void)
|
||||
{
|
||||
enum nss_status result;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
result = internal_setgrent (&ext_ent);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static enum nss_status
|
||||
internal_endgrent (ent_t *ent)
|
||||
{
|
||||
if (ent->stream != NULL)
|
||||
{
|
||||
fclose (ent->stream);
|
||||
ent->stream = NULL;
|
||||
}
|
||||
|
||||
ent->nis = ent->nis_first = 0;
|
||||
|
||||
if (ent->oldkey != NULL)
|
||||
{
|
||||
free (ent->oldkey);
|
||||
ent->oldkey = NULL;
|
||||
ent->oldkeylen = 0;
|
||||
}
|
||||
|
||||
if (ent->blacklist.data != NULL)
|
||||
{
|
||||
ent->blacklist.current = 1;
|
||||
ent->blacklist.data[0] = '|';
|
||||
ent->blacklist.data[1] = '\0';
|
||||
}
|
||||
else
|
||||
ent->blacklist.current = 0;
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_compat_endgrent (void)
|
||||
{
|
||||
enum nss_status result;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
result = internal_endgrent (&ext_ent);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
getgrent_next_nis (struct group *result, ent_t *ent, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
char *domain;
|
||||
char *outkey, *outval;
|
||||
int outkeylen, outvallen, parse_res;
|
||||
char *p;
|
||||
|
||||
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
|
||||
{
|
||||
ent->nis = 0;
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
char *save_oldkey;
|
||||
int save_oldlen;
|
||||
bool_t save_nis_first;
|
||||
|
||||
if (ent->nis_first)
|
||||
{
|
||||
if (yp_first (domain, "group.byname", &outkey, &outkeylen,
|
||||
&outval, &outvallen) != YPERR_SUCCESS)
|
||||
{
|
||||
ent->nis = 0;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
save_oldkey = ent->oldkey;
|
||||
save_oldlen = ent->oldkeylen;
|
||||
save_nis_first = TRUE;
|
||||
ent->oldkey = outkey;
|
||||
ent->oldkeylen = outkeylen;
|
||||
ent->nis_first = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (yp_next (domain, "group.byname", ent->oldkey, ent->oldkeylen,
|
||||
&outkey, &outkeylen, &outval, &outvallen)
|
||||
!= YPERR_SUCCESS)
|
||||
{
|
||||
ent->nis = 0;
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
save_oldkey = ent->oldkey;
|
||||
save_oldlen = ent->oldkeylen;
|
||||
save_nis_first = FALSE;
|
||||
ent->oldkey = outkey;
|
||||
ent->oldkeylen = outkeylen;
|
||||
}
|
||||
|
||||
/* Copy the found data to our buffer */
|
||||
p = strncpy (buffer, outval, buflen);
|
||||
|
||||
/* ...and free the data. */
|
||||
free (outval);
|
||||
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
|
||||
if ((parse_res = _nss_files_parse_grent (p, result, data, buflen)) == -1)
|
||||
{
|
||||
free (ent->oldkey);
|
||||
ent->oldkey = save_oldkey;
|
||||
ent->oldkeylen = save_oldlen;
|
||||
ent->nis_first = save_nis_first;
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!save_nis_first)
|
||||
free (save_oldkey);
|
||||
}
|
||||
|
||||
if (parse_res &&
|
||||
in_blacklist (result->gr_name, strlen (result->gr_name), ent))
|
||||
parse_res = 0; /* if result->gr_name in blacklist,search next entry */
|
||||
}
|
||||
while (!parse_res);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* This function handle the +group entrys in /etc/group */
|
||||
static enum nss_status
|
||||
getgrnam_plusgroup (const char *name, struct group *result, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
int parse_res;
|
||||
char *domain, *outval, *p;
|
||||
int outvallen;
|
||||
|
||||
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
if (yp_match (domain, "group.byname", name, strlen (name),
|
||||
&outval, &outvallen) != YPERR_SUCCESS)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
p = strncpy (buffer, outval,
|
||||
buflen < (size_t) outvallen ? buflen : (size_t) outvallen);
|
||||
free (outval);
|
||||
while (isspace (*p))
|
||||
p++;
|
||||
if ((parse_res = _nss_files_parse_grent (p, result, data, buflen)) == -1)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
if (parse_res)
|
||||
/* We found the entry. */
|
||||
return NSS_STATUS_SUCCESS;
|
||||
else
|
||||
return NSS_STATUS_RETURN;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
getgrent_next_file (struct group *result, ent_t *ent,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
while (1)
|
||||
{
|
||||
fpos_t pos;
|
||||
int parse_res = 0;
|
||||
char *p;
|
||||
|
||||
do
|
||||
{
|
||||
fgetpos (ent->stream, &pos);
|
||||
buffer[buflen - 1] = '\xff';
|
||||
p = fgets (buffer, buflen, ent->stream);
|
||||
if (p == NULL && feof (ent->stream))
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
if (p == NULL || buffer[buflen - 1] != '\xff')
|
||||
{
|
||||
fsetpos (ent->stream, &pos);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
/* Terminate the line for any case. */
|
||||
buffer[buflen - 1] = '\0';
|
||||
|
||||
/* Skip leading blanks. */
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
}
|
||||
while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */
|
||||
/* Parse the line. If it is invalid, loop to
|
||||
get the next line of the file to parse. */
|
||||
!(parse_res = _nss_files_parse_grent (p, result, data, buflen)));
|
||||
|
||||
if (parse_res == -1)
|
||||
{
|
||||
/* The parser ran out of space. */
|
||||
fsetpos (ent->stream, &pos);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
if (result->gr_name[0] != '+' && result->gr_name[0] != '-')
|
||||
/* This is a real entry. */
|
||||
break;
|
||||
|
||||
/* -group */
|
||||
if (result->gr_name[0] == '-' && result->gr_name[1] != '\0'
|
||||
&& result->gr_name[1] != '@')
|
||||
{
|
||||
blacklist_store_name (&result->gr_name[1], ent);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* +group */
|
||||
if (result->gr_name[0] == '+' && result->gr_name[1] != '\0'
|
||||
&& result->gr_name[1] != '@')
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
/* Store the group in the blacklist for the "+" at the end of
|
||||
/etc/group */
|
||||
blacklist_store_name (&result->gr_name[1], ent);
|
||||
status = getgrnam_plusgroup (&result->gr_name[1], result, buffer,
|
||||
buflen);
|
||||
if (status == NSS_STATUS_SUCCESS) /* We found the entry. */
|
||||
break;
|
||||
else
|
||||
if (status == NSS_STATUS_RETURN /* We couldn't parse the entry */
|
||||
|| status == NSS_STATUS_NOTFOUND) /* No group in NIS */
|
||||
continue;
|
||||
else
|
||||
{
|
||||
if (status == NSS_STATUS_TRYAGAIN)
|
||||
/* The parser ran out of space. */
|
||||
fsetpos (ent->stream, &pos);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* +:... */
|
||||
if (result->gr_name[0] == '+' && result->gr_name[1] == '\0')
|
||||
{
|
||||
ent->nis = TRUE;
|
||||
ent->nis_first = TRUE;
|
||||
|
||||
return getgrent_next_nis (result, ent, buffer, buflen);
|
||||
}
|
||||
}
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static enum nss_status
|
||||
internal_getgrent_r (struct group *gr, ent_t *ent, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
if (ent->nis)
|
||||
{
|
||||
return getgrent_next_nis (gr, ent, buffer, buflen);
|
||||
}
|
||||
else
|
||||
return getgrent_next_file (gr, ent, buffer, buflen);
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_compat_getgrent_r (struct group *grp, char *buffer, size_t buflen)
|
||||
{
|
||||
enum nss_status status = NSS_STATUS_SUCCESS;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
/* Be prepared that the setgrent function was not called before. */
|
||||
if (ext_ent.stream == NULL)
|
||||
status = internal_setgrent (&ext_ent);
|
||||
|
||||
if (status == NSS_STATUS_SUCCESS)
|
||||
status = internal_getgrent_r (grp, &ext_ent, buffer, buflen);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Searches in /etc/group and the NIS/NIS+ map for a special group */
|
||||
static enum nss_status
|
||||
internal_getgrnam_r (const char *name, struct group *result, ent_t *ent,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
while (1)
|
||||
{
|
||||
fpos_t pos;
|
||||
int parse_res = 0;
|
||||
char *p;
|
||||
|
||||
do
|
||||
{
|
||||
fgetpos (ent->stream, &pos);
|
||||
buffer[buflen - 1] = '\xff';
|
||||
p = fgets (buffer, buflen, ent->stream);
|
||||
if (p == NULL && feof (ent->stream))
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
if (p == NULL || buffer[buflen - 1] != '\xff')
|
||||
{
|
||||
fsetpos (ent->stream, &pos);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
/* Terminate the line for any case. */
|
||||
buffer[buflen - 1] = '\0';
|
||||
|
||||
/* Skip leading blanks. */
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
}
|
||||
while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */
|
||||
/* Parse the line. If it is invalid, loop to
|
||||
get the next line of the file to parse. */
|
||||
!(parse_res = _nss_files_parse_grent (p, result, data, buflen)));
|
||||
|
||||
if (parse_res == -1)
|
||||
{
|
||||
/* The parser ran out of space. */
|
||||
fsetpos (ent->stream, &pos);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
/* This is a real entry. */
|
||||
if (result->gr_name[0] != '+' && result->gr_name[0] != '-')
|
||||
{
|
||||
if (strcmp (result->gr_name, name) == 0)
|
||||
return NSS_STATUS_SUCCESS;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
/* -group */
|
||||
if (result->gr_name[0] == '-' && result->gr_name[1] != '\0')
|
||||
{
|
||||
if (strcmp (&result->gr_name[1], name) == 0)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
/* +group */
|
||||
if (result->gr_name[0] == '+' && result->gr_name[1] != '\0')
|
||||
{
|
||||
if (strcmp (name, &result->gr_name[1]) == 0)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
status = getgrnam_plusgroup (name, result, buffer, buflen);
|
||||
if (status == NSS_STATUS_RETURN)
|
||||
/* We couldn't parse the entry */
|
||||
continue;
|
||||
else
|
||||
return status;
|
||||
}
|
||||
}
|
||||
/* +:... */
|
||||
if (result->gr_name[0] == '+' && result->gr_name[1] == '\0')
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
status = getgrnam_plusgroup (name, result, buffer, buflen);
|
||||
if (status == NSS_STATUS_RETURN)
|
||||
/* We couldn't parse the entry */
|
||||
continue;
|
||||
else
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_compat_getgrnam_r (const char *name, struct group *grp,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
ent_t ent = {0, 0, NULL, 0, NULL, {NULL, 0, 0}};
|
||||
enum nss_status status;
|
||||
|
||||
if (name[0] == '-' || name[0] == '+')
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_setgrent (&ent);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
status = internal_getgrnam_r (name, grp, &ent, buffer, buflen);
|
||||
|
||||
internal_endgrent (&ent);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* This function handle the + entry in /etc/group */
|
||||
static enum nss_status
|
||||
getgrgid_plusgroup (gid_t gid, struct group *result, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
int parse_res;
|
||||
char buf[1024];
|
||||
char *domain, *outval, *p;
|
||||
int outvallen;
|
||||
|
||||
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
|
||||
snprintf (buf, sizeof (buf), "%d", gid);
|
||||
|
||||
if (yp_match (domain, "group.bygid", buf, strlen (buf),
|
||||
&outval, &outvallen) != YPERR_SUCCESS)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
p = strncpy (buffer, outval,
|
||||
buflen < (size_t) outvallen ? buflen : (size_t) outvallen);
|
||||
free (outval);
|
||||
while (isspace (*p))
|
||||
p++;
|
||||
if ((parse_res = _nss_files_parse_grent (p, result, data, buflen)) == -1)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
if (parse_res)
|
||||
/* We found the entry. */
|
||||
return NSS_STATUS_SUCCESS;
|
||||
else
|
||||
return NSS_STATUS_RETURN;
|
||||
}
|
||||
|
||||
/* Searches in /etc/group and the NIS/NIS+ map for a special group id */
|
||||
static enum nss_status
|
||||
internal_getgrgid_r (gid_t gid, struct group *result, ent_t *ent,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
while (1)
|
||||
{
|
||||
fpos_t pos;
|
||||
int parse_res = 0;
|
||||
char *p;
|
||||
|
||||
do
|
||||
{
|
||||
fgetpos (ent->stream, &pos);
|
||||
buffer[buflen - 1] = '\xff';
|
||||
p = fgets (buffer, buflen, ent->stream);
|
||||
if (p == NULL && feof (ent->stream))
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
if (p == NULL || buffer[buflen - 1] != '\xff')
|
||||
{
|
||||
fsetpos (ent->stream, &pos);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
/* Terminate the line for any case. */
|
||||
buffer[buflen - 1] = '\0';
|
||||
|
||||
/* Skip leading blanks. */
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
}
|
||||
while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */
|
||||
/* Parse the line. If it is invalid, loop to
|
||||
get the next line of the file to parse. */
|
||||
!(parse_res = _nss_files_parse_grent (p, result, data, buflen)));
|
||||
|
||||
if (parse_res == -1)
|
||||
{
|
||||
/* The parser ran out of space. */
|
||||
fsetpos (ent->stream, &pos);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
/* This is a real entry. */
|
||||
if (result->gr_name[0] != '+' && result->gr_name[0] != '-')
|
||||
{
|
||||
if (result->gr_gid == gid)
|
||||
return NSS_STATUS_SUCCESS;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
/* -group */
|
||||
if (result->gr_name[0] == '-' && result->gr_name[1] != '\0')
|
||||
{
|
||||
blacklist_store_name (&result->gr_name[1], ent);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* +group */
|
||||
if (result->gr_name[0] == '+' && result->gr_name[1] != '\0')
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
/* Store the group in the blacklist for the "+" at the end of
|
||||
/etc/group */
|
||||
blacklist_store_name (&result->gr_name[1], ent);
|
||||
status = getgrnam_plusgroup (&result->gr_name[1], result, buffer,
|
||||
buflen);
|
||||
if (status == NSS_STATUS_SUCCESS && result->gr_gid == gid)
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
/* +:... */
|
||||
if (result->gr_name[0] == '+' && result->gr_name[1] == '\0')
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
status = getgrgid_plusgroup (gid, result, buffer, buflen);
|
||||
if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
else
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_compat_getgrgid_r (gid_t gid, struct group *grp,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
ent_t ent = {0, 0, NULL, 0, NULL, {NULL, 0, 0}};
|
||||
enum nss_status status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_setgrent (&ent);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
status = internal_getgrgid_r (gid, grp, &ent, buffer, buflen);
|
||||
|
||||
internal_endgrent (&ent);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* Support routines for remembering -@netgroup and -user entries.
|
||||
The names are stored in a single string with `|' as separator. */
|
||||
static void
|
||||
blacklist_store_name (const char *name, ent_t *ent)
|
||||
{
|
||||
int namelen = strlen (name);
|
||||
char *tmp;
|
||||
|
||||
/* first call, setup cache */
|
||||
if (ent->blacklist.size == 0)
|
||||
{
|
||||
ent->blacklist.size = MAX (BLACKLIST_INITIAL_SIZE, 2 * namelen);
|
||||
ent->blacklist.data = malloc (ent->blacklist.size);
|
||||
if (ent->blacklist.data == NULL)
|
||||
return;
|
||||
ent->blacklist.data[0] = '|';
|
||||
ent->blacklist.data[1] = '\0';
|
||||
ent->blacklist.current = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (in_blacklist (name, namelen, ent))
|
||||
return; /* no duplicates */
|
||||
|
||||
if (ent->blacklist.current + namelen + 1 >= ent->blacklist.size)
|
||||
{
|
||||
ent->blacklist.size += MAX (BLACKLIST_INCREMENT, 2 * namelen);
|
||||
tmp = realloc (ent->blacklist.data, ent->blacklist.size);
|
||||
if (tmp == NULL)
|
||||
{
|
||||
free (ent->blacklist.data);
|
||||
ent->blacklist.size = 0;
|
||||
return;
|
||||
}
|
||||
ent->blacklist.data = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
tmp = stpcpy (ent->blacklist.data + ent->blacklist.current, name);
|
||||
*tmp++ = '|';
|
||||
*tmp = '\0';
|
||||
ent->blacklist.current += namelen + 1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* returns TRUE if ent->blacklist contains name, else FALSE */
|
||||
static bool_t
|
||||
in_blacklist (const char *name, int namelen, ent_t *ent)
|
||||
{
|
||||
char buf[namelen + 3];
|
||||
char *cp;
|
||||
|
||||
if (ent->blacklist.data == NULL)
|
||||
return FALSE;
|
||||
|
||||
buf[0] = '|';
|
||||
cp = stpcpy (&buf[1], name);
|
||||
*cp++= '|';
|
||||
*cp = '\0';
|
||||
return strstr (ent->blacklist.data, buf) != NULL;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,915 @@
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <nss.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <glibc-compat/include/netdb.h>
|
||||
#include <glibc-compat/include/shadow.h>
|
||||
#include <string.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include <rpcsvc/yp.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
#include <nsswitch.h>
|
||||
|
||||
#include "netgroup.h"
|
||||
|
||||
/* Get the declaration of the parser function. */
|
||||
#define ENTNAME spent
|
||||
#define STRUCTURE spwd
|
||||
#define EXTERN_PARSER
|
||||
#include "../nss_files/files-parse.c"
|
||||
|
||||
/* Structure for remembering -@netgroup and -user members ... */
|
||||
#define BLACKLIST_INITIAL_SIZE 512
|
||||
#define BLACKLIST_INCREMENT 256
|
||||
struct blacklist_t
|
||||
{
|
||||
char *data;
|
||||
int current;
|
||||
int size;
|
||||
};
|
||||
|
||||
struct ent_t
|
||||
{
|
||||
bool_t netgroup;
|
||||
bool_t nis;
|
||||
bool_t first;
|
||||
char *oldkey;
|
||||
int oldkeylen;
|
||||
FILE *stream;
|
||||
struct blacklist_t blacklist;
|
||||
struct spwd pwd;
|
||||
struct __netgrent netgrdata;
|
||||
};
|
||||
typedef struct ent_t ent_t;
|
||||
|
||||
static ent_t ext_ent = {0, 0, 0, NULL, 0, NULL, {NULL, 0, 0},
|
||||
{NULL, NULL, 0, 0, 0, 0, 0, 0, 0}};
|
||||
|
||||
/* Protect global state against multiple changers. */
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
static void blacklist_store_name (const char *, ent_t *);
|
||||
static int in_blacklist (const char *, int, ent_t *);
|
||||
|
||||
static void
|
||||
give_spwd_free (struct spwd *pwd)
|
||||
{
|
||||
if (pwd->sp_namp != NULL)
|
||||
free (pwd->sp_namp);
|
||||
if (pwd->sp_pwdp != NULL)
|
||||
free (pwd->sp_pwdp);
|
||||
|
||||
memset (pwd, '\0', sizeof (struct spwd));
|
||||
}
|
||||
|
||||
static int
|
||||
spwd_need_buflen (struct spwd *pwd)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
if (pwd->sp_pwdp != NULL)
|
||||
len += strlen (pwd->sp_pwdp) + 1;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_spwd_changes (struct spwd *dest, struct spwd *src,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
if (src->sp_pwdp != NULL && strlen (src->sp_pwdp))
|
||||
{
|
||||
if (buffer == NULL)
|
||||
dest->sp_pwdp = strdup (src->sp_pwdp);
|
||||
else if (dest->sp_pwdp &&
|
||||
strlen (dest->sp_pwdp) >= strlen (src->sp_pwdp))
|
||||
strcpy (dest->sp_pwdp, src->sp_pwdp);
|
||||
else
|
||||
{
|
||||
dest->sp_pwdp = buffer;
|
||||
strcpy (dest->sp_pwdp, src->sp_pwdp);
|
||||
buffer += strlen (dest->sp_pwdp) + 1;
|
||||
buflen = buflen - (strlen (dest->sp_pwdp) + 1);
|
||||
}
|
||||
}
|
||||
if (src->sp_lstchg != 0)
|
||||
dest->sp_lstchg = src->sp_lstchg;
|
||||
if (src->sp_min != 0)
|
||||
dest->sp_min = src->sp_min;
|
||||
if (src->sp_max != 0)
|
||||
dest->sp_max = src->sp_max;
|
||||
if (src->sp_warn != 0)
|
||||
dest->sp_warn = src->sp_warn;
|
||||
if (src->sp_inact != 0)
|
||||
dest->sp_inact = src->sp_inact;
|
||||
if (src->sp_expire != 0)
|
||||
dest->sp_expire = src->sp_expire;
|
||||
if (src->sp_flag != 0)
|
||||
dest->sp_flag = src->sp_flag;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
internal_setspent (ent_t *ent)
|
||||
{
|
||||
enum nss_status status = NSS_STATUS_SUCCESS;
|
||||
|
||||
ent->nis = ent->first = ent->netgroup = 0;
|
||||
|
||||
/* If something was left over free it. */
|
||||
if (ent->netgroup)
|
||||
__internal_endnetgrent (&ent->netgrdata);
|
||||
|
||||
if (ent->oldkey != NULL)
|
||||
{
|
||||
free (ent->oldkey);
|
||||
ent->oldkey = NULL;
|
||||
ent->oldkeylen = 0;
|
||||
}
|
||||
|
||||
if (ent->blacklist.data != NULL)
|
||||
{
|
||||
ent->blacklist.current = 1;
|
||||
ent->blacklist.data[0] = '|';
|
||||
ent->blacklist.data[1] = '\0';
|
||||
}
|
||||
else
|
||||
ent->blacklist.current = 0;
|
||||
|
||||
if (ent->stream == NULL)
|
||||
{
|
||||
ent->stream = fopen ("/etc/shadow", "r");
|
||||
|
||||
if (ent->stream == NULL)
|
||||
status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
|
||||
else
|
||||
{
|
||||
/* We have to make sure the file is `closed on exec'. */
|
||||
int result, flags;
|
||||
|
||||
result = flags = fcntl (fileno (ent->stream), F_GETFD, 0);
|
||||
if (result >= 0)
|
||||
{
|
||||
flags |= FD_CLOEXEC;
|
||||
result = fcntl (fileno (ent->stream), F_SETFD, flags);
|
||||
}
|
||||
if (result < 0)
|
||||
{
|
||||
/* Something went wrong. Close the stream and return a
|
||||
failure. */
|
||||
fclose (ent->stream);
|
||||
ent->stream = NULL;
|
||||
status = NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
rewind (ent->stream);
|
||||
|
||||
give_spwd_free (&ent->pwd);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_compat_setspent (void)
|
||||
{
|
||||
enum nss_status result;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
result = internal_setspent (&ext_ent);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static enum nss_status
|
||||
internal_endspent (ent_t *ent)
|
||||
{
|
||||
if (ent->stream != NULL)
|
||||
{
|
||||
fclose (ent->stream);
|
||||
ent->stream = NULL;
|
||||
}
|
||||
|
||||
if (ent->netgroup)
|
||||
__internal_endnetgrent (&ent->netgrdata);
|
||||
|
||||
ent->nis = ent->first = ent->netgroup = 0;
|
||||
|
||||
if (ent->oldkey != NULL)
|
||||
{
|
||||
free (ent->oldkey);
|
||||
ent->oldkey = NULL;
|
||||
ent->oldkeylen = 0;
|
||||
}
|
||||
|
||||
if (ent->blacklist.data != NULL)
|
||||
{
|
||||
ent->blacklist.current = 1;
|
||||
ent->blacklist.data[0] = '|';
|
||||
ent->blacklist.data[1] = '\0';
|
||||
}
|
||||
else
|
||||
ent->blacklist.current = 0;
|
||||
|
||||
give_spwd_free (&ent->pwd);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_compat_endspent (void)
|
||||
{
|
||||
enum nss_status result;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
result = internal_endspent (&ext_ent);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static enum nss_status
|
||||
getspent_next_nis_netgr (const char *name, struct spwd *result, ent_t *ent,
|
||||
char *group, char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
char *ypdomain, *host, *user, *domain, *outval, *p, *p2;
|
||||
int status, outvallen;
|
||||
size_t p2len;
|
||||
|
||||
if (yp_get_default_domain (&ypdomain) != YPERR_SUCCESS)
|
||||
{
|
||||
ent->netgroup = 0;
|
||||
ent->first = 0;
|
||||
give_spwd_free (&ent->pwd);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
if (ent->first == TRUE)
|
||||
{
|
||||
bzero (&ent->netgrdata, sizeof (struct __netgrent));
|
||||
__internal_setnetgrent (group, &ent->netgrdata);
|
||||
ent->first = FALSE;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
char *saved_cursor;
|
||||
int parse_res;
|
||||
|
||||
saved_cursor = ent->netgrdata.cursor;
|
||||
status = __internal_getnetgrent_r (&host, &user, &domain,
|
||||
&ent->netgrdata, buffer, buflen,
|
||||
&errno);
|
||||
if (status != 1)
|
||||
{
|
||||
__internal_endnetgrent (&ent->netgrdata);
|
||||
ent->netgroup = 0;
|
||||
give_spwd_free (&ent->pwd);
|
||||
return NSS_STATUS_RETURN;
|
||||
}
|
||||
|
||||
if (user == NULL || user[0] == '-')
|
||||
continue;
|
||||
|
||||
if (domain != NULL && strcmp (ypdomain, domain) != 0)
|
||||
continue;
|
||||
|
||||
/* If name != NULL, we are called from getpwnam */
|
||||
if (name != NULL)
|
||||
if (strcmp (user, name) != 0)
|
||||
continue;
|
||||
|
||||
if (yp_match (ypdomain, "shadow.byname", user,
|
||||
strlen (user), &outval, &outvallen)
|
||||
!= YPERR_SUCCESS)
|
||||
continue;
|
||||
|
||||
p2len = spwd_need_buflen (&ent->pwd);
|
||||
if (p2len > buflen)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
p2 = buffer + (buflen - p2len);
|
||||
buflen -= p2len;
|
||||
p = strncpy (buffer, outval, buflen);
|
||||
while (isspace (*p))
|
||||
p++;
|
||||
free (outval);
|
||||
if ((parse_res = _nss_files_parse_spent (p, result, data, buflen)) == -1)
|
||||
{
|
||||
ent->netgrdata.cursor = saved_cursor;
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
if (parse_res)
|
||||
{
|
||||
/* Store the User in the blacklist for the "+" at the end of
|
||||
/etc/passwd */
|
||||
blacklist_store_name (result->sp_namp, ent);
|
||||
copy_spwd_changes (result, &ent->pwd, p2, p2len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
getspent_next_nis (struct spwd *result, ent_t *ent,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
char *domain, *outkey, *outval, *p, *p2;
|
||||
int outkeylen, outvallen, parse_res;
|
||||
size_t p2len;
|
||||
|
||||
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
|
||||
{
|
||||
ent->nis = 0;
|
||||
give_spwd_free (&ent->pwd);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
p2len = spwd_need_buflen (&ent->pwd);
|
||||
if (p2len > buflen)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
p2 = buffer + (buflen - p2len);
|
||||
buflen -= p2len;
|
||||
do
|
||||
{
|
||||
bool_t saved_first;
|
||||
char *saved_oldkey;
|
||||
int saved_oldlen;
|
||||
|
||||
if (ent->first)
|
||||
{
|
||||
if (yp_first (domain, "shadow.byname", &outkey, &outkeylen,
|
||||
&outval, &outvallen) != YPERR_SUCCESS)
|
||||
{
|
||||
ent->nis = 0;
|
||||
give_spwd_free (&ent->pwd);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
saved_first = TRUE;
|
||||
saved_oldkey = ent->oldkey;
|
||||
saved_oldlen = ent->oldkeylen;
|
||||
ent->oldkey = outkey;
|
||||
ent->oldkeylen = outkeylen;
|
||||
ent->first = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (yp_next (domain, "shadow.byname", ent->oldkey, ent->oldkeylen,
|
||||
&outkey, &outkeylen, &outval, &outvallen)
|
||||
!= YPERR_SUCCESS)
|
||||
{
|
||||
ent->nis = 0;
|
||||
give_spwd_free (&ent->pwd);
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
saved_first = FALSE;
|
||||
saved_oldkey = ent->oldkey;
|
||||
saved_oldlen = ent->oldkeylen;
|
||||
ent->oldkey = outkey;
|
||||
ent->oldkeylen = outkeylen;
|
||||
}
|
||||
|
||||
/* Copy the found data to our buffer */
|
||||
p = strncpy (buffer, outval, buflen);
|
||||
|
||||
/* ...and free the data. */
|
||||
free (outval);
|
||||
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
if ((parse_res = _nss_files_parse_spent (p, result, data, buflen)) == -1)
|
||||
{
|
||||
free (ent->oldkey);
|
||||
ent->oldkey = saved_oldkey;
|
||||
ent->oldkeylen = saved_oldlen;
|
||||
ent->first = saved_first;
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!saved_first)
|
||||
free (saved_oldkey);
|
||||
}
|
||||
if (parse_res &&
|
||||
in_blacklist (result->sp_namp, strlen (result->sp_namp), ent))
|
||||
parse_res = 0;
|
||||
}
|
||||
while (!parse_res);
|
||||
|
||||
copy_spwd_changes (result, &ent->pwd, p2, p2len);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* This function handle the +user entrys in /etc/shadow */
|
||||
static enum nss_status
|
||||
getspnam_plususer (const char *name, struct spwd *result, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
struct spwd pwd;
|
||||
int parse_res;
|
||||
char *p;
|
||||
size_t plen;
|
||||
char *domain, *outval, *ptr;
|
||||
int outvallen;
|
||||
|
||||
|
||||
memset (&pwd, '\0', sizeof (struct spwd));
|
||||
|
||||
copy_spwd_changes (&pwd, result, NULL, 0);
|
||||
|
||||
plen = spwd_need_buflen (&pwd);
|
||||
if (plen > buflen)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
p = buffer + (buflen - plen);
|
||||
buflen -= plen;
|
||||
|
||||
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
if (yp_match (domain, "shadow.byname", name, strlen (name),
|
||||
&outval, &outvallen) != YPERR_SUCCESS)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
ptr = strncpy (buffer, outval, buflen < (size_t) outvallen ?
|
||||
buflen : (size_t) outvallen);
|
||||
buffer[buflen < (size_t) outvallen ? buflen : (size_t) outvallen] = '\0';
|
||||
free (outval);
|
||||
while (isspace (*ptr))
|
||||
ptr++;
|
||||
if ((parse_res = _nss_files_parse_spent (ptr, result, data, buflen)) == -1)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
if (parse_res)
|
||||
{
|
||||
copy_spwd_changes (result, &pwd, p, plen);
|
||||
give_spwd_free (&pwd);
|
||||
/* We found the entry. */
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Give buffer the old len back */
|
||||
buflen += plen;
|
||||
give_spwd_free (&pwd);
|
||||
}
|
||||
return NSS_STATUS_RETURN;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
getspent_next_file (struct spwd *result, ent_t *ent,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
while (1)
|
||||
{
|
||||
fpos_t pos;
|
||||
int parse_res = 0;
|
||||
char *p;
|
||||
|
||||
do
|
||||
{
|
||||
fgetpos (ent->stream, &pos);
|
||||
buffer[buflen - 1] = '\xff';
|
||||
p = fgets (buffer, buflen, ent->stream);
|
||||
if (p == NULL && feof (ent->stream))
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
if (p == NULL || buffer[buflen - 1] != '\xff')
|
||||
{
|
||||
fsetpos (ent->stream, &pos);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
/* Terminate the line for any case. */
|
||||
buffer[buflen - 1] = '\0';
|
||||
|
||||
/* Skip leading blanks. */
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
}
|
||||
while (*p == '\0' || *p == '#' /* Ignore empty and comment lines. */
|
||||
/* Parse the line. If it is invalid, loop to
|
||||
get the next line of the file to parse. */
|
||||
|| !(parse_res = _nss_files_parse_spent (p, result, data,
|
||||
buflen)));
|
||||
|
||||
if (parse_res == -1)
|
||||
{
|
||||
/* The parser ran out of space. */
|
||||
fsetpos (ent->stream, &pos);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
if (result->sp_namp[0] != '+' && result->sp_namp[0] != '-')
|
||||
/* This is a real entry. */
|
||||
break;
|
||||
|
||||
/* -@netgroup */
|
||||
if (result->sp_namp[0] == '-' && result->sp_namp[1] == '@'
|
||||
&& result->sp_namp[2] != '\0')
|
||||
{
|
||||
char buf2[1024];
|
||||
char *user, *host, *domain;
|
||||
struct __netgrent netgrdata;
|
||||
|
||||
bzero (&netgrdata, sizeof (struct __netgrent));
|
||||
__internal_setnetgrent (&result->sp_namp[2], &netgrdata);
|
||||
while (__internal_getnetgrent_r (&host, &user, &domain,
|
||||
&netgrdata, buf2, sizeof (buf2),
|
||||
&errno))
|
||||
{
|
||||
if (user != NULL && user[0] != '-')
|
||||
blacklist_store_name (user, ent);
|
||||
}
|
||||
__internal_endnetgrent (&netgrdata);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* +@netgroup */
|
||||
if (result->sp_namp[0] == '+' && result->sp_namp[1] == '@'
|
||||
&& result->sp_namp[2] != '\0')
|
||||
{
|
||||
int status;
|
||||
|
||||
ent->netgroup = TRUE;
|
||||
ent->first = TRUE;
|
||||
copy_spwd_changes (&ent->pwd, result, NULL, 0);
|
||||
|
||||
status = getspent_next_nis_netgr (NULL, result, ent,
|
||||
&result->sp_namp[2],
|
||||
buffer, buflen);
|
||||
if (status == NSS_STATUS_RETURN)
|
||||
continue;
|
||||
else
|
||||
return status;
|
||||
}
|
||||
|
||||
/* -user */
|
||||
if (result->sp_namp[0] == '-' && result->sp_namp[1] != '\0'
|
||||
&& result->sp_namp[1] != '@')
|
||||
{
|
||||
blacklist_store_name (&result->sp_namp[1], ent);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* +user */
|
||||
if (result->sp_namp[0] == '+' && result->sp_namp[1] != '\0'
|
||||
&& result->sp_namp[1] != '@')
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
/* Store the User in the blacklist for the "+" at the end of
|
||||
/etc/passwd */
|
||||
blacklist_store_name (&result->sp_namp[1], ent);
|
||||
status = getspnam_plususer (&result->sp_namp[1], result, buffer,
|
||||
buflen);
|
||||
if (status == NSS_STATUS_SUCCESS) /* We found the entry. */
|
||||
break;
|
||||
else
|
||||
if (status == NSS_STATUS_RETURN /* We couldn't parse the entry */
|
||||
|| status == NSS_STATUS_NOTFOUND) /* entry doesn't exist */
|
||||
continue;
|
||||
else
|
||||
{
|
||||
if (status == NSS_STATUS_TRYAGAIN)
|
||||
fsetpos (ent->stream, &pos);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* +:... */
|
||||
if (result->sp_namp[0] == '+' && result->sp_namp[1] == '\0')
|
||||
{
|
||||
ent->nis = TRUE;
|
||||
ent->first = TRUE;
|
||||
copy_spwd_changes (&ent->pwd, result, NULL, 0);
|
||||
|
||||
return getspent_next_nis (result, ent, buffer, buflen);
|
||||
}
|
||||
}
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static enum nss_status
|
||||
internal_getspent_r (struct spwd *pw, ent_t *ent,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
if (ent->netgroup)
|
||||
{
|
||||
int status;
|
||||
|
||||
/* We are searching members in a netgroup */
|
||||
/* Since this is not the first call, we don't need the group name */
|
||||
status = getspent_next_nis_netgr (NULL, pw, ent, NULL, buffer, buflen);
|
||||
if (status == NSS_STATUS_RETURN)
|
||||
return getspent_next_file (pw, ent, buffer, buflen);
|
||||
else
|
||||
return status;
|
||||
}
|
||||
else
|
||||
if (ent->nis)
|
||||
{
|
||||
return getspent_next_nis (pw, ent, buffer, buflen);
|
||||
}
|
||||
else
|
||||
return getspent_next_file (pw, ent, buffer, buflen);
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_compat_getspent_r (struct spwd *pwd, char *buffer, size_t buflen)
|
||||
{
|
||||
enum nss_status status = NSS_STATUS_SUCCESS;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
if (ext_ent.stream == NULL)
|
||||
status = internal_setspent (&ext_ent);
|
||||
|
||||
if (status == NSS_STATUS_SUCCESS)
|
||||
status = internal_getspent_r (pwd, &ext_ent, buffer, buflen);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Searches in /etc/passwd and the NIS/NIS+ map for a special user */
|
||||
static enum nss_status
|
||||
internal_getspnam_r (const char *name, struct spwd *result, ent_t *ent,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
|
||||
while (1)
|
||||
{
|
||||
fpos_t pos;
|
||||
char *p;
|
||||
int parse_res;
|
||||
|
||||
do
|
||||
{
|
||||
fgetpos (ent->stream, &pos);
|
||||
buffer[buflen - 1] = '\xff';
|
||||
p = fgets (buffer, buflen, ent->stream);
|
||||
if (p == NULL && feof (ent->stream))
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
if (p == NULL || buffer[buflen - 1] != '\xff')
|
||||
{
|
||||
fsetpos (ent->stream, &pos);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
/* Terminate the line for any case. */
|
||||
buffer[buflen - 1] = '\0';
|
||||
|
||||
/* Skip leading blanks. */
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
}
|
||||
while (*p == '\0' || *p == '#' || /* Ignore empty and comment lines. */
|
||||
/* Parse the line. If it is invalid, loop to
|
||||
get the next line of the file to parse. */
|
||||
!(parse_res = _nss_files_parse_spent (p, result, data, buflen)));
|
||||
|
||||
if (parse_res == -1)
|
||||
{
|
||||
/* The parser ran out of space. */
|
||||
fsetpos (ent->stream, &pos);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
/* This is a real entry. */
|
||||
if (result->sp_namp[0] != '+' && result->sp_namp[0] != '-')
|
||||
{
|
||||
if (strcmp (result->sp_namp, name) == 0)
|
||||
return NSS_STATUS_SUCCESS;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
/* -@netgroup */
|
||||
if (result->sp_namp[0] == '-' && result->sp_namp[1] == '@'
|
||||
&& result->sp_namp[2] != '\0')
|
||||
{
|
||||
char buf2[1024];
|
||||
char *user, *host, *domain;
|
||||
struct __netgrent netgrdata;
|
||||
|
||||
bzero (&netgrdata, sizeof (struct __netgrent));
|
||||
__internal_setnetgrent (&result->sp_namp[2], &netgrdata);
|
||||
while (__internal_getnetgrent_r (&host, &user, &domain,
|
||||
&netgrdata, buf2, sizeof (buf2),
|
||||
&errno))
|
||||
{
|
||||
if (user != NULL && user[0] != '-')
|
||||
if (strcmp (user, name) == 0)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
__internal_endnetgrent (&netgrdata);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* +@netgroup */
|
||||
if (result->sp_namp[0] == '+' && result->sp_namp[1] == '@'
|
||||
&& result->sp_namp[2] != '\0')
|
||||
{
|
||||
char buf[strlen (result->sp_namp)];
|
||||
int status;
|
||||
|
||||
strcpy (buf, &result->sp_namp[2]);
|
||||
ent->netgroup = TRUE;
|
||||
ent->first = TRUE;
|
||||
copy_spwd_changes (&ent->pwd, result, NULL, 0);
|
||||
|
||||
do
|
||||
{
|
||||
status = getspent_next_nis_netgr (name, result, ent, buf,
|
||||
buffer, buflen);
|
||||
if (status == NSS_STATUS_RETURN)
|
||||
continue;
|
||||
|
||||
if (status == NSS_STATUS_SUCCESS &&
|
||||
strcmp (result->sp_namp, name) == 0)
|
||||
return NSS_STATUS_SUCCESS;
|
||||
} while (status == NSS_STATUS_SUCCESS);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* -user */
|
||||
if (result->sp_namp[0] == '-' && result->sp_namp[1] != '\0'
|
||||
&& result->sp_namp[1] != '@')
|
||||
{
|
||||
if (strcmp (&result->sp_namp[1], name) == 0)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
/* +user */
|
||||
if (result->sp_namp[0] == '+' && result->sp_namp[1] != '\0'
|
||||
&& result->sp_namp[1] != '@')
|
||||
{
|
||||
if (strcmp (name, &result->sp_namp[1]) == 0)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
status = getspnam_plususer (name, result, buffer, buflen);
|
||||
if (status == NSS_STATUS_RETURN)
|
||||
/* We couldn't parse the entry */
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
else
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* +:... */
|
||||
if (result->sp_namp[0] == '+' && result->sp_namp[1] == '\0')
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
status = getspnam_plususer (name, result, buffer, buflen);
|
||||
if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
else
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_compat_getspnam_r (const char *name, struct spwd *pwd,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
ent_t ent = {0, 0, 0, NULL, 0, NULL, {NULL, 0, 0},
|
||||
{NULL, NULL, 0, 0, 0, 0, 0, 0, 0}};
|
||||
enum nss_status status;
|
||||
|
||||
if (name[0] == '-' || name[0] == '+')
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
status = internal_setspent (&ent);
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
status = internal_getspnam_r (name, pwd, &ent, buffer, buflen);
|
||||
|
||||
internal_endspent (&ent);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Support routines for remembering -@netgroup and -user entries.
|
||||
The names are stored in a single string with `|' as separator. */
|
||||
static void
|
||||
blacklist_store_name (const char *name, ent_t *ent)
|
||||
{
|
||||
int namelen = strlen (name);
|
||||
char *tmp;
|
||||
|
||||
/* first call, setup cache */
|
||||
if (ent->blacklist.size == 0)
|
||||
{
|
||||
ent->blacklist.size = MAX (BLACKLIST_INITIAL_SIZE, 2 * namelen);
|
||||
ent->blacklist.data = malloc (ent->blacklist.size);
|
||||
if (ent->blacklist.data == NULL)
|
||||
return;
|
||||
ent->blacklist.data[0] = '|';
|
||||
ent->blacklist.data[1] = '\0';
|
||||
ent->blacklist.current = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (in_blacklist (name, namelen, ent))
|
||||
return; /* no duplicates */
|
||||
|
||||
if (ent->blacklist.current + namelen + 1 >= ent->blacklist.size)
|
||||
{
|
||||
ent->blacklist.size += MAX (BLACKLIST_INCREMENT, 2 * namelen);
|
||||
tmp = realloc (ent->blacklist.data, ent->blacklist.size);
|
||||
if (tmp == NULL)
|
||||
{
|
||||
free (ent->blacklist.data);
|
||||
ent->blacklist.size = 0;
|
||||
return;
|
||||
}
|
||||
ent->blacklist.data = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
tmp = stpcpy (ent->blacklist.data + ent->blacklist.current, name);
|
||||
*tmp++ = '|';
|
||||
*tmp = '\0';
|
||||
ent->blacklist.current += namelen + 1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Returns TRUE if ent->blacklist contains name, else FALSE. */
|
||||
static bool_t
|
||||
in_blacklist (const char *name, int namelen, ent_t *ent)
|
||||
{
|
||||
char buf[namelen + 3];
|
||||
char *cp;
|
||||
|
||||
if (ent->blacklist.data == NULL)
|
||||
return FALSE;
|
||||
|
||||
buf[0] = '|';
|
||||
cp = stpcpy (&buf[1], name);
|
||||
*cp++= '|';
|
||||
*cp = '\0';
|
||||
return strstr (ent->blacklist.data, buf) != NULL;
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
/* Common code for DB-based databases in nss_db module.
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <fcntl.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include "nsswitch.h"
|
||||
#include "nss_db.h"
|
||||
|
||||
/* These symbols are defined by the including source file:
|
||||
|
||||
ENTNAME -- database name of the structure and functions (hostent, pwent).
|
||||
STRUCTURE -- struct name, define only if not ENTNAME (passwd, group).
|
||||
DATABASE -- database file name, ("hosts", "passwd")
|
||||
|
||||
NEED_H_ERRNO - defined iff an arg `int *herrnop' is used.
|
||||
*/
|
||||
|
||||
#define ENTNAME_r CONCAT(ENTNAME,_r)
|
||||
|
||||
#include <paths.h>
|
||||
#define DBFILE _PATH_VARDB DATABASE ".db"
|
||||
|
||||
#ifdef NEED_H_ERRNO
|
||||
#define H_ERRNO_PROTO , int *herrnop
|
||||
#define H_ERRNO_ARG , herrnop
|
||||
#define H_ERRNO_SET(val) (*herrnop = (val))
|
||||
#else
|
||||
#define H_ERRNO_PROTO
|
||||
#define H_ERRNO_ARG
|
||||
#define H_ERRNO_SET(val) ((void) 0)
|
||||
#endif
|
||||
|
||||
/* Locks the static variables in this file. */
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
/* Maintenance of the shared handle open on the database. */
|
||||
|
||||
static NSS_DB *db;
|
||||
static int keep_db;
|
||||
static int entidx;
|
||||
|
||||
|
||||
/* Open the database. */
|
||||
enum nss_status
|
||||
CONCAT(_nss_db_set,ENTNAME) (int stayopen)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_setent (DBFILE, &db);
|
||||
|
||||
/* Remember STAYOPEN flag. */
|
||||
if (db != NULL)
|
||||
keep_db |= stayopen;
|
||||
/* Reset the sequential index. */
|
||||
entidx = 0;
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* Close it again. */
|
||||
enum nss_status
|
||||
CONCAT(_nss_db_end,ENTNAME) (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
internal_endent (&db);
|
||||
|
||||
/* Reset STAYOPEN flag. */
|
||||
keep_db = 0;
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Do a database lookup for KEY. */
|
||||
static enum nss_status
|
||||
lookup (DBT *key, struct STRUCTURE *result,
|
||||
void *buffer, int buflen H_ERRNO_PROTO)
|
||||
{
|
||||
char *p;
|
||||
enum nss_status status;
|
||||
int err;
|
||||
DBT value;
|
||||
|
||||
/* Open the database. */
|
||||
if (db == NULL)
|
||||
{
|
||||
status = internal_setent (DBFILE, &db);
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
H_ERRNO_SET (NETDB_INTERNAL);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* Succeed iff it matches a value that parses correctly. */
|
||||
value.flags = 0;
|
||||
err = DL_CALL_FCT (db->get, (db->db, NULL, key, &value, 0));
|
||||
if (err != 0)
|
||||
{
|
||||
if (err == db_notfound)
|
||||
{
|
||||
H_ERRNO_SET (HOST_NOT_FOUND);
|
||||
status = NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
else
|
||||
{
|
||||
H_ERRNO_SET (NETDB_INTERNAL);
|
||||
status = NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
}
|
||||
else if (buflen < value.size)
|
||||
{
|
||||
/* No room to copy the data to. */
|
||||
__set_errno (ERANGE);
|
||||
H_ERRNO_SET (NETDB_INTERNAL);
|
||||
status = NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy the result to a safe place. */
|
||||
p = (char *) memcpy (buffer, value.data, value.size);
|
||||
|
||||
/* Skip leading blanks. */
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
|
||||
err = parse_line (p, result, buffer, buflen);
|
||||
|
||||
if (err == 0)
|
||||
{
|
||||
/* If the key begins with '0' we are trying to get the next
|
||||
entry. We want to ignore unparsable lines in this case. */
|
||||
if (((char *) key->data)[0] == '0')
|
||||
{
|
||||
/* Super magical return value. We need to tell our caller
|
||||
that it should continue looping. This value cannot
|
||||
happen in other cases. */
|
||||
status = NSS_STATUS_RETURN;
|
||||
}
|
||||
else
|
||||
{
|
||||
H_ERRNO_SET (HOST_NOT_FOUND);
|
||||
status = NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
}
|
||||
else if (err < 0)
|
||||
{
|
||||
H_ERRNO_SET (NETDB_INTERNAL);
|
||||
status = NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
else
|
||||
status = NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (! keep_db)
|
||||
internal_endent (&db);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* Macro for defining lookup functions for this DB-based database.
|
||||
|
||||
NAME is the name of the lookup; e.g. `pwnam'.
|
||||
|
||||
KEYPATTERN gives `printf' args to construct a key string;
|
||||
e.g. `(".%s", name)'.
|
||||
|
||||
KEYSIZE gives the allocation size of a buffer to construct it in;
|
||||
e.g. `1 + strlen (name)'.
|
||||
|
||||
PROTO describes the arguments for the lookup key;
|
||||
e.g. `const char *name'.
|
||||
|
||||
BREAK_IF_MATCH is ignored, but used by ../nss_files/files-XXX.c. */
|
||||
|
||||
#define DB_LOOKUP(name, keysize, keypattern, break_if_match, proto...) \
|
||||
enum nss_status \
|
||||
_nss_db_get##name##_r (proto, \
|
||||
struct STRUCTURE *result, \
|
||||
char *buffer, size_t buflen H_ERRNO_PROTO)\
|
||||
{ \
|
||||
DBT key; \
|
||||
enum nss_status status; \
|
||||
const size_t size = (keysize) + 1; \
|
||||
key.data = __alloca (size); \
|
||||
key.size = KEYPRINTF keypattern; \
|
||||
key.flags = 0; \
|
||||
__libc_lock_lock (lock); \
|
||||
status = lookup (&key, result, buffer, buflen H_ERRNO_ARG); \
|
||||
__libc_lock_unlock (lock); \
|
||||
return status; \
|
||||
}
|
||||
|
||||
#define KEYPRINTF(pattern, args...) snprintf (key.data, size, pattern ,##args)
|
||||
|
||||
|
||||
|
||||
|
||||
/* Return the next entry from the database file, doing locking. */
|
||||
enum nss_status
|
||||
CONCAT(_nss_db_get,ENTNAME_r) (struct STRUCTURE *result, char *buffer,
|
||||
size_t buflen H_ERRNO_PROTO)
|
||||
{
|
||||
/* Return next entry in host file. */
|
||||
enum nss_status status;
|
||||
char buf[20];
|
||||
DBT key;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
/* Loop until we find a valid entry or hit EOF. See above for the
|
||||
special meaning of the status value. */
|
||||
do
|
||||
{
|
||||
key.size = snprintf (key.data = buf, sizeof buf, "0%u", entidx++);
|
||||
key.flags = 0;
|
||||
status = lookup (&key, result, buffer, buflen H_ERRNO_ARG);
|
||||
if (status == NSS_STATUS_TRYAGAIN
|
||||
#ifdef NEED_H_ERRNO
|
||||
&& *herrnop == NETDB_INTERNAL
|
||||
#endif
|
||||
&& errno == ERANGE)
|
||||
/* Give the user a chance to get the same entry with a larger
|
||||
buffer. */
|
||||
--entidx;
|
||||
}
|
||||
while (status == NSS_STATUS_RETURN);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
/* Mail alias file parser in nss_db module.
|
||||
Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <glibc-compat/include/aliases.h>
|
||||
#include <alloca.h>
|
||||
#include <ctype.h>
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include <paths.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nsswitch.h"
|
||||
#include "nss_db.h"
|
||||
|
||||
/* Locks the static variables in this file. */
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
/* Maintenance of the shared handle open on the database. */
|
||||
|
||||
static NSS_DB *db;
|
||||
static int keep_db;
|
||||
static unsigned int entidx; /* Index for `getaliasent_r'. */
|
||||
|
||||
|
||||
/* Open database. */
|
||||
enum nss_status
|
||||
_nss_db_setaliasent (int stayopen)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_setent (_PATH_VARDB "aliases.db", &db);
|
||||
|
||||
/* Remember STAYOPEN flag. */
|
||||
if (db != NULL)
|
||||
keep_db |= stayopen;
|
||||
|
||||
/* Reset the sequential index. */
|
||||
entidx = 0;
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* Close it again. */
|
||||
enum nss_status
|
||||
_nss_db_endaliasent (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
internal_endent (&db);
|
||||
|
||||
/* Reset STAYOPEN flag. */
|
||||
keep_db = 0;
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* We provide the parse function here. The parser in libnss_files
|
||||
cannot be used. The generation of the db file already resolved all
|
||||
:include: statements so we simply have to parse the list and store
|
||||
the result. */
|
||||
static enum nss_status
|
||||
lookup (DBT *key, struct aliasent *result, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
enum nss_status status;
|
||||
DBT value;
|
||||
|
||||
/* Open the database. */
|
||||
if (db == NULL)
|
||||
{
|
||||
status = internal_setent (_PATH_VARDB "aliases.db", &db);
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
return status;
|
||||
}
|
||||
|
||||
value.flags = 0;
|
||||
if (DL_CALL_FCT (db->get, (db->db, NULL, key, &value, 0)) == 0)
|
||||
{
|
||||
const char *src = value.data;
|
||||
char *cp;
|
||||
size_t cnt;
|
||||
|
||||
result->alias_members_len = 0;
|
||||
|
||||
/* We now have to fill the BUFFER with all the information. */
|
||||
if (buflen < key->size + 1)
|
||||
{
|
||||
no_more_room:
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
buffer = stpncpy (buffer, key->data, key->size) + 1;
|
||||
buflen -= key->size + 1;
|
||||
|
||||
while (*src != '\0')
|
||||
{
|
||||
const char *end, *upto;
|
||||
while (isspace (*src))
|
||||
++src;
|
||||
|
||||
end = strchr (src, ',');
|
||||
if (end == NULL)
|
||||
end = strchr (src, '\0');
|
||||
for (upto = end; upto > src && isspace (upto[-1]); --upto);
|
||||
|
||||
if (upto != src)
|
||||
{
|
||||
if ((upto - src) + __alignof__ (char *) > buflen)
|
||||
goto no_more_room;
|
||||
buffer = stpncpy (buffer, src, upto - src) + 1;
|
||||
buflen -= (upto - src) + __alignof (char *);
|
||||
++result->alias_members_len;
|
||||
}
|
||||
src = end + (*end != '\0');
|
||||
}
|
||||
|
||||
/* Now prepare the return. Provide string pointers for the
|
||||
currently selected aliases. */
|
||||
|
||||
/* Adjust the pointer so it is aligned for storing pointers. */
|
||||
buffer += __alignof__ (char *) - 1;
|
||||
buffer -= ((buffer - (char *) 0) % __alignof__ (char *));
|
||||
result->alias_members = (char **) buffer;
|
||||
|
||||
/* Compute addresses of alias entry strings. */
|
||||
cp = result->alias_name;
|
||||
for (cnt = 0; cnt < result->alias_members_len; ++cnt)
|
||||
{
|
||||
cp = strchr (cp, '\0') + 1;
|
||||
result->alias_members[cnt] = cp;
|
||||
}
|
||||
|
||||
status = (result->alias_members_len == 0
|
||||
? NSS_STATUS_RETURN : NSS_STATUS_SUCCESS);
|
||||
}
|
||||
else
|
||||
status = NSS_STATUS_NOTFOUND;
|
||||
|
||||
if (! keep_db)
|
||||
internal_endent (&db);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_db_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen)
|
||||
{
|
||||
/* Return next entry in alias file. */
|
||||
enum nss_status status;
|
||||
char buf[20];
|
||||
DBT key;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
key.size = snprintf (key.data = buf, sizeof buf, "0%u", entidx++);
|
||||
key.flags = 0;
|
||||
status = lookup (&key, result, buffer, buflen);
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_db_getaliasbyname_r (const char *name, struct aliasent *result,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
DBT key;
|
||||
enum nss_status status;
|
||||
|
||||
key.size = 1 + strlen (name);
|
||||
|
||||
key.data = __alloca (key.size);
|
||||
((char *) key.data)[0] = '.';
|
||||
memcpy (&((char *) key.data)[1], name, key.size - 1);
|
||||
key.flags = 0;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
status = lookup (&key, result, buffer, buflen);
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/* Netgroup file parser in nss_db modules.
|
||||
Copyright (C) 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netgroup.h>
|
||||
#include <string.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include <paths.h>
|
||||
|
||||
#include "nsswitch.h"
|
||||
#include "nss_db.h"
|
||||
|
||||
|
||||
#define DBFILE _PATH_VARDB "netgroup.db"
|
||||
|
||||
|
||||
/* Locks the static variables in this file. */
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
/* Maintenance of the shared handle open on the database. */
|
||||
static NSS_DB *db;
|
||||
static char *entry;
|
||||
static char *cursor;
|
||||
|
||||
enum nss_status
|
||||
_nss_db_setnetgrent (const char *group)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_setent (DBFILE, &db);
|
||||
|
||||
if (status == NSS_STATUS_SUCCESS)
|
||||
{
|
||||
DBT key = { data: (void *) group, size: strlen (group), flags: 0 };
|
||||
DBT value;
|
||||
|
||||
value.flags = 0;
|
||||
if (DL_CALL_FCT (db->get, (db->db, NULL, &key, &value, 0)) != 0)
|
||||
status = NSS_STATUS_NOTFOUND;
|
||||
else
|
||||
cursor = entry = value.data;
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_db_endnetgrent (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
internal_endent (&db);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
extern enum nss_status _nss_netgroup_parseline (char **cursor,
|
||||
struct __netgrent *result,
|
||||
char *buffer, int buflen);
|
||||
|
||||
enum nss_status
|
||||
_nss_db_getnetgrent_r (struct __netgrent *result, char *buffer, size_t buflen)
|
||||
{
|
||||
int status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = _nss_netgroup_parseline (&cursor, result, buffer, buflen);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
#include <nss/nss_db/db-open.c>
|
||||
@@ -0,0 +1 @@
|
||||
#include <nss/nss_db/dummy-db.h>
|
||||
@@ -0,0 +1 @@
|
||||
#include <nss/nss_db/nss_db.h>
|
||||
@@ -0,0 +1,641 @@
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Extended from original form by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Parts of this file are plain copies of the file `gethtnamadr.c' from
|
||||
the bind package and it has the following copyright. */
|
||||
|
||||
/*
|
||||
* ++Copyright++ 1985, 1988, 1993
|
||||
* -
|
||||
* Copyright (c) 1985, 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* -
|
||||
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies, and that
|
||||
* the name of Digital Equipment Corporation not be used in advertising or
|
||||
* publicity pertaining to distribution of the document or software without
|
||||
* specific, written prior permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
|
||||
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
* -
|
||||
* --Copyright--
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <glibc-compat/include/netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <sys/syslog.h>
|
||||
|
||||
#include "nsswitch.h"
|
||||
|
||||
/* Get implementation for some internal functions. */
|
||||
#include "../resolv/mapv4v6addr.h"
|
||||
#include "../resolv/mapv4v6hostent.h"
|
||||
|
||||
/* Maximum number of aliases we allow. */
|
||||
#define MAX_NR_ALIASES 48
|
||||
#define MAX_NR_ADDRS 48
|
||||
|
||||
#if PACKETSZ > 65536
|
||||
# define MAXPACKET PACKETSZ
|
||||
#else
|
||||
# define MAXPACKET 65536
|
||||
#endif
|
||||
/* As per RFC 1034 and 1035 a host name cannot exceed 255 octets in length. */
|
||||
#ifdef MAXHOSTNAMELEN
|
||||
# undef MAXHOSTNAMELEN
|
||||
#endif
|
||||
#define MAXHOSTNAMELEN 256
|
||||
|
||||
static const char AskedForGot[] = "\
|
||||
gethostby*.getanswer: asked for \"%s\", got \"%s\"";
|
||||
|
||||
|
||||
/* We need this time later. */
|
||||
typedef union querybuf
|
||||
{
|
||||
HEADER hdr;
|
||||
u_char buf[MAXPACKET];
|
||||
} querybuf;
|
||||
|
||||
|
||||
static enum nss_status getanswer_r (const querybuf *answer, int anslen,
|
||||
const char *qname, int qtype,
|
||||
struct hostent *result, char *buffer,
|
||||
size_t buflen, int *h_errnop);
|
||||
|
||||
enum nss_status
|
||||
_nss_dns_gethostbyname2_r (const char *name, int af, struct hostent *result,
|
||||
char *buffer, size_t buflen, int *h_errnop)
|
||||
{
|
||||
union
|
||||
{
|
||||
querybuf *buf;
|
||||
u_char *ptr;
|
||||
} host_buffer;
|
||||
querybuf *orig_host_buffer;
|
||||
int size, type, n;
|
||||
const char *cp;
|
||||
enum nss_status status;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
|
||||
{
|
||||
*h_errnop = NETDB_INTERNAL;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
size = INADDRSZ;
|
||||
type = T_A;
|
||||
break;
|
||||
case AF_INET6:
|
||||
size = IN6ADDRSZ;
|
||||
type = T_AAAA;
|
||||
break;
|
||||
default:
|
||||
*h_errnop = NETDB_INTERNAL;
|
||||
__set_errno (EAFNOSUPPORT);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
result->h_addrtype = af;
|
||||
result->h_length = size;
|
||||
|
||||
/*
|
||||
* if there aren't any dots, it could be a user-level alias.
|
||||
* this is also done in res_query() since we are not the only
|
||||
* function that looks up host names.
|
||||
*/
|
||||
if (strchr (name, '.') == NULL && (cp = __hostalias (name)) != NULL)
|
||||
name = cp;
|
||||
|
||||
host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024);
|
||||
|
||||
n = __libc_res_nsearch (&_res, name, C_IN, type, host_buffer.buf->buf, 1024,
|
||||
&host_buffer.ptr);
|
||||
if (n < 0)
|
||||
{
|
||||
*h_errnop = h_errno;
|
||||
if (host_buffer.buf != orig_host_buffer)
|
||||
free (host_buffer.buf);
|
||||
return errno == ECONNREFUSED ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
status = getanswer_r (host_buffer.buf, n, name, type, result, buffer, buflen,
|
||||
h_errnop);
|
||||
if (host_buffer.buf != orig_host_buffer)
|
||||
free (host_buffer.buf);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_dns_gethostbyname_r (const char *name, struct hostent *result,
|
||||
char *buffer, size_t buflen, int *h_errnop)
|
||||
{
|
||||
enum nss_status status = NSS_STATUS_NOTFOUND;
|
||||
|
||||
if (_res.options & RES_USE_INET6)
|
||||
status = _nss_dns_gethostbyname2_r (name, AF_INET6, result, buffer,
|
||||
buflen, h_errnop);
|
||||
if (status == NSS_STATUS_NOTFOUND)
|
||||
status = _nss_dns_gethostbyname2_r (name, AF_INET, result, buffer,
|
||||
buflen, h_errnop);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_dns_gethostbyaddr_r (const char *addr, int len, int af,
|
||||
struct hostent *result, char *buffer, size_t buflen,
|
||||
int *h_errnop)
|
||||
{
|
||||
static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
|
||||
static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
|
||||
const u_char *uaddr = (const u_char *)addr;
|
||||
struct host_data
|
||||
{
|
||||
char *aliases[MAX_NR_ALIASES];
|
||||
unsigned char host_addr[16]; /* IPv4 or IPv6 */
|
||||
char *h_addr_ptrs[MAX_NR_ADDRS + 1];
|
||||
char linebuffer[0];
|
||||
} *host_data = (struct host_data *) buffer;
|
||||
union
|
||||
{
|
||||
querybuf *buf;
|
||||
u_char *ptr;
|
||||
} host_buffer;
|
||||
querybuf *orig_host_buffer;
|
||||
char qbuf[MAXDNAME+1], *qp;
|
||||
int size, n, status;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
|
||||
{
|
||||
*h_errnop = NETDB_INTERNAL;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
if (af == AF_INET6 && len == IN6ADDRSZ &&
|
||||
(memcmp (uaddr, mapped, sizeof mapped) == 0
|
||||
|| memcmp (uaddr, tunnelled, sizeof tunnelled) == 0))
|
||||
{
|
||||
/* Unmap. */
|
||||
addr += sizeof mapped;
|
||||
uaddr += sizeof mapped;
|
||||
af = AF_INET;
|
||||
len = INADDRSZ;
|
||||
}
|
||||
|
||||
switch (af)
|
||||
{
|
||||
case AF_INET:
|
||||
size = INADDRSZ;
|
||||
break;
|
||||
case AF_INET6:
|
||||
size = IN6ADDRSZ;
|
||||
break;
|
||||
default:
|
||||
__set_errno (EAFNOSUPPORT);
|
||||
*h_errnop = NETDB_INTERNAL;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
if (size != len)
|
||||
{
|
||||
__set_errno (EAFNOSUPPORT);
|
||||
*h_errnop = NETDB_INTERNAL;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
switch (af)
|
||||
{
|
||||
case AF_INET:
|
||||
sprintf (qbuf, "%u.%u.%u.%u.in-addr.arpa", (uaddr[3] & 0xff),
|
||||
(uaddr[2] & 0xff), (uaddr[1] & 0xff), (uaddr[0] & 0xff));
|
||||
break;
|
||||
case AF_INET6:
|
||||
qp = qbuf;
|
||||
for (n = IN6ADDRSZ - 1; n >= 0; n--)
|
||||
qp += sprintf (qp, "%x.%x.", uaddr[n] & 0xf, (uaddr[n] >> 4) & 0xf);
|
||||
strcpy(qp, "ip6.int");
|
||||
break;
|
||||
default:
|
||||
/* Cannot happen. */
|
||||
break;
|
||||
}
|
||||
|
||||
host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024);
|
||||
|
||||
n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
|
||||
1024, &host_buffer.ptr);
|
||||
if (n < 0)
|
||||
{
|
||||
*h_errnop = h_errno;
|
||||
if (host_buffer.buf != orig_host_buffer)
|
||||
free (host_buffer.buf);
|
||||
return errno == ECONNREFUSED ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
status = getanswer_r (host_buffer.buf, n, qbuf, T_PTR, result, buffer, buflen,
|
||||
h_errnop);
|
||||
if (host_buffer.buf != orig_host_buffer)
|
||||
free (host_buffer.buf);
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
*h_errnop = h_errno;
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef SUNSECURITY
|
||||
This is not implemented because it is not possible to use the current
|
||||
source from bind in a multi-threaded program.
|
||||
#endif
|
||||
|
||||
result->h_addrtype = af;
|
||||
result->h_length = len;
|
||||
memcpy (host_data->host_addr, addr, len);
|
||||
host_data->h_addr_ptrs[0] = (char *) host_data->host_addr;
|
||||
host_data->h_addr_ptrs[1] = NULL;
|
||||
if (af == AF_INET && (_res.options & RES_USE_INET6))
|
||||
{
|
||||
map_v4v6_address ((char *) host_data->host_addr,
|
||||
(char *) host_data->host_addr);
|
||||
result->h_addrtype = AF_INET6;
|
||||
result->h_length = IN6ADDRSZ;
|
||||
}
|
||||
*h_errnop = NETDB_SUCCESS;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static enum nss_status
|
||||
getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
|
||||
struct hostent *result, char *buffer, size_t buflen,
|
||||
int *h_errnop)
|
||||
{
|
||||
struct host_data
|
||||
{
|
||||
char *aliases[MAX_NR_ALIASES];
|
||||
unsigned char host_addr[16]; /* IPv4 or IPv6 */
|
||||
char *h_addr_ptrs[MAX_NR_ADDRS + 1];
|
||||
char linebuffer[0];
|
||||
} *host_data = (struct host_data *) buffer;
|
||||
int linebuflen = buflen - offsetof (struct host_data, linebuffer);
|
||||
register const HEADER *hp;
|
||||
const u_char *end_of_message, *cp;
|
||||
int n, ancount, qdcount;
|
||||
int haveanswer, had_error;
|
||||
char *bp, **ap, **hap;
|
||||
char tbuf[MAXDNAME];
|
||||
const char *tname;
|
||||
int (*name_ok) (const char *);
|
||||
|
||||
tname = qname;
|
||||
result->h_name = NULL;
|
||||
end_of_message = answer->buf + anslen;
|
||||
switch (qtype)
|
||||
{
|
||||
case T_A:
|
||||
case T_AAAA:
|
||||
name_ok = res_hnok;
|
||||
break;
|
||||
case T_PTR:
|
||||
name_ok = res_dnok;
|
||||
break;
|
||||
default:
|
||||
return NSS_STATUS_UNAVAIL; /* XXX should be abort(); */
|
||||
}
|
||||
|
||||
/*
|
||||
* find first satisfactory answer
|
||||
*/
|
||||
hp = &answer->hdr;
|
||||
bp = host_data->linebuffer;
|
||||
ancount = ntohs (hp->ancount);
|
||||
qdcount = ntohs (hp->qdcount);
|
||||
cp = answer->buf + HFIXEDSZ;
|
||||
if (qdcount != 1)
|
||||
{
|
||||
*h_errnop = NO_RECOVERY;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
n = dn_expand (answer->buf, end_of_message, cp, bp, linebuflen);
|
||||
if (n < 0 || (*name_ok) (bp) == 0)
|
||||
{
|
||||
*h_errnop = NO_RECOVERY;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
cp += n + QFIXEDSZ;
|
||||
|
||||
if (qtype == T_A || qtype == T_AAAA)
|
||||
{
|
||||
/* res_send() has already verified that the query name is the
|
||||
* same as the one we sent; this just gets the expanded name
|
||||
* (i.e., with the succeeding search-domain tacked on).
|
||||
*/
|
||||
n = strlen (bp) + 1; /* for the \0 */
|
||||
if (n >= MAXHOSTNAMELEN)
|
||||
{
|
||||
__set_h_errno (NO_RECOVERY);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
result->h_name = bp;
|
||||
bp += n;
|
||||
linebuflen -= n;
|
||||
/* The qname can be abbreviated, but h_name is now absolute. */
|
||||
qname = result->h_name;
|
||||
}
|
||||
|
||||
ap = host_data->aliases;
|
||||
*ap = NULL;
|
||||
result->h_aliases = host_data->aliases;
|
||||
hap = host_data->h_addr_ptrs;
|
||||
*hap = NULL;
|
||||
result->h_addr_list = host_data->h_addr_ptrs;
|
||||
haveanswer = 0;
|
||||
had_error = 0;
|
||||
|
||||
while (ancount-- > 0 && cp < end_of_message && had_error == 0)
|
||||
{
|
||||
int type, class;
|
||||
|
||||
n = dn_expand (answer->buf, end_of_message, cp, bp, linebuflen);
|
||||
if (n < 0 || (*name_ok) (bp) == 0)
|
||||
{
|
||||
++had_error;
|
||||
continue;
|
||||
}
|
||||
cp += n; /* name */
|
||||
type = _getshort (cp);
|
||||
cp += INT16SZ; /* type */
|
||||
class = _getshort(cp);
|
||||
cp += INT16SZ + INT32SZ; /* class, TTL */
|
||||
n = _getshort(cp);
|
||||
cp += INT16SZ; /* len */
|
||||
if (class != C_IN)
|
||||
{
|
||||
/* XXX - debug? syslog? */
|
||||
cp += n;
|
||||
continue; /* XXX - had_error++ ? */
|
||||
}
|
||||
|
||||
if ((qtype ==T_A || qtype == T_AAAA) && type == T_CNAME)
|
||||
{
|
||||
if (ap >= &host_data->aliases[MAX_NR_ALIASES - 1])
|
||||
continue;
|
||||
n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf);
|
||||
if (n < 0 || (*name_ok) (tbuf) == 0)
|
||||
{
|
||||
++had_error;
|
||||
continue;
|
||||
}
|
||||
cp += n;
|
||||
/* Store alias. */
|
||||
*ap++ = bp;
|
||||
n = strlen (bp) + 1; /* For the \0. */
|
||||
if (n >= MAXHOSTNAMELEN)
|
||||
{
|
||||
++had_error;
|
||||
continue;
|
||||
}
|
||||
bp += n;
|
||||
linebuflen -= n;
|
||||
/* Get canonical name. */
|
||||
n = strlen (tbuf) + 1; /* For the \0. */
|
||||
if ((size_t) n > linebuflen || n >= MAXHOSTNAMELEN)
|
||||
{
|
||||
++had_error;
|
||||
continue;
|
||||
}
|
||||
strcpy (bp, tbuf); /* Cannot overflow. */
|
||||
result->h_name = bp;
|
||||
bp += n;
|
||||
linebuflen -= n;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (qtype == T_PTR && type == T_CNAME)
|
||||
{
|
||||
n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf);
|
||||
if (n < 0 || res_dnok (tbuf) == 0)
|
||||
{
|
||||
++had_error;
|
||||
continue;
|
||||
}
|
||||
cp += n;
|
||||
/* Get canonical name. */
|
||||
n = strlen (tbuf) + 1; /* For the \0. */
|
||||
if ((size_t) n > linebuflen || n >= MAXHOSTNAMELEN)
|
||||
{
|
||||
++had_error;
|
||||
continue;
|
||||
}
|
||||
strcpy (bp, tbuf); /* Cannot overflow. */
|
||||
tname = bp;
|
||||
bp += n;
|
||||
linebuflen -= n;
|
||||
continue;
|
||||
}
|
||||
if (type != qtype)
|
||||
{
|
||||
syslog (LOG_NOTICE | LOG_AUTH,
|
||||
"gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
|
||||
qname, p_class (C_IN), p_type (qtype), p_type (type));
|
||||
cp += n;
|
||||
continue; /* XXX - had_error++ ? */
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case T_PTR:
|
||||
if (strcasecmp (tname, bp) != 0)
|
||||
{
|
||||
syslog (LOG_NOTICE | LOG_AUTH, AskedForGot, qname, bp);
|
||||
cp += n;
|
||||
continue; /* XXX - had_error++ ? */
|
||||
}
|
||||
n = dn_expand (answer->buf, end_of_message, cp, bp, linebuflen);
|
||||
if (n < 0 || res_hnok (bp) == 0)
|
||||
{
|
||||
++had_error;
|
||||
break;
|
||||
}
|
||||
#if MULTI_PTRS_ARE_ALIASES
|
||||
cp += n;
|
||||
if (haveanswer == 0)
|
||||
result->h_name = bp;
|
||||
else if (ap < &host_data->aliases[MAXALIASES-1])
|
||||
*ap++ = bp;
|
||||
else
|
||||
n = -1;
|
||||
if (n != -1)
|
||||
{
|
||||
n = strlen (bp) + 1; /* for the \0 */
|
||||
if (n >= MAXHOSTNAMELEN)
|
||||
{
|
||||
++had_error;
|
||||
break;
|
||||
}
|
||||
bp += n;
|
||||
linebuflen -= n;
|
||||
}
|
||||
break;
|
||||
#else
|
||||
result->h_name = bp;
|
||||
if (_res.options & RES_USE_INET6)
|
||||
{
|
||||
n = strlen (bp) + 1; /* for the \0 */
|
||||
if (n >= MAXHOSTNAMELEN)
|
||||
{
|
||||
++had_error;
|
||||
break;
|
||||
}
|
||||
bp += n;
|
||||
linebuflen -= n;
|
||||
map_v4v6_hostent (result, &bp, &linebuflen);
|
||||
}
|
||||
*h_errnop = NETDB_SUCCESS;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
#endif
|
||||
case T_A:
|
||||
case T_AAAA:
|
||||
if (strcasecmp (result->h_name, bp) != 0)
|
||||
{
|
||||
syslog (LOG_NOTICE | LOG_AUTH, AskedForGot, result->h_name, bp);
|
||||
cp += n;
|
||||
continue; /* XXX - had_error++ ? */
|
||||
}
|
||||
if (n != result->h_length)
|
||||
{
|
||||
cp += n;
|
||||
continue;
|
||||
}
|
||||
if (!haveanswer)
|
||||
{
|
||||
register int nn;
|
||||
|
||||
result->h_name = bp;
|
||||
nn = strlen (bp) + 1; /* for the \0 */
|
||||
bp += nn;
|
||||
linebuflen -= nn;
|
||||
}
|
||||
|
||||
linebuflen -= sizeof (align) - ((u_long) bp % sizeof (align));
|
||||
bp += sizeof (align) - ((u_long) bp % sizeof (align));
|
||||
|
||||
if (n >= linebuflen)
|
||||
{
|
||||
++had_error;
|
||||
continue;
|
||||
}
|
||||
if (hap >= &host_data->h_addr_ptrs[MAX_NR_ADDRS-1])
|
||||
{
|
||||
cp += n;
|
||||
continue;
|
||||
}
|
||||
memcpy (*hap++ = bp, cp, n);
|
||||
bp += n;
|
||||
cp += n;
|
||||
linebuflen -= n;
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
if (had_error == 0)
|
||||
++haveanswer;
|
||||
}
|
||||
|
||||
if (haveanswer > 0)
|
||||
{
|
||||
*ap = NULL;
|
||||
*hap = NULL;
|
||||
#if defined(RESOLVSORT)
|
||||
/*
|
||||
* Note: we sort even if host can take only one address
|
||||
* in its return structures - should give it the "best"
|
||||
* address in that case, not some random one
|
||||
*/
|
||||
if (_res.nsort && haveanswer > 1 && qtype == T_A)
|
||||
addrsort (host_data->h_addr_ptrs, haveanswer);
|
||||
#endif /*RESOLVSORT*/
|
||||
|
||||
if (result->h_name == NULL)
|
||||
{
|
||||
n = strlen (qname) + 1; /* For the \0. */
|
||||
if (n > linebuflen || n >= MAXHOSTNAMELEN)
|
||||
goto no_recovery;
|
||||
strcpy (bp, qname); /* Cannot overflow. */
|
||||
result->h_name = bp;
|
||||
bp += n;
|
||||
linebuflen -= n;
|
||||
}
|
||||
|
||||
if (_res.options & RES_USE_INET6)
|
||||
map_v4v6_hostent (result, &bp, &linebuflen);
|
||||
*h_errnop = NETDB_SUCCESS;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
no_recovery:
|
||||
*h_errnop = NO_RECOVERY;
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
@@ -0,0 +1,420 @@
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Extended from original form by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* Parts of this file are plain copies of the file `getnetnamadr.c' from
|
||||
the bind package and it has the following copyright. */
|
||||
|
||||
/* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
|
||||
* Dep. Matematica Universidade de Coimbra, Portugal, Europe
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <glibc-compat/include/netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nsswitch.h"
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/* Maximum number of aliases we allow. */
|
||||
#define MAX_NR_ALIASES 48
|
||||
|
||||
|
||||
#if PACKETSZ > 65536
|
||||
#define MAXPACKET PACKETSZ
|
||||
#else
|
||||
#define MAXPACKET 65536
|
||||
#endif
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BYADDR,
|
||||
BYNAME
|
||||
} lookup_method;
|
||||
|
||||
|
||||
/* We need this time later. */
|
||||
typedef union querybuf
|
||||
{
|
||||
HEADER hdr;
|
||||
u_char buf[MAXPACKET];
|
||||
} querybuf;
|
||||
|
||||
|
||||
/* Prototypes for local functions. */
|
||||
static enum nss_status getanswer_r (const querybuf *answer, int anslen,
|
||||
struct netent *result, char *buffer,
|
||||
size_t buflen, lookup_method net_i);
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_dns_getnetbyname_r (const char *name, struct netent *result,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
/* Return entry for network with NAME. */
|
||||
union
|
||||
{
|
||||
querybuf *buf;
|
||||
u_char *ptr;
|
||||
} net_buffer;
|
||||
querybuf *orig_net_buffer;
|
||||
int anslen;
|
||||
char *qbuf;
|
||||
enum nss_status status;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
qbuf = strdupa (name);
|
||||
|
||||
net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
|
||||
|
||||
anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
|
||||
1024, &net_buffer.ptr);
|
||||
if (anslen < 0)
|
||||
{
|
||||
if (net_buffer.buf != orig_net_buffer)
|
||||
free (net_buffer.buf);
|
||||
/* Nothing found. */
|
||||
return (errno == ECONNREFUSED
|
||||
|| errno == EPFNOSUPPORT
|
||||
|| errno == EAFNOSUPPORT)
|
||||
? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
status = getanswer_r (net_buffer.buf, anslen, result, buffer, buflen, BYNAME);
|
||||
if (net_buffer.buf != orig_net_buffer)
|
||||
free (net_buffer.buf);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_dns_getnetbyaddr_r (long net, int type, struct netent *result,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
/* Return entry for network with NAME. */
|
||||
enum nss_status status;
|
||||
union
|
||||
{
|
||||
querybuf *buf;
|
||||
u_char *ptr;
|
||||
} net_buffer;
|
||||
querybuf *orig_net_buffer;
|
||||
unsigned int net_bytes[4];
|
||||
char qbuf[MAXDNAME];
|
||||
int cnt, anslen;
|
||||
u_int32_t net2;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
/* No net address lookup for IPv6 yet. */
|
||||
if (type != AF_INET)
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
net2 = (u_int32_t) net;
|
||||
for (cnt = 4; net2 != 0; net2 >>= 8)
|
||||
net_bytes[--cnt] = net2 & 0xff;
|
||||
|
||||
switch (cnt)
|
||||
{
|
||||
case 3:
|
||||
/* Class A network. */
|
||||
sprintf (qbuf, "0.0.0.%u.in-addr.arpa", net_bytes[3]);
|
||||
break;
|
||||
case 2:
|
||||
/* Class B network. */
|
||||
sprintf (qbuf, "0.0.%u.%u.in-addr.arpa", net_bytes[3], net_bytes[2]);
|
||||
break;
|
||||
case 1:
|
||||
/* Class C network. */
|
||||
sprintf (qbuf, "0.%u.%u.%u.in-addr.arpa", net_bytes[3], net_bytes[2],
|
||||
net_bytes[1]);
|
||||
break;
|
||||
case 0:
|
||||
/* Class D - E network. */
|
||||
sprintf (qbuf, "%u.%u.%u.%u.in-addr.arpa", net_bytes[3], net_bytes[2],
|
||||
net_bytes[1], net_bytes[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
|
||||
|
||||
anslen = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
|
||||
1024, &net_buffer.ptr);
|
||||
if (anslen < 0)
|
||||
{
|
||||
if (net_buffer.buf != orig_net_buffer)
|
||||
free (net_buffer.buf);
|
||||
/* Nothing found. */
|
||||
return (errno == ECONNREFUSED
|
||||
|| errno == EPFNOSUPPORT
|
||||
|| errno == EAFNOSUPPORT)
|
||||
? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
status = getanswer_r (net_buffer.buf, anslen, result, buffer, buflen, BYADDR);
|
||||
if (net_buffer.buf != orig_net_buffer)
|
||||
free (net_buffer.buf);
|
||||
if (status == NSS_STATUS_SUCCESS)
|
||||
{
|
||||
/* Strip trailing zeros. */
|
||||
unsigned int u_net = net; /* Maybe net should be unsigned? */
|
||||
|
||||
while ((u_net & 0xff) == 0 && u_net != 0)
|
||||
u_net >>= 8;
|
||||
result->n_net = u_net;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
#undef offsetof
|
||||
#define offsetof(Type, Member) ((size_t) &((Type *) NULL)->Member)
|
||||
|
||||
static enum nss_status
|
||||
getanswer_r (const querybuf *answer, int anslen, struct netent *result,
|
||||
char *buffer, size_t buflen, lookup_method net_i)
|
||||
{
|
||||
/*
|
||||
* Find first satisfactory answer
|
||||
*
|
||||
* answer --> +------------+ ( MESSAGE )
|
||||
* | Header |
|
||||
* +------------+
|
||||
* | Question | the question for the name server
|
||||
* +------------+
|
||||
* | Answer | RRs answering the question
|
||||
* +------------+
|
||||
* | Authority | RRs pointing toward an authority
|
||||
* | Additional | RRs holding additional information
|
||||
* +------------+
|
||||
*/
|
||||
struct net_data
|
||||
{
|
||||
char *aliases[MAX_NR_ALIASES];
|
||||
char linebuffer[0];
|
||||
} *net_data = (struct net_data *) buffer;
|
||||
int linebuflen = buflen - offsetof (struct net_data, linebuffer);
|
||||
const char *end_of_message = &answer->buf[anslen];
|
||||
const HEADER *header_pointer = &answer->hdr;
|
||||
/* #/records in the answer section. */
|
||||
int answer_count = ntohs (header_pointer->ancount);
|
||||
/* #/entries in the question section. */
|
||||
int question_count = ntohs (header_pointer->qdcount);
|
||||
char *bp = net_data->linebuffer;
|
||||
const char *cp = &answer->buf[HFIXEDSZ];
|
||||
char **alias_pointer;
|
||||
int have_answer;
|
||||
char *ans;
|
||||
|
||||
if (question_count == 0)
|
||||
{
|
||||
/* FIXME: the Sun version uses for host name lookup an additional
|
||||
parameter for pointing to h_errno. this is missing here.
|
||||
OSF/1 has a per-thread h_errno variable. */
|
||||
if (header_pointer->aa != 0)
|
||||
{
|
||||
__set_h_errno (HOST_NOT_FOUND);
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
else
|
||||
{
|
||||
__set_h_errno (TRY_AGAIN);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip the question part. */
|
||||
while (question_count-- > 0)
|
||||
{
|
||||
int n = __dn_skipname (cp, end_of_message);
|
||||
if (n < 0 || end_of_message - (cp + n) < QFIXEDSZ)
|
||||
{
|
||||
__set_h_errno (NO_RECOVERY);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
cp += n + QFIXEDSZ;
|
||||
}
|
||||
|
||||
alias_pointer = result->n_aliases = &net_data->aliases[0];
|
||||
*alias_pointer = NULL;
|
||||
have_answer = 0;
|
||||
ans = NULL;
|
||||
|
||||
while (--answer_count >= 0 && cp < end_of_message)
|
||||
{
|
||||
int n = dn_expand (answer->buf, end_of_message, cp, bp, linebuflen);
|
||||
int type, class;
|
||||
|
||||
if (n < 0 || res_dnok (bp) == 0)
|
||||
break;
|
||||
cp += n;
|
||||
ans = strdupa (bp);
|
||||
GETSHORT (type, cp);
|
||||
GETSHORT (class, cp);
|
||||
cp += INT32SZ; /* TTL */
|
||||
GETSHORT (n, cp);
|
||||
|
||||
if (class == C_IN && type == T_PTR)
|
||||
{
|
||||
n = dn_expand (answer->buf, end_of_message, cp, bp, linebuflen);
|
||||
if (n < 0 || !res_hnok (bp))
|
||||
{
|
||||
/* XXX What does this mean? The original form from bind
|
||||
returns NULL. Incrementing cp has no effect in any case.
|
||||
What should I return here. ??? */
|
||||
cp += n;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
cp += n;
|
||||
if (alias_pointer + 2 < &net_data->aliases[MAX_NR_ALIASES])
|
||||
{
|
||||
*alias_pointer++ = bp;
|
||||
n = strlen (bp) + 1;
|
||||
bp += n;
|
||||
linebuflen -= n;
|
||||
result->n_addrtype = class == C_IN ? AF_INET : AF_UNSPEC;
|
||||
++have_answer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (have_answer)
|
||||
{
|
||||
*alias_pointer = NULL;
|
||||
switch (net_i)
|
||||
{
|
||||
case BYADDR:
|
||||
result->n_name = *result->n_aliases++;
|
||||
result->n_net = 0L;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
|
||||
case BYNAME:
|
||||
{
|
||||
char **ap = result->n_aliases++;
|
||||
while (*ap != NULL)
|
||||
{
|
||||
/* Check each alias name for being of the forms:
|
||||
4.3.2.1.in-addr.arpa = net 1.2.3.4
|
||||
3.2.1.in-addr.arpa = net 0.1.2.3
|
||||
2.1.in-addr.arpa = net 0.0.1.2
|
||||
1.in-addr.arpa = net 0.0.0.1
|
||||
*/
|
||||
uint32_t val = 0; /* Accumulator for n_net value. */
|
||||
unsigned int shift = 0; /* Which part we are parsing now. */
|
||||
const char *p = *ap; /* Consuming the string. */
|
||||
do
|
||||
{
|
||||
/* Match the leading 0 or 0[xX] base indicator. */
|
||||
unsigned int base = 10;
|
||||
if (*p == '0' && p[1] != '.')
|
||||
{
|
||||
base = 8;
|
||||
++p;
|
||||
if (*p == 'x' || *p == 'X')
|
||||
{
|
||||
base = 16;
|
||||
++p;
|
||||
if (*p == '.')
|
||||
break; /* No digit here. Give up on alias. */
|
||||
}
|
||||
if (*p == '\0')
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t part = 0; /* Accumulates this part's number. */
|
||||
do
|
||||
{
|
||||
if (isdigit (*p) && (*p - '0' < base))
|
||||
part = (part * base) + (*p - '0');
|
||||
else if (base == 16 && isxdigit (*p))
|
||||
part = (part << 4) + 10 + (tolower (*p) - 'a');
|
||||
++p;
|
||||
} while (*p != '\0' && *p != '.');
|
||||
|
||||
if (*p != '.')
|
||||
break; /* Bad form. Give up on this name. */
|
||||
|
||||
/* Install this as the next more significant byte. */
|
||||
val |= part << shift;
|
||||
shift += 8;
|
||||
++p;
|
||||
|
||||
/* If we are out of digits now, there are two cases:
|
||||
1. We are done with digits and now see "in-addr.arpa".
|
||||
2. This is not the droid we are looking for. */
|
||||
if (!isdigit (*p) && !strcasecmp (p, "in-addr.arpa"))
|
||||
{
|
||||
result->n_net = val;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Keep going when we have seen fewer than 4 parts. */
|
||||
} while (shift < 32);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__set_h_errno (TRY_AGAIN);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
/* Common code for file-based databases in nss_files module.
|
||||
Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include "nsswitch.h"
|
||||
|
||||
/* These symbols are defined by the including source file:
|
||||
|
||||
ENTNAME -- database name of the structure and functions (hostent, pwent).
|
||||
STRUCTURE -- struct name, define only if not ENTNAME (passwd, group).
|
||||
DATABASE -- string of the database file's name ("hosts", "passwd").
|
||||
|
||||
NEED_H_ERRNO - defined iff an arg `int *herrnop' is used.
|
||||
|
||||
Also see files-parse.c.
|
||||
*/
|
||||
|
||||
#define ENTNAME_r CONCAT(ENTNAME,_r)
|
||||
|
||||
#define DATAFILE "/etc/" DATABASE
|
||||
|
||||
#ifdef NEED_H_ERRNO
|
||||
# include <glibc-compat/include/netdb.h>
|
||||
# define H_ERRNO_PROTO , int *herrnop
|
||||
# define H_ERRNO_ARG , herrnop
|
||||
# define H_ERRNO_SET(val) (*herrnop = (val))
|
||||
#else
|
||||
# define H_ERRNO_PROTO
|
||||
# define H_ERRNO_ARG
|
||||
# define H_ERRNO_SET(val) ((void) 0)
|
||||
#endif
|
||||
|
||||
/* Locks the static variables in this file. */
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
/* Maintenance of the shared stream open on the database file. */
|
||||
|
||||
static FILE *stream;
|
||||
static fpos_t position;
|
||||
static enum { none, getent, getby } last_use;
|
||||
static int keep_stream;
|
||||
|
||||
/* Open database file if not already opened. */
|
||||
static enum nss_status
|
||||
internal_setent (int stayopen)
|
||||
{
|
||||
enum nss_status status = NSS_STATUS_SUCCESS;
|
||||
|
||||
if (stream == NULL)
|
||||
{
|
||||
stream = fopen (DATAFILE, "r");
|
||||
|
||||
if (stream == NULL)
|
||||
status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
|
||||
else
|
||||
{
|
||||
/* We have to make sure the file is `closed on exec'. */
|
||||
int result, flags;
|
||||
|
||||
result = flags = fcntl (fileno (stream), F_GETFD, 0);
|
||||
if (result >= 0)
|
||||
{
|
||||
flags |= FD_CLOEXEC;
|
||||
result = fcntl (fileno (stream), F_SETFD, flags);
|
||||
}
|
||||
if (result < 0)
|
||||
{
|
||||
/* Something went wrong. Close the stream and return a
|
||||
failure. */
|
||||
fclose (stream);
|
||||
stream = NULL;
|
||||
status = NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
rewind (stream);
|
||||
|
||||
/* Remember STAYOPEN flag. */
|
||||
if (stream != NULL)
|
||||
keep_stream |= stayopen;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* Thread-safe, exported version of that. */
|
||||
enum nss_status
|
||||
CONCAT(_nss_files_set,ENTNAME) (int stayopen)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_setent (stayopen);
|
||||
|
||||
if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0)
|
||||
{
|
||||
fclose (stream);
|
||||
stream = NULL;
|
||||
status = NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
last_use = getent;
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* Close the database file. */
|
||||
static void
|
||||
internal_endent (void)
|
||||
{
|
||||
if (stream != NULL)
|
||||
{
|
||||
fclose (stream);
|
||||
stream = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Thread-safe, exported version of that. */
|
||||
enum nss_status
|
||||
CONCAT(_nss_files_end,ENTNAME) (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
internal_endent ();
|
||||
|
||||
/* Reset STAYOPEN flag. */
|
||||
keep_stream = 0;
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Parsing the database file into `struct STRUCTURE' data structures. */
|
||||
|
||||
static enum nss_status
|
||||
internal_getent (struct STRUCTURE *result,
|
||||
char *buffer, int buflen H_ERRNO_PROTO)
|
||||
{
|
||||
char *p;
|
||||
struct parser_data *data = (void *) buffer;
|
||||
int linebuflen = buffer + buflen - data->linebuffer;
|
||||
int parse_result;
|
||||
|
||||
if (buflen < (int) sizeof *data + 1)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
H_ERRNO_SET (NETDB_INTERNAL);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
/* Terminate the line so that we can test for overflow. */
|
||||
data->linebuffer[linebuflen - 1] = '\xff';
|
||||
|
||||
p = fgets (data->linebuffer, linebuflen, stream);
|
||||
if (p == NULL && feof (stream))
|
||||
{
|
||||
/* End of file or read error. */
|
||||
__set_errno (ENOENT);
|
||||
H_ERRNO_SET (HOST_NOT_FOUND);
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
else if (p == NULL || data->linebuffer[linebuflen - 1] != '\xff')
|
||||
{
|
||||
/* The line is too long. Give the user the opportunity to
|
||||
enlarge the buffer. */
|
||||
__set_errno (ERANGE);
|
||||
H_ERRNO_SET (NETDB_INTERNAL);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
/* Skip leading blanks. */
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
}
|
||||
while (*p == '\0' || *p == '#' /* Ignore empty and comment lines. */
|
||||
/* Parse the line. If it is invalid, loop to get the next
|
||||
line of the file to parse. */
|
||||
|| ! (parse_result = parse_line (p, result, data, buflen)));
|
||||
|
||||
/* Filled in RESULT with the next entry from the database file. */
|
||||
return parse_result == -1 ? NSS_STATUS_TRYAGAIN : NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* Return the next entry from the database file, doing locking. */
|
||||
enum nss_status
|
||||
CONCAT(_nss_files_get,ENTNAME_r) (struct STRUCTURE *result,
|
||||
char *buffer, size_t buflen H_ERRNO_PROTO)
|
||||
{
|
||||
/* Return next entry in host file. */
|
||||
enum nss_status status = NSS_STATUS_SUCCESS;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
/* Be prepared that the set*ent function was not called before. */
|
||||
if (stream == NULL)
|
||||
{
|
||||
status = internal_setent (0);
|
||||
|
||||
if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0)
|
||||
{
|
||||
fclose (stream);
|
||||
stream = NULL;
|
||||
status = NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (status == NSS_STATUS_SUCCESS)
|
||||
{
|
||||
/* If the last use was not by the getent function we need the
|
||||
position the stream. */
|
||||
if (last_use != getent)
|
||||
{
|
||||
if (fsetpos (stream, &position) < 0)
|
||||
status = NSS_STATUS_UNAVAIL;
|
||||
else
|
||||
last_use = getent;
|
||||
}
|
||||
|
||||
if (status == NSS_STATUS_SUCCESS)
|
||||
{
|
||||
status = internal_getent (result, buffer, buflen H_ERRNO_ARG);
|
||||
|
||||
/* Remember this position if we were successful. If the
|
||||
operation failed we give the user a chance to repeat the
|
||||
operation (perhaps the buffer was too small). */
|
||||
if (status == NSS_STATUS_SUCCESS)
|
||||
fgetpos (stream, &position);
|
||||
else
|
||||
/* We must make sure we reposition the stream the next call. */
|
||||
last_use = none;
|
||||
}
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Macro for defining lookup functions for this file-based database.
|
||||
|
||||
NAME is the name of the lookup; e.g. `hostbyname'.
|
||||
|
||||
KEYSIZE and KEYPATTERN are ignored here but used by ../nss_db/db-XXX.c.
|
||||
|
||||
PROTO describes the arguments for the lookup key;
|
||||
e.g. `const char *hostname'.
|
||||
|
||||
BREAK_IF_MATCH is a block of code which compares `struct STRUCTURE *result'
|
||||
to the lookup key arguments and does `break;' if they match. */
|
||||
|
||||
#define 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 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 H_ERRNO_ARG)) \
|
||||
== NSS_STATUS_SUCCESS) \
|
||||
{ break_if_match } \
|
||||
\
|
||||
if (! keep_stream) \
|
||||
internal_endent (); \
|
||||
} \
|
||||
\
|
||||
__libc_lock_unlock (lock); \
|
||||
\
|
||||
return status; \
|
||||
}
|
||||
@@ -0,0 +1,451 @@
|
||||
/* Mail alias file parser in nss_files module.
|
||||
Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <glibc-compat/include/aliases.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nsswitch.h"
|
||||
|
||||
/* Locks the static variables in this file. */
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
/* Maintenance of the shared stream open on the database file. */
|
||||
|
||||
static FILE *stream;
|
||||
static fpos_t position;
|
||||
static enum { none, getent, getby } last_use;
|
||||
|
||||
|
||||
static enum nss_status
|
||||
internal_setent (void)
|
||||
{
|
||||
enum nss_status status = NSS_STATUS_SUCCESS;
|
||||
|
||||
if (stream == NULL)
|
||||
{
|
||||
stream = fopen ("/etc/aliases", "r");
|
||||
|
||||
if (stream == NULL)
|
||||
status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
|
||||
else
|
||||
{
|
||||
/* We have to make sure the file is `closed on exec'. */
|
||||
int result, flags;
|
||||
|
||||
result = flags = fcntl (fileno (stream), F_GETFD, 0);
|
||||
if (result >= 0)
|
||||
{
|
||||
flags |= FD_CLOEXEC;
|
||||
result = fcntl (fileno (stream), F_SETFD, flags);
|
||||
}
|
||||
if (result < 0)
|
||||
{
|
||||
/* Something went wrong. Close the stream and return a
|
||||
failure. */
|
||||
fclose (stream);
|
||||
stream = NULL;
|
||||
status = NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
rewind (stream);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* Thread-safe, exported version of that. */
|
||||
enum nss_status
|
||||
_nss_files_setaliasent (void)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_setent ();
|
||||
|
||||
if (status == NSS_STATUS_SUCCESS && fgetpos (stream, &position) < 0)
|
||||
{
|
||||
fclose (stream);
|
||||
stream = NULL;
|
||||
status = NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
last_use = getent;
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* Close the database file. */
|
||||
static void
|
||||
internal_endent (void)
|
||||
{
|
||||
if (stream != NULL)
|
||||
{
|
||||
fclose (stream);
|
||||
stream = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Thread-safe, exported version of that. */
|
||||
enum nss_status
|
||||
_nss_files_endaliasent (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
internal_endent ();
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Parsing the database file into `struct aliasent' data structures. */
|
||||
static enum nss_status
|
||||
get_next_alias (const char *match, struct aliasent *result,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
enum nss_status status = NSS_STATUS_NOTFOUND;
|
||||
int ignore = 0;
|
||||
|
||||
result->alias_members_len = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* Now we are ready to process the input. We have to read a
|
||||
line and all its continuations and construct the array of
|
||||
string pointers. This pointers and the names itself have to
|
||||
be placed in BUFFER. */
|
||||
char *first_unused = buffer;
|
||||
size_t room_left = buflen - (buflen % __alignof__ (char *));
|
||||
char *line;
|
||||
|
||||
/* Read the first line. It must contain the alias name and
|
||||
possibly some alias names. */
|
||||
first_unused[room_left - 1] = '\xff';
|
||||
line = fgets (first_unused, room_left, stream);
|
||||
if (line == NULL && feof (stream))
|
||||
/* Nothing to read. */
|
||||
break;
|
||||
else if (line == NULL || first_unused[room_left - 1] != '\xff')
|
||||
{
|
||||
/* The line is too long for our buffer. */
|
||||
no_more_room:
|
||||
__set_errno (ERANGE);
|
||||
status = NSS_STATUS_TRYAGAIN;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *cp;
|
||||
|
||||
/* If we are in IGNORE mode and the first character in the
|
||||
line is a white space we ignore the line and start
|
||||
reading the next. */
|
||||
if (ignore && isspace (*first_unused))
|
||||
continue;
|
||||
|
||||
/* Terminate the line for any case. */
|
||||
cp = strpbrk (first_unused, "#\n");
|
||||
if (cp != NULL)
|
||||
*cp = '\0';
|
||||
|
||||
/* Skip leading blanks. */
|
||||
while (isspace (*line))
|
||||
++line;
|
||||
|
||||
result->alias_name = first_unused;
|
||||
while (*line != '\0' && *line != ':')
|
||||
*first_unused++ = *line++;
|
||||
if (*line == '\0' || result->alias_name == first_unused)
|
||||
/* No valid name. Ignore the line. */
|
||||
continue;
|
||||
|
||||
*first_unused++ = '\0';
|
||||
if (room_left < (size_t) (first_unused - result->alias_name))
|
||||
goto no_more_room;
|
||||
room_left -= first_unused - result->alias_name;
|
||||
++line;
|
||||
|
||||
/* When we search for a specific alias we can avoid all the
|
||||
difficult parts and compare now with the name we are
|
||||
looking for. If it does not match we simply ignore all
|
||||
lines until the next line containing the start of a new
|
||||
alias is found. */
|
||||
ignore = (match != NULL
|
||||
&& __strcasecmp (result->alias_name, match) != 0);
|
||||
|
||||
while (! ignore)
|
||||
{
|
||||
while (isspace (*line))
|
||||
++line;
|
||||
|
||||
cp = first_unused;
|
||||
while (*line != '\0' && *line != ',')
|
||||
*first_unused++ = *line++;
|
||||
|
||||
if (first_unused != cp)
|
||||
{
|
||||
/* OK, we can have a regular entry or an include
|
||||
request. */
|
||||
if (*line != '\0')
|
||||
++line;
|
||||
*first_unused++ = '\0';
|
||||
|
||||
if (strncmp (cp, ":include:", 9) != 0)
|
||||
{
|
||||
if (room_left < (first_unused - cp) + sizeof (char *))
|
||||
goto no_more_room;
|
||||
room_left -= (first_unused - cp) + sizeof (char *);
|
||||
|
||||
++result->alias_members_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Oh well, we have to read the addressed file. */
|
||||
FILE *listfile;
|
||||
char *old_line = NULL;
|
||||
|
||||
first_unused = cp;
|
||||
|
||||
listfile = fopen (&cp[9], "r");
|
||||
/* If the file does not exist we simply ignore
|
||||
the statement. */
|
||||
if (listfile != NULL
|
||||
&& (old_line = strdup (line)) != NULL)
|
||||
{
|
||||
while (! feof (listfile))
|
||||
{
|
||||
first_unused[room_left - 1] = '\xff';
|
||||
line = fgets (first_unused, room_left, listfile);
|
||||
if (line == NULL && feof (listfile))
|
||||
break;
|
||||
if (line == NULL
|
||||
|| first_unused[room_left - 1] != '\xff')
|
||||
{
|
||||
free (old_line);
|
||||
goto no_more_room;
|
||||
}
|
||||
|
||||
/* Parse the line. */
|
||||
cp = strpbrk (line, "#\n");
|
||||
if (cp != NULL)
|
||||
*cp = '\0';
|
||||
|
||||
do
|
||||
{
|
||||
while (isspace (*line))
|
||||
++line;
|
||||
|
||||
cp = first_unused;
|
||||
while (*line != '\0' && *line != ',')
|
||||
*first_unused++ = *line++;
|
||||
|
||||
if (*line != '\0')
|
||||
++line;
|
||||
|
||||
if (first_unused != cp)
|
||||
{
|
||||
*first_unused++ = '\0';
|
||||
if (room_left < ((first_unused - cp)
|
||||
+ __alignof__ (char *)))
|
||||
{
|
||||
free (old_line);
|
||||
goto no_more_room;
|
||||
}
|
||||
room_left -= ((first_unused - cp)
|
||||
+ __alignof__ (char *));
|
||||
++result->alias_members_len;
|
||||
}
|
||||
}
|
||||
while (*line != '\0');
|
||||
}
|
||||
fclose (listfile);
|
||||
|
||||
first_unused[room_left - 1] = '\0';
|
||||
strncpy (first_unused, old_line, room_left);
|
||||
|
||||
if (old_line != NULL)
|
||||
free (old_line);
|
||||
|
||||
if (first_unused[room_left - 1] != '\0')
|
||||
goto no_more_room;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*line == '\0')
|
||||
{
|
||||
/* Get the next line. But we must be careful. We
|
||||
must not read the whole line at once since it
|
||||
might belong to the current alias. Simply read
|
||||
the first character. If it is a white space we
|
||||
have a continuation line. Otherwise it is the
|
||||
beginning of a new alias and we can push back the
|
||||
just read character. */
|
||||
int ch;
|
||||
|
||||
ch = fgetc (stream);
|
||||
if (ch == EOF || ch == '\n' || !isspace (ch))
|
||||
{
|
||||
size_t cnt;
|
||||
|
||||
/* Now prepare the return. Provide string
|
||||
pointers for the currently selected aliases. */
|
||||
if (ch != EOF)
|
||||
ungetc (ch, stream);
|
||||
|
||||
/* Adjust the pointer so it is aligned for
|
||||
storing pointers. */
|
||||
first_unused += __alignof__ (char *) - 1;
|
||||
first_unused -= ((first_unused - (char *) 0)
|
||||
% __alignof__ (char *));
|
||||
result->alias_members = (char **) first_unused;
|
||||
|
||||
/* Compute addresses of alias entry strings. */
|
||||
cp = result->alias_name;
|
||||
for (cnt = 0; cnt < result->alias_members_len; ++cnt)
|
||||
{
|
||||
cp = strchr (cp, '\0') + 1;
|
||||
result->alias_members[cnt] = cp;
|
||||
}
|
||||
|
||||
status = (result->alias_members_len == 0
|
||||
? NSS_STATUS_RETURN : NSS_STATUS_SUCCESS);
|
||||
break;
|
||||
}
|
||||
|
||||
/* The just read character is a white space and so
|
||||
can be ignored. */
|
||||
first_unused[room_left - 1] = '\xff';
|
||||
line = fgets (first_unused, room_left, stream);
|
||||
if (line == NULL && feof (stream))
|
||||
break;
|
||||
if (line == NULL || first_unused[room_left - 1] != '\xff')
|
||||
goto no_more_room;
|
||||
cp = strpbrk (line, "#\n");
|
||||
if (cp != NULL)
|
||||
*cp = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (status != NSS_STATUS_NOTFOUND)
|
||||
/* We read something. In any case break here. */
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_files_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen)
|
||||
{
|
||||
/* Return next entry in host file. */
|
||||
enum nss_status status = NSS_STATUS_SUCCESS;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
/* Be prepared that the set*ent function was not called before. */
|
||||
if (stream == NULL)
|
||||
status = internal_setent ();
|
||||
|
||||
if (status == NSS_STATUS_SUCCESS)
|
||||
{
|
||||
/* If the last use was not by the getent function we need the
|
||||
position the stream. */
|
||||
if (last_use != getent)
|
||||
{
|
||||
if (fsetpos (stream, &position) < 0)
|
||||
status = NSS_STATUS_UNAVAIL;
|
||||
else
|
||||
last_use = getent;
|
||||
}
|
||||
|
||||
if (status == NSS_STATUS_SUCCESS)
|
||||
{
|
||||
result->alias_local = 1;
|
||||
|
||||
/* Read lines until we get a definite result. */
|
||||
do
|
||||
status = get_next_alias (NULL, result, buffer, buflen);
|
||||
while (status == NSS_STATUS_RETURN);
|
||||
|
||||
/* If we successfully read an entry remember this position. */
|
||||
if (status == NSS_STATUS_SUCCESS)
|
||||
fgetpos (stream, &position);
|
||||
else
|
||||
last_use = none;
|
||||
}
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_files_getaliasbyname_r (const char *name, struct aliasent *result,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
/* Return next entry in host file. */
|
||||
enum nss_status status = NSS_STATUS_SUCCESS;
|
||||
|
||||
if (name == NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
/* Open the stream or rest it. */
|
||||
status = internal_setent ();
|
||||
last_use = getby;
|
||||
|
||||
if (status == NSS_STATUS_SUCCESS)
|
||||
{
|
||||
result->alias_local = 1;
|
||||
|
||||
/* Read lines until we get a definite result. */
|
||||
do
|
||||
status = get_next_alias (name, result, buffer, buflen);
|
||||
while (status == NSS_STATUS_RETURN);
|
||||
}
|
||||
|
||||
internal_endent ();
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/* Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <string.h>
|
||||
#include <netinet/if_ether.h>
|
||||
|
||||
/* Because the `ethers' lookup does not fit so well in the scheme so
|
||||
we define a dummy struct here which helps us to use the available
|
||||
functions. */
|
||||
struct etherent
|
||||
{
|
||||
const char *e_name;
|
||||
struct ether_addr e_addr;
|
||||
};
|
||||
struct etherent_data {};
|
||||
|
||||
#define ENTNAME etherent
|
||||
#define DATABASE "ethers"
|
||||
#include "files-parse.c"
|
||||
LINE_PARSER
|
||||
("#",
|
||||
/* Read the ethernet address: 6 x 8bit hexadecimal number. */
|
||||
{
|
||||
size_t cnt;
|
||||
|
||||
for (cnt = 0; cnt < 6; ++cnt)
|
||||
{
|
||||
unsigned int number;
|
||||
|
||||
if (cnt < 5)
|
||||
INT_FIELD (number, ISCOLON , 0, 16, (unsigned int))
|
||||
else
|
||||
INT_FIELD (number, isspace, 0, 16, (unsigned int))
|
||||
|
||||
if (number > 0xff)
|
||||
return 0;
|
||||
result->e_addr.ether_addr_octet[cnt] = number;
|
||||
}
|
||||
};
|
||||
STRING_FIELD (result->e_name, isspace, 1);
|
||||
)
|
||||
|
||||
|
||||
#include GENERIC
|
||||
|
||||
DB_LOOKUP (hostton, 1 + strlen (name), (".%s", name),
|
||||
{
|
||||
if (strcmp (result->e_name, name) == 0)
|
||||
break;
|
||||
}, const char *name)
|
||||
|
||||
DB_LOOKUP (ntohost, 18, ("=%x:%x:%x:%x:%x:%x",
|
||||
addr->ether_addr_octet[0], addr->ether_addr_octet[1],
|
||||
addr->ether_addr_octet[2], addr->ether_addr_octet[3],
|
||||
addr->ether_addr_octet[4], addr->ether_addr_octet[5]),
|
||||
{
|
||||
if (memcmp (&result->e_addr, addr,
|
||||
sizeof (struct ether_addr)) == 0)
|
||||
break;
|
||||
}, struct ether_addr *addr)
|
||||
@@ -0,0 +1,45 @@
|
||||
/* Group file parser in nss_files module.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <glibc-compat/include/grp.h>
|
||||
|
||||
#define STRUCTURE group
|
||||
#define ENTNAME grent
|
||||
#define DATABASE "group"
|
||||
struct grent_data {};
|
||||
|
||||
/* Our parser function is already defined in fgetgrent.c, so use that.
|
||||
to parse lines from the database file. */
|
||||
#define EXTERN_PARSER
|
||||
#include "files-parse.c"
|
||||
#include GENERIC
|
||||
|
||||
DB_LOOKUP (grnam, 1 + strlen (name), (".%s", name),
|
||||
{
|
||||
if (name[0] != '-' && name[0] != '+'
|
||||
&& ! strcmp (name, result->gr_name))
|
||||
break;
|
||||
}, const char *name)
|
||||
|
||||
DB_LOOKUP (grgid, 20, ("=%lu", (unsigned long int) gid),
|
||||
{
|
||||
if (result->gr_gid == gid && result->gr_name[0] != '+'
|
||||
&& result->gr_name[0] != '-')
|
||||
break;
|
||||
}, gid_t gid)
|
||||
@@ -0,0 +1,107 @@
|
||||
/* Hosts file parser in nss_files module.
|
||||
Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <glibc-compat/include/netdb.h>
|
||||
#include <resolv.h>
|
||||
|
||||
|
||||
/* Get implementation for some internal functions. */
|
||||
#include "../resolv/mapv4v6addr.h"
|
||||
|
||||
|
||||
#define ENTNAME hostent
|
||||
#define DATABASE "hosts"
|
||||
#define NEED_H_ERRNO
|
||||
|
||||
#define ENTDATA hostent_data
|
||||
struct hostent_data
|
||||
{
|
||||
unsigned char host_addr[16]; /* IPv4 or IPv6 address. */
|
||||
char *h_addr_ptrs[2]; /* Points to that and null terminator. */
|
||||
};
|
||||
|
||||
#define TRAILING_LIST_MEMBER h_aliases
|
||||
#define TRAILING_LIST_SEPARATOR_P isspace
|
||||
#include "files-parse.c"
|
||||
LINE_PARSER
|
||||
("#",
|
||||
{
|
||||
char *addr;
|
||||
|
||||
STRING_FIELD (addr, isspace, 1);
|
||||
|
||||
/* Parse address. */
|
||||
if (inet_pton (AF_INET, addr, entdata->host_addr) > 0)
|
||||
{
|
||||
if (_res.options & RES_USE_INET6)
|
||||
{
|
||||
map_v4v6_address ((char *) entdata->host_addr,
|
||||
(char *) entdata->host_addr);
|
||||
result->h_addrtype = AF_INET6;
|
||||
result->h_length = IN6ADDRSZ;
|
||||
}
|
||||
else
|
||||
{
|
||||
result->h_addrtype = AF_INET;
|
||||
result->h_length = INADDRSZ;
|
||||
}
|
||||
}
|
||||
else if (inet_pton (AF_INET6, addr, entdata->host_addr) > 0)
|
||||
{
|
||||
result->h_addrtype = AF_INET6;
|
||||
result->h_length = IN6ADDRSZ;
|
||||
}
|
||||
else
|
||||
/* Illegal address: ignore line. */
|
||||
return 0;
|
||||
|
||||
/* Store a pointer to the address in the expected form. */
|
||||
entdata->h_addr_ptrs[0] = entdata->host_addr;
|
||||
entdata->h_addr_ptrs[1] = NULL;
|
||||
result->h_addr_list = entdata->h_addr_ptrs;
|
||||
|
||||
STRING_FIELD (result->h_name, isspace, 1);
|
||||
})
|
||||
|
||||
#include "files-XXX.c"
|
||||
|
||||
DB_LOOKUP (hostbyname, ,,
|
||||
{
|
||||
if (result->h_addrtype != ((_res.options & RES_USE_INET6)
|
||||
? AF_INET6 : AF_INET))
|
||||
continue;
|
||||
LOOKUP_NAME_CASE (h_name, h_aliases)
|
||||
}, const char *name)
|
||||
|
||||
DB_LOOKUP (hostbyname2, ,,
|
||||
{
|
||||
if (result->h_addrtype != af)
|
||||
continue;
|
||||
LOOKUP_NAME_CASE (h_name, h_aliases)
|
||||
}, const char *name, int af)
|
||||
|
||||
DB_LOOKUP (hostbyaddr, ,,
|
||||
{
|
||||
if (result->h_addrtype == type && result->h_length == len &&
|
||||
! memcmp (addr, result->h_addr_list[0], len))
|
||||
break;
|
||||
}, const char *addr, int len, int type)
|
||||
@@ -0,0 +1,268 @@
|
||||
/* Netgroup file parser in nss_files modules.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <glibc-compat/include/netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "nsswitch.h"
|
||||
#include "netgroup.h"
|
||||
|
||||
#define DATAFILE "/etc/netgroup"
|
||||
|
||||
|
||||
#define EXPAND(needed) \
|
||||
do \
|
||||
{ \
|
||||
size_t old_cursor = result->cursor - result->data; \
|
||||
\
|
||||
result->data_size += 512 > 2 * needed ? 512 : 2 * needed; \
|
||||
result->data = realloc (result->data, result->data_size); \
|
||||
\
|
||||
if (result->data == NULL) \
|
||||
{ \
|
||||
status = NSS_STATUS_UNAVAIL; \
|
||||
goto the_end; \
|
||||
} \
|
||||
\
|
||||
result->cursor = result->data + old_cursor; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_files_setnetgrent (const char *group, struct __netgrent *result)
|
||||
{
|
||||
FILE *fp;
|
||||
enum nss_status status;
|
||||
|
||||
if (group[0] == '\0')
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
/* Find the netgroups file and open it. */
|
||||
fp = fopen (DATAFILE, "r");
|
||||
if (fp == NULL)
|
||||
status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
|
||||
else
|
||||
{
|
||||
/* Read the file line by line and try to find the description
|
||||
GROUP. We must take care for long lines. */
|
||||
char *line = NULL;
|
||||
size_t line_len = 0;
|
||||
const ssize_t group_len = strlen (group);
|
||||
|
||||
status = NSS_STATUS_NOTFOUND;
|
||||
result->cursor = result->data;
|
||||
|
||||
while (!feof (fp))
|
||||
{
|
||||
ssize_t curlen = getline (&line, &line_len, fp);
|
||||
int found;
|
||||
|
||||
if (curlen < 0)
|
||||
{
|
||||
status = NSS_STATUS_NOTFOUND;
|
||||
break;
|
||||
}
|
||||
|
||||
found = (curlen > group_len && strncmp (line, group, group_len) == 0
|
||||
&& isspace (line[group_len]));
|
||||
|
||||
/* Read the whole line (including continuation) and store it
|
||||
if FOUND in nonzero. Otherwise we don't need it. */
|
||||
if (found)
|
||||
{
|
||||
/* Store the data from the first line. */
|
||||
EXPAND (curlen - group_len);
|
||||
memcpy (result->cursor, &line[group_len + 1],
|
||||
curlen - group_len);
|
||||
result->cursor += (curlen - group_len) - 1;
|
||||
}
|
||||
|
||||
while (line[curlen - 1] == '\n' && line[curlen - 2] == '\\')
|
||||
{
|
||||
/* Yes, we have a continuation line. */
|
||||
if (found)
|
||||
/* Remove these characters from the stored line. */
|
||||
result->cursor -= 2;
|
||||
|
||||
/* Get next line. */
|
||||
curlen = getline (&line, &line_len, fp);
|
||||
if (curlen <= 0)
|
||||
break;
|
||||
|
||||
if (found)
|
||||
{
|
||||
/* Make sure we have enough room. */
|
||||
EXPAND (1 + curlen + 1);
|
||||
|
||||
/* Add separator in case next line starts immediately. */
|
||||
*result->cursor++ = ' ';
|
||||
|
||||
/* Copy new line. */
|
||||
memcpy (result->cursor, line, curlen + 1);
|
||||
result->cursor += curlen;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
/* Now we have read the line. */
|
||||
status = NSS_STATUS_SUCCESS;
|
||||
result->cursor = result->data;
|
||||
result->first = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
the_end:
|
||||
/* We don't need the file and the line buffer anymore. */
|
||||
free (line);
|
||||
fclose (fp);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_nss_files_endnetgrent (struct __netgrent *result)
|
||||
{
|
||||
/* Free allocated memory for data if some is present. */
|
||||
if (result->data != NULL)
|
||||
{
|
||||
free (result->data);
|
||||
result->data = NULL;
|
||||
result->data_size = 0;
|
||||
result->cursor = NULL;
|
||||
}
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_netgroup_parseline (char **cursor, struct __netgrent *result,
|
||||
char *buffer, int buflen)
|
||||
{
|
||||
enum nss_status status;
|
||||
const char *host, *user, *domain;
|
||||
char *cp = *cursor;
|
||||
|
||||
/* Some sanity checks. */
|
||||
if (cp == NULL)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
/* First skip leading spaces. */
|
||||
while (isspace (*cp))
|
||||
++cp;
|
||||
|
||||
if (*cp != '(')
|
||||
{
|
||||
/* We have a list of other netgroups. */
|
||||
char *name = cp;
|
||||
|
||||
while (*cp != '\0' && ! isspace (*cp))
|
||||
++cp;
|
||||
|
||||
if (name != cp)
|
||||
{
|
||||
/* It is another netgroup name. */
|
||||
int last = *cp == '\0';
|
||||
|
||||
result->type = group_val;
|
||||
result->val.group = name;
|
||||
*cp = '\0';
|
||||
if (! last)
|
||||
++cp;
|
||||
*cursor = cp;
|
||||
result->first = 0;
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
|
||||
}
|
||||
|
||||
/* Match host name. */
|
||||
host = ++cp;
|
||||
while (*cp != ',')
|
||||
if (*cp++ == '\0')
|
||||
return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
|
||||
|
||||
/* Match user name. */
|
||||
user = ++cp;
|
||||
while (*cp != ',')
|
||||
if (*cp++ == '\0')
|
||||
return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
|
||||
|
||||
/* Match domain name. */
|
||||
domain = ++cp;
|
||||
while (*cp != ')')
|
||||
if (*cp++ == '\0')
|
||||
return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
|
||||
++cp;
|
||||
|
||||
|
||||
/* When we got here we have found an entry. Before we can copy it
|
||||
to the private buffer we have to make sure it is big enough. */
|
||||
if (cp - host > buflen)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
status = NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy (buffer, host, cp - host);
|
||||
result->type = triple_val;
|
||||
|
||||
buffer[(user - host) - 1] = '\0';
|
||||
result->val.triple.host = *host == ',' ? NULL : buffer;
|
||||
|
||||
buffer[(domain - host) - 1] = '\0';
|
||||
result->val.triple.user = *user == ',' ? NULL : buffer + (user - host);
|
||||
|
||||
buffer[(cp - host) - 1] = '\0';
|
||||
result->val.triple.domain =
|
||||
*domain == ')' ? NULL : buffer + (domain - host);
|
||||
|
||||
status = NSS_STATUS_SUCCESS;
|
||||
|
||||
/* Remember where we stopped reading. */
|
||||
*cursor = cp;
|
||||
|
||||
result->first = 0;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_files_getnetgrent_r (struct __netgrent *result, char *buffer, int buflen)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
status = _nss_netgroup_parseline (&result->cursor, result, buffer, buflen);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/* Networks file parser in nss_files module.
|
||||
Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <glibc-compat/include/netdb.h>
|
||||
|
||||
#define ENTNAME netent
|
||||
#define DATABASE "networks"
|
||||
|
||||
struct netent_data {};
|
||||
|
||||
#define TRAILING_LIST_MEMBER n_aliases
|
||||
#define TRAILING_LIST_SEPARATOR_P isspace
|
||||
#include "files-parse.c"
|
||||
LINE_PARSER
|
||||
("#",
|
||||
{
|
||||
char *addr;
|
||||
|
||||
STRING_FIELD (result->n_name, isspace, 1);
|
||||
|
||||
STRING_FIELD (addr, isspace, 1);
|
||||
result->n_net = inet_network (addr);
|
||||
result->n_addrtype = AF_INET;
|
||||
|
||||
})
|
||||
|
||||
#include "files-XXX.c"
|
||||
|
||||
DB_LOOKUP (netbyname, ,,
|
||||
LOOKUP_NAME_CASE (n_name, n_aliases),
|
||||
const char *name)
|
||||
|
||||
DB_LOOKUP (netbyaddr, ,,
|
||||
{
|
||||
if (result->n_addrtype == type && result->n_net == net)
|
||||
/* Bingo! */
|
||||
break;
|
||||
}, unsigned long int net, int type)
|
||||
@@ -0,0 +1,252 @@
|
||||
/* Common code for file-based database parsers in nss_files module.
|
||||
Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* These symbols are defined by the including source file:
|
||||
|
||||
ENTNAME -- database name of the structure and functions (hostent, pwent).
|
||||
STRUCTURE -- struct name, define only if not ENTNAME (passwd, group).
|
||||
DATABASE -- string of the database file's name ("hosts", "passwd").
|
||||
|
||||
ENTDATA -- if defined, `struct ENTDATA' is used by the parser to store
|
||||
things pointed to by the resultant `struct STRUCTURE'.
|
||||
|
||||
NEED_H_ERRNO - defined iff an arg `int *herrnop' is used.
|
||||
|
||||
Also see files-XXX.c. */
|
||||
|
||||
#define CONCAT(a,b) CONCAT1(a,b)
|
||||
#define CONCAT1(a,b) a##b
|
||||
|
||||
#ifndef STRUCTURE
|
||||
# define STRUCTURE ENTNAME
|
||||
#endif
|
||||
|
||||
|
||||
struct parser_data
|
||||
{
|
||||
#ifdef ENTDATA
|
||||
struct ENTDATA entdata;
|
||||
# define ENTDATA_DECL(data) struct ENTDATA *const entdata = &data->entdata;
|
||||
#else
|
||||
# define ENTDATA_DECL(data)
|
||||
#endif
|
||||
char linebuffer[0];
|
||||
};
|
||||
|
||||
#ifdef ENTDATA
|
||||
/* The function can't be exported, because the entdata structure
|
||||
is defined only in files-foo.c. */
|
||||
# define parser_stclass static
|
||||
#else
|
||||
/* Export the line parser function so it can be used in nss_db. */
|
||||
# define parser_stclass /* Global */
|
||||
# define parse_line CONCAT(_nss_files_parse_,ENTNAME)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef EXTERN_PARSER
|
||||
|
||||
/* The parser is defined in a different module. */
|
||||
extern int parse_line (char *line, struct STRUCTURE *result,
|
||||
struct parser_data *data, size_t datalen);
|
||||
|
||||
# define LINE_PARSER(EOLSET, BODY) /* Do nothing */
|
||||
|
||||
#else
|
||||
|
||||
/* Define a line parsing function. */
|
||||
|
||||
# define LINE_PARSER(EOLSET, BODY) \
|
||||
parser_stclass int \
|
||||
parse_line (char *line, struct STRUCTURE *result, \
|
||||
struct parser_data *data, size_t datalen) \
|
||||
{ \
|
||||
ENTDATA_DECL (data) \
|
||||
char *p = strpbrk (line, EOLSET "\n"); \
|
||||
if (p != NULL) \
|
||||
*p = '\0'; \
|
||||
BODY; \
|
||||
TRAILING_LIST_PARSER; \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
|
||||
# define STRING_FIELD(variable, terminator_p, swallow) \
|
||||
{ \
|
||||
variable = line; \
|
||||
while (*line != '\0' && !terminator_p (*line)) \
|
||||
++line; \
|
||||
if (*line != '\0') \
|
||||
{ \
|
||||
*line = '\0'; \
|
||||
do \
|
||||
++line; \
|
||||
while (swallow && terminator_p (*line)); \
|
||||
} \
|
||||
}
|
||||
|
||||
# define INT_FIELD(variable, terminator_p, swallow, base, convert) \
|
||||
{ \
|
||||
char *endp; \
|
||||
variable = convert (strtoul (line, &endp, base)); \
|
||||
if (endp == line) \
|
||||
return 0; \
|
||||
else if (terminator_p (*endp)) \
|
||||
do \
|
||||
++endp; \
|
||||
while (swallow && terminator_p (*endp)); \
|
||||
else if (*endp != '\0') \
|
||||
return 0; \
|
||||
line = endp; \
|
||||
}
|
||||
|
||||
# define INT_FIELD_MAYBE_NULL(variable, terminator_p, swallow, base, convert, default) \
|
||||
{ \
|
||||
char *endp; \
|
||||
if (*line == '\0') \
|
||||
/* We expect some more input, so don't allow the string to end here. */ \
|
||||
return 0; \
|
||||
variable = convert (strtoul (line, &endp, base)); \
|
||||
if (endp == line) \
|
||||
variable = default; \
|
||||
if (terminator_p (*endp)) \
|
||||
do \
|
||||
++endp; \
|
||||
while (swallow && terminator_p (*endp)); \
|
||||
else if (*endp != '\0') \
|
||||
return 0; \
|
||||
line = endp; \
|
||||
}
|
||||
|
||||
# define ISCOLON(c) ((c) == ':')
|
||||
|
||||
|
||||
# ifndef TRAILING_LIST_MEMBER
|
||||
# define TRAILING_LIST_PARSER /* Nothing to do. */
|
||||
# else
|
||||
|
||||
# define TRAILING_LIST_PARSER \
|
||||
{ \
|
||||
char **list = parse_list (line, data, datalen); \
|
||||
if (list) \
|
||||
result->TRAILING_LIST_MEMBER = list; \
|
||||
else \
|
||||
return -1; /* -1 indicates we ran out of space. */ \
|
||||
}
|
||||
|
||||
static inline char **
|
||||
__attribute ((always_inline))
|
||||
parse_list (char *line, struct parser_data *data, size_t datalen)
|
||||
{
|
||||
char *eol, **list, **p;
|
||||
|
||||
if (line >= data->linebuffer && line < (char *) data + datalen)
|
||||
/* Find the end of the line buffer, we will use the space in DATA after
|
||||
it for storing the vector of pointers. */
|
||||
eol = strchr (line, '\0') + 1;
|
||||
else
|
||||
/* LINE does not point within DATA->linebuffer, so that space is
|
||||
not being used for scratch space right now. We can use all of
|
||||
it for the pointer vector storage. */
|
||||
eol = data->linebuffer;
|
||||
/* Adjust the pointer so it is aligned for storing pointers. */
|
||||
eol += __alignof__ (char *) - 1;
|
||||
eol -= (eol - (char *) 0) % __alignof__ (char *);
|
||||
/* We will start the storage here for the vector of pointers. */
|
||||
list = (char **) eol;
|
||||
|
||||
p = list;
|
||||
while (1)
|
||||
{
|
||||
char *elt;
|
||||
|
||||
if ((size_t) ((char *) &p[1] - (char *) data) > datalen)
|
||||
{
|
||||
/* We cannot fit another pointer in the buffer. */
|
||||
__set_errno (ERANGE);
|
||||
return NULL;
|
||||
}
|
||||
if (*line == '\0')
|
||||
break;
|
||||
|
||||
/* Skip leading white space. This might not be portable but useful. */
|
||||
while (isspace (*line))
|
||||
++line;
|
||||
|
||||
elt = line;
|
||||
while (1)
|
||||
{
|
||||
if (*line == '\0' || TRAILING_LIST_SEPARATOR_P (*line))
|
||||
{
|
||||
/* End of the next entry. */
|
||||
if (line > elt)
|
||||
/* We really found some data. */
|
||||
*p++ = elt;
|
||||
|
||||
/* Terminate string if necessary. */
|
||||
if (*line != '\0')
|
||||
*line++ = '\0';
|
||||
break;
|
||||
}
|
||||
++line;
|
||||
}
|
||||
}
|
||||
*p = NULL;
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
# endif /* TRAILING_LIST_MEMBER */
|
||||
#endif /* EXTERN_PARSER */
|
||||
|
||||
|
||||
#define LOOKUP_NAME(nameelt, aliaselt) \
|
||||
{ \
|
||||
char **ap; \
|
||||
if (! strcmp (name, result->nameelt)) \
|
||||
break; \
|
||||
for (ap = result->aliaselt; *ap; ++ap) \
|
||||
if (! strcmp (name, *ap)) \
|
||||
break; \
|
||||
if (*ap) \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define LOOKUP_NAME_CASE(nameelt, aliaselt) \
|
||||
{ \
|
||||
char **ap; \
|
||||
if (! __strcasecmp (name, result->nameelt)) \
|
||||
break; \
|
||||
for (ap = result->aliaselt; *ap; ++ap) \
|
||||
if (! __strcasecmp (name, *ap)) \
|
||||
break; \
|
||||
if (*ap) \
|
||||
break; \
|
||||
}
|
||||
|
||||
|
||||
/* This is defined by db-*.c to include "../nss_db/db-XXX.c" instead. */
|
||||
#ifndef GENERIC
|
||||
# define GENERIC "files-XXX.c"
|
||||
#endif
|
||||
@@ -0,0 +1,47 @@
|
||||
/* Protocols file parser in nss_files module.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <glibc-compat/include/netdb.h>
|
||||
|
||||
|
||||
#define ENTNAME protoent
|
||||
#define DATABASE "protocols"
|
||||
|
||||
struct protoent_data {};
|
||||
|
||||
#define TRAILING_LIST_MEMBER p_aliases
|
||||
#define TRAILING_LIST_SEPARATOR_P isspace
|
||||
#include "files-parse.c"
|
||||
LINE_PARSER
|
||||
("#",
|
||||
STRING_FIELD (result->p_name, isspace, 1);
|
||||
INT_FIELD (result->p_proto, isspace, 1, 10,);
|
||||
)
|
||||
|
||||
#include GENERIC
|
||||
|
||||
DB_LOOKUP (protobyname, 1 + strlen (name), (".%s", name),
|
||||
LOOKUP_NAME (p_name, p_aliases),
|
||||
const char *name)
|
||||
|
||||
DB_LOOKUP (protobynumber, 20, ("=%d", proto),
|
||||
{
|
||||
if (result->p_proto == proto)
|
||||
break;
|
||||
}, int proto)
|
||||
@@ -0,0 +1,45 @@
|
||||
/* User file parser in nss_files module.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <glibc-compat/include/pwd.h>
|
||||
|
||||
#define STRUCTURE passwd
|
||||
#define ENTNAME pwent
|
||||
#define DATABASE "passwd"
|
||||
struct pwent_data {};
|
||||
|
||||
/* Our parser function is already defined in fgetpwent_r.c, so use that
|
||||
to parse lines from the database file. */
|
||||
#define EXTERN_PARSER
|
||||
#include "files-parse.c"
|
||||
#include GENERIC
|
||||
|
||||
DB_LOOKUP (pwnam, 1 + strlen (name), (".%s", name),
|
||||
{
|
||||
if (name[0] != '+' && name[0] != '-'
|
||||
&& ! strcmp (name, result->pw_name))
|
||||
break;
|
||||
}, const char *name)
|
||||
|
||||
DB_LOOKUP (pwuid, 20, ("=%lu", (unsigned long int) uid),
|
||||
{
|
||||
if (result->pw_uid == uid && result->pw_name[0] != '+'
|
||||
&& result->pw_name[0] != '-')
|
||||
break;
|
||||
}, uid_t uid)
|
||||
@@ -0,0 +1,47 @@
|
||||
/* SunRPC program number file parser in nss_files module.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <glibc-compat/include/rpc/netdb.h>
|
||||
|
||||
|
||||
#define ENTNAME rpcent
|
||||
#define DATABASE "rpc"
|
||||
|
||||
struct rpcent_data {};
|
||||
|
||||
#define TRAILING_LIST_MEMBER r_aliases
|
||||
#define TRAILING_LIST_SEPARATOR_P isspace
|
||||
#include "files-parse.c"
|
||||
LINE_PARSER
|
||||
("#",
|
||||
STRING_FIELD (result->r_name, isspace, 1);
|
||||
INT_FIELD (result->r_number, isspace, 1, 10,);
|
||||
)
|
||||
|
||||
#include GENERIC
|
||||
|
||||
DB_LOOKUP (rpcbyname, 1 + strlen (name), (".%s", name),
|
||||
LOOKUP_NAME (r_name, r_aliases),
|
||||
const char *name)
|
||||
|
||||
DB_LOOKUP (rpcbynumber, 20, ("=%d", number),
|
||||
{
|
||||
if (result->r_number == number)
|
||||
break;
|
||||
}, int number)
|
||||
@@ -0,0 +1,60 @@
|
||||
/* Services file parser in nss_files module.
|
||||
Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <glibc-compat/include/netdb.h>
|
||||
|
||||
|
||||
#define ENTNAME servent
|
||||
#define DATABASE "services"
|
||||
|
||||
struct servent_data {};
|
||||
|
||||
#define TRAILING_LIST_MEMBER s_aliases
|
||||
#define TRAILING_LIST_SEPARATOR_P isspace
|
||||
#include "files-parse.c"
|
||||
#define ISSLASH(c) ((c) == '/')
|
||||
LINE_PARSER
|
||||
("#",
|
||||
STRING_FIELD (result->s_name, isspace, 1);
|
||||
INT_FIELD (result->s_port, ISSLASH, 10, 0, htons);
|
||||
STRING_FIELD (result->s_proto, isspace, 1);
|
||||
)
|
||||
|
||||
#include GENERIC
|
||||
|
||||
DB_LOOKUP (servbyname, 2 + strlen (name) + (proto ? strlen (proto) : 0),
|
||||
(".%s/%s", name, proto ?: ""),
|
||||
{
|
||||
/* Must match both protocol (if specified) and name. */
|
||||
if (proto != NULL && strcmp (result->s_proto, proto))
|
||||
continue;
|
||||
LOOKUP_NAME (s_name, s_aliases)
|
||||
},
|
||||
const char *name, const char *proto)
|
||||
|
||||
DB_LOOKUP (servbyport, 21 + (proto ? strlen (proto) : 0),
|
||||
("=%d/%s", ntohs (port), proto ?: ""),
|
||||
{
|
||||
/* Must match both port and protocol. */
|
||||
if (result->s_port == port
|
||||
&& (proto == NULL
|
||||
|| strcmp (result->s_proto, proto) == 0))
|
||||
break;
|
||||
}, int port, const char *proto)
|
||||
@@ -0,0 +1,38 @@
|
||||
/* User file parser in nss_files module.
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <glibc-compat/include/shadow.h>
|
||||
|
||||
#define STRUCTURE spwd
|
||||
#define ENTNAME spent
|
||||
#define DATABASE "shadow"
|
||||
struct spent_data {};
|
||||
|
||||
/* Our parser function is already defined in sgetspent_r.c, so use that
|
||||
to parse lines from the database file. */
|
||||
#define EXTERN_PARSER
|
||||
#include "files-parse.c"
|
||||
#include GENERIC
|
||||
|
||||
DB_LOOKUP (spnam, 1 + strlen (name), (".%s", name),
|
||||
{
|
||||
if (name[0] != '+' && name[0] != '-'
|
||||
&& ! strcmp (name, result->sp_namp))
|
||||
break;
|
||||
}, const char *name)
|
||||
@@ -0,0 +1,278 @@
|
||||
/* Copyright (C) 1996, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <nss.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <glibc-compat/include/aliases.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include <rpcsvc/yp.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include "nss-nis.h"
|
||||
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
static bool_t new_start = 1;
|
||||
static char *oldkey = NULL;
|
||||
static int oldkeylen = 0;
|
||||
|
||||
static int
|
||||
_nss_nis_parse_aliasent (const char *key, char *alias, struct aliasent *result,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
char *first_unused = buffer + strlen (alias) + 1;
|
||||
size_t room_left =
|
||||
buflen - (buflen % __alignof__ (char *)) - strlen (alias) - 2;
|
||||
char *line;
|
||||
char *cp;
|
||||
|
||||
result->alias_members_len = 0;
|
||||
*first_unused = '\0';
|
||||
first_unused++;
|
||||
strcpy (first_unused, key);
|
||||
|
||||
if (first_unused[room_left - 1] != '\0')
|
||||
{
|
||||
/* The line is too long for our buffer. */
|
||||
no_more_room:
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
result->alias_name = first_unused;
|
||||
|
||||
/* Terminate the line for any case. */
|
||||
cp = strpbrk (alias, "#\n");
|
||||
if (cp != NULL)
|
||||
*cp = '\0';
|
||||
|
||||
first_unused += strlen (result->alias_name) + 1;
|
||||
/* Adjust the pointer so it is aligned for
|
||||
storing pointers. */
|
||||
first_unused += __alignof__ (char *) - 1;
|
||||
first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *));
|
||||
result->alias_members = (char **) first_unused;
|
||||
|
||||
line = alias;
|
||||
|
||||
while (*line != '\0')
|
||||
{
|
||||
/* Skip leading blanks. */
|
||||
while (isspace (*line))
|
||||
line++;
|
||||
|
||||
if (*line == '\0')
|
||||
break;
|
||||
|
||||
if (room_left < sizeof (char *))
|
||||
goto no_more_room;
|
||||
room_left -= sizeof (char *);
|
||||
result->alias_members[result->alias_members_len] = line;
|
||||
|
||||
while (*line != '\0' && *line != ',')
|
||||
line++;
|
||||
|
||||
if (line != result->alias_members[result->alias_members_len])
|
||||
{
|
||||
*line = '\0';
|
||||
line++;
|
||||
result->alias_members_len++;
|
||||
}
|
||||
}
|
||||
return result->alias_members_len == 0 ? 0 : 1;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_setaliasent (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
new_start = 1;
|
||||
if (oldkey != NULL)
|
||||
{
|
||||
free (oldkey);
|
||||
oldkey = NULL;
|
||||
oldkeylen = 0;
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_endaliasent (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
new_start = 1;
|
||||
if (oldkey != NULL)
|
||||
{
|
||||
free (oldkey);
|
||||
oldkey = NULL;
|
||||
oldkeylen = 0;
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
internal_nis_getaliasent_r (struct aliasent *alias, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
char *domain;
|
||||
char *result;
|
||||
int len;
|
||||
char *outkey;
|
||||
int keylen;
|
||||
char *p;
|
||||
int parse_res;
|
||||
|
||||
if (yp_get_default_domain (&domain))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
alias->alias_local = 0;
|
||||
|
||||
/* Get the next entry until we found a correct one. */
|
||||
do
|
||||
{
|
||||
enum nss_status retval;
|
||||
|
||||
if (new_start)
|
||||
retval = yperr2nss (yp_first (domain, "mail.aliases",
|
||||
&outkey, &keylen, &result, &len));
|
||||
else
|
||||
retval = yperr2nss ( yp_next (domain, "mail.aliases", oldkey,
|
||||
oldkeylen, &outkey, &keylen,
|
||||
&result, &len));
|
||||
if (retval != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if (retval == NSS_STATUS_TRYAGAIN)
|
||||
__set_errno (EAGAIN);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if ((size_t) (len + 1) > buflen)
|
||||
{
|
||||
free (result);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
p = strncpy (buffer, result, len);
|
||||
buffer[len] = '\0';
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
free (result);
|
||||
|
||||
parse_res = _nss_nis_parse_aliasent (outkey, p, alias, buffer, buflen);
|
||||
if (parse_res == -1)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
free (oldkey);
|
||||
oldkey = outkey;
|
||||
oldkeylen = keylen;
|
||||
new_start = 0;
|
||||
}
|
||||
while (!parse_res);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getaliasent_r (struct aliasent *alias, char *buffer, size_t buflen)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_nis_getaliasent_r (alias, buffer, buflen);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getaliasbyname_r (const char *name, struct aliasent *alias,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
enum nss_status retval;
|
||||
int parse_res;
|
||||
char *domain;
|
||||
char *result;
|
||||
int len;
|
||||
char *p;
|
||||
size_t namlen = strlen (name);
|
||||
char name2[namlen + 1];
|
||||
int i;
|
||||
|
||||
if (name == NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
if (yp_get_default_domain (&domain))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
/* Convert name to lowercase. */
|
||||
for (i = 0; i < namlen; ++i)
|
||||
name2[i] = tolower (name[i]);
|
||||
name2[i] = '\0';
|
||||
|
||||
retval = yperr2nss (yp_match (domain, "mail.aliases", name, namlen,
|
||||
&result, &len));
|
||||
|
||||
if (retval != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if (retval == NSS_STATUS_TRYAGAIN)
|
||||
__set_errno (EAGAIN);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if ((size_t) (len + 1) > buflen)
|
||||
{
|
||||
free (result);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
p = strncpy (buffer, result, len);
|
||||
buffer[len] = '\0';
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
free (result);
|
||||
|
||||
alias->alias_local = 0;
|
||||
parse_res = _nss_nis_parse_aliasent (name, p, alias, buffer, buflen);
|
||||
if (parse_res == -1)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
else
|
||||
if (parse_res == 0)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
else
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,299 @@
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <nss.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include <rpcsvc/yp.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
#include <netinet/if_ether.h>
|
||||
|
||||
#include "nss-nis.h"
|
||||
|
||||
/* Protect global state against multiple changers */
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
struct ether
|
||||
{
|
||||
const char *e_name;
|
||||
struct ether_addr e_addr;
|
||||
};
|
||||
|
||||
/* Get the declaration of the parser function. */
|
||||
#define ENTNAME etherent
|
||||
#define STRUCTURE ether
|
||||
#define EXTERN_PARSER
|
||||
#include "../nss_files/files-parse.c"
|
||||
|
||||
struct response
|
||||
{
|
||||
char *val;
|
||||
struct response *next;
|
||||
};
|
||||
|
||||
static struct response *start = NULL;
|
||||
static struct response *next = NULL;
|
||||
|
||||
static int
|
||||
saveit (int instatus, char *inkey, int inkeylen, char *inval,
|
||||
int invallen, char *indata)
|
||||
{
|
||||
if (instatus != YP_TRUE)
|
||||
return instatus;
|
||||
|
||||
if (inkey && inkeylen > 0 && inval && invallen > 0)
|
||||
{
|
||||
if (start == NULL)
|
||||
{
|
||||
start = malloc (sizeof (struct response));
|
||||
next = start;
|
||||
}
|
||||
else
|
||||
{
|
||||
next->next = malloc (sizeof (struct response));
|
||||
next = next->next;
|
||||
}
|
||||
next->next = NULL;
|
||||
next->val = malloc (invallen + 1);
|
||||
strncpy (next->val, inval, invallen);
|
||||
next->val[invallen] = '\0';
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
internal_nis_setetherent (void)
|
||||
{
|
||||
char *domainname;
|
||||
struct ypall_callback ypcb;
|
||||
enum nss_status status;
|
||||
|
||||
yp_get_default_domain (&domainname);
|
||||
|
||||
while (start != NULL)
|
||||
{
|
||||
if (start->val != NULL)
|
||||
free (start->val);
|
||||
next = start;
|
||||
start = start->next;
|
||||
free (next);
|
||||
}
|
||||
start = NULL;
|
||||
|
||||
ypcb.foreach = saveit;
|
||||
ypcb.data = NULL;
|
||||
status = yperr2nss (yp_all (domainname, "ethers.byname", &ypcb));
|
||||
next = start;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_setetherent (void)
|
||||
{
|
||||
enum nss_status result;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
result = internal_nis_setetherent ();
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_endetherent (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
while (start != NULL)
|
||||
{
|
||||
if (start->val != NULL)
|
||||
free (start->val);
|
||||
next = start;
|
||||
start = start->next;
|
||||
free (next);
|
||||
}
|
||||
start = NULL;
|
||||
next = NULL;
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
internal_nis_getetherent_r (struct ether *eth, char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
int parse_res;
|
||||
|
||||
if (start == NULL)
|
||||
internal_nis_setetherent ();
|
||||
|
||||
/* Get the next entry until we found a correct one. */
|
||||
do
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (next == NULL)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
p = strncpy (buffer, next->val, buflen);
|
||||
next = next->next;
|
||||
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
|
||||
parse_res = _nss_files_parse_etherent (p, eth, data, buflen);
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
while (!parse_res);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getetherent_r (struct ether *result, char *buffer, size_t buflen)
|
||||
{
|
||||
int status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_nis_getetherent_r (result, buffer, buflen);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_gethostton_r (const char *name, struct ether *eth,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
enum nss_status retval;
|
||||
char *domain, *result, *p;
|
||||
int len, parse_res;
|
||||
|
||||
if (name == NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
if (yp_get_default_domain (&domain))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
retval = yperr2nss (yp_match (domain, "ethers.byname", name,
|
||||
strlen (name), &result, &len));
|
||||
|
||||
if (retval != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if (retval == NSS_STATUS_TRYAGAIN)
|
||||
__set_errno (EAGAIN);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if ((size_t) (len + 1) > buflen)
|
||||
{
|
||||
free (result);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
p = strncpy (buffer, result, len);
|
||||
buffer[len] = '\0';
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
free (result);
|
||||
|
||||
parse_res = _nss_files_parse_etherent (p, eth, data, buflen);
|
||||
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
else if (parse_res == 0)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getntohost_r (struct ether_addr *addr, struct ether *eth,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
enum nss_status retval;
|
||||
char *domain, *result, *p;
|
||||
int len, nlen, parse_res;
|
||||
char buf[33];
|
||||
|
||||
if (addr == NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
if (yp_get_default_domain (&domain))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
nlen = sprintf (buf, "%x:%x:%x:%x:%x:%x",
|
||||
(int) addr->ether_addr_octet[0],
|
||||
(int) addr->ether_addr_octet[1],
|
||||
(int) addr->ether_addr_octet[2],
|
||||
(int) addr->ether_addr_octet[3],
|
||||
(int) addr->ether_addr_octet[4],
|
||||
(int) addr->ether_addr_octet[5]);
|
||||
|
||||
retval = yperr2nss (yp_match (domain, "ethers.byaddr", buf,
|
||||
nlen, &result, &len));
|
||||
|
||||
if (retval != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if (retval == NSS_STATUS_TRYAGAIN)
|
||||
__set_errno (EAGAIN);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if ((size_t) (len + 1) > buflen)
|
||||
{
|
||||
free (result);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
p = strncpy (buffer, result, len);
|
||||
buffer[len] = '\0';
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
free (result);
|
||||
|
||||
parse_res = _nss_files_parse_etherent (p, eth, data, buflen);
|
||||
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
else if (parse_res == 0)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <nss.h>
|
||||
#include <glibc-compat/include/grp.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include <rpcsvc/yp.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include "nss-nis.h"
|
||||
|
||||
/* Get the declaration of the parser function. */
|
||||
#define ENTNAME grent
|
||||
#define STRUCTURE group
|
||||
#define EXTERN_PARSER
|
||||
#include "../nss_files/files-parse.c"
|
||||
|
||||
/* Protect global state against multiple changers */
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
static bool_t new_start = 1;
|
||||
static char *oldkey = NULL;
|
||||
static int oldkeylen = 0;
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_setgrent (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
new_start = 1;
|
||||
if (oldkey != NULL)
|
||||
{
|
||||
free (oldkey);
|
||||
oldkey = NULL;
|
||||
oldkeylen = 0;
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_endgrent (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
new_start = 1;
|
||||
if (oldkey != NULL)
|
||||
{
|
||||
free (oldkey);
|
||||
oldkey = NULL;
|
||||
oldkeylen = 0;
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
internal_nis_getgrent_r (struct group *grp, char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
char *domain, *result, *outkey;
|
||||
int len, keylen, parse_res;
|
||||
|
||||
if (yp_get_default_domain (&domain))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
/* Get the next entry until we found a correct one. */
|
||||
do
|
||||
{
|
||||
enum nss_status retval;
|
||||
char *p;
|
||||
|
||||
if (new_start)
|
||||
retval = yperr2nss (yp_first (domain, "group.byname",
|
||||
&outkey, &keylen, &result, &len));
|
||||
else
|
||||
retval = yperr2nss ( yp_next (domain, "group.byname",
|
||||
oldkey, oldkeylen,
|
||||
&outkey, &keylen, &result, &len));
|
||||
|
||||
if (retval != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if (retval == NSS_STATUS_TRYAGAIN)
|
||||
__set_errno (EAGAIN);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if ((size_t) (len + 1) > buflen)
|
||||
{
|
||||
free (result);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
p = strncpy (buffer, result, len);
|
||||
buffer[len] = '\0';
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
free (result);
|
||||
|
||||
parse_res = _nss_files_parse_grent (p, grp, data, buflen);
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
|
||||
free (oldkey);
|
||||
oldkey = outkey;
|
||||
oldkeylen = keylen;
|
||||
new_start = 0;
|
||||
}
|
||||
while (!parse_res);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getgrent_r (struct group *result, char *buffer, size_t buflen)
|
||||
{
|
||||
int status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_nis_getgrent_r (result, buffer, buflen);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getgrnam_r (const char *name, struct group *grp,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
enum nss_status retval;
|
||||
char *domain, *result, *p;
|
||||
int len, parse_res;
|
||||
|
||||
if (name == NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
if (yp_get_default_domain (&domain))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
retval = yperr2nss (yp_match (domain, "group.byname", name,
|
||||
strlen (name), &result, &len));
|
||||
|
||||
if (retval != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if (retval == NSS_STATUS_TRYAGAIN)
|
||||
__set_errno (EAGAIN);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if ((size_t) (len + 1) > buflen)
|
||||
{
|
||||
free (result);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
p = strncpy (buffer, result, len);
|
||||
buffer[len] = '\0';
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
free (result);
|
||||
|
||||
parse_res = _nss_files_parse_grent (p, grp, data, buflen);
|
||||
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
else if (parse_res == 0)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getgrgid_r (gid_t gid, struct group *grp,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
enum nss_status retval;
|
||||
char *domain, *result, *p;
|
||||
int len, nlen, parse_res;
|
||||
char buf[32];
|
||||
|
||||
if (yp_get_default_domain (&domain))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
nlen = sprintf (buf, "%d", gid);
|
||||
|
||||
retval = yperr2nss (yp_match (domain, "group.bygid", buf,
|
||||
nlen, &result, &len));
|
||||
|
||||
if (retval != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if (retval == NSS_STATUS_TRYAGAIN)
|
||||
__set_errno (EAGAIN);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if ((size_t) (len + 1) > buflen)
|
||||
{
|
||||
free (result);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
p = strncpy (buffer, result, len);
|
||||
buffer[len] = '\0';
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
free (result);
|
||||
|
||||
parse_res = _nss_files_parse_grent (p, grp, data, buflen);
|
||||
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
else if (parse_res == 0)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,417 @@
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <nss.h>
|
||||
#include <ctype.h>
|
||||
#include <glibc-compat/include/netdb.h>
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <resolv.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include <rpcsvc/yp.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include "nss-nis.h"
|
||||
|
||||
/* Get implementation for some internal functions. */
|
||||
#include "../../resolv/mapv4v6addr.h"
|
||||
#include "../../resolv/mapv4v6hostent.h"
|
||||
|
||||
#define ENTNAME hostent
|
||||
#define DATABASE "hosts"
|
||||
#define NEED_H_ERRNO
|
||||
|
||||
#define ENTDATA hostent_data
|
||||
struct hostent_data
|
||||
{
|
||||
unsigned char host_addr[16]; /* IPv4 or IPv6 address. */
|
||||
char *h_addr_ptrs[2]; /* Points to that and null terminator. */
|
||||
};
|
||||
|
||||
#define TRAILING_LIST_MEMBER h_aliases
|
||||
#define TRAILING_LIST_SEPARATOR_P isspace
|
||||
#include "../nss_files/files-parse.c"
|
||||
LINE_PARSER
|
||||
("#",
|
||||
{
|
||||
char *addr;
|
||||
|
||||
STRING_FIELD (addr, isspace, 1);
|
||||
|
||||
/* Parse address. */
|
||||
if ((_res.options & RES_USE_INET6)
|
||||
&& inet_pton (AF_INET6, addr, entdata->host_addr) > 0)
|
||||
{
|
||||
result->h_addrtype = AF_INET6;
|
||||
result->h_length = IN6ADDRSZ;
|
||||
}
|
||||
else
|
||||
if (inet_pton (AF_INET, addr, entdata->host_addr) > 0)
|
||||
{
|
||||
if (_res.options & RES_USE_INET6)
|
||||
{
|
||||
map_v4v6_address ((char *) entdata->host_addr,
|
||||
(char *) entdata->host_addr);
|
||||
result->h_addrtype = AF_INET6;
|
||||
result->h_length = IN6ADDRSZ;
|
||||
}
|
||||
else
|
||||
{
|
||||
result->h_addrtype = AF_INET;
|
||||
result->h_length = INADDRSZ;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* Illegal address: ignore line. */
|
||||
return 0;
|
||||
|
||||
/* Store a pointer to the address in the expected form. */
|
||||
entdata->h_addr_ptrs[0] = entdata->host_addr;
|
||||
entdata->h_addr_ptrs[1] = NULL;
|
||||
result->h_addr_list = entdata->h_addr_ptrs;
|
||||
|
||||
/* If we need the host entry in IPv6 form change it now. */
|
||||
if (_res.options & RES_USE_INET6)
|
||||
{
|
||||
char *bufptr = data->linebuffer;
|
||||
size_t buflen = (char *) data + datalen - bufptr;
|
||||
int ibuflen = buflen; /* Use this for machines with size_t > int. */
|
||||
map_v4v6_hostent (result, &bufptr, &ibuflen);
|
||||
buflen = ibuflen;
|
||||
}
|
||||
|
||||
STRING_FIELD (result->h_name, isspace, 1);
|
||||
}
|
||||
)
|
||||
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
static bool_t new_start = 1;
|
||||
static char *oldkey = NULL;
|
||||
static int oldkeylen = 0;
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_sethostent (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
new_start = 1;
|
||||
if (oldkey != NULL)
|
||||
{
|
||||
free (oldkey);
|
||||
oldkey = NULL;
|
||||
oldkeylen = 0;
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_endhostent (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
new_start = 1;
|
||||
if (oldkey != NULL)
|
||||
{
|
||||
free (oldkey);
|
||||
oldkey = NULL;
|
||||
oldkeylen = 0;
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
internal_nis_gethostent_r (struct hostent *host, char *buffer,
|
||||
size_t buflen, int *h_errnop)
|
||||
{
|
||||
char *domain;
|
||||
char *result;
|
||||
int len, parse_res;
|
||||
char *outkey;
|
||||
int keylen;
|
||||
struct parser_data *data = (void *) buffer;
|
||||
size_t linebuflen = buffer + buflen - data->linebuffer;
|
||||
|
||||
if (yp_get_default_domain (&domain))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
if (buflen < sizeof *data + 1)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
*h_errnop = NETDB_INTERNAL;
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
/* Get the next entry until we found a correct one. */
|
||||
do
|
||||
{
|
||||
enum nss_status retval;
|
||||
char *p;
|
||||
|
||||
if (new_start)
|
||||
retval = yperr2nss (yp_first (domain, "hosts.byname",
|
||||
&outkey, &keylen, &result, &len));
|
||||
else
|
||||
retval = yperr2nss ( yp_next (domain, "hosts.byname",
|
||||
oldkey, oldkeylen,
|
||||
&outkey, &keylen, &result, &len));
|
||||
|
||||
if (retval != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
switch (retval)
|
||||
{
|
||||
case NSS_STATUS_TRYAGAIN:
|
||||
__set_errno (EAGAIN);
|
||||
*h_errnop = TRY_AGAIN;
|
||||
break;
|
||||
case NSS_STATUS_NOTFOUND:
|
||||
*h_errnop = HOST_NOT_FOUND;
|
||||
break;
|
||||
default:
|
||||
*h_errnop = NO_RECOVERY;
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
if ((size_t) (len + 1) > linebuflen)
|
||||
{
|
||||
free (result);
|
||||
*h_errnop = NETDB_INTERNAL;
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
p = strncpy (data->linebuffer, result, len);
|
||||
data->linebuffer[len] = '\0';
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
free (result);
|
||||
|
||||
parse_res = parse_line (p, host, data, buflen);
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
{
|
||||
*h_errnop = NETDB_INTERNAL;;
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
free (oldkey);
|
||||
oldkey = outkey;
|
||||
oldkeylen = keylen;
|
||||
new_start = 0;
|
||||
}
|
||||
while (!parse_res);
|
||||
|
||||
*h_errnop = NETDB_SUCCESS;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
_nss_nis_gethostent_r (struct hostent *host, char *buffer, size_t buflen,
|
||||
int *h_errnop)
|
||||
{
|
||||
int status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_nis_gethostent_r (host, buffer, buflen, h_errnop);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_gethostbyname2_r (const char *name, int af, struct hostent *host,
|
||||
char *buffer, size_t buflen, int *h_errnop)
|
||||
{
|
||||
enum nss_status retval;
|
||||
char *domain, *result, *p;
|
||||
int len, parse_res;
|
||||
struct parser_data *data = (void *) buffer;
|
||||
size_t linebuflen = buffer + buflen - data->linebuffer;
|
||||
|
||||
if (name == NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
if (yp_get_default_domain (&domain))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
if (buflen < sizeof *data + 1)
|
||||
{
|
||||
*h_errnop = NETDB_INTERNAL;
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Convert name to lowercase. */
|
||||
size_t namelen = strlen (name);
|
||||
char name2[namelen + 1];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < namelen; ++i)
|
||||
name2[i] = tolower (name[i]);
|
||||
name2[i] = '\0';
|
||||
|
||||
retval = yperr2nss (yp_match (domain, "hosts.byname", name2,
|
||||
namelen, &result, &len));
|
||||
|
||||
}
|
||||
|
||||
if (retval != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if (retval == NSS_STATUS_TRYAGAIN)
|
||||
{
|
||||
*h_errnop = TRY_AGAIN;
|
||||
__set_errno (EAGAIN);
|
||||
}
|
||||
if (retval == NSS_STATUS_NOTFOUND)
|
||||
*h_errnop = HOST_NOT_FOUND;
|
||||
return retval;
|
||||
}
|
||||
|
||||
if ((size_t) (len + 1) > linebuflen)
|
||||
{
|
||||
free (result);
|
||||
*h_errnop = NETDB_INTERNAL;
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
p = strncpy (data->linebuffer, result, len);
|
||||
data->linebuffer[len] = '\0';
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
free (result);
|
||||
|
||||
parse_res = parse_line (p, host, data, buflen);
|
||||
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
{
|
||||
*h_errnop = NETDB_INTERNAL;
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
if (parse_res == 0 || host->h_addrtype != af)
|
||||
{
|
||||
*h_errnop = HOST_NOT_FOUND;
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
*h_errnop = NETDB_SUCCESS;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_gethostbyname_r (const char *name, struct hostent *host,
|
||||
char *buffer, size_t buflen, int *h_errnop)
|
||||
{
|
||||
if (_res.options & RES_USE_INET6)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
status = _nss_nis_gethostbyname2_r (name, AF_INET6, host, buffer, buflen,
|
||||
h_errnop);
|
||||
if (status == NSS_STATUS_SUCCESS)
|
||||
return status;
|
||||
}
|
||||
|
||||
return _nss_nis_gethostbyname2_r (name, AF_INET, host, buffer, buflen,
|
||||
h_errnop);
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_gethostbyaddr_r (char *addr, int addrlen, int type,
|
||||
struct hostent *host, char *buffer, size_t buflen,
|
||||
int *h_errnop)
|
||||
{
|
||||
enum nss_status retval;
|
||||
char *domain, *result, *p;
|
||||
int len, parse_res;
|
||||
char *buf;
|
||||
struct parser_data *data = (void *) buffer;
|
||||
size_t linebuflen = buffer + buflen - data->linebuffer;
|
||||
|
||||
if (yp_get_default_domain (&domain))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
if (buflen < sizeof *data + 1)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
*h_errnop = NETDB_INTERNAL;
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
buf = inet_ntoa (*(struct in_addr *) addr);
|
||||
|
||||
retval = yperr2nss (yp_match (domain, "hosts.byaddr", buf,
|
||||
strlen (buf), &result, &len));
|
||||
|
||||
if (retval != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if (retval == NSS_STATUS_TRYAGAIN)
|
||||
{
|
||||
*h_errnop = TRY_AGAIN;
|
||||
__set_errno (EAGAIN);
|
||||
}
|
||||
if (retval == NSS_STATUS_NOTFOUND)
|
||||
*h_errnop = HOST_NOT_FOUND;
|
||||
return retval;
|
||||
}
|
||||
|
||||
if ((size_t) (len + 1) > linebuflen)
|
||||
{
|
||||
free (result);
|
||||
__set_errno (ERANGE);
|
||||
*h_errnop = NETDB_INTERNAL;
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
p = strncpy (data->linebuffer, result, len);
|
||||
data->linebuffer[len] = '\0';
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
free (result);
|
||||
|
||||
parse_res = parse_line (p, host, data, buflen);
|
||||
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
{
|
||||
*h_errnop = NETDB_INTERNAL;
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
else if (parse_res == 0)
|
||||
{
|
||||
*h_errnop = HOST_NOT_FOUND;
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
*h_errnop = NETDB_SUCCESS;
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/* Copyright (C) 1996 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <nss.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include <glibc-compat/include/netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <netgroup.h>
|
||||
#include <rpcsvc/yp.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include "nss-nis.h"
|
||||
|
||||
/* Locks the static variables in this file. */
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
static char *data = NULL;
|
||||
static size_t data_size = 0;
|
||||
static char *cursor = NULL;;
|
||||
|
||||
extern enum nss_status
|
||||
_nss_netgroup_parseline (char **cursor, struct __netgrent *result,
|
||||
char *buffer, size_t buflen);
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_setnetgrent (char *group)
|
||||
{
|
||||
char *domain;
|
||||
char *result;
|
||||
int len, group_len;
|
||||
enum nss_status status;
|
||||
|
||||
status = NSS_STATUS_SUCCESS;
|
||||
|
||||
if (group[0] == '\0')
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
if (yp_get_default_domain (&domain))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
if (data != NULL)
|
||||
{
|
||||
free (data);
|
||||
data = NULL;
|
||||
data_size = 0;
|
||||
cursor = NULL;
|
||||
}
|
||||
|
||||
group_len = strlen (group);
|
||||
|
||||
status = yperr2nss (yp_match (domain, "netgroup", group, group_len,
|
||||
&result, &len));
|
||||
if (status == NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if (len > 0)
|
||||
{
|
||||
data = malloc (len + 1);
|
||||
data_size = len;
|
||||
cursor = strncpy (data, result, len + 1);
|
||||
data[len] = '\0';
|
||||
free (result);
|
||||
}
|
||||
else
|
||||
status = NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_endnetgrent (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
if (data != NULL)
|
||||
{
|
||||
free (data);
|
||||
data = NULL;
|
||||
data_size = 0;
|
||||
cursor = NULL;
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getnetgrent_r (struct __netgrent *result, char *buffer, size_t buflen)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
if (cursor == NULL)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = _nss_netgroup_parseline (&cursor, result, buffer, buflen);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -0,0 +1,318 @@
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <nss.h>
|
||||
#include <glibc-compat/include/netdb.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include <rpcsvc/yp.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include "nss-nis.h"
|
||||
|
||||
/* Get the declaration of the parser function. */
|
||||
#define ENTNAME netent
|
||||
#define EXTERN_PARSER
|
||||
#include "../nss_files/files-parse.c"
|
||||
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
static bool_t new_start = 1;
|
||||
static char *oldkey = NULL;
|
||||
static int oldkeylen = 0;
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_setnetent (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
new_start = 1;
|
||||
if (oldkey != NULL)
|
||||
{
|
||||
free (oldkey);
|
||||
oldkey = NULL;
|
||||
oldkeylen = 0;
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_endnetent (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
new_start = 1;
|
||||
if (oldkey != NULL)
|
||||
{
|
||||
free (oldkey);
|
||||
oldkey = NULL;
|
||||
oldkeylen = 0;
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
internal_nis_getnetent_r (struct netent *net, char *buffer, size_t buflen,
|
||||
int *herrnop)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
char *domain, *result, *outkey;
|
||||
int len, keylen, parse_res;
|
||||
|
||||
if (yp_get_default_domain (&domain))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
/* Get the next entry until we found a correct one. */
|
||||
do
|
||||
{
|
||||
enum nss_status retval;
|
||||
char *p;
|
||||
|
||||
if (new_start)
|
||||
retval = yperr2nss (yp_first (domain, "networks.byname",
|
||||
&outkey, &keylen, &result, &len));
|
||||
else
|
||||
retval = yperr2nss ( yp_next (domain, "networks.byname",
|
||||
oldkey, oldkeylen,
|
||||
&outkey, &keylen, &result, &len));
|
||||
|
||||
if (retval != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if (retval == NSS_STATUS_TRYAGAIN)
|
||||
{
|
||||
*herrnop = NETDB_INTERNAL;
|
||||
__set_errno (EAGAIN);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
if ((size_t) (len + 1) > buflen)
|
||||
{
|
||||
free (result);
|
||||
__set_errno (ERANGE);
|
||||
*herrnop = NETDB_INTERNAL;
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
p = strncpy (buffer, result, len);
|
||||
buffer[len] = '\0';
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
free (result);
|
||||
|
||||
parse_res = _nss_files_parse_netent (p, net, data, buflen);
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
{
|
||||
*herrnop = NETDB_INTERNAL;
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
free (oldkey);
|
||||
oldkey = outkey;
|
||||
oldkeylen = keylen;
|
||||
new_start = 0;
|
||||
}
|
||||
while (!parse_res);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getnetent_r (struct netent *net, char *buffer, size_t buflen,
|
||||
int *herrnop)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_nis_getnetent_r (net, buffer, buflen, herrnop);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getnetbyname_r (const char *name, struct netent *net,
|
||||
char *buffer, size_t buflen, int *herrnop)
|
||||
{
|
||||
enum nss_status retval;
|
||||
struct parser_data *data = (void *) buffer;
|
||||
char *domain, *result, *p;
|
||||
int len, parse_res;
|
||||
|
||||
if (name == NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
*herrnop = NETDB_INTERNAL;
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
if (yp_get_default_domain (&domain))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
if (buflen < sizeof *data + 1)
|
||||
{
|
||||
*herrnop = NETDB_INTERNAL;
|
||||
__set_errno(ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Convert name to lowercase. */
|
||||
size_t namlen = strlen (name);
|
||||
char name2[namlen + 1];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < namlen; ++i)
|
||||
name2[i] = tolower (name[i]);
|
||||
name2[i] = '\0';
|
||||
|
||||
retval = yperr2nss (yp_match (domain, "networks.byname", name2,
|
||||
namlen, &result, &len));
|
||||
}
|
||||
|
||||
if (retval != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if (retval == NSS_STATUS_TRYAGAIN)
|
||||
{
|
||||
__set_errno (EAGAIN);
|
||||
*herrnop = NETDB_INTERNAL;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
if ((size_t) (len + 1) > buflen)
|
||||
{
|
||||
free (result);
|
||||
__set_errno (ERANGE);
|
||||
*herrnop = NETDB_INTERNAL;
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
p = strncpy (buffer, result, len);
|
||||
buffer[len] = '\0';
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
free (result);
|
||||
|
||||
parse_res = _nss_files_parse_netent (p, net, data, buflen);
|
||||
|
||||
if (parse_res <= 0)
|
||||
{
|
||||
*herrnop = NETDB_INTERNAL;
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
else
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
else
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getnetbyaddr_r (unsigned long addr, int type, struct netent *net,
|
||||
char *buffer, size_t buflen, int *herrnop)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
char *domain;
|
||||
char *result;
|
||||
int len;
|
||||
char buf[256];
|
||||
int blen;
|
||||
struct in_addr in;
|
||||
char *p;
|
||||
|
||||
if (yp_get_default_domain (&domain))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
in = inet_makeaddr (addr, 0);
|
||||
strcpy (buf, inet_ntoa (in));
|
||||
blen = strlen (buf);
|
||||
|
||||
while (1)
|
||||
{
|
||||
enum nss_status retval;
|
||||
int parse_res;
|
||||
|
||||
retval = yperr2nss (yp_match (domain, "networks.byaddr", buf,
|
||||
strlen (buf), &result, &len));
|
||||
|
||||
if (retval != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if (retval == NSS_STATUS_NOTFOUND)
|
||||
{
|
||||
if (buf[blen - 2] == '.' && buf[blen - 1] == '0')
|
||||
{
|
||||
/* Try again, but with trailing dot(s)
|
||||
removed (one by one) */
|
||||
buf[blen - 2] = '\0';
|
||||
blen -= 2;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (retval == NSS_STATUS_TRYAGAIN)
|
||||
__set_errno (EAGAIN);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
if ((size_t) (len + 1) > buflen)
|
||||
{
|
||||
free (result);
|
||||
__set_errno (ERANGE);
|
||||
*herrnop = NETDB_INTERNAL;
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
p = strncpy (buffer, result, len);
|
||||
buffer[len] = '\0';
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
free (result);
|
||||
|
||||
parse_res = _nss_files_parse_netent (p, net, data, buflen);
|
||||
|
||||
|
||||
if (parse_res <= 0)
|
||||
{
|
||||
*herrnop = NETDB_INTERNAL;
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
else
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
else
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <nss.h>
|
||||
#include <glibc-compat/include/netdb.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include <rpcsvc/yp.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include "nss-nis.h"
|
||||
|
||||
/* Get the declaration of the parser function. */
|
||||
#define ENTNAME protoent
|
||||
#define EXTERN_PARSER
|
||||
#include "../nss_files/files-parse.c"
|
||||
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
struct response
|
||||
{
|
||||
char *val;
|
||||
struct response *next;
|
||||
};
|
||||
|
||||
static struct response *start = NULL;
|
||||
static struct response *next = NULL;
|
||||
|
||||
static int
|
||||
saveit (int instatus, char *inkey, int inkeylen, char *inval,
|
||||
int invallen, char *indata)
|
||||
{
|
||||
if (instatus != YP_TRUE)
|
||||
return instatus;
|
||||
|
||||
if (inkey && inkeylen > 0 && inval && invallen > 0)
|
||||
{
|
||||
if (start == NULL)
|
||||
{
|
||||
start = malloc (sizeof (struct response));
|
||||
next = start;
|
||||
}
|
||||
else
|
||||
{
|
||||
next->next = malloc (sizeof (struct response));
|
||||
next = next->next;
|
||||
}
|
||||
next->next = NULL;
|
||||
next->val = malloc (invallen + 1);
|
||||
strncpy (next->val, inval, invallen);
|
||||
next->val[invallen] = '\0';
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
internal_nis_setprotoent (void)
|
||||
{
|
||||
char *domainname;
|
||||
struct ypall_callback ypcb;
|
||||
enum nss_status status;
|
||||
|
||||
yp_get_default_domain (&domainname);
|
||||
|
||||
while (start != NULL)
|
||||
{
|
||||
if (start->val != NULL)
|
||||
free (start->val);
|
||||
next = start;
|
||||
start = start->next;
|
||||
free (next);
|
||||
}
|
||||
start = NULL;
|
||||
|
||||
ypcb.foreach = saveit;
|
||||
ypcb.data = NULL;
|
||||
status = yperr2nss (yp_all (domainname, "protocols.bynumber", &ypcb));
|
||||
next = start;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_setprotoent (void)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_nis_setprotoent ();
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_endprotoent (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
while (start != NULL)
|
||||
{
|
||||
if (start->val != NULL)
|
||||
free (start->val);
|
||||
next = start;
|
||||
start = start->next;
|
||||
free (next);
|
||||
}
|
||||
start = NULL;
|
||||
next = NULL;
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
internal_nis_getprotoent_r (struct protoent *proto,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
int parse_res;
|
||||
|
||||
if (start == NULL)
|
||||
internal_nis_setprotoent ();
|
||||
|
||||
/* Get the next entry until we found a correct one. */
|
||||
do
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (next == NULL)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
p = strncpy (buffer, next->val, buflen);
|
||||
next = next->next;
|
||||
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
|
||||
parse_res = _nss_files_parse_protoent (p, proto, data, buflen);
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
while (!parse_res);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getprotoent_r (struct protoent *proto, char *buffer, size_t buflen)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_nis_getprotoent_r (proto, buffer, buflen);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getprotobyname_r (const char *name, struct protoent *proto,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
enum nss_status retval;
|
||||
char *domain, *result, *p;
|
||||
int len, parse_res;
|
||||
|
||||
if (name == NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
if (yp_get_default_domain (&domain))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
retval = yperr2nss (yp_match (domain, "protocols.byname", name,
|
||||
strlen (name), &result, &len));
|
||||
|
||||
if (retval != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if (retval == NSS_STATUS_TRYAGAIN)
|
||||
__set_errno (EAGAIN);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if ((size_t) (len + 1) > buflen)
|
||||
{
|
||||
free (result);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
p = strncpy (buffer, result, len);
|
||||
buffer[len] = '\0';
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
free (result);
|
||||
|
||||
parse_res = _nss_files_parse_protoent (p, proto, data, buflen);
|
||||
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
else if (parse_res == 0)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getprotobynumber_r (int number, struct protoent *proto,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
enum nss_status retval;
|
||||
char *domain, *result, *p;
|
||||
int len, nlen, parse_res;
|
||||
char buf[32];
|
||||
|
||||
if (yp_get_default_domain (&domain))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
nlen = sprintf (buf, "%d", number);
|
||||
|
||||
retval = yperr2nss (yp_match (domain, "protocols.bynumber", buf,
|
||||
nlen, &result, &len));
|
||||
|
||||
if (retval != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if (retval == NSS_STATUS_TRYAGAIN)
|
||||
__set_errno (EAGAIN);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if ((size_t) (len + 1) > buflen)
|
||||
{
|
||||
free (result);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
p = strncpy (buffer, result, len);
|
||||
buffer[len] = '\0';
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
free (result);
|
||||
|
||||
parse_res = _nss_files_parse_protoent (p, proto, data, buflen);
|
||||
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
else if (parse_res == 0)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,407 @@
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <nss.h>
|
||||
#include <glibc-compat/include/pwd.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include <rpcsvc/yp.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include "nss-nis.h"
|
||||
|
||||
/* Get the declaration of the parser function. */
|
||||
#define ENTNAME pwent
|
||||
#define STRUCTURE passwd
|
||||
#define EXTERN_PARSER
|
||||
#include "../nss_files/files-parse.c"
|
||||
|
||||
/* Protect global state against multiple changers */
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
static bool_t new_start = 1;
|
||||
static char *oldkey = NULL;
|
||||
static int oldkeylen = 0;
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_setpwent (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
new_start = 1;
|
||||
if (oldkey != NULL)
|
||||
{
|
||||
free (oldkey);
|
||||
oldkey = NULL;
|
||||
oldkeylen = 0;
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_endpwent (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
new_start = 1;
|
||||
if (oldkey != NULL)
|
||||
{
|
||||
free (oldkey);
|
||||
oldkey = NULL;
|
||||
oldkeylen = 0;
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
internal_nis_getpwent_r (struct passwd *pwd, char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
char *domain;
|
||||
int parse_res;
|
||||
|
||||
if (yp_get_default_domain (&domain))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
/* Get the next entry until we found a correct one. */
|
||||
do
|
||||
{
|
||||
enum nss_status retval;
|
||||
char *result, *outkey, *result2, *p;
|
||||
int len, keylen, len2;
|
||||
size_t namelen;
|
||||
|
||||
if (new_start)
|
||||
retval = yperr2nss (yp_first (domain, "passwd.byname",
|
||||
&outkey, &keylen, &result, &len));
|
||||
else
|
||||
retval = yperr2nss ( yp_next (domain, "passwd.byname",
|
||||
oldkey, oldkeylen,
|
||||
&outkey, &keylen, &result, &len));
|
||||
|
||||
if (retval != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if (retval == NSS_STATUS_TRYAGAIN)
|
||||
__set_errno (EAGAIN);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Check for adjunct style secret passwords. They can be
|
||||
recognized by a password starting with "##". */
|
||||
p = strchr (result, ':');
|
||||
if (p != NULL /* This better should be true in all cases. */
|
||||
&& p[1] == '#' && p[2] == '#'
|
||||
&& (namelen = p - result,
|
||||
yp_match (domain, "passwd.adjunct.byname", result, namelen,
|
||||
&result2, &len2)) == YPERR_SUCCESS)
|
||||
{
|
||||
/* We found a passwd.adjunct entry. Merge encrypted
|
||||
password therein into original result. */
|
||||
char *encrypted = strchr (result2, ':');
|
||||
char *endp, *tmp;
|
||||
size_t restlen;
|
||||
|
||||
if (encrypted == NULL
|
||||
|| (endp = strchr (++encrypted, ':')) == NULL
|
||||
|| (p = strchr (p + 1, ':')) == NULL)
|
||||
{
|
||||
/* Invalid format of the entry. This never should happen
|
||||
unless the data from which the NIS table is generated is
|
||||
wrong. We simply ignore it. */
|
||||
free (result2);
|
||||
goto non_adjunct;
|
||||
}
|
||||
|
||||
restlen = len - (p - result);
|
||||
if ((size_t) (namelen + (endp - encrypted) + restlen + 2) > buflen)
|
||||
{
|
||||
free (result2);
|
||||
free (result);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
memcpy (buffer, result, namelen);
|
||||
tmp = buffer + namelen;
|
||||
*tmp++ = ':';
|
||||
memcpy (tmp, encrypted, endp - encrypted);
|
||||
tmp += endp - encrypted;
|
||||
memcpy (tmp, p, restlen + 1);
|
||||
p = buffer;
|
||||
|
||||
free (result2);
|
||||
}
|
||||
else
|
||||
{
|
||||
non_adjunct:
|
||||
if ((size_t) (len + 1) > buflen)
|
||||
{
|
||||
free (result);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
p = strncpy (buffer, result, len);
|
||||
buffer[len] = '\0';
|
||||
}
|
||||
|
||||
p = strncpy (buffer, result, len);
|
||||
buffer[len] = '\0';
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
free (result);
|
||||
|
||||
parse_res = _nss_files_parse_pwent (p, pwd, data, buflen);
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
|
||||
free (oldkey);
|
||||
oldkey = outkey;
|
||||
oldkeylen = keylen;
|
||||
new_start = 0;
|
||||
}
|
||||
while (!parse_res);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getpwent_r (struct passwd *result, char *buffer, size_t buflen)
|
||||
{
|
||||
int status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_nis_getpwent_r (result, buffer, buflen);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getpwnam_r (const char *name, struct passwd *pwd,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
enum nss_status retval;
|
||||
char *domain, *result, *result2, *p;
|
||||
int len, len2, parse_res;
|
||||
size_t namelen;
|
||||
|
||||
if (name == NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
if (yp_get_default_domain (&domain))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
namelen = strlen (name);
|
||||
|
||||
retval = yperr2nss (yp_match (domain, "passwd.byname", name,
|
||||
namelen, &result, &len));
|
||||
|
||||
if (retval != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if (retval == NSS_STATUS_TRYAGAIN)
|
||||
__set_errno (EAGAIN);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Check for adjunct style secret passwords. They can be recognized
|
||||
by a password starting with "##". */
|
||||
p = strchr (result, ':');
|
||||
if (p != NULL /* This better should be true in all cases. */
|
||||
&& p[1] == '#' && p[2] == '#'
|
||||
&& (namelen = p - result,
|
||||
yp_match (domain, "passwd.adjunct.byname", name, namelen,
|
||||
&result2, &len2)) == YPERR_SUCCESS)
|
||||
{
|
||||
/* We found a passwd.adjunct entry. Merge encrypted password
|
||||
therein into original result. */
|
||||
char *encrypted = strchr (result2, ':');
|
||||
char *endp, *tmp;
|
||||
size_t restlen;
|
||||
|
||||
if (encrypted == NULL
|
||||
|| (endp = strchr (++encrypted, ':')) == NULL
|
||||
|| (p = strchr (p + 1, ':')) == NULL)
|
||||
{
|
||||
/* Invalid format of the entry. This never should happen
|
||||
unless the data from which the NIS table is generated is
|
||||
wrong. We simply ignore it. */
|
||||
free (result2);
|
||||
goto non_adjunct;
|
||||
}
|
||||
|
||||
restlen = len - (p - result);
|
||||
if ((size_t) (namelen + (endp - encrypted) + restlen + 2) > buflen)
|
||||
{
|
||||
free (result2);
|
||||
free (result);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
memcpy (buffer, name, namelen);
|
||||
tmp = buffer + namelen;
|
||||
*tmp++ = ':';
|
||||
memcpy (tmp, encrypted, endp - encrypted);
|
||||
tmp += endp - encrypted;
|
||||
memcpy (tmp, p, restlen + 1);
|
||||
p = buffer;
|
||||
|
||||
free (result2);
|
||||
}
|
||||
else
|
||||
{
|
||||
non_adjunct:
|
||||
if ((size_t) (len + 1) > buflen)
|
||||
{
|
||||
free (result);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
p = strncpy (buffer, result, len);
|
||||
buffer[len] = '\0';
|
||||
}
|
||||
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
free (result);
|
||||
|
||||
parse_res = _nss_files_parse_pwent (p, pwd, data, buflen);
|
||||
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
else if (parse_res == 0)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getpwuid_r (uid_t uid, struct passwd *pwd,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
enum nss_status retval;
|
||||
char *domain, *result, *p, *result2;
|
||||
int len, nlen, parse_res, len2;
|
||||
char buf[32];
|
||||
size_t namelen;
|
||||
|
||||
if (yp_get_default_domain (&domain))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
nlen = sprintf (buf, "%d", uid);
|
||||
|
||||
retval = yperr2nss (yp_match (domain, "passwd.byuid", buf,
|
||||
nlen, &result, &len));
|
||||
|
||||
if (retval != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if (retval == NSS_STATUS_TRYAGAIN)
|
||||
__set_errno (EAGAIN);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Check for adjunct style secret passwords. They can be recognized
|
||||
by a password starting with "##". */
|
||||
p = strchr (result, ':');
|
||||
if (p != NULL /* This better should be true in all cases. */
|
||||
&& p[1] == '#' && p[2] == '#'
|
||||
&& (namelen = p - result,
|
||||
yp_match (domain, "passwd.adjunct.byname", result, namelen,
|
||||
&result2, &len2)) == YPERR_SUCCESS)
|
||||
{
|
||||
/* We found a passwd.adjunct entry. Merge encrypted password
|
||||
therein into original result. */
|
||||
char *encrypted = strchr (result2, ':');
|
||||
char *endp, *tmp;
|
||||
size_t restlen;
|
||||
|
||||
if (encrypted == NULL
|
||||
|| (endp = strchr (++encrypted, ':')) == NULL
|
||||
|| (p = strchr (p + 1, ':')) == NULL)
|
||||
{
|
||||
/* Invalid format of the entry. This never should happen
|
||||
unless the data from which the NIS table is generated is
|
||||
wrong. We simply ignore it. */
|
||||
free (result2);
|
||||
goto non_adjunct;
|
||||
}
|
||||
|
||||
restlen = len - (p - result);
|
||||
if ((size_t) (namelen + (endp - encrypted) + restlen + 2) > buflen)
|
||||
{
|
||||
free (result2);
|
||||
free (result);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
memcpy (buffer, result, namelen);
|
||||
tmp = buffer + namelen;
|
||||
*tmp++ = ':';
|
||||
memcpy (tmp, encrypted, endp - encrypted);
|
||||
tmp += endp - encrypted;
|
||||
memcpy (tmp, p, restlen + 1);
|
||||
p = buffer;
|
||||
|
||||
free (result2);
|
||||
}
|
||||
else
|
||||
{
|
||||
non_adjunct:
|
||||
if ((size_t) (len + 1) > buflen)
|
||||
{
|
||||
free (result);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
p = strncpy (buffer, result, len);
|
||||
buffer[len] = '\0';
|
||||
}
|
||||
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
free (result);
|
||||
|
||||
parse_res = _nss_files_parse_pwent (p, pwd, data, buflen);
|
||||
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
else if (parse_res == 0)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,295 @@
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <nss.h>
|
||||
#include <glibc-compat/include/netdb.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include <rpcsvc/yp.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include "nss-nis.h"
|
||||
|
||||
/* Get the declaration of the parser function. */
|
||||
#define ENTNAME rpcent
|
||||
#define EXTERN_PARSER
|
||||
#include "../nss_files/files-parse.c"
|
||||
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
struct response_t
|
||||
{
|
||||
char *val;
|
||||
struct response_t *next;
|
||||
};
|
||||
|
||||
struct intern_t
|
||||
{
|
||||
struct response_t *start;
|
||||
struct response_t *next;
|
||||
};
|
||||
typedef struct intern_t intern_t;
|
||||
|
||||
static intern_t intern = {NULL, NULL};
|
||||
|
||||
static int
|
||||
saveit (int instatus, char *inkey, int inkeylen, char *inval,
|
||||
int invallen, char *indata)
|
||||
{
|
||||
intern_t *intern = (intern_t *)indata;
|
||||
|
||||
if (instatus != YP_TRUE)
|
||||
return instatus;
|
||||
|
||||
if (inkey && inkeylen > 0 && inval && invallen > 0)
|
||||
{
|
||||
if (intern->start == NULL)
|
||||
{
|
||||
intern->start = malloc (sizeof (struct response_t));
|
||||
intern->next = intern->start;
|
||||
}
|
||||
else
|
||||
{
|
||||
intern->next->next = malloc (sizeof (struct response_t));
|
||||
intern->next = intern->next->next;
|
||||
}
|
||||
intern->next->next = NULL;
|
||||
intern->next->val = malloc (invallen + 1);
|
||||
strncpy (intern->next->val, inval, invallen);
|
||||
intern->next->val[invallen] = '\0';
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
internal_nis_setrpcent (intern_t *intern)
|
||||
{
|
||||
char *domainname;
|
||||
struct ypall_callback ypcb;
|
||||
enum nss_status status;
|
||||
|
||||
if (yp_get_default_domain (&domainname))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
while (intern->start != NULL)
|
||||
{
|
||||
if (intern->start->val != NULL)
|
||||
free (intern->start->val);
|
||||
intern->next = intern->start;
|
||||
intern->start = intern->start->next;
|
||||
free (intern->next);
|
||||
}
|
||||
intern->start = NULL;
|
||||
|
||||
ypcb.foreach = saveit;
|
||||
ypcb.data = (char *)intern;
|
||||
status = yperr2nss (yp_all(domainname, "rpc.bynumber", &ypcb));
|
||||
intern->next = intern->start;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_setrpcent (void)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_nis_setrpcent (&intern);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
internal_nis_endrpcent (intern_t *intern)
|
||||
{
|
||||
while (intern->start != NULL)
|
||||
{
|
||||
if (intern->start->val != NULL)
|
||||
free (intern->start->val);
|
||||
intern->next = intern->start;
|
||||
intern->start = intern->start->next;
|
||||
free (intern->next);
|
||||
}
|
||||
intern->start = NULL;
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_endrpcent (void)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_nis_endrpcent (&intern);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
internal_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen,
|
||||
intern_t *data)
|
||||
{
|
||||
struct parser_data *pdata = (void *) buffer;
|
||||
int parse_res;
|
||||
char *p;
|
||||
|
||||
if (data->start == NULL)
|
||||
internal_nis_setrpcent (data);
|
||||
|
||||
/* Get the next entry until we found a correct one. */
|
||||
do
|
||||
{
|
||||
if (data->next == NULL)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
p = strncpy (buffer, data->next->val, buflen);
|
||||
data->next = data->next->next;
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
|
||||
parse_res = _nss_files_parse_rpcent (p, rpc, pdata, buflen);
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
while (!parse_res);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_nis_getrpcent_r (rpc, buffer, buflen, &intern);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getrpcbyname_r (const char *name, struct rpcent *rpc,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
intern_t data = {NULL, NULL};
|
||||
enum nss_status status;
|
||||
int found;
|
||||
|
||||
if (name == NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
status = internal_nis_setrpcent (&data);
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
found = 0;
|
||||
while (!found &&
|
||||
((status = internal_nis_getrpcent_r (rpc, buffer, buflen, &data))
|
||||
== NSS_STATUS_SUCCESS))
|
||||
{
|
||||
if (strcmp (rpc->r_name, name) == 0)
|
||||
found = 1;
|
||||
else
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (rpc->r_aliases[i] != NULL)
|
||||
{
|
||||
if (strcmp (rpc->r_aliases[i], name) == 0)
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal_nis_endrpcent (&data);
|
||||
|
||||
if (!found && status == NSS_STATUS_SUCCESS)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
else
|
||||
return status;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getrpcbynumber_r (int number, struct rpcent *rpc,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
enum nss_status retval;
|
||||
char *domain, *result, *p;
|
||||
int len, nlen, parse_res;
|
||||
char buf[32];
|
||||
|
||||
if (yp_get_default_domain (&domain))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
nlen = sprintf (buf, "%d", number);
|
||||
|
||||
retval = yperr2nss (yp_match (domain, "rpc.bynumber", buf,
|
||||
nlen, &result, &len));
|
||||
|
||||
if (retval != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if (retval == NSS_STATUS_TRYAGAIN)
|
||||
__set_errno (EAGAIN);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if ((size_t) (len + 1) > buflen)
|
||||
{
|
||||
free (result);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
p = strncpy (buffer, result, len);
|
||||
buffer[len] = '\0';
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
free (result);
|
||||
|
||||
parse_res = _nss_files_parse_rpcent (p, rpc, data, buflen);
|
||||
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
else if (parse_res == 0)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <nss.h>
|
||||
#include <glibc-compat/include/netdb.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include <rpcsvc/yp.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include "nss-nis.h"
|
||||
|
||||
/* Get the declaration of the parser function. */
|
||||
#define ENTNAME servent
|
||||
#define EXTERN_PARSER
|
||||
#include "../nss_files/files-parse.c"
|
||||
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
struct response_t
|
||||
{
|
||||
char *val;
|
||||
struct response_t *next;
|
||||
};
|
||||
|
||||
struct intern_t
|
||||
{
|
||||
struct response_t *start;
|
||||
struct response_t *next;
|
||||
};
|
||||
typedef struct intern_t intern_t;
|
||||
|
||||
static intern_t intern = { NULL, NULL };
|
||||
|
||||
static int
|
||||
saveit (int instatus, char *inkey, int inkeylen, char *inval,
|
||||
int invallen, char *indata)
|
||||
{
|
||||
intern_t *intern = (intern_t *) indata;
|
||||
|
||||
if (instatus != YP_TRUE)
|
||||
return instatus;
|
||||
|
||||
if (inkey && inkeylen > 0 && inval && invallen > 0)
|
||||
{
|
||||
if (intern->start == NULL)
|
||||
{
|
||||
intern->start = malloc (sizeof (struct response_t));
|
||||
intern->next = intern->start;
|
||||
}
|
||||
else
|
||||
{
|
||||
intern->next->next = malloc (sizeof (struct response_t));
|
||||
intern->next = intern->next->next;
|
||||
}
|
||||
intern->next->next = NULL;
|
||||
intern->next->val = malloc (invallen + 1);
|
||||
strncpy (intern->next->val, inval, invallen);
|
||||
intern->next->val[invallen] = '\0';
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
internal_nis_setservent (intern_t *intern)
|
||||
{
|
||||
char *domainname;
|
||||
struct ypall_callback ypcb;
|
||||
enum nss_status status;
|
||||
|
||||
if (yp_get_default_domain (&domainname))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
while (intern->start != NULL)
|
||||
{
|
||||
if (intern->start->val != NULL)
|
||||
free (intern->start->val);
|
||||
intern->next = intern->start;
|
||||
intern->start = intern->start->next;
|
||||
free (intern->next);
|
||||
}
|
||||
intern->start = NULL;
|
||||
|
||||
ypcb.foreach = saveit;
|
||||
ypcb.data = (char *) intern;
|
||||
status = yperr2nss (yp_all (domainname, "services.byname", &ypcb));
|
||||
intern->next = intern->start;
|
||||
|
||||
return status;
|
||||
}
|
||||
enum nss_status
|
||||
_nss_nis_setservent (void)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_nis_setservent (&intern);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
internal_nis_endservent (intern_t * intern)
|
||||
{
|
||||
while (intern->start != NULL)
|
||||
{
|
||||
if (intern->start->val != NULL)
|
||||
free (intern->start->val);
|
||||
intern->next = intern->start;
|
||||
intern->start = intern->start->next;
|
||||
free (intern->next);
|
||||
}
|
||||
intern->start = NULL;
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_endservent (void)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_nis_endservent (&intern);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
internal_nis_getservent_r (struct servent *serv, char *buffer,
|
||||
size_t buflen, intern_t *data)
|
||||
{
|
||||
struct parser_data *pdata = (void *) buffer;
|
||||
int parse_res;
|
||||
char *p;
|
||||
|
||||
if (data->start == NULL)
|
||||
internal_nis_setservent (data);
|
||||
|
||||
/* Get the next entry until we found a correct one. */
|
||||
do
|
||||
{
|
||||
if (data->next == NULL)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
p = strncpy (buffer, data->next->val, buflen);
|
||||
data->next = data->next->next;
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
|
||||
parse_res = _nss_files_parse_servent (p, serv, pdata, buflen);
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
while (!parse_res);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getservent_r (struct servent *serv, char *buffer, size_t buflen)
|
||||
{
|
||||
enum nss_status status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_nis_getservent_r (serv, buffer, buflen, &intern);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getservbyname_r (const char *name, char *protocol,
|
||||
struct servent *serv, char *buffer, size_t buflen)
|
||||
{
|
||||
intern_t data = { NULL, NULL };
|
||||
enum nss_status status;
|
||||
int found;
|
||||
|
||||
if (name == NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
status = internal_nis_setservent (&data);
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
found = 0;
|
||||
while (!found &&
|
||||
((status = internal_nis_getservent_r (serv, buffer, buflen, &data))
|
||||
== NSS_STATUS_SUCCESS))
|
||||
{
|
||||
if (protocol == NULL || strcmp (serv->s_proto, protocol) == 0)
|
||||
{
|
||||
char **cp;
|
||||
|
||||
if (strcmp (serv->s_name, name) == 0)
|
||||
found = 1;
|
||||
else
|
||||
for (cp = serv->s_aliases; *cp; cp++)
|
||||
if (strcmp (name, *cp) == 0)
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
internal_nis_endservent (&data);
|
||||
|
||||
if (!found && status == NSS_STATUS_SUCCESS)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
else
|
||||
return status;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getservbyport_r (int port, char *protocol, struct servent *serv,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
intern_t data = { NULL, NULL };
|
||||
enum nss_status status;
|
||||
int found;
|
||||
|
||||
if (protocol == NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
status = internal_nis_setservent (&data);
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
return status;
|
||||
|
||||
found = 0;
|
||||
while (!found &&
|
||||
((status = internal_nis_getservent_r (serv, buffer, buflen, &data))
|
||||
== NSS_STATUS_SUCCESS))
|
||||
{
|
||||
if (htons (serv->s_port) == port)
|
||||
{
|
||||
if (strcmp (serv->s_proto, protocol) == 0)
|
||||
{
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal_nis_endservent (&data);
|
||||
|
||||
if (!found && status == NSS_STATUS_SUCCESS)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
else
|
||||
return status;
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <nss.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <glibc-compat/include/shadow.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include <rpcsvc/yp.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include "nss-nis.h"
|
||||
|
||||
/* Get the declaration of the parser function. */
|
||||
#define ENTNAME spent
|
||||
#define STRUCTURE spwd
|
||||
#define EXTERN_PARSER
|
||||
#include "../nss_files/files-parse.c"
|
||||
|
||||
/* Protect global state against multiple changers */
|
||||
__libc_lock_define_initialized (static, lock)
|
||||
|
||||
static bool_t new_start = 1;
|
||||
static char *oldkey = NULL;
|
||||
static int oldkeylen = 0;
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_setspent (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
new_start = 1;
|
||||
if (oldkey != NULL)
|
||||
{
|
||||
free (oldkey);
|
||||
oldkey = NULL;
|
||||
oldkeylen = 0;
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_endspent (void)
|
||||
{
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
new_start = 1;
|
||||
if (oldkey != NULL)
|
||||
{
|
||||
free (oldkey);
|
||||
oldkey = NULL;
|
||||
oldkeylen = 0;
|
||||
}
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static enum nss_status
|
||||
internal_nis_getspent_r (struct spwd *sp, char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
char *domain, *result, *outkey;
|
||||
int len, keylen, parse_res;
|
||||
|
||||
if (yp_get_default_domain (&domain))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
/* Get the next entry until we found a correct one. */
|
||||
do
|
||||
{
|
||||
enum nss_status retval;
|
||||
char *p;
|
||||
|
||||
if (new_start)
|
||||
retval = yperr2nss (yp_first (domain, "shadow.byname",
|
||||
&outkey, &keylen, &result, &len));
|
||||
else
|
||||
retval = yperr2nss ( yp_next (domain, "shadow.byname",
|
||||
oldkey, oldkeylen,
|
||||
&outkey, &keylen, &result, &len));
|
||||
|
||||
if (retval != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if (retval == NSS_STATUS_TRYAGAIN)
|
||||
__set_errno (EAGAIN);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if ((size_t) (len + 1) > buflen)
|
||||
{
|
||||
free (result);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
p = strncpy (buffer, result, len);
|
||||
buffer[len] = '\0';
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
free (result);
|
||||
|
||||
parse_res = _nss_files_parse_spent (p, sp, data, buflen);
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
|
||||
free (oldkey);
|
||||
oldkey = outkey;
|
||||
oldkeylen = keylen;
|
||||
new_start = 0;
|
||||
}
|
||||
while (!parse_res);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getspent_r (struct spwd *result, char *buffer, size_t buflen)
|
||||
{
|
||||
int status;
|
||||
|
||||
__libc_lock_lock (lock);
|
||||
|
||||
status = internal_nis_getspent_r (result, buffer, buflen);
|
||||
|
||||
__libc_lock_unlock (lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
enum nss_status
|
||||
_nss_nis_getspnam_r (const char *name, struct spwd *sp,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
struct parser_data *data = (void *) buffer;
|
||||
enum nss_status retval;
|
||||
char *domain, *result, *p;
|
||||
int len, parse_res;
|
||||
|
||||
if (name == NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
if (yp_get_default_domain (&domain))
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
retval = yperr2nss (yp_match (domain, "shadow.byname", name,
|
||||
strlen (name), &result, &len));
|
||||
|
||||
if (retval != NSS_STATUS_SUCCESS)
|
||||
{
|
||||
if (retval == NSS_STATUS_TRYAGAIN)
|
||||
__set_errno (EAGAIN);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if ((size_t) (len + 1) > buflen)
|
||||
{
|
||||
free (result);
|
||||
__set_errno (ERANGE);
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
}
|
||||
|
||||
p = strncpy (buffer, result, len);
|
||||
buffer[len] = '\0';
|
||||
while (isspace (*p))
|
||||
++p;
|
||||
free (result);
|
||||
|
||||
parse_res = _nss_files_parse_spent (p, sp, data, buflen);
|
||||
|
||||
if (parse_res == -1 && errno == ERANGE)
|
||||
return NSS_STATUS_TRYAGAIN;
|
||||
else if (parse_res == 0)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,774 @@
|
||||
/* Copyright (C) 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU IO Library.
|
||||
Written by Per Bothner <bothner@cygnus.com>.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2, or (at
|
||||
your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this library; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
|
||||
MA 02111-1307, USA.
|
||||
|
||||
As a special exception, if you link this library with files
|
||||
compiled with a GNU compiler to produce an executable, this does
|
||||
not cause the resulting executable to be covered by the GNU General
|
||||
Public License. This exception does not however invalidate any
|
||||
other reasons why the executable file might be covered by the GNU
|
||||
General Public License. */
|
||||
|
||||
/* This is a compatibility file. If we don't build the libc with
|
||||
versioning don't compile this file. */
|
||||
|
||||
#ifndef _POSIX_SOURCE
|
||||
# define _POSIX_SOURCE
|
||||
#endif
|
||||
#define _IO_USE_OLD_IO_FILE
|
||||
#include "libioP.h"
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif
|
||||
#ifndef __set_errno
|
||||
# define __set_errno(Val) errno = (Val)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _LIBC
|
||||
# define open(Name, Flags, Prot) __open (Name, Flags, Prot)
|
||||
# define close(FD) __close (FD)
|
||||
# define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence)
|
||||
# define read(FD, Buf, NBytes) __read (FD, Buf, NBytes)
|
||||
# define write(FD, Buf, NBytes) __write (FD, Buf, NBytes)
|
||||
#endif
|
||||
|
||||
/* An fstream can be in at most one of put mode, get mode, or putback mode.
|
||||
Putback mode is a variant of get mode.
|
||||
|
||||
In a filebuf, there is only one current position, instead of two
|
||||
separate get and put pointers. In get mode, the current position
|
||||
is that of gptr(); in put mode that of pptr().
|
||||
|
||||
The position in the buffer that corresponds to the position
|
||||
in external file system is normally _IO_read_end, except in putback
|
||||
mode, when it is _IO_save_end.
|
||||
If the field _fb._offset is >= 0, it gives the offset in
|
||||
the file as a whole corresponding to eGptr(). (?)
|
||||
|
||||
PUT MODE:
|
||||
If a filebuf is in put mode, then all of _IO_read_ptr, _IO_read_end,
|
||||
and _IO_read_base are equal to each other. These are usually equal
|
||||
to _IO_buf_base, though not necessarily if we have switched from
|
||||
get mode to put mode. (The reason is to maintain the invariant
|
||||
that _IO_read_end corresponds to the external file position.)
|
||||
_IO_write_base is non-NULL and usually equal to _IO_base_base.
|
||||
We also have _IO_write_end == _IO_buf_end, but only in fully buffered mode.
|
||||
The un-flushed character are those between _IO_write_base and _IO_write_ptr.
|
||||
|
||||
GET MODE:
|
||||
If a filebuf is in get or putback mode, eback() != egptr().
|
||||
In get mode, the unread characters are between gptr() and egptr().
|
||||
The OS file position corresponds to that of egptr().
|
||||
|
||||
PUTBACK MODE:
|
||||
Putback mode is used to remember "excess" characters that have
|
||||
been sputbackc'd in a separate putback buffer.
|
||||
In putback mode, the get buffer points to the special putback buffer.
|
||||
The unread characters are the characters between gptr() and egptr()
|
||||
in the putback buffer, as well as the area between save_gptr()
|
||||
and save_egptr(), which point into the original reserve buffer.
|
||||
(The pointers save_gptr() and save_egptr() are the values
|
||||
of gptr() and egptr() at the time putback mode was entered.)
|
||||
The OS position corresponds to that of save_egptr().
|
||||
|
||||
LINE BUFFERED OUTPUT:
|
||||
During line buffered output, _IO_write_base==base() && epptr()==base().
|
||||
However, ptr() may be anywhere between base() and ebuf().
|
||||
This forces a call to filebuf::overflow(int C) on every put.
|
||||
If there is more space in the buffer, and C is not a '\n',
|
||||
then C is inserted, and pptr() incremented.
|
||||
|
||||
UNBUFFERED STREAMS:
|
||||
If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer.
|
||||
*/
|
||||
|
||||
#define CLOSED_FILEBUF_FLAGS \
|
||||
(_IO_IS_FILEBUF+_IO_NO_READS+_IO_NO_WRITES+_IO_TIED_PUT_GET)
|
||||
|
||||
|
||||
void
|
||||
_IO_old_file_init (fp)
|
||||
_IO_FILE *fp;
|
||||
{
|
||||
/* POSIX.1 allows another file handle to be used to change the position
|
||||
of our file descriptor. Hence we actually don't know the actual
|
||||
position before we do the first fseek (and until a following fflush). */
|
||||
fp->_old_offset = _IO_pos_BAD;
|
||||
fp->_IO_file_flags |= CLOSED_FILEBUF_FLAGS;
|
||||
|
||||
_IO_link_in(fp);
|
||||
fp->_vtable_offset = ((int) sizeof (struct _IO_FILE)
|
||||
- (int) sizeof (struct _IO_FILE_complete));
|
||||
fp->_fileno = -1;
|
||||
}
|
||||
|
||||
int
|
||||
_IO_old_file_close_it (fp)
|
||||
_IO_FILE *fp;
|
||||
{
|
||||
int write_status, close_status;
|
||||
if (!_IO_file_is_open (fp))
|
||||
return EOF;
|
||||
|
||||
write_status = _IO_old_do_flush (fp);
|
||||
|
||||
_IO_unsave_markers(fp);
|
||||
|
||||
close_status = _IO_SYSCLOSE (fp);
|
||||
|
||||
/* Free buffer. */
|
||||
_IO_setb (fp, NULL, NULL, 0);
|
||||
_IO_setg (fp, NULL, NULL, NULL);
|
||||
_IO_setp (fp, NULL, NULL);
|
||||
|
||||
_IO_un_link (fp);
|
||||
fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS;
|
||||
fp->_fileno = EOF;
|
||||
fp->_old_offset = _IO_pos_BAD;
|
||||
|
||||
return close_status ? close_status : write_status;
|
||||
}
|
||||
|
||||
void
|
||||
_IO_old_file_finish (fp, dummy)
|
||||
_IO_FILE *fp;
|
||||
int dummy;
|
||||
{
|
||||
if (_IO_file_is_open (fp))
|
||||
{
|
||||
_IO_old_do_flush (fp);
|
||||
if (!(fp->_flags & _IO_DELETE_DONT_CLOSE))
|
||||
_IO_SYSCLOSE (fp);
|
||||
}
|
||||
_IO_default_finish (fp, 0);
|
||||
}
|
||||
|
||||
_IO_FILE *
|
||||
_IO_old_file_fopen (fp, filename, mode)
|
||||
_IO_FILE *fp;
|
||||
const char *filename;
|
||||
const char *mode;
|
||||
{
|
||||
int oflags = 0, omode;
|
||||
int read_write, fdesc;
|
||||
int oprot = 0666;
|
||||
if (_IO_file_is_open (fp))
|
||||
return 0;
|
||||
switch (*mode++)
|
||||
{
|
||||
case 'r':
|
||||
omode = O_RDONLY;
|
||||
read_write = _IO_NO_WRITES;
|
||||
break;
|
||||
case 'w':
|
||||
omode = O_WRONLY;
|
||||
oflags = O_CREAT|O_TRUNC;
|
||||
read_write = _IO_NO_READS;
|
||||
break;
|
||||
case 'a':
|
||||
omode = O_WRONLY;
|
||||
oflags = O_CREAT|O_APPEND;
|
||||
read_write = _IO_NO_READS|_IO_IS_APPENDING;
|
||||
break;
|
||||
default:
|
||||
__set_errno (EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+'))
|
||||
{
|
||||
omode = O_RDWR;
|
||||
read_write &= _IO_IS_APPENDING;
|
||||
}
|
||||
fdesc = open (filename, omode|oflags, oprot);
|
||||
if (fdesc < 0)
|
||||
return NULL;
|
||||
fp->_fileno = fdesc;
|
||||
_IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
|
||||
if (read_write & _IO_IS_APPENDING)
|
||||
if (_IO_SEEKOFF (fp, (_IO_off_t)0, _IO_seek_end, _IOS_INPUT|_IOS_OUTPUT)
|
||||
== _IO_pos_BAD && errno != ESPIPE)
|
||||
return NULL;
|
||||
_IO_link_in (fp);
|
||||
return fp;
|
||||
}
|
||||
|
||||
_IO_FILE *
|
||||
_IO_old_file_attach (fp, fd)
|
||||
_IO_FILE *fp;
|
||||
int fd;
|
||||
{
|
||||
if (_IO_file_is_open (fp))
|
||||
return NULL;
|
||||
fp->_fileno = fd;
|
||||
fp->_flags &= ~(_IO_NO_READS+_IO_NO_WRITES);
|
||||
fp->_flags |= _IO_DELETE_DONT_CLOSE;
|
||||
/* Get the current position of the file. */
|
||||
/* We have to do that since that may be junk. */
|
||||
fp->_old_offset = _IO_pos_BAD;
|
||||
if (_IO_SEEKOFF (fp, (_IO_off_t)0, _IO_seek_cur, _IOS_INPUT|_IOS_OUTPUT)
|
||||
== _IO_pos_BAD && errno != ESPIPE)
|
||||
return NULL;
|
||||
return fp;
|
||||
}
|
||||
|
||||
_IO_FILE *
|
||||
_IO_old_file_setbuf (fp, p, len)
|
||||
_IO_FILE *fp;
|
||||
char *p;
|
||||
_IO_ssize_t len;
|
||||
{
|
||||
if (_IO_default_setbuf (fp, p, len) == NULL)
|
||||
return NULL;
|
||||
|
||||
fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
|
||||
= fp->_IO_buf_base;
|
||||
_IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
static int old_do_write (_IO_FILE *, const char *, _IO_size_t) __THROW;
|
||||
|
||||
/* Write TO_DO bytes from DATA to FP.
|
||||
Then mark FP as having empty buffers. */
|
||||
|
||||
int
|
||||
_IO_old_do_write (fp, data, to_do)
|
||||
_IO_FILE *fp;
|
||||
const char *data;
|
||||
_IO_size_t to_do;
|
||||
{
|
||||
return (to_do == 0 || old_do_write (fp, data, to_do) == to_do)
|
||||
? 0 : EOF;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
old_do_write (fp, data, to_do)
|
||||
_IO_FILE *fp;
|
||||
const char *data;
|
||||
_IO_size_t to_do;
|
||||
{
|
||||
_IO_size_t count;
|
||||
if (fp->_flags & _IO_IS_APPENDING)
|
||||
/* On a system without a proper O_APPEND implementation,
|
||||
you would need to sys_seek(0, SEEK_END) here, but is
|
||||
is not needed nor desirable for Unix- or Posix-like systems.
|
||||
Instead, just indicate that offset (before and after) is
|
||||
unpredictable. */
|
||||
fp->_old_offset = _IO_pos_BAD;
|
||||
else if (fp->_IO_read_end != fp->_IO_write_base)
|
||||
{
|
||||
_IO_pos_t new_pos
|
||||
= _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1);
|
||||
if (new_pos == _IO_pos_BAD)
|
||||
return 0;
|
||||
fp->_old_offset = new_pos;
|
||||
}
|
||||
count = _IO_SYSWRITE (fp, data, to_do);
|
||||
if (fp->_cur_column && count)
|
||||
fp->_cur_column = _IO_adjust_column (fp->_cur_column - 1, data, count) + 1;
|
||||
_IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
|
||||
fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base;
|
||||
fp->_IO_write_end = ((fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
|
||||
? fp->_IO_buf_base : fp->_IO_buf_end);
|
||||
return count;
|
||||
}
|
||||
|
||||
int
|
||||
_IO_old_file_underflow (fp)
|
||||
_IO_FILE *fp;
|
||||
{
|
||||
_IO_ssize_t count;
|
||||
#if 0
|
||||
/* SysV does not make this test; take it out for compatibility */
|
||||
if (fp->_flags & _IO_EOF_SEEN)
|
||||
return (EOF);
|
||||
#endif
|
||||
|
||||
if (fp->_flags & _IO_NO_READS)
|
||||
{
|
||||
__set_errno (EBADF);
|
||||
return EOF;
|
||||
}
|
||||
if (fp->_IO_read_ptr < fp->_IO_read_end)
|
||||
return *(unsigned char *) fp->_IO_read_ptr;
|
||||
|
||||
if (fp->_IO_buf_base == NULL)
|
||||
_IO_doallocbuf (fp);
|
||||
|
||||
/* Flush all line buffered files before reading. */
|
||||
/* FIXME This can/should be moved to genops ?? */
|
||||
if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED))
|
||||
_IO_flush_all_linebuffered ();
|
||||
|
||||
_IO_switch_to_get_mode (fp);
|
||||
|
||||
/* This is very tricky. We have to adjust those
|
||||
pointers before we call _IO_SYSREAD () since
|
||||
we may longjump () out while waiting for
|
||||
input. Those pointers may be screwed up. H.J. */
|
||||
fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base;
|
||||
fp->_IO_read_end = fp->_IO_buf_base;
|
||||
fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
|
||||
= fp->_IO_buf_base;
|
||||
|
||||
count = _IO_SYSREAD (fp, fp->_IO_buf_base,
|
||||
fp->_IO_buf_end - fp->_IO_buf_base);
|
||||
if (count <= 0)
|
||||
{
|
||||
if (count == 0)
|
||||
fp->_flags |= _IO_EOF_SEEN;
|
||||
else
|
||||
fp->_flags |= _IO_ERR_SEEN, count = 0;
|
||||
}
|
||||
fp->_IO_read_end += count;
|
||||
if (count == 0)
|
||||
return EOF;
|
||||
if (fp->_old_offset != _IO_pos_BAD)
|
||||
_IO_pos_adjust (fp->_old_offset, count);
|
||||
return *(unsigned char *) fp->_IO_read_ptr;
|
||||
}
|
||||
|
||||
int
|
||||
_IO_old_file_overflow (f, ch)
|
||||
_IO_FILE *f;
|
||||
int ch;
|
||||
{
|
||||
if (f->_flags & _IO_NO_WRITES) /* SET ERROR */
|
||||
{
|
||||
f->_flags |= _IO_ERR_SEEN;
|
||||
__set_errno (EBADF);
|
||||
return EOF;
|
||||
}
|
||||
/* If currently reading or no buffer allocated. */
|
||||
if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0)
|
||||
{
|
||||
/* Allocate a buffer if needed. */
|
||||
if (f->_IO_write_base == 0)
|
||||
{
|
||||
_IO_doallocbuf (f);
|
||||
_IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base);
|
||||
}
|
||||
/* Otherwise must be currently reading.
|
||||
If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end,
|
||||
logically slide the buffer forwards one block (by setting the
|
||||
read pointers to all point at the beginning of the block). This
|
||||
makes room for subsequent output.
|
||||
Otherwise, set the read pointers to _IO_read_end (leaving that
|
||||
alone, so it can continue to correspond to the external position). */
|
||||
if (f->_IO_read_ptr == f->_IO_buf_end)
|
||||
f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base;
|
||||
f->_IO_write_ptr = f->_IO_read_ptr;
|
||||
f->_IO_write_base = f->_IO_write_ptr;
|
||||
f->_IO_write_end = f->_IO_buf_end;
|
||||
f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end;
|
||||
|
||||
if (f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
|
||||
f->_IO_write_end = f->_IO_write_ptr;
|
||||
f->_flags |= _IO_CURRENTLY_PUTTING;
|
||||
}
|
||||
if (ch == EOF)
|
||||
return _IO_old_do_flush (f);
|
||||
if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */
|
||||
if (_IO_old_do_flush (f) == EOF)
|
||||
return EOF;
|
||||
*f->_IO_write_ptr++ = ch;
|
||||
if ((f->_flags & _IO_UNBUFFERED)
|
||||
|| ((f->_flags & _IO_LINE_BUF) && ch == '\n'))
|
||||
if (_IO_old_do_flush (f) == EOF)
|
||||
return EOF;
|
||||
return (unsigned char) ch;
|
||||
}
|
||||
|
||||
int
|
||||
_IO_old_file_sync (fp)
|
||||
_IO_FILE *fp;
|
||||
{
|
||||
_IO_size_t delta;
|
||||
int retval = 0;
|
||||
|
||||
_IO_cleanup_region_start ((void (*) (void *)) _IO_funlockfile, fp);
|
||||
_IO_flockfile (fp);
|
||||
/* char* ptr = cur_ptr(); */
|
||||
if (fp->_IO_write_ptr > fp->_IO_write_base)
|
||||
if (_IO_old_do_flush(fp)) return EOF;
|
||||
delta = fp->_IO_read_ptr - fp->_IO_read_end;
|
||||
if (delta != 0)
|
||||
{
|
||||
#ifdef TODO
|
||||
if (_IO_in_backup (fp))
|
||||
delta -= eGptr () - Gbase ();
|
||||
#endif
|
||||
_IO_off_t new_pos = _IO_SYSSEEK (fp, delta, 1);
|
||||
if (new_pos != (_IO_off_t) EOF)
|
||||
fp->_IO_read_end = fp->_IO_read_ptr;
|
||||
#ifdef ESPIPE
|
||||
else if (errno == ESPIPE)
|
||||
; /* Ignore error from unseekable devices. */
|
||||
#endif
|
||||
else
|
||||
retval = EOF;
|
||||
}
|
||||
if (retval != EOF)
|
||||
fp->_old_offset = _IO_pos_BAD;
|
||||
/* FIXME: Cleanup - can this be shared? */
|
||||
/* setg(base(), ptr, ptr); */
|
||||
_IO_funlockfile (fp);
|
||||
_IO_cleanup_region_end (0);
|
||||
return retval;
|
||||
}
|
||||
|
||||
_IO_fpos64_t
|
||||
_IO_old_file_seekoff (fp, offset, dir, mode)
|
||||
_IO_FILE *fp;
|
||||
_IO_off64_t offset;
|
||||
int dir;
|
||||
int mode;
|
||||
{
|
||||
_IO_pos_t result;
|
||||
_IO_off64_t delta, new_offset;
|
||||
long count;
|
||||
/* POSIX.1 8.2.3.7 says that after a call the fflush() the file
|
||||
offset of the underlying file must be exact. */
|
||||
int must_be_exact = (fp->_IO_read_base == fp->_IO_read_end
|
||||
&& fp->_IO_write_base == fp->_IO_write_ptr);
|
||||
|
||||
if (mode == 0)
|
||||
dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */
|
||||
|
||||
/* Flush unwritten characters.
|
||||
(This may do an unneeded write if we seek within the buffer.
|
||||
But to be able to switch to reading, we would need to set
|
||||
egptr to ptr. That can't be done in the current design,
|
||||
which assumes file_ptr() is eGptr. Anyway, since we probably
|
||||
end up flushing when we close(), it doesn't make much difference.)
|
||||
FIXME: simulate mem-papped files. */
|
||||
|
||||
if (fp->_IO_write_ptr > fp->_IO_write_base || _IO_in_put_mode (fp))
|
||||
if (_IO_switch_to_get_mode (fp))
|
||||
return EOF;
|
||||
|
||||
if (fp->_IO_buf_base == NULL)
|
||||
{
|
||||
_IO_doallocbuf (fp);
|
||||
_IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
|
||||
_IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
|
||||
}
|
||||
|
||||
switch (dir)
|
||||
{
|
||||
case _IO_seek_cur:
|
||||
/* Adjust for read-ahead (bytes is buffer). */
|
||||
offset -= fp->_IO_read_end - fp->_IO_read_ptr;
|
||||
if (fp->_old_offset == _IO_pos_BAD)
|
||||
goto dumb;
|
||||
/* Make offset absolute, assuming current pointer is file_ptr(). */
|
||||
offset += _IO_pos_as_off (fp->_old_offset);
|
||||
|
||||
dir = _IO_seek_set;
|
||||
break;
|
||||
case _IO_seek_set:
|
||||
break;
|
||||
case _IO_seek_end:
|
||||
{
|
||||
struct _G_stat64 st;
|
||||
if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
|
||||
{
|
||||
offset += st.st_size;
|
||||
dir = _IO_seek_set;
|
||||
}
|
||||
else
|
||||
goto dumb;
|
||||
}
|
||||
}
|
||||
/* At this point, dir==_IO_seek_set. */
|
||||
|
||||
/* If destination is within current buffer, optimize: */
|
||||
if (fp->_old_offset != _IO_pos_BAD && fp->_IO_read_base != NULL
|
||||
&& !_IO_in_backup (fp))
|
||||
{
|
||||
/* Offset relative to start of main get area. */
|
||||
_IO_pos_t rel_offset = (offset - fp->_old_offset
|
||||
+ (fp->_IO_read_end - fp->_IO_read_base));
|
||||
if (rel_offset >= 0)
|
||||
{
|
||||
#if 0
|
||||
if (_IO_in_backup (fp))
|
||||
_IO_switch_to_main_get_area (fp);
|
||||
#endif
|
||||
if (rel_offset <= fp->_IO_read_end - fp->_IO_read_base)
|
||||
{
|
||||
_IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + rel_offset,
|
||||
fp->_IO_read_end);
|
||||
_IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
|
||||
goto resync;
|
||||
}
|
||||
#ifdef TODO
|
||||
/* If we have streammarkers, seek forward by reading ahead. */
|
||||
if (_IO_have_markers (fp))
|
||||
{
|
||||
int to_skip = rel_offset
|
||||
- (fp->_IO_read_ptr - fp->_IO_read_base);
|
||||
if (ignore (to_skip) != to_skip)
|
||||
goto dumb;
|
||||
goto resync;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef TODO
|
||||
if (rel_offset < 0 && rel_offset >= Bbase () - Bptr ())
|
||||
{
|
||||
if (!_IO_in_backup (fp))
|
||||
_IO_switch_to_backup_area (fp);
|
||||
gbump (fp->_IO_read_end + rel_offset - fp->_IO_read_ptr);
|
||||
goto resync;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef TODO
|
||||
_IO_unsave_markers (fp);
|
||||
#endif
|
||||
|
||||
if (fp->_flags & _IO_NO_READS)
|
||||
goto dumb;
|
||||
|
||||
/* Try to seek to a block boundary, to improve kernel page management. */
|
||||
new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1);
|
||||
delta = offset - new_offset;
|
||||
if (delta > fp->_IO_buf_end - fp->_IO_buf_base)
|
||||
{
|
||||
new_offset = offset;
|
||||
delta = 0;
|
||||
}
|
||||
result = _IO_SYSSEEK (fp, new_offset, 0);
|
||||
if (result < 0)
|
||||
return EOF;
|
||||
if (delta == 0)
|
||||
count = 0;
|
||||
else
|
||||
{
|
||||
count = _IO_SYSREAD (fp, fp->_IO_buf_base,
|
||||
(must_be_exact
|
||||
? delta : fp->_IO_buf_end - fp->_IO_buf_base));
|
||||
if (count < delta)
|
||||
{
|
||||
/* We weren't allowed to read, but try to seek the remainder. */
|
||||
offset = count == EOF ? delta : delta-count;
|
||||
dir = _IO_seek_cur;
|
||||
goto dumb;
|
||||
}
|
||||
}
|
||||
_IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta,
|
||||
fp->_IO_buf_base + count);
|
||||
_IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
|
||||
fp->_old_offset = result + count;
|
||||
_IO_mask_flags (fp, 0, _IO_EOF_SEEN);
|
||||
return offset;
|
||||
dumb:
|
||||
|
||||
_IO_unsave_markers (fp);
|
||||
result = _IO_SYSSEEK (fp, offset, dir);
|
||||
if (result != EOF)
|
||||
{
|
||||
_IO_mask_flags (fp, 0, _IO_EOF_SEEN);
|
||||
fp->_old_offset = result;
|
||||
_IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
|
||||
_IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
|
||||
}
|
||||
return result;
|
||||
|
||||
resync:
|
||||
/* We need to do it since it is possible that the file offset in
|
||||
the kernel may be changed behind our back. It may happen when
|
||||
we fopen a file and then do a fork. One process may access the
|
||||
the file and the kernel file offset will be changed. */
|
||||
if (fp->_old_offset >= 0)
|
||||
_IO_SYSSEEK (fp, fp->_old_offset, 0);
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
_IO_ssize_t
|
||||
_IO_old_file_write (f, data, n)
|
||||
_IO_FILE *f;
|
||||
const void *data;
|
||||
_IO_ssize_t n;
|
||||
{
|
||||
_IO_ssize_t to_do = n;
|
||||
while (to_do > 0)
|
||||
{
|
||||
_IO_ssize_t count = write (f->_fileno, data, to_do);
|
||||
if (count == EOF)
|
||||
{
|
||||
f->_flags |= _IO_ERR_SEEN;
|
||||
break;
|
||||
}
|
||||
to_do -= count;
|
||||
data = (void *) ((char *) data + count);
|
||||
}
|
||||
n -= to_do;
|
||||
if (f->_old_offset >= 0)
|
||||
f->_old_offset += n;
|
||||
return n;
|
||||
}
|
||||
|
||||
_IO_size_t
|
||||
_IO_old_file_xsputn (f, data, n)
|
||||
_IO_FILE *f;
|
||||
const void *data;
|
||||
_IO_size_t n;
|
||||
{
|
||||
register const char *s = (char *) data;
|
||||
_IO_size_t to_do = n;
|
||||
int must_flush = 0;
|
||||
_IO_size_t count;
|
||||
|
||||
if (n <= 0)
|
||||
return 0;
|
||||
/* This is an optimized implementation.
|
||||
If the amount to be written straddles a block boundary
|
||||
(or the filebuf is unbuffered), use sys_write directly. */
|
||||
|
||||
/* First figure out how much space is available in the buffer. */
|
||||
count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
|
||||
if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING))
|
||||
{
|
||||
count = f->_IO_buf_end - f->_IO_write_ptr;
|
||||
if (count >= n)
|
||||
{
|
||||
register const char *p;
|
||||
for (p = s + n; p > s; )
|
||||
{
|
||||
if (*--p == '\n')
|
||||
{
|
||||
count = p - s + 1;
|
||||
must_flush = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Then fill the buffer. */
|
||||
if (count > 0)
|
||||
{
|
||||
if (count > to_do)
|
||||
count = to_do;
|
||||
if (count > 20)
|
||||
{
|
||||
memcpy (f->_IO_write_ptr, s, count);
|
||||
s += count;
|
||||
}
|
||||
else
|
||||
{
|
||||
register char *p = f->_IO_write_ptr;
|
||||
register int i = (int) count;
|
||||
while (--i >= 0)
|
||||
*p++ = *s++;
|
||||
}
|
||||
f->_IO_write_ptr += count;
|
||||
to_do -= count;
|
||||
}
|
||||
if (to_do + must_flush > 0)
|
||||
{
|
||||
_IO_size_t block_size, do_write;
|
||||
/* Next flush the (full) buffer. */
|
||||
if (__overflow (f, EOF) == EOF)
|
||||
return n - to_do;
|
||||
|
||||
/* Try to maintain alignment: write a whole number of blocks.
|
||||
dont_write is what gets left over. */
|
||||
block_size = f->_IO_buf_end - f->_IO_buf_base;
|
||||
do_write = to_do - (block_size >= 128 ? to_do % block_size : 0);
|
||||
|
||||
if (do_write)
|
||||
{
|
||||
count = old_do_write (f, s, do_write);
|
||||
to_do -= count;
|
||||
if (count < do_write)
|
||||
return n - to_do;
|
||||
}
|
||||
|
||||
/* Now write out the remainder. Normally, this will fit in the
|
||||
buffer, but it's somewhat messier for line-buffered files,
|
||||
so we let _IO_default_xsputn handle the general case. */
|
||||
if (to_do)
|
||||
to_do -= _IO_default_xsputn (f, s+do_write, to_do);
|
||||
}
|
||||
return n - to_do;
|
||||
}
|
||||
|
||||
|
||||
struct _IO_jump_t _IO_old_file_jumps =
|
||||
{
|
||||
JUMP_INIT_DUMMY,
|
||||
JUMP_INIT(finish, _IO_old_file_finish),
|
||||
JUMP_INIT(overflow, _IO_old_file_overflow),
|
||||
JUMP_INIT(underflow, _IO_old_file_underflow),
|
||||
JUMP_INIT(uflow, _IO_default_uflow),
|
||||
JUMP_INIT(pbackfail, _IO_default_pbackfail),
|
||||
JUMP_INIT(xsputn, _IO_old_file_xsputn),
|
||||
JUMP_INIT(xsgetn, _IO_default_xsgetn),
|
||||
JUMP_INIT(seekoff, _IO_old_file_seekoff),
|
||||
JUMP_INIT(seekpos, _IO_default_seekpos),
|
||||
JUMP_INIT(setbuf, _IO_old_file_setbuf),
|
||||
JUMP_INIT(sync, _IO_old_file_sync),
|
||||
JUMP_INIT(doallocate, _IO_file_doallocate),
|
||||
JUMP_INIT(read, _IO_file_read),
|
||||
JUMP_INIT(write, _IO_old_file_write),
|
||||
JUMP_INIT(seek, _IO_file_seek),
|
||||
JUMP_INIT(close, _IO_file_close),
|
||||
JUMP_INIT(stat, _IO_file_stat)
|
||||
};
|
||||
|
||||
#ifdef SHARED
|
||||
symbol_version (_IO_old_do_write, _IO_do_write, GLIBC_2.0);
|
||||
symbol_version (_IO_old_file_attach, _IO_file_attach, GLIBC_2.0);
|
||||
symbol_version (_IO_old_file_close_it, _IO_file_close_it, GLIBC_2.0);
|
||||
symbol_version (_IO_old_file_finish, _IO_file_finish, GLIBC_2.0);
|
||||
symbol_version (_IO_old_file_fopen, _IO_file_fopen, GLIBC_2.0);
|
||||
symbol_version (_IO_old_file_init, _IO_file_init, GLIBC_2.0);
|
||||
symbol_version (_IO_old_file_setbuf, _IO_file_setbuf, GLIBC_2.0);
|
||||
symbol_version (_IO_old_file_sync, _IO_file_sync, GLIBC_2.0);
|
||||
symbol_version (_IO_old_file_overflow, _IO_file_overflow, GLIBC_2.0);
|
||||
symbol_version (_IO_old_file_seekoff, _IO_file_seekoff, GLIBC_2.0);
|
||||
symbol_version (_IO_old_file_underflow, _IO_file_underflow, GLIBC_2.0);
|
||||
symbol_version (_IO_old_file_write, _IO_file_write, GLIBC_2.0);
|
||||
symbol_version (_IO_old_file_xsputn, _IO_file_xsputn, GLIBC_2.0);
|
||||
#else
|
||||
strong_alias (_IO_old_do_write, _IO_do_write);
|
||||
strong_alias (_IO_old_file_attach, _IO_file_attach);
|
||||
strong_alias (_IO_old_file_close_it, _IO_file_close_it);
|
||||
strong_alias (_IO_old_file_finish, _IO_file_finish);
|
||||
strong_alias (_IO_old_file_fopen, _IO_file_fopen);
|
||||
strong_alias (_IO_old_file_init, _IO_file_init);
|
||||
strong_alias (_IO_old_file_setbuf, _IO_file_setbuf);
|
||||
strong_alias (_IO_old_file_sync, _IO_file_sync);
|
||||
strong_alias (_IO_old_file_overflow, _IO_file_overflow);
|
||||
strong_alias (_IO_old_file_seekoff, _IO_file_seekoff);
|
||||
strong_alias (_IO_old_file_underflow, _IO_file_underflow);
|
||||
strong_alias (_IO_old_file_write, _IO_file_write);
|
||||
strong_alias (_IO_old_file_xsputn, _IO_file_xsputn);
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user