1997-04-05 03:11  Ulrich Drepper  <drepper@cygnus.com>

	* inet/arpa/inet.h: Rewrite.  Don't use the ugly BSD way to write
	headers but instead add comments and parameter names.
	Don't use BSD specific types in prototypes.

	* manual/nss.texi: Correct a few typos and errors.

	* sysdeps/libm-ieee754/s_cbrt.c: Complete rewrite based on better
	algorithm.
	* sysdeps/libm-ieee754/s_cbrtf.c: Likewise.
	* sysdeps/libm-ieee754/s_cbrtl.c: Likewise.

	* sysdeps/libm-i387/s_cbrt.S: New file.  Optimized assembler version
	with new algorithm.
	* sysdeps/libm-i387/s_cbrtf.S: New file.
	* sysdeps/libm-i387/s_cbrtl.S: New file.

	* sysdeps/libm-i387/s_frexp.S: Optimize even more.
	* sysdeps/libm-i387/s_frexpf.S: Likewise.
	* sysdeps/libm-i387/s_frexpl.S: Likewise.

1997-04-04 18:55  Thorsten Kukuk  <kukuk@vt.uni-paderborn.de>

	* nis/Makefile: Remove CFLAGS-*, add publickey to databases.

	* nis/nis_call.c: Add MASTER_ONLY and HARD_LOOKUP flags, compile
	DES part only with secure RPC add-on.

	* nis/nis_names.c (nis_modify): Fix rpc function number.

	* nis/nis_server.c: Fix typos.

	* nis/nss_compat/compat-grp.c: Add NIS+ support.
	* nis/nss_compat/compat-pwd.c: Likewise.
	* nis/nss_compat/compat-spwd.c: Likewise.

	* nis/nss_nis/nis-grp.c: Only a return value > 0 from parse_line
	signals success.

	* nis/nss_nis/nis-publickey.c: Changes for compiling with/without
	secure RPC.
	* nis/nss_nisplus/nisplus-publickey.c: Likewise.
	* nis/ypclnt.c: Likewise.
	* nis/nis_intern.h: Likewise.

	* nis/nss_nisplus/nisplus-alias.c: Correct parser return code.
	* nis/nss_nisplus/nisplus-ethers.c: Likewise.
	* nis/nss_nisplus/nisplus-hosts.c: Likewise.
	* nis/nss_nisplus/nisplus-network.c: Likewise.
	* nis/nss_nisplus/nisplus-proto.c: Likewise.
	* nis/nss_nisplus/nisplus-pwd.c: Likewise.
	* nis/nss_nisplus/nisplus-rpc.c: Likewise.
	* nis/nss_nisplus/nisplus-service.c: Likewise.
	* nis/nss_nisplus/nisplus-spwd.c: Likewise.

	* nis/nss_nisplus/nisplus-grp.c: Rewrite parser for fixing errors
	and speedup.
	* nis/nss_nisplus/nisplus-netgrp.c: Likewise.

1997-04-04 17:03  Ulrich Drepper  <drepper@cygnus.com>

	* math/libm-test.c (cbrt_test): Add tests for +-inf and NaN
	arguments.

1997-04-03 19:24  H.J. Lu  <hjl@gnu.ai.mit.edu>

	* sysdeps/unix/sysv/linux/sigset.h (__sigisemptyset): Fix a
	typo.

1997-04-03 16:10  Andreas Jaeger  <aj@arthur.pfalz.de>

	* sysdeps/libm-ieee754/s_nanf.c:
	* sysdeps/libm-ieee754/s_nan.c:
	* sysdeps/libm-ieee754/s_nanl.c: Include <stdio.h> for
	declaration of sprintf.

1997-04-03 13:37  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/libm-ieee754/s_cexp.c: Fix type: string_alias ->
	strong_alias.
	Reported by sun <asun@zoology.washington.edu>.

	* rpc/auth.h: Removed.
	* rpc/auth_des.h: Removed.
	* sunrpc/rpc/auth.h: Moved to ...
	* sysdeps/generic/rpc/auth.h: ...here.
	* sunrpc/rpc/auth_des.h: Moved to ...
	* sysdeps/generic/rpc/auth_des.h: ...here.

1997-04-03 04:28  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/libm-i387/s_frexp.S: New file.  ix87 optimized version.
	* sysdeps/libm-i387/s_frexpf.S: New file.
	* sysdeps/libm-i387/s_frexpl.S: New file.

1997-04-01 10:11  H.J. Lu  <hjl@gnu.ai.mit.edu>

	* sysdeps/unix/sysv/linux/Makefile [$(subdir)=inet]
	(sysdep_headers): Remove netinet/icmp.h.

	Describe `inf', `infinity', `nan', `nan(...)' inputs for strtod
	* sysdeps/i386/memcmp.S: Likewise.
	* time/antarctica: Likewise.
	* time/australasia: Likewise.
This commit is contained in:
Ulrich Drepper 1997-04-05 01:26:47 +00:00
parent fe7bdd630f
commit 26dee9c49c
49 changed files with 2761 additions and 1082 deletions

109
ChangeLog
View File

@ -1,3 +1,104 @@
1997-04-05 03:11 Ulrich Drepper <drepper@cygnus.com>
* inet/arpa/inet.h: Rewrite. Don't use the ugly BSD way to write
headers but instead add comments and parameter names.
Don't use BSD specific types in prototypes.
* manual/nss.texi: Correct a few typos and errors.
* sysdeps/libm-ieee754/s_cbrt.c: Complete rewrite based on better
algorithm.
* sysdeps/libm-ieee754/s_cbrtf.c: Likewise.
* sysdeps/libm-ieee754/s_cbrtl.c: Likewise.
* sysdeps/libm-i387/s_cbrt.S: New file. Optimized assembler version
with new algorithm.
* sysdeps/libm-i387/s_cbrtf.S: New file.
* sysdeps/libm-i387/s_cbrtl.S: New file.
* sysdeps/libm-i387/s_frexp.S: Optimize even more.
* sysdeps/libm-i387/s_frexpf.S: Likewise.
* sysdeps/libm-i387/s_frexpl.S: Likewise.
1997-04-04 18:55 Thorsten Kukuk <kukuk@vt.uni-paderborn.de>
* nis/Makefile: Remove CFLAGS-*, add publickey to databases.
* nis/nis_call.c: Add MASTER_ONLY and HARD_LOOKUP flags, compile
DES part only with secure RPC add-on.
* nis/nis_names.c (nis_modify): Fix rpc function number.
* nis/nis_server.c: Fix typos.
* nis/nss_compat/compat-grp.c: Add NIS+ support.
* nis/nss_compat/compat-pwd.c: Likewise.
* nis/nss_compat/compat-spwd.c: Likewise.
* nis/nss_nis/nis-grp.c: Only a return value > 0 from parse_line
signals success.
* nis/nss_nis/nis-publickey.c: Changes for compiling with/without
secure RPC.
* nis/nss_nisplus/nisplus-publickey.c: Likewise.
* nis/ypclnt.c: Likewise.
* nis/nis_intern.h: Likewise.
* nis/nss_nisplus/nisplus-alias.c: Correct parser return code.
* nis/nss_nisplus/nisplus-ethers.c: Likewise.
* nis/nss_nisplus/nisplus-hosts.c: Likewise.
* nis/nss_nisplus/nisplus-network.c: Likewise.
* nis/nss_nisplus/nisplus-proto.c: Likewise.
* nis/nss_nisplus/nisplus-pwd.c: Likewise.
* nis/nss_nisplus/nisplus-rpc.c: Likewise.
* nis/nss_nisplus/nisplus-service.c: Likewise.
* nis/nss_nisplus/nisplus-spwd.c: Likewise.
* nis/nss_nisplus/nisplus-grp.c: Rewrite parser for fixing errors
and speedup.
* nis/nss_nisplus/nisplus-netgrp.c: Likewise.
1997-04-04 17:03 Ulrich Drepper <drepper@cygnus.com>
* math/libm-test.c (cbrt_test): Add tests for +-inf and NaN
arguments.
1997-04-03 19:24 H.J. Lu <hjl@gnu.ai.mit.edu>
* sysdeps/unix/sysv/linux/sigset.h (__sigisemptyset): Fix a
typo.
1997-04-03 16:10 Andreas Jaeger <aj@arthur.pfalz.de>
* sysdeps/libm-ieee754/s_nanf.c:
* sysdeps/libm-ieee754/s_nan.c:
* sysdeps/libm-ieee754/s_nanl.c: Include <stdio.h> for
declaration of sprintf.
1997-04-03 13:37 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/libm-ieee754/s_cexp.c: Fix type: string_alias ->
strong_alias.
Reported by sun <asun@zoology.washington.edu>.
* rpc/auth.h: Removed.
* rpc/auth_des.h: Removed.
* sunrpc/rpc/auth.h: Moved to ...
* sysdeps/generic/rpc/auth.h: ...here.
* sunrpc/rpc/auth_des.h: Moved to ...
* sysdeps/generic/rpc/auth_des.h: ...here.
1997-04-03 04:28 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/libm-i387/s_frexp.S: New file. ix87 optimized version.
* sysdeps/libm-i387/s_frexpf.S: New file.
* sysdeps/libm-i387/s_frexpl.S: New file.
1997-04-01 10:11 H.J. Lu <hjl@gnu.ai.mit.edu>
* sysdeps/unix/sysv/linux/Makefile [$(subdir)=inet]
(sysdep_headers): Remove netinet/icmp.h.
1997-04-02 16:55 Ulrich Drepper <drepper@cygnus.com>
* manual/socket.texi: Document behaviour of inet_ntoa in multi-
@ -12,7 +113,7 @@
* manual/arith.texi: Add description of lldiv_t, lldiv, and atoll.
Change description of strtoll and strtoull to make clear these
are the preferred names.
Describe `inf', `inifinity', `nan', `nan(...)' inputs for strtod
Describe `inf', `infinity', `nan', `nan(...)' inputs for strtod
and friends.
Change references to HUGE_VALf and HUGE_VALl to HUGE_VALF and
HUGE_VALL.
@ -146,7 +247,7 @@
* sysdeps/i386/addmul_1.S: Likewise.
* sysdeps/i386/lshift.S: Likewise.
* sysdeps/i386/memchr.S: Likewise.
* sysdeps/i386/memset.S: Likewise.
* sysdeps/i386/memcmp.S: Likewise.
* sysdeps/i386/mul_1.S: Likewise.
* sysdeps/i386/rshift.S: Likewise.
* sysdeps/i386/stpcpy.S: Likewise.
@ -176,9 +277,9 @@
* sysdeps/stub/s_log2l.c: Correct function name.
* time/africa: Updated from ADO tzdata1997e.
* time/aantarctica: Likewise.
* time/antarctica: Likewise.
* time/asia: Likewise.
* time/australia: Likewise.
* time/australasia: Likewise.
* time/europe: Likewise.
* time/northamerica: Likewise.
* time/southamerica: Likewise.

18
FAQ
View File

@ -84,6 +84,9 @@ please let me know.
[Q23] ``When compiling GNU libc I get lots of errors saying functions
in glibc are duplicated in libgcc.''
[Q24] ``I have set up /etc/nis.conf, and the Linux libc 5 with NYS
works great. But the glibc NIS+ doesn't seem to work.''
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
[Q1] ``What systems does the GNU C Library run on?''
@ -674,6 +677,21 @@ you first delete config.cache.
some problems of this kind. The setting of CFLAGS is checked at the
very beginning and if it is not usable `configure' will bark.
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
[Q24] ``I have set up /etc/nis.conf, and the Linux libc 5 with NYS
works great. But the glibc NIS+ doesn't seem to work.''
[A24] The glibc NIS+ implementation uses a /var/nis/NIS_COLD_START
file for storing information about the NIS+ server and their
public keys, because the nis.conf file do not contain all
necessary information. You have to copy a NIS_COLD_START file
from a Solaris client (the NIS_COLD_START file is byte order
independend) or generate it new with nisinit from the nis-tools
(look at http://www-vt.uni-paderborn.de/~kukuk/linux/nisplus.html).
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
Answers were given by:

View File

@ -1,6 +1,6 @@
Open jobs for finishing GNU libc:
---------------------------------
Status: March 1997
Status: April 1997
If you have time and talent to take over any of the jobs below please
contact <bug-glibc@prep.ai.mit.edu>
@ -57,7 +57,6 @@ contact <bug-glibc@prep.ai.mit.edu>
[ 7] Several math functions have to be written:
- exp2
- log2
- nearbyint
- ceil
- round
@ -138,7 +137,9 @@ contact <bug-glibc@prep.ai.mit.edu>
+ tcgetid() and waitid() from XPG4.2
+ grantpt(), ptsname(), unlockpt() from XPG4.2
+ getdate() from XPG4.2
*** Probably underway
+ fmtmsg() from SVID
*** Probably underway
More information are available on request.
@ -147,3 +148,14 @@ contact <bug-glibc@prep.ai.mit.edu>
of text. In fact, this would be a recode-library (you know, GNU recode).
This is needed in several places in the GNU libc and I already have
rather concrete plans but so far no possibility to start this.
[15] Cleaning up the header files. Ideally, each header style should
follow the "good examples". Each variable and function should have
a short description of the function and its parameters. The prototypes
should always contain variable names which can help to identify their
meaning; better than
int foo __P ((int, int, int, int));
Blargh!

View File

@ -1,62 +1,95 @@
/*
* 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.
*
* @(#)inet.h 8.1 (Berkeley) 6/2/93
*/
/* Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
#ifndef _INET_H_
#define _INET_H_
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.
/* External definitions for functions in inet(3) */
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 _ARPA_INET_H
#define _ARPA_INET_H 1
#include <features.h>
#include <sys/cdefs.h>
#include <sys/types.h>
#include <netinet/in.h> /* To define `struct in_addr'. */
__BEGIN_DECLS
u_long inet_addr __P((const char *));
int inet_aton __P((const char *, struct in_addr *));
u_int32_t inet_lnaof __P((struct in_addr));
struct in_addr inet_makeaddr __P((u_int32_t , u_int32_t));
char * inet_neta __P((u_long, char *, size_t));
u_int32_t inet_netof __P((struct in_addr));
u_int32_t inet_network __P((const char *));
char *inet_net_ntop __P((int, const void *, int, char *, size_t));
int inet_net_pton __P((int, const char *, void *, size_t));
char *inet_ntoa __P((struct in_addr));
int inet_pton __P((int, const char *, void *));
const char *inet_ntop __P((int, const void *, char *, size_t));
u_int inet_nsap_addr __P((const char *, u_char *, int));
char *inet_nsap_ntoa __P((int, const u_char *, char *));
/* Convert Internet host address from numbers-and-dots notation in CP
into binary data in network byte order. */
extern unsigned long int inet_addr __P ((__const char *__cp));
/* Convert Internet host address from numbers-and-dots notation in CP
into binary data and store the result in the structure INP. */
extern int inet_aton __P ((__const char *__cp, struct in_addr *__inp));
/* Return the local host address part of the Internet address in IN. */
extern u_int32_t inet_lnaof __P ((struct in_addr __in));
/* Make Internet host address in network byte order by combining the
network number NET with the local address HOST. */
extern struct in_addr inet_makeaddr __P ((u_int32_t __net, u_int32_t __host));
/* Format a network number NET into presentation format and place result
in buffer starting at BUF with length of LEN bytes. */
extern char *inet_neta __P ((u_long __net, char *__buf, size_t __len));
/* Return network number part of the Internet address IN. */
extern u_int32_t inet_netof __P ((struct in_addr __in));
/* Extract the network number in network byte order from the address
in numbers-and-dots natation starting at CP. */
extern u_int32_t inet_network __P ((__const char *__cp));
/* Convert network number for interface type AF in buffer starting at
CP to presentation format. The result will specifiy BITS bits of
the number. */
extern char *inet_net_ntop __P((int __af, __const void *__cp, int __bits,
char *__buf, size_t __len));
/* Convert network number for interface type AF from presentation in
buffer starting at CP to network format and store result int
buffer starting at BUF of size LEN. */
extern int inet_net_pton __P ((int __af, __const char *__cp,
void *__buf, size_t __len));
/* Convert Internet number in IN to ASCII representation. The return value
is a pointer to an internal array containing the string. */
extern char *inet_ntoa __P ((struct in_addr __in));
/* Convert from presentation format of an Internet number in buffer
starting at CP to the binary network format and store result for
interface type AF in buffer starting at BUF. */
extern int inet_pton __P ((int __af, __const char *__cp, void *__buf));
/* Convert a Internet address in binary network format for interface
type AF in buffer starting at CP to presentation form and place
result in buffer of length LEN astarting at BUF. */
extern __const char *inet_ntop __P ((int __af, __const void *__cp,
char *__buf, size_t __len));
/* Convert ASCII representation in hexadecimal form of the Internet
address to binary form and place result in buffer of length LEN
starting at BUF. */
extern unsigned int inet_nsap_addr __P ((__const char *__cp,
unsigned char *__buf, int __len));
/* Convert internet address in binary form in LEN bytes starting at CP
a presentation form and place result in BUF. */
extern char *inet_nsap_ntoa __P ((int __len, __const unsigned char *__cp,
char *__buf));
__END_DECLS
#endif /* !_INET_H_ */
#endif /* arpa/inet.h */

View File

@ -68,6 +68,9 @@ The databases available in the NSS are
@cindex services
@cindex shadow
@vtable @code
@item aliases
Mail aliases
@comment @pxref{Mail Aliases}.
@item ethers
Ethernet numbers,
@comment @pxref{Ethernet Numbers}.
@ -94,8 +97,8 @@ Shadow user passwords,
@end vtable
@noindent
There will be some more added later (@code{aliases}, @code{automount},
@code{bootparams}, @code{netmasks}, and @code{publickey}).
There will be some more added later (@code{automount}, @code{bootparams},
@code{netmasks}, and @code{publickey}).
@node NSS Configuration File, NSS Module Internals, NSS Basics, Name Service Switch
@section The NSS Configuration File
@ -123,7 +126,7 @@ different items:
@item
the service specification like @code{files}, @code{db}, or @code{nis}.
@item
the reaction on lookup result line @code{[NOTFOUND=return]}.
the reaction on lookup result like @code{[NOTFOUND=return]}.
@end itemize
@menu
@ -346,8 +349,9 @@ functions. I.e., if the user would call the @code{gethostbyname_r}
function this also would end in the above function. For all user
interface functions the C library maps this call to a call to the
reentrant function. For reentrant functions this is trivial since the
interface is (nearly) the same. For the non-reentrant version pointers
to static buffers are used to replace the user supplied buffers.
interface is (nearly) the same. For the non-reentrant version The
library keeps internal buffers which are used to replace the user
supplied buffer.
I.e., the reentrant functions @emph{can} have counterparts. No service
module is forced to have functions for all databases and all kinds to
@ -399,9 +403,9 @@ enum nss_status _nss_files_gethostbyname_r (const char *name,
@end smallexample
I.e., the interface function is in fact the reentrant function with the
change of the return value. While the user-level function returns a
pointer to the result the reentrant function return an @code{enum
nss_status} value:
change of the return value and the omission of the @var{result}
parameter. While the user-level function returns a pointer to the
result the reentrant function return an @code{enum nss_status} value:
@vindex NSS_STATUS_TRYAGAIN
@vindex NSS_STATUS_UNAVAIL
@ -458,13 +462,13 @@ function;
the next three arguments are:
@table @code
@item STRUCT_TYPE result_buf
@item STRUCT_TYPE *result_buf
pointer to buffer where the result is stored. @code{STRUCT_TYPE} is
normally a struct which corresponds to the database.
@item char *buffer
pointer to a buffer where the function can store additional adata for
the result etc.
@item int buflen
@item size_t buflen
length of the buffer pointed to by @var{buffer}.
@end table

View File

@ -572,6 +572,10 @@ cbrt_test (void)
check ("cbrt (+0) == +0", FUNC(cbrt) (0.0), 0.0);
check ("cbrt (-0) == -0", FUNC(cbrt) (minus_zero), minus_zero);
check_isinfp ("cbrt (+inf) == +inf", FUNC(cbrt) (plus_infty));
check_isinfn ("cbrt (-inf) == -inf", FUNC(cbrt) (minus_infty));
check_isnan ("cbrt (NaN) == NaN", FUNC(cbrt) (nan_value));
check ("cbrt (8) == 2", FUNC(cbrt) (8), 2);
check ("cbrt (-27) == -3", FUNC(cbrt) (-27.0), -3.0);
}

View File

@ -27,7 +27,7 @@ distribute := nss-nis.h nss-nisplus.h
# These are the databases available for the nis (and perhaps later nisplus)
# service. This must be a superset of the services in nss.
databases = proto service hosts network grp pwd rpc ethers \
spwd netgrp alias
spwd netgrp alias publickey
# Specify rules for the nss_* modules.
services := nis compat nisplus
@ -55,57 +55,12 @@ libnss_nis-inhibit-o = $(filter-out .so,$(object-suffixes))
libnss_nisplus-routines := $(addprefix nisplus-,$(databases))
libnss_nisplus-inhibit-o = $(filter-out .so,$(object-suffixes))
# Sun's header files are not too clean.
CFLAGS-compat-pwd.c = -Wno-strict-prototypes
CFLAGS-compat-spwd.c = -Wno-strict-prototypes
CFLAGS-compat-grp.c = -Wno-strict-prototypes
CFLAGS-nis-alias.c = -Wno-strict-prototypes
CFLAGS-nis-ethers.c = -Wno-strict-prototypes
CFLAGS-nis-grp.c = -Wno-strict-prototypes
CFLAGS-nis-hosts.c = -Wno-strict-prototypes
CFLAGS-nis-netgrp.c = -Wno-strict-prototypes
CFLAGS-nis-network.c = -Wno-strict-prototypes
CFLAGS-nis-proto.c = -Wno-strict-prototypes
CFLAGS-nis-publickey.c = -Wno-strict-prototypes
CFLAGS-nis-pwd.c = -Wno-strict-prototypes
CFLAGS-nis-rpc.c = -Wno-strict-prototypes
CFLAGS-nis-service.c = -Wno-strict-prototypes
CFLAGS-nis-spwd.c = -Wno-strict-prototypes
CFLAGS-ypclnt.c = -Wno-strict-prototypes -Wno-write-strings -Irpcsvc
CFLAGS-yp_xdr.c = -Wno-strict-prototypes -Irpcsvc
CFLAGS-ypupdate_xdr.c = -Wno-strict-prototypes -Irpcsvc
# For the NIS+ Code
CFLAGS-nis_call.c = -DNO_DES_RPC -Wno-strict-prototypes
CFLAGS-nis_subr.c = -Wno-strict-prototypes
CFLAGS-nis_local_names.c = -Wno-strict-prototypes
CFLAGS-nis_free.c = -Wno-strict-prototypes
CFLAGS-nis_file.c = -Wno-strict-prototypes
CFLAGS-nis_print.c = -Wno-strict-prototypes
CFLAGS-nis_error.c = -Wno-strict-prototypes
CFLAGS-nis_names.c = -Wno-strict-prototypes
CFLAGS-nis_clone.c = -Wno-strict-prototypes
CFLAGS-nis_table.c = -Wno-strict-prototypes
CFLAGS-nis_server.c = -Wno-strict-prototypes
CFLAGS-nis_xdr.c = -Wno-strict-prototypes
CFLAGS-nis_intern.c = -Wno-strict-prototypes
CFLAGS-nisplus-alias.c = -Wno-strict-prototypes
CFLAGS-nisplus-ethers.c = -Wno-strict-prototypes
CFLAGS-nisplus-grp.c = -Wno-strict-prototypes
CFLAGS-nisplus-hosts.c = -Wno-strict-prototypes
CFLAGS-nisplus-netgrp.c = -Wno-strict-prototypes
CFLAGS-nisplus-network.c = -Wno-strict-prototypes
CFLAGS-nisplus-proto.c = -Wno-strict-prototypes
CFLAGS-nisplus-publickey.c = -Wno-strict-prototypes
CFLAGS-nisplus-pwd.c = -Wno-strict-prototypes
CFLAGS-nisplus-rpc.c = -Wno-strict-prototypes
CFLAGS-nisplus-service.c = -Wno-strict-prototypes
CFLAGS-nisplus-spwd.c = -Wno-strict-prototypes
include ../Rules
$(objpfx)libnss_compat.so: $(objpfx)libnsl.so$(libnsl.so-version) \
$(common-objpfx)nss/libnss_files.so
$(common-objpfx)nss/libnss_files.so \
$(common-objpfx)nis/libnss_nisplus.so
$(objpfx)libnss_nis.so: $(objpfx)libnsl.so$(libnsl.so-version) \
$(common-objpfx)nss/libnss_files.so
$(objpfx)libnss_nisplus.so: $(objpfx)libnsl.so$(libnsl.so-version)

View File

@ -1,8 +1,9 @@
* nss_nisplus: When using parser form nss_files, rewrite parser
* compat could use data from nisplus, too. Implement this
* nss_nisplus: Search the data in the complete NIS+ namespace
specified by NIS_PATH
* nis_server: implement nis_getservlist, nis_stats, nis_servstate
* nis_groups: implement it
@ -22,10 +23,10 @@
* Possible flags:
- FOLLOW_LINKS (nis_list, nis_lookup)
- FOLLOW_PATH (nis_list, not supported)
- HARD_LOOKUP (__do_niscall, not supported)
- HARD_LOOKUP (__do_niscall)
- ALL_RESULTS (nis_list, not supported, needs server callback)
- NO_CACHE (__do_niscall, cache not supported yet)
- MASTER_ONLY (__do_niscall, not supported)
- MASTER_ONLY (__do_niscall)
- EXPAND_NAME (nis_lookup, nis_list)
- RETURN_RESULT (nis_table.c)
- ADD_OVERWRITE (nis_table.c)
@ -37,4 +38,3 @@
- USE_DGRAM (__do_niscall)
- NO_AUTHINFO (__do_niscall)

View File

@ -60,13 +60,11 @@ __nis_dobind (const nis_server *server, u_long flags)
int clnt_sock;
size_t i;
CLIENT *client = NULL;
/* XXX What is this variable for? */
void *out = NULL;
memset (&clnt_saddr, '\0', sizeof clnt_saddr);
clnt_saddr.sin_family = AF_INET;
for (i = 0; i < server->ep.ep_len; i++)
{
memset (&clnt_saddr, '\0', sizeof clnt_saddr);
clnt_saddr.sin_family = AF_INET;
if (strcmp (server->ep.ep_val[i].family,"loopback") == 0)
{
if (server->ep.ep_val[i].uaddr[i] == '-')
@ -79,14 +77,14 @@ __nis_dobind (const nis_server *server, u_long flags)
else
continue;
}
else
if (strcmp (server->ep.ep_val[i].proto,"tcp") == 0)
{
if ((flags & USE_DGRAM) == USE_DGRAM)
continue;
else
clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
}
else
if (strcmp (server->ep.ep_val[i].proto,"tcp") == 0)
{
if ((flags & USE_DGRAM) == USE_DGRAM)
continue;
else
clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
}
}
else
if (strcmp (server->ep.ep_val[i].family,"inet") == 0)
@ -115,7 +113,7 @@ __nis_dobind (const nis_server *server, u_long flags)
}
else
continue;
clnt_sock = RPC_ANYSOCK;
if ((flags & USE_DGRAM) == USE_DGRAM)
client = clntudp_create (&clnt_saddr, NIS_PROG, NIS_VERSION,
@ -123,42 +121,41 @@ __nis_dobind (const nis_server *server, u_long flags)
else
client = clnttcp_create (&clnt_saddr, NIS_PROG, NIS_VERSION,
&clnt_sock, 0, 0);
if (client == NULL)
continue;
#if 1
if (clnt_call (client, 0, (xdrproc_t) xdr_void, NULL,
(xdrproc_t) xdr_void, out, TIMEOUT) != RPC_SUCCESS)
(xdrproc_t) xdr_void, NULL, TIMEOUT) != RPC_SUCCESS)
{
clnt_destroy (client);
continue;
}
#endif
if ((flags & NO_AUTHINFO) != NO_AUTHINFO)
{
#if !defined(NO_DES_RPC)
if (server->key_type == NIS_PK_DH)
{
char netname[MAXNETNAMELEN+1];
char *p;
strcpy (netname, "unix.");
strncat (netname, server->name,MAXNETNAMELEN-5);
netname[MAXNETNAMELEN-5] = '\0';
p = strchr (netname, '.');
*p = '@';
client->cl_auth =
authdes_pk_create (netname, &server->pkey, 300, NULL, NULL);
if (!client->cl_auth)
client->cl_auth = authunix_create_default ();
}
else
if ((flags & NO_AUTHINFO) != NO_AUTHINFO)
{
#if defined(HAVE_SECURE_RPC)
if (server->key_type == NIS_PK_DH)
{
char netname[MAXNETNAMELEN+1];
char *p;
p = stpcpy (netname, "unix.");
strncpy (p, server->name,MAXNETNAMELEN-5);
netname[MAXNETNAMELEN] = '\0';
p = strchr (netname, '.');
*p = '@';
client->cl_auth =
authdes_pk_create (netname, &server->pkey, 300, NULL, NULL);
if (!client->cl_auth)
client->cl_auth = authunix_create_default ();
}
else
#endif
client->cl_auth = authunix_create_default ();
}
client->cl_auth = authunix_create_default ();
}
return client;
}
return NULL;
}
@ -189,14 +186,19 @@ __do_niscall (const nis_server *serv, int serv_len, u_long prog,
server_len = serv_len;
}
if (((flags & MASTER_ONLY) == MASTER_ONLY) && server_len > 1)
server_len = 1; /* The first entry is the master */
try = 0;
result = NIS_NAMEUNREACHABLE;
while (try < MAXTRIES && result != RPC_SUCCESS)
{
unsigned int i;
++try;
if ((flags & HARD_LOOKUP) == 0)
++try;
for (i = 0; i < server_len; i++)
{
if ((clnt = __nis_dobind (&server[i], flags)) == NULL)
@ -206,9 +208,7 @@ __do_niscall (const nis_server *serv, int serv_len, u_long prog,
if (result != RPC_SUCCESS)
{
/* XXX Grrr. The cast is needed for now since Sun code does
note know about `const'. */
clnt_perror (clnt, (char *) "do_niscall: clnt_call");
clnt_perror (clnt, "do_niscall: clnt_call");
clnt_destroy (clnt);
result = NIS_RPCERROR;
}

View File

@ -27,11 +27,10 @@ __BEGIN_DECLS
extern nis_error __do_niscall (__const nis_server *server, int server_len,
u_long prog, xdrproc_t xargs, caddr_t req,
xdrproc_t xres, caddr_t resp, u_long flags);
#if !defined(NO_DES_RPC)
extern AUTH *authdes_pk_create (char *, netobj *, u_int,
#if defined (HAVE_SECURE_RPC)
extern AUTH *authdes_pk_create (const char *, const netobj *, u_int,
struct sockaddr *, des_block *);
#endif
extern nis_name *__nis_expandname (__const nis_name);
__END_DECLS

View File

@ -227,7 +227,7 @@ nis_modify (const nis_name name, const nis_object *obj)
req.ns_object.ns_object_len = 1;
req.ns_object.ns_object_val = nis_clone_object (obj, NULL);
if ((status = __do_niscall (NULL, 0, NIS_REMOVE, (xdrproc_t) xdr_ns_request,
if ((status = __do_niscall (NULL, 0, NIS_MODIFY, (xdrproc_t) xdr_ns_request,
(caddr_t) & req, (xdrproc_t) xdr_nis_result,
(caddr_t) res, 0)) != RPC_SUCCESS)
res->status = status;

View File

@ -30,8 +30,8 @@ nis_mkdir (const nis_name dir, const nis_server *server)
{
int result;
if ((result = __do_niscall (NULL, 0, NIS_MKDIR, (xdrproc_t) xdr_nis_name,
(caddr_t) dir, (xdrproc_t) xdr_nis_error,
(caddr_t) & res, 0)) != RPC_SUCCESS)
(caddr_t) &dir, (xdrproc_t) xdr_nis_error,
(caddr_t) &res, 0)) != RPC_SUCCESS)
{
fprintf (stderr, _("__do_niscall: Error #%d\n"), result);
return NIS_RPCERROR;
@ -42,8 +42,8 @@ nis_mkdir (const nis_name dir, const nis_server *server)
int result;
if ((result = __do_niscall (server, 1, NIS_MKDIR,
(xdrproc_t) xdr_nis_name,
(caddr_t) dir, (xdrproc_t) xdr_nis_error,
(caddr_t) & res, 0)) != RPC_SUCCESS)
(caddr_t) &dir, (xdrproc_t) xdr_nis_error,
(caddr_t) &res, 0)) != RPC_SUCCESS)
{
fprintf (stderr, _("__do_niscall: Error #%d\n"), result);
return NIS_RPCERROR;
@ -62,8 +62,8 @@ nis_rmdir (const nis_name dir, const nis_server *server)
{
int result;
if ((result = __do_niscall (NULL, 0, NIS_RMDIR, (xdrproc_t) xdr_nis_name,
(caddr_t) dir, (xdrproc_t) xdr_nis_error,
(caddr_t) & res, 0)) != RPC_SUCCESS)
(caddr_t) &dir, (xdrproc_t) xdr_nis_error,
(caddr_t) &res, 0)) != RPC_SUCCESS)
{
fprintf (stderr, _("__do_niscall: Error #%d\n"), result);
return NIS_RPCERROR;
@ -74,8 +74,8 @@ nis_rmdir (const nis_name dir, const nis_server *server)
int result;
if ((result = __do_niscall (server, 1, NIS_RMDIR,
(xdrproc_t) xdr_nis_name,
(caddr_t) dir, (xdrproc_t) xdr_nis_error,
(caddr_t) & res, 0)) != RPC_SUCCESS)
(caddr_t) &dir, (xdrproc_t) xdr_nis_error,
(caddr_t) &res, 0)) != RPC_SUCCESS)
{
fprintf (stderr, _("__do_niscall: Error #%d\n"), result);
return NIS_RPCERROR;

View File

@ -25,6 +25,14 @@
#include <string.h>
#include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
#include <nsswitch.h>
#include "nss-nisplus.h"
static service_user *ni = NULL;
static bool_t use_nisplus = FALSE; /* default: group_compat: nis */
/* Get the declaration of the parser function. */
#define ENTNAME grent
@ -32,7 +40,7 @@
#define EXTERN_PARSER
#include "../../nss/nss_files/files-parse.c"
/* Structure for remembering -@netgroup and -user members ... */
/* Structure for remembering -group members ... */
#define BLACKLIST_INITIAL_SIZE 512
#define BLACKLIST_INCREMENT 256
struct blacklist_t
@ -48,12 +56,15 @@ struct ent_t
bool_t nis_first;
char *oldkey;
int oldkeylen;
nis_result *result;
nis_name *names;
u_long names_nr;
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}};
static ent_t ext_ent = {0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0}};
/* Protect global state against multiple changers. */
__libc_lock_define_initialized (static, lock)
@ -61,6 +72,8 @@ __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 *);
extern int _nss_nisplus_parse_grent (nis_result *, struct group *,
char *, size_t);
static enum nss_status
internal_setgrent (ent_t *ent)
@ -75,15 +88,27 @@ internal_setgrent (ent_t *ent)
ent->oldkey = NULL;
ent->oldkeylen = 0;
}
if (ent->result != NULL)
{
nis_freeresult (ent->result);
ent->result = NULL;
}
if (ent->names != NULL)
{
nis_freenames (ent->names);
ent->names = NULL;
}
ent->names_nr = 0;
ent->blacklist.current = 0;
if (ent->blacklist.data != NULL)
ent->blacklist.data[0] = '\0';
if (ent->stream == NULL)
{
ent->stream = fopen ("/etc/group", "r");
if (ent->stream == NULL)
status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
}
@ -101,6 +126,12 @@ _nss_compat_setgrent (void)
__libc_lock_lock (lock);
if (ni == NULL)
{
__nss_database_lookup ("group_compat", NULL, "nis", &ni);
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
}
result = internal_setgrent (&ext_ent);
__libc_lock_unlock (lock);
@ -127,6 +158,18 @@ internal_endgrent (ent_t *ent)
ent->oldkeylen = 0;
}
if (ent->result != NULL)
{
nis_freeresult (ent->result);
ent->result = NULL;
}
if (ent->names != NULL)
{
nis_freenames (ent->names);
ent->names = NULL;
}
ent->names_nr = 0;
ent->blacklist.current = 0;
if (ent->blacklist.data != NULL)
ent->blacklist.data[0] = '\0';
@ -155,7 +198,7 @@ getgrent_next_nis (struct group *result, ent_t *ent, char *buffer,
struct parser_data *data = (void *) buffer;
char *domain;
char *outkey, *outval;
int outkeylen, outvallen;
int outkeylen, outvallen, parse_res;
char *p;
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
@ -202,13 +245,133 @@ getgrent_next_nis (struct group *result, ent_t *ent, char *buffer,
while (isspace (*p))
++p;
parse_res = _nss_files_parse_grent (p, result, data, buflen);
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 (!_nss_files_parse_grent (p, result, data, buflen));
while (!parse_res);
return NSS_STATUS_SUCCESS;
}
if (!in_blacklist (result->gr_name, strlen (result->gr_name), ent))
static enum nss_status
getgrent_next_nisplus (struct group *result, ent_t *ent, char *buffer,
size_t buflen)
{
int parse_res;
if (ent->names == NULL)
{
ent->names = nis_getnames ("group.org_dir");
if (ent->names == NULL || ent->names[0] == NULL)
{
ent->nis = 0;
return NSS_STATUS_UNAVAIL;
}
}
do
{
if (ent->nis_first)
{
next_name:
ent->result = nis_first_entry(ent->names[ent->names_nr]);
if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
{
ent->nis = 0;
return niserr2nss (ent->result->status);
}
ent->nis_first = FALSE;
}
else
{
nis_result *res;
res = nis_next_entry(ent->names[ent->names_nr],
&ent->result->cookie);
nis_freeresult (ent->result);
ent->result = res;
if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
{
if ((ent->result->status == NIS_NOTFOUND) &&
ent->names[ent->names_nr + 1] != NULL)
{
nis_freeresult (ent->result);
ent->names_nr += 1;
goto next_name;
}
else
{
ent->nis = 0;
return niserr2nss (ent->result->status);
}
}
}
parse_res = _nss_nisplus_parse_grent (ent->result, result, buffer,
buflen);
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
getgrent_next_file_plusgroup (struct group *result, char *buffer,
size_t buflen)
{
struct parser_data *data = (void *) buffer;
int parse_res;
if (use_nisplus) /* Do the NIS+ query here */
{
nis_result *res;
char buf[strlen (result->gr_name) + 24];
sprintf(buf, "[name=%s],group.org_dir",
&result->gr_name[1]);
res = nis_list(buf, EXPAND_NAME, NULL, NULL);
if (niserr2nss (res->status) != NSS_STATUS_SUCCESS)
{
enum nss_status status = niserr2nss (res->status);
nis_freeresult (res);
return status;
}
parse_res = _nss_nisplus_parse_grent (res, result, buffer, buflen);
nis_freeresult (res);
}
else /* Use NIS */
{
char *domain, *outval, *p;
int outvallen;
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
return NSS_STATUS_TRYAGAIN;
if (yp_match (domain, "group.byname", &result->gr_name[1],
strlen (result->gr_name) - 1, &outval, &outvallen)
!= YPERR_SUCCESS)
return NSS_STATUS_TRYAGAIN;
p = strncpy (buffer, outval,
buflen < outvallen ? buflen : outvallen);
free (outval);
while (isspace (*p))
p++;
parse_res = _nss_files_parse_grent (p, result, data, buflen);
}
if (parse_res)
/* We found the entry. */
return NSS_STATUS_SUCCESS;
else
return NSS_STATUS_NOTFOUND;
return NSS_STATUS_RETURN;
}
@ -256,27 +419,16 @@ getgrent_next_file (struct group *result, ent_t *ent,
if (result->gr_name[0] == '+' && result->gr_name[1] != '\0'
&& result->gr_name[1] != '@')
{
char *domain;
char *outval;
int outvallen;
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
/* XXX Should we regard this as an fatal error? I don't
think so. Just continue working. --drepper@gnu */
continue;
if (yp_match (domain, "group.byname", &result->gr_name[1],
strlen (result->gr_name) - 1, &outval, &outvallen)
!= YPERR_SUCCESS)
continue;
p = strncpy (buffer, outval, buflen);
while (isspace (*p))
p++;
free (outval);
if (_nss_files_parse_grent (p, result, data, buflen))
/* We found the entry. */
break;
enum nss_status status;
status = getgrent_next_file_plusgroup (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 */
continue;
else
return status;
}
/* +:... */
@ -285,7 +437,10 @@ getgrent_next_file (struct group *result, ent_t *ent,
ent->nis = TRUE;
ent->nis_first = TRUE;
return getgrent_next_nis (result, ent, buffer, buflen);
if (use_nisplus)
return getgrent_next_nisplus (result, ent, buffer, buflen);
else
return getgrent_next_nis (result, ent, buffer, buflen);
}
}
@ -298,7 +453,12 @@ 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);
{
if (use_nisplus)
return getgrent_next_nisplus (gr, ent, buffer, buflen);
else
return getgrent_next_nis (gr, ent, buffer, buflen);
}
else
return getgrent_next_file (gr, ent, buffer, buflen);
}
@ -310,6 +470,12 @@ _nss_compat_getgrent_r (struct group *grp, char *buffer, size_t buflen)
__libc_lock_lock (lock);
if (ni == NULL)
{
__nss_database_lookup ("group_compat", NULL, "nis", &ni);
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
}
/* Be prepared that the setgrent function was not called before. */
if (ext_ent.stream == NULL)
status = internal_setgrent (&ext_ent);
@ -327,12 +493,21 @@ 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}};
ent_t ent = {0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0}};
enum nss_status status;
if (name[0] == '-' || name[0] == '+')
return NSS_STATUS_NOTFOUND;
__libc_lock_lock (lock);
if (ni == NULL)
{
__nss_database_lookup ("group_compat", NULL, "nis", &ni);
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
}
__libc_lock_unlock (lock);
status = internal_setgrent (&ent);
if (status != NSS_STATUS_SUCCESS)
@ -352,9 +527,19 @@ 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}};
ent_t ent = {0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0}};
enum nss_status status;
__libc_lock_lock (lock);
if (ni == NULL)
{
__nss_database_lookup ("group_compat", NULL, "nis", &ni);
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
}
__libc_lock_unlock (lock);
status = internal_setgrent (&ent);
if (status != NSS_STATUS_SUCCESS)
return status;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1996 Free Software Foundation, Inc.
/* 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.
@ -26,8 +26,15 @@
#include <libc-lock.h>
#include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
#include <nsswitch.h>
#include "netgroup.h"
#include "nss-nisplus.h"
static service_user *ni = NULL;
static bool_t use_nisplus = FALSE; /* default: passwd_compat: nis */
/* Get the declaration of the parser function. */
#define ENTNAME pwent
@ -52,6 +59,9 @@ struct ent_t
bool_t first;
char *oldkey;
int oldkeylen;
nis_result *result;
nis_name *names;
u_long names_nr;
FILE *stream;
struct blacklist_t blacklist;
struct passwd pwd;
@ -59,7 +69,7 @@ struct ent_t
};
typedef struct ent_t ent_t;
static ent_t ext_ent = {0, 0, 0, NULL, 0, NULL, {NULL, 0, 0},
static ent_t ext_ent = {0, 0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0},
{NULL, NULL, 0, 0, NULL, NULL, NULL}};
/* Protect global state against multiple changers. */
@ -68,7 +78,8 @@ __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 *);
extern int _nss_nisplus_parse_pwent (nis_result *, struct passwd *,
char *, size_t);
static void
give_pwd_free (struct passwd *pwd)
{
@ -192,6 +203,18 @@ internal_setpwent (ent_t *ent)
ent->oldkeylen = 0;
}
if (ent->result != NULL)
{
nis_freeresult (ent->result);
ent->result = NULL;
}
if (ent->names != NULL)
{
nis_freenames (ent->names);
ent->names = NULL;
}
ent->names_nr = 0;
ent->blacklist.current = 0;
if (ent->blacklist.data != NULL)
ent->blacklist.data[0] = '\0';
@ -219,6 +242,12 @@ _nss_compat_setpwent (void)
__libc_lock_lock (lock);
if (ni == NULL)
{
__nss_database_lookup ("passwd_compat", NULL, "nis", &ni);
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
}
result = internal_setpwent (&ext_ent);
__libc_lock_unlock (lock);
@ -245,6 +274,19 @@ internal_endpwent (ent_t *ent)
ent->oldkeylen = 0;
}
if (ent->result != NULL)
{
nis_freeresult (ent->result);
ent->result = NULL;
}
if (ent->names != NULL)
{
nis_freenames (ent->names);
ent->names = NULL;
}
ent->names_nr = 0;
ent->blacklist.current = 0;
if (ent->blacklist.data != NULL)
ent->blacklist.data[0] = '\0';
@ -272,14 +314,14 @@ _nss_compat_endpwent (void)
}
static enum nss_status
getpwent_next_netgr (struct passwd *result, ent_t *ent, char *group,
char *buffer, size_t buflen)
getpwent_next_nis_netgr (struct passwd *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;
@ -340,13 +382,176 @@ getpwent_next_netgr (struct passwd *result, ent_t *ent, char *group,
return NSS_STATUS_SUCCESS;
}
static enum nss_status
getpwent_next_nisplus_netgr (struct passwd *result, ent_t *ent, char *group,
char *buffer, size_t buflen)
{
char *ypdomain, *host, *user, *domain, *p2;
int status, parse_res;
size_t p2len;
nis_result *nisres;
/* Maybe we should use domainname here ? We need the current
domainname for the domain field in netgroups */
if (yp_get_default_domain (&ypdomain) != YPERR_SUCCESS)
{
ent->netgroup = 0;
ent->first = 0;
give_pwd_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)
{
status = __internal_getnetgrent_r (&host, &user, &domain,
&ent->netgrdata, buffer, buflen);
if (status != 1)
{
__internal_endnetgrent (&ent->netgrdata);
ent->netgroup = 0;
give_pwd_free (&ent->pwd);
return NSS_STATUS_RETURN;
}
if (user == NULL || user[0] == '-')
continue;
if (domain != NULL && strcmp (ypdomain, domain) != 0)
continue;
p2len = pwd_need_buflen (&ent->pwd);
if (p2len > buflen)
{
__set_errno (ERANGE);
return NSS_STATUS_TRYAGAIN;
}
p2 = buffer + (buflen - p2len);
buflen -= p2len;
{
char buf[strlen (user) + 30];
sprintf(buf, "[name=%s],passwd.org_dir", user);
nisres = nis_list(buf, EXPAND_NAME, NULL, NULL);
}
if (niserr2nss (nisres->status) != NSS_STATUS_SUCCESS)
{
nis_freeresult (nisres);
continue;
}
parse_res = _nss_nisplus_parse_pwent (nisres, result, buffer, buflen);
nis_freeresult (nisres);
if (parse_res)
{
copy_pwd_changes (result, &ent->pwd, p2, p2len);
break;
}
}
return NSS_STATUS_SUCCESS;
}
static enum nss_status
getpwent_next_netgr (struct passwd *result, ent_t *ent, char *group,
char *buffer, size_t buflen)
{
if (use_nisplus)
return getpwent_next_nisplus_netgr (result, ent, group, buffer, buflen);
else
return getpwent_next_nis_netgr (result, ent, group, buffer, buflen);
}
static enum nss_status
getpwent_next_nisplus (struct passwd *result, ent_t *ent, char *buffer,
size_t buflen)
{
int parse_res;
size_t p2len;
char *p2;
if (ent->names == NULL)
{
ent->names = nis_getnames ("passwd.org_dir");
if (ent->names == NULL || ent->names[0] == NULL)
{
ent->nis = 0;
return NSS_STATUS_UNAVAIL;
}
}
p2len = pwd_need_buflen (&ent->pwd);
if (p2len > buflen)
{
__set_errno (ERANGE);
return NSS_STATUS_TRYAGAIN;
}
p2 = buffer + (buflen - p2len);
buflen -= p2len;
do
{
if (ent->first)
{
next_name:
ent->result = nis_first_entry(ent->names[ent->names_nr]);
if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
{
ent->nis = 0;
give_pwd_free (&ent->pwd);
return niserr2nss (ent->result->status);
}
ent->first = FALSE;
}
else
{
nis_result *res;
res = nis_next_entry(ent->names[ent->names_nr],
&ent->result->cookie);
nis_freeresult (ent->result);
ent->result = res;
if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
{
if ((ent->result->status == NIS_NOTFOUND) &&
ent->names[ent->names_nr + 1] != NULL)
{
nis_freeresult (ent->result);
ent->names_nr += 1;
goto next_name;
}
else
{
ent->nis = 0;
give_pwd_free (&ent->pwd);
return niserr2nss (ent->result->status);
}
}
}
parse_res = _nss_nisplus_parse_pwent (ent->result, result, buffer,
buflen);
if (parse_res &&
in_blacklist (result->pw_name, strlen (result->pw_name), ent))
parse_res = 0; /* if result->pw_name in blacklist,search next entry */
}
while (!parse_res);
copy_pwd_changes (result, &ent->pwd, p2, p2len);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
getpwent_next_nis (struct passwd *result, ent_t *ent, char *buffer,
size_t buflen)
{
struct parser_data *data = (void *) buffer;
char *domain, *outkey, *outval, *p, *p2;
int outkeylen, outvallen;
int outkeylen, outvallen, parse_res;
size_t p2len;
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
@ -404,17 +609,96 @@ getpwent_next_nis (struct passwd *result, ent_t *ent, char *buffer,
while (isspace (*p))
++p;
parse_res = _nss_files_parse_pwent (p, result, data, buflen);
if (parse_res &&
in_blacklist (result->pw_name, strlen (result->pw_name), ent))
parse_res = 0;
}
while (!_nss_files_parse_pwent (p, result, data, buflen));
while (!parse_res);
copy_pwd_changes (result, &ent->pwd, p2, p2len);
if (!in_blacklist (result->pw_name, strlen (result->pw_name), ent))
return NSS_STATUS_SUCCESS;
else
return NSS_STATUS_NOTFOUND;
return NSS_STATUS_SUCCESS;
}
/* This function handle the +user entrys in /etc/passwd */
static enum nss_status
getpwent_next_file_plususer (struct passwd *result, char *buffer,
size_t buflen)
{
struct parser_data *data = (void *) buffer;
struct passwd pwd;
int parse_res;
char *p;
size_t plen;
memset (&pwd, '\0', sizeof (struct passwd));
copy_pwd_changes (&pwd, result, NULL, 0);
plen = pwd_need_buflen (&pwd);
if (plen > buflen)
{
__set_errno (ERANGE);
return NSS_STATUS_TRYAGAIN;
}
p = buffer + (buflen - plen);
buflen -= plen;
if (use_nisplus) /* Do the NIS+ query here */
{
nis_result *res;
char buf[strlen (result->pw_name) + 24];
sprintf(buf, "[name=%s],passwd.org_dir",
&result->pw_name[1]);
res = nis_list(buf, EXPAND_NAME, NULL, NULL);
if (niserr2nss (res->status) != NSS_STATUS_SUCCESS)
{
enum nss_status status = niserr2nss (res->status);
nis_freeresult (res);
return status;
}
parse_res = _nss_nisplus_parse_pwent (res, result, buffer, buflen);
nis_freeresult (res);
}
else /* Use NIS */
{
char *domain;
char *outval;
int outvallen;
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
return NSS_STATUS_TRYAGAIN;
if (yp_match (domain, "passwd.byname", &result->pw_name[1],
strlen (result->pw_name) - 1, &outval, &outvallen)
!= YPERR_SUCCESS)
return NSS_STATUS_TRYAGAIN;
p = strncpy (buffer, outval,
buflen < outvallen ? buflen : outvallen);
free (outval);
while (isspace (*p))
p++;
parse_res = _nss_files_parse_pwent (p, result, data, buflen);
}
if (parse_res)
{
copy_pwd_changes (result, &pwd, p, plen);
give_pwd_free (&pwd);
/* We found the entry. */
return NSS_STATUS_SUCCESS;
}
else
{
/* Give buffer the old len back */
buflen += plen;
give_pwd_free (&pwd);
}
return NSS_STATUS_RETURN;
}
static enum nss_status
getpwent_next_file (struct passwd *result, ent_t *ent,
@ -423,8 +707,7 @@ getpwent_next_file (struct passwd *result, ent_t *ent,
struct parser_data *data = (void *) buffer;
while (1)
{
char *p, *p2;
size_t p2len;
char *p;
do
{
@ -494,50 +777,16 @@ getpwent_next_file (struct passwd *result, ent_t *ent,
if (result->pw_name[0] == '+' && result->pw_name[1] != '\0'
&& result->pw_name[1] != '@')
{
char *domain;
char *outval;
int outvallen;
struct passwd pwd;
memset (&pwd, '\0', sizeof (struct passwd));
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
/* XXX Should we regard this as an fatal error? I don't
think so. Just continue working. --drepper@gnu */
continue;
if (yp_match (domain, "passwd.byname", &result->pw_name[1],
strlen (result->pw_name) - 1, &outval, &outvallen)
!= YPERR_SUCCESS)
continue;
copy_pwd_changes (&pwd, result, NULL, 0);
p2len = pwd_need_buflen (&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 (_nss_files_parse_pwent (p, result, data, buflen))
{
copy_pwd_changes (result, &pwd, p2, p2len);
give_pwd_free (&pwd);
/* We found the entry. */
break;
}
enum nss_status status;
status = getpwent_next_file_plususer (result, buffer, buflen);
if (status == NSS_STATUS_SUCCESS) /* We found the entry. */
break;
else
{
/* Give buffer the old len back */
buflen += p2len;
give_pwd_free (&pwd);
}
if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */
continue;
else
return status;
}
/* +:... */
@ -547,7 +796,10 @@ getpwent_next_file (struct passwd *result, ent_t *ent,
ent->first = TRUE;
copy_pwd_changes (&ent->pwd, result, NULL, 0);
return getpwent_next_nis (result, ent, buffer, buflen);
if (use_nisplus)
return getpwent_next_nisplus (result, ent, buffer, buflen);
else
return getpwent_next_nis (result, ent, buffer, buflen);
}
}
@ -572,7 +824,12 @@ internal_getpwent_r (struct passwd *pw, ent_t *ent, char *buffer,
return status;
}
else if (ent->nis)
return getpwent_next_nis (pw, ent, buffer, buflen);
{
if (use_nisplus)
return getpwent_next_nisplus (pw, ent, buffer, buflen);
else
return getpwent_next_nis (pw, ent, buffer, buflen);
}
else
return getpwent_next_file (pw, ent, buffer, buflen);
}
@ -585,6 +842,12 @@ _nss_compat_getpwent_r (struct passwd *pwd, char *buffer,
__libc_lock_lock (lock);
if (ni == NULL)
{
__nss_database_lookup ("passwd_compat", NULL, "nis", &ni);
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
}
/* Be prepared that the setpwent function was not called before. */
if (ext_ent.stream == NULL)
status = internal_setpwent (&ext_ent);
@ -602,13 +865,22 @@ enum nss_status
_nss_compat_getpwnam_r (const char *name, struct passwd *pwd,
char *buffer, size_t buflen)
{
ent_t ent = {0, 0, 0, NULL, 0, NULL, {NULL, 0, 0},
ent_t ent = {0, 0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0},
{NULL, NULL, 0, 0, NULL, NULL, NULL}};
enum nss_status status;
if (name[0] == '-' || name[0] == '+')
return NSS_STATUS_NOTFOUND;
__libc_lock_lock (lock);
if (ni == NULL)
{
__nss_database_lookup ("passwd_compat", NULL, "nis", &ni);
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
}
__libc_lock_unlock (lock);
status = internal_setpwent (&ent);
if (status != NSS_STATUS_SUCCESS)
@ -628,10 +900,20 @@ enum nss_status
_nss_compat_getpwuid_r (uid_t uid, struct passwd *pwd,
char *buffer, size_t buflen)
{
ent_t ent = {0, 0, 0, NULL, 0, NULL, {NULL, 0, 0},
ent_t ent = {0, 0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0},
{NULL, NULL, 0, 0, NULL, NULL, NULL}};
enum nss_status status;
__libc_lock_lock (lock);
if (ni == NULL)
{
__nss_database_lookup ("passwd_compat", NULL, "nis", &ni);
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
}
__libc_lock_unlock (lock);
status = internal_setpwent (&ent);
if (status != NSS_STATUS_SUCCESS)
return status;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1996 Free Software Foundation, Inc.
/* 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.
@ -26,6 +26,15 @@
#include <libc-lock.h>
#include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
#include <nsswitch.h>
#include "netgroup.h"
#include "nss-nisplus.h"
static service_user *ni = NULL;
static bool_t use_nisplus = FALSE; /* default: passwd_compat: nis */
/* Get the declaration of the parser function. */
#define ENTNAME spent
@ -50,13 +59,17 @@ struct ent_t
bool_t first;
char *oldkey;
int oldkeylen;
nis_result *result;
nis_name *names;
u_long names_nr;
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},
static ent_t ext_ent = {0, 0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0},
{NULL, NULL, 0, 0, 0, 0, 0, 0, 0}};
/* Protect global state against multiple changers. */
@ -65,7 +78,8 @@ __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 *);
extern int _nss_nisplus_parse_spent (nis_result *, struct spwd *,
char *, size_t);
static void
give_spwd_free (struct spwd *pwd)
{
@ -130,6 +144,10 @@ internal_setspent (ent_t *ent)
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);
@ -137,6 +155,18 @@ internal_setspent (ent_t *ent)
ent->oldkeylen = 0;
}
if (ent->result != NULL)
{
nis_freeresult (ent->result);
ent->result = NULL;
}
if (ent->names != NULL)
{
nis_freenames (ent->names);
ent->names = NULL;
}
ent->names_nr = 0;
ent->blacklist.current = 0;
if (ent->blacklist.data != NULL)
ent->blacklist.data[0] = '\0';
@ -164,6 +194,12 @@ _nss_compat_setspent (void)
__libc_lock_lock (lock);
if (ni == NULL)
{
__nss_database_lookup ("shadow_compat", "passwd_compat", "nis", &ni);
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
}
result = internal_setspent (&ext_ent);
__libc_lock_unlock (lock);
@ -181,6 +217,9 @@ internal_endspent (ent_t *ent)
ent->stream = NULL;
}
if (ent->netgroup)
__internal_endnetgrent (&ent->netgrdata);
ent->nis = ent->first = ent->netgroup = 0;
if (ent->oldkey != NULL)
@ -190,10 +229,22 @@ internal_endspent (ent_t *ent)
ent->oldkeylen = 0;
}
if (ent->result != NULL)
{
nis_freeresult (ent->result);
ent->result = NULL;
}
if (ent->names != NULL)
{
nis_freenames (ent->names);
ent->names = NULL;
}
ent->names_nr = 0;
ent->blacklist.current = 0;
if (ent->blacklist.data != NULL)
ent->blacklist.data[0] = '\0';
give_spwd_free (&ent->pwd);
return NSS_STATUS_SUCCESS;
@ -215,8 +266,8 @@ _nss_compat_endspent (void)
static enum nss_status
getspent_next_netgr (struct spwd *result, ent_t *ent, char *group,
char *buffer, size_t buflen)
getspent_next_nis_netgr (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;
@ -233,15 +284,18 @@ getspent_next_netgr (struct spwd *result, ent_t *ent, char *group,
if (ent->first == TRUE)
{
setnetgrent (group);
bzero (&ent->netgrdata, sizeof (struct __netgrent));
__internal_setnetgrent (group, &ent->netgrdata);
ent->first = FALSE;
}
while (1)
{
if ((status = getnetgrent (&host, &user, &domain)) != 1)
status = __internal_getnetgrent_r (&host, &user, &domain,
&ent->netgrdata, buffer, buflen);
if (status != 1)
{
endnetgrent ();
__internal_endnetgrent (&ent->netgrdata);
ent->netgroup = 0;
give_spwd_free (&ent->pwd);
return NSS_STATUS_RETURN;
@ -280,13 +334,177 @@ getspent_next_netgr (struct spwd *result, ent_t *ent, char *group,
return NSS_STATUS_SUCCESS;
}
static enum nss_status
getspent_next_nisplus_netgr (struct spwd *result, ent_t *ent, char *group,
char *buffer, size_t buflen)
{
char *ypdomain, *host, *user, *domain, *p2;
int status, parse_res;
size_t p2len;
nis_result *nisres;
/* Maybe we should use domainname here ? We need the current
domainname for the domain field in netgroups */
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)
{
status = __internal_getnetgrent_r (&host, &user, &domain,
&ent->netgrdata, buffer, buflen);
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;
p2len = spwd_need_buflen (&ent->pwd);
if (p2len > buflen)
{
__set_errno (ERANGE);
return NSS_STATUS_TRYAGAIN;
}
p2 = buffer + (buflen - p2len);
buflen -= p2len;
{
char buf[strlen (user) + 30];
sprintf(buf, "[name=%s],passwd.org_dir", user);
nisres = nis_list(buf, EXPAND_NAME, NULL, NULL);
}
if (niserr2nss (nisres->status) != NSS_STATUS_SUCCESS)
{
nis_freeresult (nisres);
continue;
}
parse_res = _nss_nisplus_parse_spent (nisres, result, buffer, buflen);
nis_freeresult (nisres);
if (parse_res)
{
copy_spwd_changes (result, &ent->pwd, p2, p2len);
break;
}
}
return NSS_STATUS_SUCCESS;
}
static enum nss_status
getspent_next_netgr (struct spwd *result, ent_t *ent, char *group,
char *buffer, size_t buflen)
{
if (use_nisplus)
return getpwent_next_nisplus_netgr (result, ent, group, buffer, buflen);
else
return getpwent_next_nis_netgr (result, ent, group, buffer, buflen);
}
static enum nss_status
getspent_next_nisplus (struct spwd *result, ent_t *ent, char *buffer,
size_t buflen)
{
int parse_res;
size_t p2len;
char *p2;
if (ent->names == NULL)
{
ent->names = nis_getnames ("passwd.org_dir");
if (ent->names == NULL || ent->names[0] == NULL)
{
ent->nis = 0;
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
{
if (ent->first)
{
next_name:
ent->result = nis_first_entry(ent->names[ent->names_nr]);
if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
{
ent->nis = 0;
give_spwd_free (&ent->pwd);
return niserr2nss (ent->result->status);
}
ent->first = FALSE;
}
else
{
nis_result *res;
res = nis_next_entry(ent->names[ent->names_nr],
&ent->result->cookie);
nis_freeresult (ent->result);
ent->result = res;
if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
{
if ((ent->result->status == NIS_NOTFOUND) &&
ent->names[ent->names_nr + 1] != NULL)
{
nis_freeresult (ent->result);
ent->names_nr += 1;
goto next_name;
}
else
{
ent->nis = 0;
give_spwd_free (&ent->pwd);
return niserr2nss (ent->result->status);
}
}
}
parse_res = _nss_nisplus_parse_spent (ent->result, result, buffer,
buflen);
if (parse_res &&
in_blacklist (result->sp_namp, strlen (result->sp_namp), ent))
parse_res = 0; /* if result->pw_name in blacklist,search next entry */
}
while (!parse_res);
copy_spwd_changes (result, &ent->pwd, p2, p2len);
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;
int outkeylen, outvallen, parse_res;
size_t p2len;
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
@ -344,17 +562,96 @@ getspent_next_nis (struct spwd *result, ent_t *ent,
while (isspace (*p))
++p;
parse_res = _nss_files_parse_spent (p, result, data, buflen);
if (parse_res &&
in_blacklist (result->sp_namp, strlen (result->sp_namp), ent))
parse_res = 0;
}
while (!_nss_files_parse_spent (p, result, data, buflen));
while (!parse_res);
copy_spwd_changes (result, &ent->pwd, p2, p2len);
if (!in_blacklist (result->sp_namp, strlen (result->sp_namp), ent))
return NSS_STATUS_SUCCESS;
else
return NSS_STATUS_NOTFOUND;
return NSS_STATUS_SUCCESS;
}
/* This function handle the +user entrys in /etc/shadow */
static enum nss_status
getspent_next_file_plususer (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;
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 (use_nisplus) /* Do the NIS+ query here */
{
nis_result *res;
char buf[strlen (result->sp_namp) + 24];
sprintf(buf, "[name=%s],passwd.org_dir",
&result->sp_namp[1]);
res = nis_list(buf, EXPAND_NAME, NULL, NULL);
if (niserr2nss (res->status) != NSS_STATUS_SUCCESS)
{
enum nss_status status = niserr2nss (res->status);
nis_freeresult (res);
return status;
}
parse_res = _nss_nisplus_parse_spent (res, result, buffer, buflen);
nis_freeresult (res);
}
else /* Use NIS */
{
char *domain;
char *outval;
int outvallen;
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
return NSS_STATUS_TRYAGAIN;
if (yp_match (domain, "passwd.byname", &result->sp_namp[1],
strlen (result->sp_namp) - 1, &outval, &outvallen)
!= YPERR_SUCCESS)
return NSS_STATUS_TRYAGAIN;
p = strncpy (buffer, outval,
buflen < outvallen ? buflen : outvallen);
free (outval);
while (isspace (*p))
p++;
parse_res = _nss_files_parse_spent (p, result, data, buflen);
}
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,
@ -434,50 +731,16 @@ getspent_next_file (struct spwd *result, ent_t *ent,
if (result->sp_namp[0] == '+' && result->sp_namp[1] != '\0'
&& result->sp_namp[1] != '@')
{
char *domain;
char *outval;
int outvallen;
struct spwd pwd;
memset (&pwd, '\0', sizeof (struct spwd));
if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
/* XXX Should we regard this as an fatal error? I don't
think so. Just continue working. --drepper@gnu */
continue;
if (yp_match (domain, "shadow.byname", &result->sp_namp[1],
strlen (result->sp_namp) - 1, &outval, &outvallen)
!= YPERR_SUCCESS)
continue;
copy_spwd_changes (&pwd, result, NULL, 0);
p2len = spwd_need_buflen (&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 (_nss_files_parse_spent (p, result, data, buflen))
{
copy_spwd_changes (result, &pwd, p2, p2len);
give_spwd_free (&pwd);
/* We found the entry. */
break;
}
else
{
/* Give buffer the old len back */
buflen += p2len;
give_spwd_free (&pwd);
}
enum nss_status status;
status = getspent_next_file_plususer (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 */
continue;
else
return status;
}
/* +:... */
@ -487,7 +750,10 @@ getspent_next_file (struct spwd *result, ent_t *ent,
ent->first = TRUE;
copy_spwd_changes (&ent->pwd, result, NULL, 0);
return getspent_next_nis (result, ent, buffer, buflen);
if (use_nisplus)
return getspent_next_nisplus (result, ent, buffer, buflen);
else
return getspent_next_nis (result, ent, buffer, buflen);
}
}
@ -512,7 +778,12 @@ internal_getspent_r (struct spwd *pw, ent_t *ent,
return status;
}
else if (ent->nis)
return getspent_next_nis (pw, ent, buffer, buflen);
{
if (use_nisplus)
return getspent_next_nisplus (pw, ent, buffer, buflen);
else
return getspent_next_nis (pw, ent, buffer, buflen);
}
else
return getspent_next_file (pw, ent, buffer, buflen);
}
@ -524,6 +795,12 @@ _nss_compat_getspent_r (struct spwd *pwd, char *buffer, size_t buflen)
__libc_lock_lock (lock);
if (ni == NULL)
{
__nss_database_lookup ("shadow_compat", "passwd_compat", "nis", &ni);
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
}
/* Be prepared that the setspent function was not called before. */
if (ext_ent.stream == NULL)
status = internal_setspent (&ext_ent);
@ -541,13 +818,19 @@ 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},
ent_t ent = {0, 0, 0, NULL, 0, NULL, 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;
if (ni == NULL)
{
__nss_database_lookup ("shadow_compat", "passwd_compat", "nis", &ni);
use_nisplus = (strcmp (ni->name, "nisplus") == 0);
}
status = internal_setspent (&ent);
if (status != NSS_STATUS_SUCCESS)
return status;
@ -619,3 +902,4 @@ in_blacklist (const char *name, int namelen, ent_t *ent)
stpcpy (stpcpy (stpcpy (buf, "|"), name), "|");
return strstr (ent->blacklist.data, buf) != NULL;
}

View File

@ -122,7 +122,7 @@ internal_nis_getgrent_r (struct group *grp, char *buffer, size_t buflen)
free (result);
parse_res = _nss_files_parse_grent (p, grp, data, buflen);
if (!parse_res && errno == ERANGE)
if (parse_res < 1 && errno == ERANGE)
return NSS_STATUS_TRYAGAIN;
free (oldkey);
@ -130,7 +130,7 @@ internal_nis_getgrent_r (struct group *grp, char *buffer, size_t buflen)
oldkeylen = keylen;
new_start = 0;
}
while (!parse_res);
while (parse_res < 1);
return NSS_STATUS_SUCCESS;
}
@ -192,7 +192,7 @@ _nss_nis_getgrnam_r (const char *name, struct group *grp,
parse_res = _nss_files_parse_grent (p, grp, data, buflen);
if (!parse_res)
if (parse_res < 1)
{
if (errno == ERANGE)
return NSS_STATUS_TRYAGAIN;
@ -243,7 +243,7 @@ _nss_nis_getgrgid_r (gid_t gid, struct group *grp,
parse_res = _nss_files_parse_grent (p, grp, data, buflen);
if (!parse_res)
if (parse_res < 1)
{
if (errno == ERANGE)
return NSS_STATUS_TRYAGAIN;

View File

@ -23,22 +23,24 @@
#include <string.h>
#include <syslog.h>
#include <libc-lock.h>
#include <rpc/key_prot.h>
#include <rpc/rpc.h>
#include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h>
#if defined (HAVE_SECURE_RPC)
#include <rpc/key_prot.h>
extern int xdecrypt (char *, char *);
#endif
#include "nss-nis.h"
extern int xdecrypt (char *, char *);
/* If we found the entry, we give a SUCCESS and an empty key back. */
/* If we haven't found the entry, we give a SUCCESS and an empty key back. */
enum nss_status
_nss_nis_getpublickey (const char *netname, char *pkey)
{
enum nss_status retval;
char *domain, *result;
int len;
pkey[0] = 0;
if (netname == NULL)
@ -75,6 +77,7 @@ _nss_nis_getpublickey (const char *netname, char *pkey)
enum nss_status
_nss_nis_getsecretkey (const char *netname, char *skey, char *passwd)
{
#if defined (HAVE_SECURE_RPC)
enum nss_status retval;
char buf[1024];
char *domain, *result;
@ -120,6 +123,9 @@ _nss_nis_getsecretkey (const char *netname, char *skey, char *passwd)
buf[HEXKEYBYTES] = 0;
strcpy (skey, buf);
}
#else
skey[0] = 0;
#endif
return NSS_STATUS_SUCCESS;
}

View File

@ -44,7 +44,7 @@ _nss_nisplus_parse_aliasent (nis_result *result, struct aliasent *alias,
char *buffer, size_t buflen)
{
if (result == NULL)
return -1;
return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
result->objects.objects_len != 1 ||
@ -52,7 +52,7 @@ _nss_nisplus_parse_aliasent (nis_result *result, struct aliasent *alias,
strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
"mail_aliases") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 2)
return -1;
return 0;
else
{
char *first_unused = buffer + NISENTRYLEN(0, 1, result) + 1;
@ -67,7 +67,7 @@ _nss_nisplus_parse_aliasent (nis_result *result, struct aliasent *alias,
/* The line is too long for our buffer. */
no_more_room:
__set_errno (ERANGE);
return -1;
return 0;
}
else
{

View File

@ -86,7 +86,7 @@ _nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether,
struct parser_data *data = (void *) buffer;
if (result == NULL)
return -1;
return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
result->objects.objects_len != 1 ||
@ -94,7 +94,7 @@ _nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether,
strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
"ethers_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 2)
return -1;
return 0;
memset (p, '\0', room_left);
@ -102,7 +102,7 @@ _nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether,
if (NISENTRYLEN (0, 0, result) +1 > room_left)
{
__set_errno (ERANGE);
return -1;
return 0;
}
strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
room_left -= (NISENTRYLEN (0, 0, result) +1);
@ -110,7 +110,7 @@ _nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether,
if (NISENTRYLEN (0, 1, result) +1 > room_left)
{
__set_errno (ERANGE);
return -1;
return 0;
}
strcat (p, "\t");
strncat (p, NISENTRYVAL (0, 1, result), NISENTRYLEN (0, 1, result));

View File

@ -39,63 +39,34 @@ static nis_name *names = NULL;
#define NISENTRYLEN(idx,col,res) \
((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
#define STRUCTURE group
#define ENTNAME grent
struct grent_data {};
#define TRAILING_LIST_MEMBER gr_mem
#define TRAILING_LIST_SEPARATOR_P(c) ((c) == ',')
#include "../../nss/nss_files/files-parse.c"
LINE_PARSER
(,
STRING_FIELD (result->gr_name, ISCOLON, 0);
if (line[0] == '\0'
&& (result->gr_name[0] == '+' || result->gr_name[0] == '-'))
{
result->gr_passwd = NULL;
result->gr_gid = 0;
}
else
{
STRING_FIELD (result->gr_passwd, ISCOLON, 0);
if (result->gr_name[0] == '+' || result->gr_name[0] == '-')
INT_FIELD_MAYBE_NULL (result->gr_gid, ISCOLON, 0, 10, , 0)
else
INT_FIELD (result->gr_gid, ISCOLON, 0, 10,)
}
)
static int
int
_nss_nisplus_parse_grent (nis_result * result, struct group *gr,
char *buffer, size_t buflen)
{
#if 0
/* XXX here is a bug, sometimes we get some special characters at the
end of a line */
char *first_unused = buffer;
size_t room_left = buflen;
char *line;
int count;
if (result == NULL)
return -1;
return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
result->objects.objects_len != 1 ||
result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
"group_tbl") != 0 ||
strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
"group_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 4)
return -1;
return 0;
if (NISENTRYLEN (0, 0, result) >= room_left)
{
/* The line is too long for our buffer. */
no_more_room:
__set_errno (ERANGE);
return -1;
return 0;
}
strncpy (first_unused, NISENTRYVAL (0, 0, result),
NISENTRYLEN (0, 0, result));
first_unused[NISENTRYLEN (0, 0, result)] = '\0';
@ -158,8 +129,11 @@ _nss_nisplus_parse_grent (nis_result * result, struct group *gr,
if (line != gr->gr_mem[count])
{
*line = '\0';
++line;
if (*line != '\0')
{
*line = '\0';
++line;
}
++count;
}
else
@ -171,59 +145,6 @@ _nss_nisplus_parse_grent (nis_result * result, struct group *gr,
gr->gr_mem[count] = NULL;
return 1;
#else
char *p = buffer;
size_t room_left = buflen;
struct parser_data *data = (void *) buffer;
if (result == NULL)
return -1;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
result->objects.objects_len != 1 ||
result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
"group_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 4)
return -1;
memset (p, '\0', room_left);
if (NISENTRYLEN (0, 0, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
}
strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
room_left -= (NISENTRYLEN (0, 0, result) + 1);
strcat (p, ":");
if (NISENTRYLEN (0, 1, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
}
strncat (p, NISENTRYVAL (0, 1, result), NISENTRYLEN (0, 1, result));
room_left -= (NISENTRYLEN (0, 1, result) + 1);
strcat (p, ":");
if (NISENTRYLEN (0, 2, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
}
strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result));
room_left -= (NISENTRYLEN (0, 2, result) + 1);
strcat (p, ":");
if (NISENTRYLEN (0, 3, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
}
strncat (p, NISENTRYVAL (0, 3, result), NISENTRYLEN (0, 3, result));
room_left -= (NISENTRYLEN (0, 3, result) + 1);
return _nss_files_parse_grent (p, gr, data, buflen);
#endif
}
enum nss_status

View File

@ -121,14 +121,14 @@ _nss_nisplus_parse_hostent (nis_result *result, struct hostent *host,
struct parser_data *data = (void *) buffer;
if (result == NULL)
return -1;
return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
"hosts_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 4)
return -1;
return 0;
memset (p, '\0', room_left);
@ -136,7 +136,7 @@ _nss_nisplus_parse_hostent (nis_result *result, struct hostent *host,
if (NISENTRYLEN (0, 2, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
return 0;
}
strncpy (p, NISENTRYVAL (0, 2, result),
NISENTRYLEN (0, 2, result));
@ -145,7 +145,7 @@ _nss_nisplus_parse_hostent (nis_result *result, struct hostent *host,
if (NISENTRYLEN (0, 0, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
return 0;
}
strcat (p, "\t");
strncat (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
@ -157,7 +157,7 @@ _nss_nisplus_parse_hostent (nis_result *result, struct hostent *host,
if (NISENTRYLEN (i, 1, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
return 0;
}
strcat (p, " ");
strcat (p, NISENTRYVAL (i, 1, result));

View File

@ -31,13 +31,9 @@
__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);
static nis_result *data = NULL;
static unsigned long data_size = 0;
static unsigned long position = 0;
#define NISENTRYVAL(idx,col,res) \
((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
@ -45,15 +41,103 @@ _nss_netgroup_parseline (char **cursor, struct __netgrent *result,
#define NISENTRYLEN(idx,col,res) \
((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
static enum nss_status
_nss_nisplus_parse_netgroup (struct __netgrent *result, char *buffer,
size_t buflen)
{
enum nss_status status;
/* Some sanity checks. */
if (data == NULL || data_size == 0)
/* User bug. setnetgrent() wasn't called before. */
abort ();
if (position == data_size)
return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
if (NISENTRYLEN (position, 1, data) > 0)
{
/* We have a list of other netgroups. */
result->type = group_val;
if (NISENTRYLEN (position, 1, data) >= buflen)
{
__set_errno (ERANGE);
return NSS_STATUS_TRYAGAIN;
}
strncpy (buffer, NISENTRYVAL (position, 1, data),
NISENTRYLEN (position, 1, data));
buffer[NISENTRYLEN (position, 1, data)] = '\0';
result->val.group = buffer;
++position;
result->first = 0;
return NSS_STATUS_SUCCESS;
}
/* Before we can copy the entry to the private buffer we have to make
sure it is big enough. */
if (NISENTRYLEN (position, 2, data) + NISENTRYLEN (position, 3, data) +
NISENTRYLEN (position, 4, data) + 6 > buflen)
{
__set_errno (ERANGE);
status = NSS_STATUS_UNAVAIL;
}
else
{
char *cp = buffer;
result->type = triple_val;
if (NISENTRYLEN (position, 2, data) == 0)
result->val.triple.host = NULL;
else
{
result->val.triple.host = cp;
cp = stpncpy (cp, NISENTRYVAL (position, 2, data),
NISENTRYLEN (position, 2, data));
*cp = '\0';
++cp;
}
if (NISENTRYLEN (position, 3, data) == 0)
result->val.triple.user = NULL;
else
{
result->val.triple.user = cp;
cp = stpncpy (cp, NISENTRYVAL (position, 3, data),
NISENTRYLEN (position, 3, data));
*cp = '\0';
++cp;
}
if (NISENTRYLEN (position, 4, data) == 0)
result->val.triple.domain = NULL;
else
{
result->val.triple.domain = cp;
cp = stpncpy (cp, NISENTRYVAL (position, 4, data),
NISENTRYLEN (position, 4, data));
*cp = '\0';
}
status = NSS_STATUS_SUCCESS;
/* Remember where we stopped reading. */
++position;
result->first = 0;
}
return status;
}
enum nss_status
_nss_nisplus_setnetgrent (char *group)
{
enum nss_status status;
nis_result *result;
char buf[strlen (group) + 30];
int i;
size_t len;
if (group == NULL || group[0] == '\0')
return NSS_STATUS_UNAVAIL;
@ -64,43 +148,27 @@ _nss_nisplus_setnetgrent (char *group)
if (data != NULL)
{
free (data);
nis_freeresult (data);
data = NULL;
data_size = 0;
cursor = NULL;
position = 0;
}
sprintf(buf, "[name=%s],netgroup.org_dir", group);
result = nis_list(buf, EXPAND_NAME, NULL, NULL);
data = nis_list(buf, EXPAND_NAME, NULL, NULL);
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
status = niserr2nss (result->status);
len = 0;
for (i = 0; i < result->objects.objects_len; i++)
len += 1 + NISENTRYLEN (i, 1, result) + 1 + NISENTRYLEN(i,2,result)
+ 1 + NISENTRYLEN(i,3,result) + 1 + NISENTRYLEN(i,4,result) + 2;
data = malloc (len+1);
memset (data, '\0', len+1);
for (i = 0; i < result->objects.objects_len; i++)
if (niserr2nss (data->status) != NSS_STATUS_SUCCESS)
{
strncat (data, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));
strcat (data," (");
strncat (data, NISENTRYVAL(i,2,result), NISENTRYLEN (i, 2, result));
strcat (data, ",");
strncat (data, NISENTRYVAL(i,3,result), NISENTRYLEN (i, 3, result));
strcat (data, ",");
strncat (data, NISENTRYVAL(i,4,result), NISENTRYLEN (i, 4, result));
strcat (data, ") ");
status = niserr2nss (data->status);
nis_freeresult (data);
data = NULL;
}
nis_freeresult (result);
else
data_size = data->objects.objects_len;
__libc_lock_unlock (lock);
return status;
}
@ -111,10 +179,10 @@ _nss_nisplus_endnetgrent (void)
if (data != NULL)
{
free (data);
nis_freeresult (data);
data = NULL;
data_size = 0;
cursor = NULL;
position = 0;
}
__libc_lock_unlock (lock);
@ -128,12 +196,9 @@ _nss_nisplus_getnetgrent_r (struct __netgrent *result,
{
enum nss_status status;
if (cursor == NULL)
return NSS_STATUS_NOTFOUND;
__libc_lock_lock (lock);
status = _nss_netgroup_parseline (&cursor, result, buffer, buflen);
status = _nss_nisplus_parse_netgroup (result, buffer, buflen);
__libc_lock_unlock (lock);

View File

@ -69,20 +69,20 @@ _nss_nisplus_parse_netent (nis_result *result, struct netent *network,
struct parser_data *data = (void *) buffer;
if (result == NULL)
return -1;
return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
"networks_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3)
return -1;
return 0;
/* Generate the network entry format and use the normal parser */
if (NISENTRYLEN (0, 0, result) +1 > room_left)
{
__set_errno (ERANGE);
return -1;
return 0;
}
memset (p, '\0', room_left);
@ -93,7 +93,7 @@ _nss_nisplus_parse_netent (nis_result *result, struct netent *network,
if (NISENTRYLEN (0, 2, result) +1 > room_left)
{
__set_errno (ERANGE);
return -1;
return 0;
}
strcat (p, "\t");
strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result));
@ -101,12 +101,11 @@ _nss_nisplus_parse_netent (nis_result *result, struct netent *network,
/* + 1: We overwrite the last \0 */
for (i = 1; i < result->objects.objects_len; i++)
/* XXX should we start with i = 0 or with i = 1 ? */
{
if (NISENTRYLEN (i, 1, result) +1 > room_left)
{
__set_errno (ERANGE);
return -1;
return 0;
}
strcat (p, " ");
strncat (p, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));

View File

@ -60,14 +60,14 @@ _nss_nisplus_parse_protoent (nis_result * result, struct protoent *proto,
struct parser_data *data = (void *) buffer;
if (result == NULL)
return -1;
return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
"protocols_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3)
return -1;
return 0;
memset (p, '\0', room_left);
@ -75,7 +75,7 @@ _nss_nisplus_parse_protoent (nis_result * result, struct protoent *proto,
if (NISENTRYLEN (0, 0, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
return 0;
}
strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
room_left -= (NISENTRYLEN (0, 0, result) + 1);
@ -83,7 +83,7 @@ _nss_nisplus_parse_protoent (nis_result * result, struct protoent *proto,
if (NISENTRYLEN (0, 2, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
return 0;
}
strcat (p, "\t");
strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result));
@ -95,7 +95,7 @@ _nss_nisplus_parse_protoent (nis_result * result, struct protoent *proto,
if (NISENTRYLEN (i, 1, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
return 0;
}
strcat (p, " ");
strncat (p, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));

View File

@ -23,15 +23,17 @@
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include <rpc/key_prot.h>
#include <rpc/rpc.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
#ifdef HAVE_SECURE_RPC
#include <rpc/key_prot.h>
extern int xdecrypt (char *, char *);
#endif
#include <nss-nisplus.h>
extern int xdecrypt (char *, char *);
/* If we found the entry, we give a SUCCESS and an empty key back. */
/* If we haven't found the entry, we give a SUCCESS and an empty key back. */
enum nss_status
_nss_nisplus_getpublickey (const char *netname, char *pkey)
{
@ -70,6 +72,8 @@ _nss_nisplus_getpublickey (const char *netname, char *pkey)
{
if (retval == NSS_STATUS_TRYAGAIN)
__set_errno (EAGAIN);
if (res->status == NIS_NOTFOUND)
retval = NSS_STATUS_SUCCESS;
nis_freeresult (res);
return retval;
}
@ -100,6 +104,7 @@ _nss_nisplus_getpublickey (const char *netname, char *pkey)
enum nss_status
_nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd)
{
#ifdef HAVE_SECURE_RPC
nis_result *res;
enum nss_status retval;
char buf[NIS_MAXNAMELEN+2];
@ -167,6 +172,9 @@ _nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd)
buf[HEXKEYBYTES] = 0;
strcpy (skey, buf);
#else
skey[0] = 0;
#endif
return NSS_STATUS_SUCCESS;
}

View File

@ -38,7 +38,7 @@ static nis_name *names = NULL;
#define NISENTRYLEN(idx,col,res) \
((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
static int
int
_nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
char *buffer, size_t buflen)
{
@ -46,7 +46,7 @@ _nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
size_t room_left = buflen;
if (result == NULL)
return -1;
return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
result->objects.objects_len != 1 ||
@ -54,14 +54,14 @@ _nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
"passwd_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 7)
return -1;
return 0;
if (NISENTRYLEN(0, 0, result) >= room_left)
{
/* The line is too long for our buffer. */
no_more_room:
__set_errno (ERANGE);
return -1;
return 0;
}
strncpy (first_unused, NISENTRYVAL(0, 0, result),

View File

@ -60,14 +60,14 @@ _nss_nisplus_parse_rpcent (nis_result *result, struct rpcent *rpc,
struct parser_data *data = (void *) buffer;
if (result == NULL)
return -1;
return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
"rpc_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3)
return -1;
return 0;
memset (p, '\0', room_left);
@ -75,7 +75,7 @@ _nss_nisplus_parse_rpcent (nis_result *result, struct rpcent *rpc,
if (NISENTRYLEN (0, 0, result) +1 > room_left)
{
__set_errno (ERANGE);
return -1;
return 0;
}
strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
room_left -= (NISENTRYLEN (0, 0, result) +1);
@ -83,7 +83,7 @@ _nss_nisplus_parse_rpcent (nis_result *result, struct rpcent *rpc,
if (NISENTRYLEN (0, 2, result) +1 > room_left)
{
__set_errno (ERANGE);
return -1;
return 0;
}
strcat (p, "\t");
strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result));
@ -96,7 +96,7 @@ _nss_nisplus_parse_rpcent (nis_result *result, struct rpcent *rpc,
if (NISENTRYLEN (i, 1, result) +1 > room_left)
{
__set_errno (ERANGE);
return -1;
return 0;
}
strcat (p, " ");
strncat (p, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));

View File

@ -63,14 +63,14 @@ _nss_nisplus_parse_servent (nis_result *result, struct servent *serv,
struct parser_data *data = (void *) buffer;
if (result == NULL)
return -1;
return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
"services_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 4)
return -1;
return 0;
memset (p, '\0', room_left);
@ -78,7 +78,7 @@ _nss_nisplus_parse_servent (nis_result *result, struct servent *serv,
if (NISENTRYLEN (0, 0, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
return 0;
}
strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
room_left -= (NISENTRYLEN (0, 0, result) + 1);
@ -86,7 +86,7 @@ _nss_nisplus_parse_servent (nis_result *result, struct servent *serv,
if (NISENTRYLEN (0, 3, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
return 0;
}
strcat (p, "\t");
strncat (p, NISENTRYVAL (0, 3, result), NISENTRYLEN (0, 3, result));
@ -94,7 +94,7 @@ _nss_nisplus_parse_servent (nis_result *result, struct servent *serv,
if (NISENTRYLEN (0, 2, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
return 0;
}
strcat (p, "/");
strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result));
@ -105,7 +105,7 @@ _nss_nisplus_parse_servent (nis_result *result, struct servent *serv,
if (NISENTRYLEN (i, 1, result) + 1 > room_left)
{
__set_errno (ERANGE);
return -1;
return 0;
}
strcat (p, " ");
strcat (p, NISENTRYVAL (i, 1, result));

View File

@ -38,7 +38,7 @@ static nis_name *names = NULL;
#define NISENTRYLEN(idx,col,res) \
((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
static int
int
_nss_nisplus_parse_spent (nis_result *result, struct spwd *sp,
char *buffer, size_t buflen)
{
@ -47,7 +47,7 @@ _nss_nisplus_parse_spent (nis_result *result, struct spwd *sp,
char *line, *cp;
if (result == NULL)
return -1;
return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
result->objects.objects_len != 1 ||
@ -55,14 +55,14 @@ _nss_nisplus_parse_spent (nis_result *result, struct spwd *sp,
strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
"passwd_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 8)
return -1;
return 0;
if (NISENTRYLEN(0, 0, result) >= room_left)
{
/* The line is too long for our buffer. */
no_more_room:
__set_errno (ERANGE);
return -1;
return 0;
}
strncpy (first_unused, NISENTRYVAL (0, 0, result),

View File

@ -21,6 +21,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <libc-lock.h>
#include <rpc/rpc.h>
#include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h>
#include <rpcsvc/ypupd.h>
@ -781,7 +782,7 @@ int
yp_update (char *domain, char *map, unsigned ypop,
char *key, int keylen, char *data, int datalen)
{
#if 0
#if defined (HAVE_SECURE_RPC)
union
{
ypupdate_args update_args;
@ -847,8 +848,8 @@ yp_update (char *domain, char *map, unsigned ypop,
clnt->cl_auth = authunix_create_default ();
again:
r = clnt_call (clnt, ypop, xdr_argument, &args,
(xdrproc_t) xdr_u_int, &res, TIMEOUT);
r = clnt_call (clnt, ypop, xdr_argument, (caddr_t) &args,
(xdrproc_t) xdr_u_int, (caddr_t) &res, TIMEOUT);
if (r == RPC_AUTHERROR)
{

700
po/fr.po

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
#include <sunrpc/rpc/auth.h>

View File

@ -1 +0,0 @@
#include <sunrpc/rpc/auth_des.h>

185
sysdeps/libm-i387/s_cbrt.S Normal file
View File

@ -0,0 +1,185 @@
/* Compute cubic root of double value.
Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Dirk Alboth <dirka@uni-paderborn.de> and
Ulrich Drepper <drepper@cygnus.com>, 1997.
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 <machine/asm.h>
#ifdef __ELF__
.section .rodata
#else
.text
#endif
.align ALIGNARG(4)
ASM_TYPE_DIRECTIVE(f1,@object)
f1: .double 0.354895765043919860
ASM_SIZE_DIRECTIVE(f1)
ASM_TYPE_DIRECTIVE(f2,@object)
f2: .double 1.50819193781584896
ASM_SIZE_DIRECTIVE(f2)
ASM_TYPE_DIRECTIVE(f3,@object)
f3: .double -2.11499494167371287
ASM_SIZE_DIRECTIVE(f3)
ASM_TYPE_DIRECTIVE(f4,@object)
f4: .double 2.44693122563534430
ASM_SIZE_DIRECTIVE(f4)
ASM_TYPE_DIRECTIVE(f5,@object)
f5: .double -1.83469277483613086
ASM_SIZE_DIRECTIVE(f5)
ASM_TYPE_DIRECTIVE(f6,@object)
f6: .double 0.784932344976639262
ASM_SIZE_DIRECTIVE(f6)
ASM_TYPE_DIRECTIVE(f7,@object)
f7: .double -0.145263899385486377
ASM_SIZE_DIRECTIVE(f7)
#define CBRT2 1.2599210498948731648
#define SQR_CBRT2 1.5874010519681994748
ASM_TYPE_DIRECTIVE(factor,@object)
factor: .double 1.0 / SQR_CBRT2
.double 1.0 / CBRT2
.double 1.0
.double CBRT2
.double SQR_CBRT2
ASM_SIZE_DIRECTIVE(factor)
ASM_TYPE_DIRECTIVE(two54,@object)
two54: .byte 0, 0, 0, 0, 0, 0, 0x50, 0x43
ASM_SIZE_DIRECTIVE(two54)
#ifdef PIC
#define MO(op) op##@GOTOFF(%ebx)
#define MOX(op,x,f) op##@GOTOFF(%ebx,x,f)
#else
#define MO(op) op
#define MOX(op,x,f) op(,x,f)
#endif
.text
ENTRY(__cbrt)
movl 4(%esp), %ecx
movl 8(%esp), %eax
movl %eax, %edx
andl $0x7fffffff, %eax
orl %eax, %ecx
jz 1f
xorl %ecx, %ecx
cmpl $0x7ff00000, %eax
jae 1f
#ifdef PIC
pushl %ebx
call 3f
3: popl %ebx
addl $_GLOBAL_OFFSET_TABLE_+[.-3b], %ebx
#endif
cmpl $0x00100000, %eax
jae 2f
#ifdef PIC
fldl 8(%esp)
#else
fldl 4(%esp)
#endif
fmull MO(two54)
movl $-54, %ecx
fstpl 4(%esp)
movl 8(%esp), %eax
movl %eax, %edx
andl $0x7fffffff, %eax
2: shrl $20, %eax
andl $0x800fffff, %edx
subl $1022, %eax
orl $0x3fe00000, %edx
addl %eax, %ecx
#ifdef PIC
movl %edx, 12(%esp)
fldl 8(%esp) /* xm */
#else
movl %edx, 8(%esp)
fldl 4(%esp) /* xm */
#endif
fabs
/* The following code has two track:
a) compute the normalized cbrt value
b) compute xe/3 and xe%3
The right track computes the value for b) and this is done
in an optimized way by avoiding division. */
fld %st(0) /* xm : xm */
fmull MO(f7) /* f7*xm : xm */
movl $1431655766, %eax
faddl MO(f6) /* f6+f7*xm : xm */
imull %ecx
fmul %st(1) /* (f6+f7*xm)*xm : xm */
movl %ecx, %eax
faddl MO(f5) /* f5+(f6+f7*xm)*xm : xm */
sarl $31, %eax
fmul %st(1) /* (f5+(f6+f7*xm)*xm)*xm : xm */
subl %eax, %edx
faddl MO(f4) /* f4+(f5+(f6+f7*xm)*xm)*xm : xm */
fmul %st(1) /* (f4+(f5+(f6+f7*xm)*xm)*xm)*xm : xm */
faddl MO(f3) /* f3+(f4+(f5+(f6+f7*xm)*xm)*xm)*xm : xm */
fmul %st(1) /* (f3+(f4+(f5+(f6+f7*xm)*xm)*xm)*xm)*xm : xm */
faddl MO(f2) /* f2+(f3+(f4+(f5+(f6+f7*xm)*xm)*xm)*xm)*xm : xm */
fmul %st(1) /* (f2+(f3+(f4+(f5+(f6+f7*xm)*xm)*xm)*xm)*xm)*xm : xm */
faddl MO(f1) /* u:=f1+(f2+(f3+(f4+(f5+(f6+f7*xm)*xm)*xm)*xm)*xm)*xm : xm */
fld %st /* u : u : xm */
fmul %st(1) /* u*u : u : xm */
fld %st(2) /* xm : u*u : u : xm */
fadd %st /* 2*xm : u*u : u : xm */
fxch %st(1) /* u*u : 2*xm : u : xm */
fmul %st(2) /* t2:=u*u*u : 2*xm : u : xm */
movl %edx, %eax
fadd %st, %st(1) /* t2 : t2+2*xm : u : xm */
leal (%edx,%edx,2),%edx
fadd %st(0) /* 2*t2 : t2+2*xm : u : xm */
subl %edx, %ecx
faddp %st, %st(3) /* t2+2*xm : u : 2*t2+xm */
fmulp /* u*(t2+2*xm) : 2*t2+xm */
fdivp %st, %st(1) /* u*(t2+2*xm)/(2*t2+xm) */
fmull MOX(16+factor,%ecx,8) /* u*(t2+2*xm)/(2*t2+xm)*FACT */
pushl %eax
fildl (%esp) /* xe/3 : u*(t2+2*xm)/(2*t2+xm)*FACT */
fxch /* u*(t2+2*xm)/(2*t2+xm)*FACT : xe/3 */
popl %eax
fscale /* u*(t2+2*xm)/(2*t2+xm)*FACT*2^xe/3 */
fstp %st(1)
#ifdef PIC
popl %ebx
#endif
testl $0x80000000, 8(%esp)
jz 4f
fchs
4: ret
/* Return the argument. */
1: fldl 4(%esp)
ret
END(__cbrt)
weak_alias (__cbrt, cbrt)

166
sysdeps/libm-i387/s_cbrtf.S Normal file
View File

@ -0,0 +1,166 @@
/* Compute cubic root of float value.
Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Dirk Alboth <dirka@uni-paderborn.de> and
Ulrich Drepper <drepper@cygnus.com>, 1997.
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 <machine/asm.h>
#ifdef __ELF__
.section .rodata
#else
.text
#endif
.align ALIGNARG(4)
ASM_TYPE_DIRECTIVE(f1,@object)
f1: .double 0.492659620528969547
ASM_SIZE_DIRECTIVE(f1)
ASM_TYPE_DIRECTIVE(f2,@object)
f2: .double 0.697570460207922770
ASM_SIZE_DIRECTIVE(f2)
ASM_TYPE_DIRECTIVE(f3,@object)
f3: .double 0.191502161678719066
ASM_SIZE_DIRECTIVE(f3)
#define CBRT2 1.2599210498948731648
#define SQR_CBRT2 1.5874010519681994748
ASM_TYPE_DIRECTIVE(factor,@object)
factor: .double 1.0 / SQR_CBRT2
.double 1.0 / CBRT2
.double 1.0
.double CBRT2
.double SQR_CBRT2
ASM_SIZE_DIRECTIVE(factor)
ASM_TYPE_DIRECTIVE(two25,@object)
two25: .byte 0, 0, 0, 0x4c
ASM_SIZE_DIRECTIVE(two25)
#ifdef PIC
#define MO(op) op##@GOTOFF(%ebx)
#define MOX(op,x,f) op##@GOTOFF(%ebx,x,f)
#else
#define MO(op) op
#define MOX(op,x,f) op(,x,f)
#endif
.text
ENTRY(__cbrtf)
movl 4(%esp), %eax
xorl %ecx, %ecx
movl %eax, %edx
andl $0x7fffffff, %eax
jz 1f
cmpl $0x7f800000, %eax
jae 1f
#ifdef PIC
pushl %ebx
call 3f
3: popl %ebx
addl $_GLOBAL_OFFSET_TABLE_+[.-3b], %ebx
#endif
cmpl $0x00800000, %eax
jae 2f
#ifdef PIC
flds 8(%esp)
#else
flds 4(%esp)
#endif
fmuls MO(two25)
movl $-25, %ecx
#ifdef PIC
fstps 8(%esp)
movl 8(%esp), %eax
#else
fstps 4(%esp)
movl 4(%esp), %eax
#endif
movl %eax, %edx
andl $0x7fffffff, %eax
2: shrl $23, %eax
andl $0x807fffff, %edx
subl $126, %eax
orl $0x3f000000, %edx
addl %eax, %ecx
#ifdef PIC
movl %edx, 8(%esp)
flds 8(%esp) /* xm */
#else
movl %edx, 4(%esp)
flds 4(%esp) /* xm */
#endif
fabs
/* The following code has two track:
a) compute the normalized cbrt value
b) compute xe/3 and xe%3
The right track computes the value for b) and this is done
in an optimized way by avoiding division. */
fld %st(0) /* xm : xm */
fmull MO(f3) /* f3*xm : xm */
movl $1431655766, %eax
fsubrl MO(f2) /* f2-f3*xm : xm */
imull %ecx
fmul %st(1) /* (f2-f3*xm)*xm : xm */
movl %ecx, %eax
faddl MO(f1) /* u:=f1+(f2-f3*xm)*xm : xm */
sarl $31, %eax
fld %st /* u : u : xm */
subl %eax, %edx
fmul %st(1) /* u*u : u : xm */
fld %st(2) /* xm : u*u : u : xm */
fadd %st /* 2*xm : u*u : u : xm */
fxch %st(1) /* u*u : 2*xm : u : xm */
fmul %st(2) /* t2:=u*u*u : 2*xm : u : xm */
movl %edx, %eax
fadd %st, %st(1) /* t2 : t2+2*xm : u : xm */
leal (%edx,%edx,2),%edx
fadd %st(0) /* 2*t2 : t2+2*xm : u : xm */
subl %edx, %ecx
faddp %st, %st(3) /* t2+2*xm : u : 2*t2+xm */
fmulp /* u*(t2+2*xm) : 2*t2+xm */
fdivp %st, %st(1) /* u*(t2+2*xm)/(2*t2+xm) */
fmull MOX(16+factor,%ecx,8) /* u*(t2+2*xm)/(2*t2+xm)*FACT */
pushl %eax
fildl (%esp) /* xe/3 : u*(t2+2*xm)/(2*t2+xm)*FACT */
fxch /* u*(t2+2*xm)/(2*t2+xm)*FACT : xe/3 */
popl %eax
fscale /* u*(t2+2*xm)/(2*t2+xm)*FACT*2^xe/3 */
fstp %st(1)
#ifdef PIC
popl %ebx
#endif
testl $0x80000000, 4(%esp)
jz 4f
fchs
4: ret
/* Return the argument. */
1: flds 4(%esp)
ret
END(__cbrtf)
weak_alias (__cbrtf, cbrtf)

188
sysdeps/libm-i387/s_cbrtl.S Normal file
View File

@ -0,0 +1,188 @@
/* Compute cubic root of long double value.
Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Dirk Alboth <dirka@uni-paderborn.de> and
Ulrich Drepper <drepper@cygnus.com>, 1997.
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 <machine/asm.h>
#ifdef __ELF__
.section .rodata
#else
.text
#endif
.align ALIGNARG(4)
ASM_TYPE_DIRECTIVE(f1,@object)
f1: .double 0.338058687610520237
ASM_SIZE_DIRECTIVE(f1)
ASM_TYPE_DIRECTIVE(f2,@object)
f2: .double 1.67595307700780102
ASM_SIZE_DIRECTIVE(f2)
ASM_TYPE_DIRECTIVE(f3,@object)
f3: .double -2.82414939754975962
ASM_SIZE_DIRECTIVE(f3)
ASM_TYPE_DIRECTIVE(f4,@object)
f4: .double 4.09559907378707839
ASM_SIZE_DIRECTIVE(f4)
ASM_TYPE_DIRECTIVE(f5,@object)
f5: .double -4.11151425200350531
ASM_SIZE_DIRECTIVE(f5)
ASM_TYPE_DIRECTIVE(f6,@object)
f6: .double 2.65298938441952296
ASM_SIZE_DIRECTIVE(f6)
ASM_TYPE_DIRECTIVE(f7,@object)
f7: .double -0.988553671195413709
ASM_SIZE_DIRECTIVE(f7)
ASM_TYPE_DIRECTIVE(f8,@object)
f8: .double 0.161617097923756032
ASM_SIZE_DIRECTIVE(f8)
#define CBRT2 1.2599210498948731648
#define SQR_CBRT2 1.5874010519681994748
ASM_TYPE_DIRECTIVE(factor,@object)
factor: .double 1.0 / SQR_CBRT2
.double 1.0 / CBRT2
.double 1.0
.double CBRT2
.double SQR_CBRT2
ASM_SIZE_DIRECTIVE(factor)
ASM_TYPE_DIRECTIVE(two64,@object)
two64: .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x43
ASM_SIZE_DIRECTIVE(two64)
#ifdef PIC
#define MO(op) op##@GOTOFF(%ebx)
#define MOX(op,x,f) op##@GOTOFF(%ebx,x,f)
#else
#define MO(op) op
#define MOX(op,x,f) op(,x,f)
#endif
.text
ENTRY(__cbrtl)
movl 4(%esp), %ecx
movl 12(%esp), %eax
orl 8(%esp), %ecx
movl %eax, %edx
andl $0x7fff, %eax
orl %eax, %ecx
jz 1f
xorl %ecx, %ecx
cmpl $0x7fff, %eax
je 1f
#ifdef PIC
pushl %ebx
call 3f
3: popl %ebx
addl $_GLOBAL_OFFSET_TABLE_+[.-3b], %ebx
#endif
cmpl $0, %eax
je 2f
#ifdef PIC
fldt 8(%esp)
#else
fldt 4(%esp)
#endif
fmull MO(two64)
movl $-64, %ecx
fstpt 4(%esp)
movl 12(%esp), %eax
movl %eax, %edx
andl $0x7fff, %eax
2: andl $0x8000, %edx
subl $16382, %eax
orl $0x3ffe, %edx
addl %eax, %ecx
#ifdef PIC
movl %edx, 16(%esp)
fldt 8(%esp) /* xm */
#else
movl %edx, 12(%esp)
fldt 4(%esp) /* xm */
#endif
fabs
/* The following code has two track:
a) compute the normalized cbrt value
b) compute xe/3 and xe%3
The right track computes the value for b) and this is done
in an optimized way by avoiding division. */
fld %st(0) /* xm : xm */
fmull MO(f7) /* f7*xm : xm */
movl $1431655766, %eax
faddl MO(f6) /* f6+f7*xm : xm */
imull %ecx
fmul %st(1) /* (f6+f7*xm)*xm : xm */
movl %ecx, %eax
faddl MO(f5) /* f5+(f6+f7*xm)*xm : xm */
sarl $31, %eax
fmul %st(1) /* (f5+(f6+f7*xm)*xm)*xm : xm */
subl %eax, %edx
faddl MO(f4) /* f4+(f5+(f6+f7*xm)*xm)*xm : xm */
fmul %st(1) /* (f4+(f5+(f6+f7*xm)*xm)*xm)*xm : xm */
faddl MO(f3) /* f3+(f4+(f5+(f6+f7*xm)*xm)*xm)*xm : xm */
fmul %st(1) /* (f3+(f4+(f5+(f6+f7*xm)*xm)*xm)*xm)*xm : xm */
faddl MO(f2) /* f2+(f3+(f4+(f5+(f6+f7*xm)*xm)*xm)*xm)*xm : xm */
fmul %st(1) /* (f2+(f3+(f4+(f5+(f6+f7*xm)*xm)*xm)*xm)*xm)*xm : xm */
faddl MO(f1) /* u:=f1+(f2+(f3+(f4+(f5+(f6+f7*xm)*xm)*xm)*xm)*xm)*xm : xm */
fld %st /* u : u : xm */
fmul %st(1) /* u*u : u : xm */
fld %st(2) /* xm : u*u : u : xm */
fadd %st /* 2*xm : u*u : u : xm */
fxch %st(1) /* u*u : 2*xm : u : xm */
fmul %st(2) /* t2:=u*u*u : 2*xm : u : xm */
movl %edx, %eax
fadd %st, %st(1) /* t2 : t2+2*xm : u : xm */
leal (%edx,%edx,2),%edx
fadd %st(0) /* 2*t2 : t2+2*xm : u : xm */
subl %edx, %ecx
faddp %st, %st(3) /* t2+2*xm : u : 2*t2+xm */
fmulp /* u*(t2+2*xm) : 2*t2+xm */
fdivp %st, %st(1) /* u*(t2+2*xm)/(2*t2+xm) */
fmull MOX(16+factor,%ecx,8) /* u*(t2+2*xm)/(2*t2+xm)*FACT */
pushl %eax
fildl (%esp) /* xe/3 : u*(t2+2*xm)/(2*t2+xm)*FACT */
fxch /* u*(t2+2*xm)/(2*t2+xm)*FACT : xe/3 */
popl %eax
fscale /* u*(t2+2*xm)/(2*t2+xm)*FACT*2^xe/3 */
fstp %st(1)
#ifdef PIC
popl %ebx
#endif
testl $0x8000, 12(%esp)
jz 4f
fchs
4: ret
/* Return the argument. */
1: fldt 4(%esp)
ret
END(__cbrtl)
weak_alias (__cbrtl, cbrtl)

View File

@ -0,0 +1,82 @@
/* ix87 specific frexp implementation for double.
Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
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 <machine/asm.h>
#ifdef __ELF__
.section .rodata
#else
.text
#endif
.align ALIGNARG(4)
ASM_TYPE_DIRECTIVE(two54,@object)
two54: .byte 0, 0, 0, 0, 0, 0, 0x50, 0x43
ASM_SIZE_DIRECTIVE(two54)
#ifdef PIC
#define MO(op) op##@GOTOFF(%edx)
#else
#define MO(op) op
#endif
.text
ENTRY(__frexp)
movl 4(%esp), %ecx
movl 8(%esp), %eax
movl %eax, %edx
andl $0x7fffffff, %eax
orl %eax, %ecx
jz 1f
xorl %ecx, %ecx
cmpl $0x7ff00000, %eax
jae 1f
cmpl $0x00100000, %eax
jae 2f
fldl 4(%esp)
#ifdef PIC
call 3f
3: popl %edx
addl $_GLOBAL_OFFSET_TABLE_+[.-3b], %edx
#endif
fmull MO(two54)
movl $-54, %ecx
fstpl 4(%esp)
movl 8(%esp), %eax
movl %eax, %edx
andl $0x7fffffff, %eax
2: shrl $20, %eax
andl $0x800fffff, %edx
subl $1022, %eax
orl $0x3fe00000, %edx
addl %eax, %ecx
movl %edx, 8(%esp)
/* Store %ecx in the variable pointed to by the second argument,
get the factor from the stack and return. */
1: movl 12(%esp), %eax
fldl 4(%esp)
movl %ecx, (%eax)
ret
END(__frexp)
weak_alias (__frexp, frexp)

View File

@ -0,0 +1,80 @@
/* ix87 specific frexp implementation for float.
Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
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 <machine/asm.h>
#ifdef __ELF__
.section .rodata
#else
.text
#endif
.align ALIGNARG(4)
ASM_TYPE_DIRECTIVE(two25,@object)
two25: .byte 0, 0, 0, 0x4c
ASM_SIZE_DIRECTIVE(two25)
#ifdef PIC
#define MO(op) op##@GOTOFF(%edx)
#else
#define MO(op) op
#endif
.text
ENTRY(__frexpf)
movl 4(%esp), %eax
xorl %ecx, %ecx
movl %eax, %edx
andl $0x7fffffff, %eax
jz 1f
cmpl $0x7f800000, %eax
jae 1f
cmpl $0x00800000, %eax
jae 2f
flds 4(%esp)
#ifdef PIC
call 3f
3: popl %edx
addl $_GLOBAL_OFFSET_TABLE_+[.-3b], %edx
#endif
fmuls MO(two25)
movl $-25, %ecx
fstps 4(%esp)
movl 4(%esp), %eax
movl %eax, %edx
andl $0x7fffffff, %eax
2: shrl $23, %eax
andl $0x807fffff, %edx
subl $126, %eax
orl $0x3f000000, %edx
addl %eax, %ecx
movl %edx, 4(%esp)
/* Store %ecx in the variable pointed to by the second argument,
get the factor from the stack and return. */
1: movl 8(%esp), %eax
flds 4(%esp)
movl %ecx, (%eax)
ret
END(__frexpf)
weak_alias (__frexpf, frexpf)

View File

@ -0,0 +1,82 @@
/* ix87 specific frexp implementation for long double.
Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
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 <machine/asm.h>
#ifdef __ELF__
.section .rodata
#else
.text
#endif
.align ALIGNARG(4)
ASM_TYPE_DIRECTIVE(two64,@object)
two64: .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x43
ASM_SIZE_DIRECTIVE(two64)
#ifdef PIC
#define MO(op) op##@GOTOFF(%edx)
#else
#define MO(op) op
#endif
.text
ENTRY(__frexpl)
movl 4(%esp), %ecx
movl 12(%esp), %eax
orl 8(%esp), %ecx
movl %eax, %edx
andl $0x7fff, %eax
orl %eax, %ecx
jz 1f
xorl %ecx, %ecx
cmpl $0x7fff, %eax
je 1f
cmpl $0, %eax
je 2f
fldt 4(%esp)
#ifdef PIC
call 3f
3: popl %edx
addl $_GLOBAL_OFFSET_TABLE_+[.-3b], %edx
#endif
fmull MO(two64) /* It's not necessary to use a 80bit factor */
movl $-64, %ecx
fstpt 4(%esp)
movl 12(%esp), %eax
movl %eax, %edx
andl $0x7fff, %eax
2: andl $0x8000, %edx
subl $16382, %eax
orl $0x3ffe, %edx
addl %eax, %ecx
movl %edx, 12(%esp)
/* Store %ecx in the variable pointed to by the second argument,
get the factor from the stack and return. */
1: movl 16(%esp), %eax
fldt 4(%esp)
movl %ecx, (%eax)
ret
END(__frexpl)
weak_alias (__frexpl, frexpl)

View File

@ -1,95 +1,71 @@
/* @(#)s_cbrt.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* Compute cubic root of double value.
Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Dirk Alboth <dirka@uni-paderborn.de> and
Ulrich Drepper <drepper@cygnus.com>, 1997.
#if defined(LIBM_SCCS) && !defined(lint)
static char rcsid[] = "$NetBSD: s_cbrt.c,v 1.8 1995/05/10 20:46:49 jtc Exp $";
#endif
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 "math.h"
#include "math_private.h"
/* cbrt(x)
* Return cube root of x
*/
#ifdef __STDC__
static const u_int32_t
#else
static u_int32_t
#endif
B1 = 715094163, /* B1 = (682-0.03306235651)*2**20 */
B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */
#ifdef __STDC__
static const double
#else
static double
#endif
C = 5.42857142857142815906e-01, /* 19/35 = 0x3FE15F15, 0xF15F15F1 */
D = -7.05306122448979611050e-01, /* -864/1225 = 0xBFE691DE, 0x2532C834 */
E = 1.41428571428571436819e+00, /* 99/70 = 0x3FF6A0EA, 0x0EA0EA0F */
F = 1.60714285714285720630e+00, /* 45/28 = 0x3FF9B6DB, 0x6DB6DB6E */
G = 3.57142857142857150787e-01; /* 5/14 = 0x3FD6DB6D, 0xB6DB6DB7 */
#define CBRT2 1.2599210498948731648 /* 2^(1/3) */
#define SQR_CBRT2 1.5874010519681994748 /* 2^(2/3) */
#ifdef __STDC__
double __cbrt(double x)
#else
double __cbrt(x)
double x;
#endif
static const double factor[5] =
{
int32_t hx;
double r,s,t=0.0,w;
u_int32_t sign;
u_int32_t high,low;
GET_HIGH_WORD(hx,x);
sign=hx&0x80000000; /* sign= sign(x) */
hx ^=sign;
if(hx>=0x7ff00000) return(x+x); /* cbrt(NaN,INF) is itself */
GET_LOW_WORD(low,x);
if((hx|low)==0)
return(x); /* cbrt(0) is itself */
SET_HIGH_WORD(x,hx); /* x <- |x| */
/* rough cbrt to 5 bits */
if(hx<0x00100000) /* subnormal number */
{SET_HIGH_WORD(t,0x43500000); /* set t= 2**54 */
t*=x; GET_HIGH_WORD(high,t); SET_HIGH_WORD(t,high/3+B2);
}
else
SET_HIGH_WORD(t,hx/3+B1);
1.0 / SQR_CBRT2,
1.0 / CBRT2,
1.0,
CBRT2,
SQR_CBRT2
};
/* new cbrt to 23 bits, may be implemented in single precision */
r=t*t/x;
s=C+r*t;
t*=G+F/(s+E+D/s);
double
__cbrt (double x)
{
double xm, ym, u, t2;
int xe;
/* chopped to 20 bits and make it larger than cbrt(x) */
GET_HIGH_WORD(high,t);
INSERT_WORDS(t,high+0x00000001,0);
/* Reduce X. XM now is an range 1.0 to 0.5. */
xm = __frexp (fabs (x), &xe);
/* If X is not finite or is null return it (with raising exceptions
if necessary. */
if (xe == 0)
return x + x;
/* one step newton iteration to 53 bits with error less than 0.667 ulps */
s=t*t; /* t*t is exact */
r=x/s;
w=t+t;
r=(r-t)/(w+r); /* r-s is exact */
t=t+t*r;
u = (0.354895765043919860
+ ((1.50819193781584896
+ ((-2.11499494167371287
+ ((2.44693122563534430
+ ((-1.83469277483613086
+ (0.784932344976639262 - 0.145263899385486377 * xm) * xm)
* xm))
* xm))
* xm))
* xm));
/* retore the sign bit */
GET_HIGH_WORD(high,t);
SET_HIGH_WORD(t,high|sign);
return(t);
t2 = u * u * u;
ym = u * (t2 + 2.0 * xm) / (2.0 * t2 + xm) * factor[2 + xe % 3];
return __ldexp (x > 0.0 ? ym : -ym, xe / 3);
}
weak_alias (__cbrt, cbrt)
#ifdef NO_LONG_DOUBLE

View File

@ -1,84 +1,62 @@
/* s_cbrtf.c -- float version of s_cbrt.c.
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/* Compute cubic root of float value.
Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Dirk Alboth <dirka@uni-paderborn.de> and
Ulrich Drepper <drepper@cygnus.com>, 1997.
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
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.
#if defined(LIBM_SCCS) && !defined(lint)
static char rcsid[] = "$NetBSD: s_cbrtf.c,v 1.4 1995/05/10 20:46:51 jtc Exp $";
#endif
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 "math.h"
#include "math_private.h"
/* cbrtf(x)
* Return cube root of x
*/
#ifdef __STDC__
static const unsigned
#else
static unsigned
#endif
B1 = 709958130, /* B1 = (84+2/3-0.03306235651)*2**23 */
B2 = 642849266; /* B2 = (76+2/3-0.03306235651)*2**23 */
#ifdef __STDC__
static const float
#else
static float
#endif
C = 5.4285717010e-01, /* 19/35 = 0x3f0af8b0 */
D = -7.0530611277e-01, /* -864/1225 = 0xbf348ef1 */
E = 1.4142856598e+00, /* 99/70 = 0x3fb50750 */
F = 1.6071428061e+00, /* 45/28 = 0x3fcdb6db */
G = 3.5714286566e-01; /* 5/14 = 0x3eb6db6e */
#define CBRT2 1.2599210498948731648 /* 2^(1/3) */
#define SQR_CBRT2 1.5874010519681994748 /* 2^(2/3) */
#ifdef __STDC__
float __cbrtf(float x)
#else
float __cbrtf(x)
float x;
#endif
static const double factor[5] =
{
float r,s,t;
int32_t hx;
u_int32_t sign;
u_int32_t high;
GET_FLOAT_WORD(hx,x);
sign=hx&0x80000000; /* sign= sign(x) */
hx ^=sign;
if(hx>=0x7f800000) return(x+x); /* cbrt(NaN,INF) is itself */
if(hx==0)
return(x); /* cbrt(0) is itself */
SET_FLOAT_WORD(x,hx); /* x <- |x| */
/* rough cbrt to 5 bits */
if(hx<0x00800000) /* subnormal number */
{SET_FLOAT_WORD(t,0x4b800000); /* set t= 2**24 */
t*=x; GET_FLOAT_WORD(high,t); SET_FLOAT_WORD(t,high/3+B2);
}
else
SET_FLOAT_WORD(t,hx/3+B1);
1.0 / SQR_CBRT2,
1.0 / CBRT2,
1.0,
CBRT2,
SQR_CBRT2
};
/* new cbrt to 23 bits */
r=t*t/x;
s=C+r*t;
t*=G+F/(s+E+D/s);
float
__cbrtf (float x)
{
float xm, ym, u, t2;
int xe;
/* retore the sign bit */
GET_FLOAT_WORD(high,t);
SET_FLOAT_WORD(t,high|sign);
return(t);
/* Reduce X. XM now is an range 1.0 to 0.5. */
xm = __frexpf (fabsf (x), &xe);
/* If X is not finite or is null return it (with raising exceptions
if necessary. */
if (xe == 0)
return x + x;
u = (0.492659620528969547 + (0.697570460207922770
- 0.191502161678719066 * xm) * xm);
t2 = u * u * u;
ym = u * (t2 + 2.0 * xm) / (2.0 * t2 + xm) * factor[2 + xe % 3];
return __ldexpf (x > 0.0 ? ym : -ym, xe / 3);
}
weak_alias (__cbrtf, cbrtf)

View File

@ -1,122 +1,76 @@
/* s_cbrtl.c -- long double version of s_cbrt.c.
* Conversion to long double by Ulrich Drepper,
* Cygnus Support, drepper@cygnus.com.
*/
/* Compute cubic root of double value.
Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Dirk Alboth <dirka@uni-paderborn.de> and
Ulrich Drepper <drepper@cygnus.com>, 1997.
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
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.
#if defined(LIBM_SCCS) && !defined(lint)
static char rcsid[] = "$NetBSD: $";
#endif
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 "math.h"
#include "math_private.h"
/* cbrtl(x)
* Return cube root of x
*/
#ifdef __STDC__
static const u_int32_t
#else
static u_int32_t
#endif
B1_EXP = 10921, /* = Int(B1) */
B1_MANT = 0x7bc4b064, /* = Int(1.0-0.03306235651)*2**31 */
B2_EXP = 10900,
B2_MANT = 0x7bc4b064; /* = Int(1.0-0.03306235651)*2**31 */
#define CBRT2 1.2599210498948731648 /* 2^(1/3) */
#define SQR_CBRT2 1.5874010519681994748 /* 2^(2/3) */
#ifdef __STDC__
static const long double
#else
static long double
#endif
C = 5.42857142857142815906e-01L, /* 19/35 */
D = -7.05306122448979611050e-01L, /* -864/1225 */
E = 1.41428571428571436819e+00L, /* 99/70 */
F = 1.60714285714285720630e+00L, /* 45/28 */
G = 3.57142857142857150787e-01L; /* 5/14 */
#ifdef __STDC__
long double __cbrtl(long double x)
#else
long double __cbrtl(x)
long double x;
#endif
/* We don't use long double values here since U need not be computed
with full precision. */
static const double factor[5] =
{
long double r,s,t=0.0,w;
u_int32_t sign, se, x0, x1;
GET_LDOUBLE_WORDS(se,x0,x1,x);
sign=se&0x8000; /* sign= sign(x) */
se ^= sign;
if(se==0x7fff) return(x+x); /* cbrt(NaN,INF) is itself */
if((se|x0|x1)==0)
return(x); /* cbrt(0) is itself */
SET_LDOUBLE_EXP(x,se); /* x <- |x| */
/* XXX I don't know whether the numbers for correct are correct. The
precalculation is extended from 20 bits to 32 bits. This hopefully
gives us the needed bits to get us still along with one iteration
step. */
/* rough cbrt to 5 bits */
if(se==0) /* subnormal number */
{
u_int64_t xxl;
u_int32_t set,t0,t1;
SET_LDOUBLE_EXP(t,0x4035); /* set t= 2**54 */
SET_LDOUBLE_MSW(t,0x80000000);
t*=x;
GET_LDOUBLE_WORDS(set,t0,t1,t);
xxl = ((u_int64_t) set) << 32 | t0;
xxl /= 3;
xxl += B2_EXP << 16 | B2_MANT;
t0 = xxl & 0xffffffffu;
set = xxl >> 32;
SET_LDOUBLE_WORDS(t,set,t0,t1);
}
else
{
u_int64_t xxl = ((u_int64_t) se) << 32 | x0;
xxl /= 3;
xxl += ((u_int64_t) B1_EXP) << 32 | B1_MANT;
SET_LDOUBLE_MSW(t,xxl&0xffffffffu);
xxl >>= 32;
SET_LDOUBLE_EXP(t,xxl);
}
1.0 / SQR_CBRT2,
1.0 / CBRT2,
1.0,
CBRT2,
SQR_CBRT2
};
/* new cbrt to 23 bits, may be implemented in single precision */
r=t*t/x;
s=C+r*t;
t*=G+F/(s+E+D/s);
long double
__cbrtl (long double x)
{
long double xm, ym, u, t2;
int xe;
/* chopped to 32 bits and make it larger than cbrt(x) */
GET_LDOUBLE_WORDS(se,x0,x1,t);
SET_LDOUBLE_WORDS(t,se,x0+1,0);
/* Reduce X. XM now is an range 1.0 to 0.5. */
xm = __frexpl (fabs (x), &xe);
/* If X is not finite or is null return it (with raising exceptions
if necessary. */
if (xe == 0)
return x + x;
/* one step newton iteration to 53 bits with error less than 0.667 ulps */
s=t*t; /* t*t is exact */
r=x/s;
w=t+t;
r=(r-t)/(w+r); /* r-s is exact */
t=t+t*r;
u = (0.338058687610520237
+ (1.67595307700780102
+ (-2.82414939754975962
+ (4.09559907378707839 +
(-4.11151425200350531
+ (2.65298938441952296 +
(-0.988553671195413709
+ 0.161617097923756032 * xm)
* xm)
* xm)
* xm)
* xm)
* xm)
*xm);
/* retore the sign bit */
GET_LDOUBLE_EXP(se,t);
SET_LDOUBLE_EXP(t,se|sign);
return(t);
t2 = u * u * u;
ym = u * (t2 + 2.0 * xm) / (2.0 * t2 + xm) * factor[2 + xe % 3];
return __ldexpl (x > 0.0 ? ym : -ym, xe / 3);
}
weak_alias (__cbrtl, cbrtl)

View File

@ -19,6 +19,7 @@
Boston, MA 02111-1307, USA. */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ieee754.h>

View File

@ -19,6 +19,7 @@
Boston, MA 02111-1307, USA. */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ieee754.h>

View File

@ -19,6 +19,7 @@
Boston, MA 02111-1307, USA. */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ieee754.h>

View File

@ -53,7 +53,7 @@ inhibit-siglist := yes
endif
ifeq ($(subdir),inet)
sysdep_headers += netinet/in_systm.h netinet/udp.h netinet/icmp.h \
sysdep_headers += netinet/in_systm.h netinet/udp.h \
netinet/if_fddi.h netinet/if_tr.h netinet/igmp.h \
netinet/ip_fw.h netinet/ip_icmp.h sys/socketvar.h
endif

View File

@ -75,7 +75,7 @@ typedef struct
int __ret = __set->__val[--__cnt]; \
while (!__ret && --__cnt >= 0) \
__ret = __set->__val[__cnt]; \
__ret; }))
__ret == 0; }))
# define __sigandset(dest, left, right) \
(__extension__ ({ int __cnt = _SIGSET_NWORDS; \
sigset_t *__dest = (dest); \