1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-28 00:21:52 +03:00
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> 1997-04-02 16:55 Ulrich Drepper <drepper@cygnus.com>
* manual/socket.texi: Document behaviour of inet_ntoa in multi- * 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. * manual/arith.texi: Add description of lldiv_t, lldiv, and atoll.
Change description of strtoll and strtoull to make clear these Change description of strtoll and strtoull to make clear these
are the preferred names. are the preferred names.
Describe `inf', `inifinity', `nan', `nan(...)' inputs for strtod Describe `inf', `infinity', `nan', `nan(...)' inputs for strtod
and friends. and friends.
Change references to HUGE_VALf and HUGE_VALl to HUGE_VALF and Change references to HUGE_VALf and HUGE_VALl to HUGE_VALF and
HUGE_VALL. HUGE_VALL.
@ -146,7 +247,7 @@
* sysdeps/i386/addmul_1.S: Likewise. * sysdeps/i386/addmul_1.S: Likewise.
* sysdeps/i386/lshift.S: Likewise. * sysdeps/i386/lshift.S: Likewise.
* sysdeps/i386/memchr.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/mul_1.S: Likewise.
* sysdeps/i386/rshift.S: Likewise. * sysdeps/i386/rshift.S: Likewise.
* sysdeps/i386/stpcpy.S: Likewise. * sysdeps/i386/stpcpy.S: Likewise.
@ -176,9 +277,9 @@
* sysdeps/stub/s_log2l.c: Correct function name. * sysdeps/stub/s_log2l.c: Correct function name.
* time/africa: Updated from ADO tzdata1997e. * time/africa: Updated from ADO tzdata1997e.
* time/aantarctica: Likewise. * time/antarctica: Likewise.
* time/asia: Likewise. * time/asia: Likewise.
* time/australia: Likewise. * time/australasia: Likewise.
* time/europe: Likewise. * time/europe: Likewise.
* time/northamerica: Likewise. * time/northamerica: Likewise.
* time/southamerica: 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 [Q23] ``When compiling GNU libc I get lots of errors saying functions
in glibc are duplicated in libgcc.'' 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?'' [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 some problems of this kind. The setting of CFLAGS is checked at the
very beginning and if it is not usable `configure' will bark. 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: Answers were given by:

View File

@ -1,6 +1,6 @@
Open jobs for finishing GNU libc: 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 If you have time and talent to take over any of the jobs below please
contact <bug-glibc@prep.ai.mit.edu> 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: [ 7] Several math functions have to be written:
- exp2 - exp2
- log2
- nearbyint - nearbyint
- ceil - ceil
- round - round
@ -138,7 +137,9 @@ contact <bug-glibc@prep.ai.mit.edu>
+ tcgetid() and waitid() from XPG4.2 + tcgetid() and waitid() from XPG4.2
+ grantpt(), ptsname(), unlockpt() from XPG4.2 + grantpt(), ptsname(), unlockpt() from XPG4.2
+ getdate() from XPG4.2 + getdate() from XPG4.2
*** Probably underway
+ fmtmsg() from SVID + fmtmsg() from SVID
*** Probably underway
More information are available on request. 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). 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 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. 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) 1997 Free Software Foundation, Inc.
* Copyright (c) 1983, 1993 This file is part of the GNU C Library.
* 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
*/
#ifndef _INET_H_ The GNU C Library is free software; you can redistribute it and/or
#define _INET_H_ 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 <sys/types.h>
#include <netinet/in.h> /* To define `struct in_addr'. */ #include <netinet/in.h> /* To define `struct in_addr'. */
__BEGIN_DECLS __BEGIN_DECLS
u_long inet_addr __P((const char *));
int inet_aton __P((const char *, struct in_addr *)); /* Convert Internet host address from numbers-and-dots notation in CP
u_int32_t inet_lnaof __P((struct in_addr)); into binary data in network byte order. */
struct in_addr inet_makeaddr __P((u_int32_t , u_int32_t)); extern unsigned long int inet_addr __P ((__const char *__cp));
char * inet_neta __P((u_long, char *, size_t));
u_int32_t inet_netof __P((struct in_addr)); /* Convert Internet host address from numbers-and-dots notation in CP
u_int32_t inet_network __P((const char *)); into binary data and store the result in the structure INP. */
char *inet_net_ntop __P((int, const void *, int, char *, size_t)); extern int inet_aton __P ((__const char *__cp, struct in_addr *__inp));
int inet_net_pton __P((int, const char *, void *, size_t));
char *inet_ntoa __P((struct in_addr)); /* Return the local host address part of the Internet address in IN. */
int inet_pton __P((int, const char *, void *)); extern u_int32_t inet_lnaof __P ((struct in_addr __in));
const char *inet_ntop __P((int, const void *, char *, size_t));
u_int inet_nsap_addr __P((const char *, u_char *, int)); /* Make Internet host address in network byte order by combining the
char *inet_nsap_ntoa __P((int, const u_char *, char *)); 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 __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 services
@cindex shadow @cindex shadow
@vtable @code @vtable @code
@item aliases
Mail aliases
@comment @pxref{Mail Aliases}.
@item ethers @item ethers
Ethernet numbers, Ethernet numbers,
@comment @pxref{Ethernet Numbers}. @comment @pxref{Ethernet Numbers}.
@ -94,8 +97,8 @@ Shadow user passwords,
@end vtable @end vtable
@noindent @noindent
There will be some more added later (@code{aliases}, @code{automount}, There will be some more added later (@code{automount}, @code{bootparams},
@code{bootparams}, @code{netmasks}, and @code{publickey}). @code{netmasks}, and @code{publickey}).
@node NSS Configuration File, NSS Module Internals, NSS Basics, Name Service Switch @node NSS Configuration File, NSS Module Internals, NSS Basics, Name Service Switch
@section The NSS Configuration File @section The NSS Configuration File
@ -123,7 +126,7 @@ different items:
@item @item
the service specification like @code{files}, @code{db}, or @code{nis}. the service specification like @code{files}, @code{db}, or @code{nis}.
@item @item
the reaction on lookup result line @code{[NOTFOUND=return]}. the reaction on lookup result like @code{[NOTFOUND=return]}.
@end itemize @end itemize
@menu @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 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 interface functions the C library maps this call to a call to the
reentrant function. For reentrant functions this is trivial since the reentrant function. For reentrant functions this is trivial since the
interface is (nearly) the same. For the non-reentrant version pointers interface is (nearly) the same. For the non-reentrant version The
to static buffers are used to replace the user supplied buffers. library keeps internal buffers which are used to replace the user
supplied buffer.
I.e., the reentrant functions @emph{can} have counterparts. No service I.e., the reentrant functions @emph{can} have counterparts. No service
module is forced to have functions for all databases and all kinds to 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 @end smallexample
I.e., the interface function is in fact the reentrant function with the 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 change of the return value and the omission of the @var{result}
pointer to the result the reentrant function return an @code{enum parameter. While the user-level function returns a pointer to the
nss_status} value: result the reentrant function return an @code{enum nss_status} value:
@vindex NSS_STATUS_TRYAGAIN @vindex NSS_STATUS_TRYAGAIN
@vindex NSS_STATUS_UNAVAIL @vindex NSS_STATUS_UNAVAIL
@ -458,13 +462,13 @@ function;
the next three arguments are: the next three arguments are:
@table @code @table @code
@item STRUCT_TYPE result_buf @item STRUCT_TYPE *result_buf
pointer to buffer where the result is stored. @code{STRUCT_TYPE} is pointer to buffer where the result is stored. @code{STRUCT_TYPE} is
normally a struct which corresponds to the database. normally a struct which corresponds to the database.
@item char *buffer @item char *buffer
pointer to a buffer where the function can store additional adata for pointer to a buffer where the function can store additional adata for
the result etc. the result etc.
@item int buflen @item size_t buflen
length of the buffer pointed to by @var{buffer}. length of the buffer pointed to by @var{buffer}.
@end table @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) (0.0), 0.0);
check ("cbrt (-0) == -0", FUNC(cbrt) (minus_zero), minus_zero); 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 (8) == 2", FUNC(cbrt) (8), 2);
check ("cbrt (-27) == -3", FUNC(cbrt) (-27.0), -3.0); 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) # These are the databases available for the nis (and perhaps later nisplus)
# service. This must be a superset of the services in nss. # service. This must be a superset of the services in nss.
databases = proto service hosts network grp pwd rpc ethers \ databases = proto service hosts network grp pwd rpc ethers \
spwd netgrp alias spwd netgrp alias publickey
# Specify rules for the nss_* modules. # Specify rules for the nss_* modules.
services := nis compat nisplus 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-routines := $(addprefix nisplus-,$(databases))
libnss_nisplus-inhibit-o = $(filter-out .so,$(object-suffixes)) 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 include ../Rules
$(objpfx)libnss_compat.so: $(objpfx)libnsl.so$(libnsl.so-version) \ $(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) \ $(objpfx)libnss_nis.so: $(objpfx)libnsl.so$(libnsl.so-version) \
$(common-objpfx)nss/libnss_files.so $(common-objpfx)nss/libnss_files.so
$(objpfx)libnss_nisplus.so: $(objpfx)libnsl.so$(libnsl.so-version) $(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 * 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_server: implement nis_getservlist, nis_stats, nis_servstate
* nis_groups: implement it * nis_groups: implement it
@ -22,10 +23,10 @@
* Possible flags: * Possible flags:
- FOLLOW_LINKS (nis_list, nis_lookup) - FOLLOW_LINKS (nis_list, nis_lookup)
- FOLLOW_PATH (nis_list, not supported) - 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) - ALL_RESULTS (nis_list, not supported, needs server callback)
- NO_CACHE (__do_niscall, cache not supported yet) - NO_CACHE (__do_niscall, cache not supported yet)
- MASTER_ONLY (__do_niscall, not supported) - MASTER_ONLY (__do_niscall)
- EXPAND_NAME (nis_lookup, nis_list) - EXPAND_NAME (nis_lookup, nis_list)
- RETURN_RESULT (nis_table.c) - RETURN_RESULT (nis_table.c)
- ADD_OVERWRITE (nis_table.c) - ADD_OVERWRITE (nis_table.c)
@ -37,4 +38,3 @@
- USE_DGRAM (__do_niscall) - USE_DGRAM (__do_niscall)
- NO_AUTHINFO (__do_niscall) - NO_AUTHINFO (__do_niscall)

View File

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

View File

@ -27,11 +27,10 @@ __BEGIN_DECLS
extern nis_error __do_niscall (__const nis_server *server, int server_len, extern nis_error __do_niscall (__const nis_server *server, int server_len,
u_long prog, xdrproc_t xargs, caddr_t req, u_long prog, xdrproc_t xargs, caddr_t req,
xdrproc_t xres, caddr_t resp, u_long flags); xdrproc_t xres, caddr_t resp, u_long flags);
#if !defined(NO_DES_RPC) #if defined (HAVE_SECURE_RPC)
extern AUTH *authdes_pk_create (char *, netobj *, u_int, extern AUTH *authdes_pk_create (const char *, const netobj *, u_int,
struct sockaddr *, des_block *); struct sockaddr *, des_block *);
#endif #endif
extern nis_name *__nis_expandname (__const nis_name); extern nis_name *__nis_expandname (__const nis_name);
__END_DECLS __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_len = 1;
req.ns_object.ns_object_val = nis_clone_object (obj, NULL); 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) & req, (xdrproc_t) xdr_nis_result,
(caddr_t) res, 0)) != RPC_SUCCESS) (caddr_t) res, 0)) != RPC_SUCCESS)
res->status = status; res->status = status;

View File

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

View File

@ -25,6 +25,14 @@
#include <string.h> #include <string.h>
#include <rpcsvc/yp.h> #include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.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. */ /* Get the declaration of the parser function. */
#define ENTNAME grent #define ENTNAME grent
@ -32,7 +40,7 @@
#define EXTERN_PARSER #define EXTERN_PARSER
#include "../../nss/nss_files/files-parse.c" #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_INITIAL_SIZE 512
#define BLACKLIST_INCREMENT 256 #define BLACKLIST_INCREMENT 256
struct blacklist_t struct blacklist_t
@ -48,12 +56,15 @@ struct ent_t
bool_t nis_first; bool_t nis_first;
char *oldkey; char *oldkey;
int oldkeylen; int oldkeylen;
nis_result *result;
nis_name *names;
u_long names_nr;
FILE *stream; FILE *stream;
struct blacklist_t blacklist; struct blacklist_t blacklist;
}; };
typedef struct ent_t ent_t; 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. */ /* Protect global state against multiple changers. */
__libc_lock_define_initialized (static, lock) __libc_lock_define_initialized (static, lock)
@ -61,6 +72,8 @@ __libc_lock_define_initialized (static, lock)
/* Prototypes for local functions. */ /* Prototypes for local functions. */
static void blacklist_store_name (const char *, ent_t *); static void blacklist_store_name (const char *, ent_t *);
static int in_blacklist (const char *, int, 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 static enum nss_status
internal_setgrent (ent_t *ent) internal_setgrent (ent_t *ent)
@ -75,15 +88,27 @@ internal_setgrent (ent_t *ent)
ent->oldkey = NULL; ent->oldkey = NULL;
ent->oldkeylen = 0; 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; ent->blacklist.current = 0;
if (ent->blacklist.data != NULL) if (ent->blacklist.data != NULL)
ent->blacklist.data[0] = '\0'; ent->blacklist.data[0] = '\0';
if (ent->stream == NULL) if (ent->stream == NULL)
{ {
ent->stream = fopen ("/etc/group", "r"); ent->stream = fopen ("/etc/group", "r");
if (ent->stream == NULL) if (ent->stream == NULL)
status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL; status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
} }
@ -101,6 +126,12 @@ _nss_compat_setgrent (void)
__libc_lock_lock (lock); __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); result = internal_setgrent (&ext_ent);
__libc_lock_unlock (lock); __libc_lock_unlock (lock);
@ -127,6 +158,18 @@ internal_endgrent (ent_t *ent)
ent->oldkeylen = 0; 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; ent->blacklist.current = 0;
if (ent->blacklist.data != NULL) if (ent->blacklist.data != NULL)
ent->blacklist.data[0] = '\0'; 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; struct parser_data *data = (void *) buffer;
char *domain; char *domain;
char *outkey, *outval; char *outkey, *outval;
int outkeylen, outvallen; int outkeylen, outvallen, parse_res;
char *p; char *p;
if (yp_get_default_domain (&domain) != YPERR_SUCCESS) 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)) while (isspace (*p))
++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; return NSS_STATUS_SUCCESS;
else 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' if (result->gr_name[0] == '+' && result->gr_name[1] != '\0'
&& result->gr_name[1] != '@') && result->gr_name[1] != '@')
{ {
char *domain; enum nss_status status;
char *outval;
int outvallen; status = getgrent_next_file_plusgroup (result, buffer, buflen);
if (status == NSS_STATUS_SUCCESS) /* We found the entry. */
if (yp_get_default_domain (&domain) != YPERR_SUCCESS) break;
/* XXX Should we regard this as an fatal error? I don't else
think so. Just continue working. --drepper@gnu */ if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */
continue; continue;
else
if (yp_match (domain, "group.byname", &result->gr_name[1], return status;
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;
} }
/* +:... */ /* +:... */
@ -285,7 +437,10 @@ getgrent_next_file (struct group *result, ent_t *ent,
ent->nis = TRUE; ent->nis = TRUE;
ent->nis_first = 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) size_t buflen)
{ {
if (ent->nis) 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 else
return getgrent_next_file (gr, ent, buffer, buflen); 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); __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. */ /* Be prepared that the setgrent function was not called before. */
if (ext_ent.stream == NULL) if (ext_ent.stream == NULL)
status = internal_setgrent (&ext_ent); status = internal_setgrent (&ext_ent);
@ -327,12 +493,21 @@ enum nss_status
_nss_compat_getgrnam_r (const char *name, struct group *grp, _nss_compat_getgrnam_r (const char *name, struct group *grp,
char *buffer, size_t buflen) 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; enum nss_status status;
if (name[0] == '-' || name[0] == '+') if (name[0] == '-' || name[0] == '+')
return NSS_STATUS_NOTFOUND; 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); status = internal_setgrent (&ent);
if (status != NSS_STATUS_SUCCESS) if (status != NSS_STATUS_SUCCESS)
@ -352,9 +527,19 @@ enum nss_status
_nss_compat_getgrgid_r (gid_t gid, struct group *grp, _nss_compat_getgrgid_r (gid_t gid, struct group *grp,
char *buffer, size_t buflen) 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; 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); status = internal_setgrent (&ent);
if (status != NSS_STATUS_SUCCESS) if (status != NSS_STATUS_SUCCESS)
return status; 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. This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996. Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
@ -26,8 +26,15 @@
#include <libc-lock.h> #include <libc-lock.h>
#include <rpcsvc/yp.h> #include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h> #include <rpcsvc/ypclnt.h>
#include <rpcsvc/nis.h>
#include <rpcsvc/nislib.h>
#include <nsswitch.h>
#include "netgroup.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. */ /* Get the declaration of the parser function. */
#define ENTNAME pwent #define ENTNAME pwent
@ -52,6 +59,9 @@ struct ent_t
bool_t first; bool_t first;
char *oldkey; char *oldkey;
int oldkeylen; int oldkeylen;
nis_result *result;
nis_name *names;
u_long names_nr;
FILE *stream; FILE *stream;
struct blacklist_t blacklist; struct blacklist_t blacklist;
struct passwd pwd; struct passwd pwd;
@ -59,7 +69,7 @@ struct ent_t
}; };
typedef struct ent_t 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}}; {NULL, NULL, 0, 0, NULL, NULL, NULL}};
/* Protect global state against multiple changers. */ /* Protect global state against multiple changers. */
@ -68,7 +78,8 @@ __libc_lock_define_initialized (static, lock)
/* Prototypes for local functions. */ /* Prototypes for local functions. */
static void blacklist_store_name (const char *, ent_t *); static void blacklist_store_name (const char *, ent_t *);
static int in_blacklist (const char *, int, 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 static void
give_pwd_free (struct passwd *pwd) give_pwd_free (struct passwd *pwd)
{ {
@ -192,6 +203,18 @@ internal_setpwent (ent_t *ent)
ent->oldkeylen = 0; 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; ent->blacklist.current = 0;
if (ent->blacklist.data != NULL) if (ent->blacklist.data != NULL)
ent->blacklist.data[0] = '\0'; ent->blacklist.data[0] = '\0';
@ -219,6 +242,12 @@ _nss_compat_setpwent (void)
__libc_lock_lock (lock); __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); result = internal_setpwent (&ext_ent);
__libc_lock_unlock (lock); __libc_lock_unlock (lock);
@ -245,6 +274,19 @@ internal_endpwent (ent_t *ent)
ent->oldkeylen = 0; 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; ent->blacklist.current = 0;
if (ent->blacklist.data != NULL) if (ent->blacklist.data != NULL)
ent->blacklist.data[0] = '\0'; ent->blacklist.data[0] = '\0';
@ -272,14 +314,14 @@ _nss_compat_endpwent (void)
} }
static enum nss_status static enum nss_status
getpwent_next_netgr (struct passwd *result, ent_t *ent, char *group, getpwent_next_nis_netgr (struct passwd *result, ent_t *ent, char *group,
char *buffer, size_t buflen) char *buffer, size_t buflen)
{ {
struct parser_data *data = (void *) buffer; struct parser_data *data = (void *) buffer;
char *ypdomain, *host, *user, *domain, *outval, *p, *p2; char *ypdomain, *host, *user, *domain, *outval, *p, *p2;
int status, outvallen; int status, outvallen;
size_t p2len; size_t p2len;
if (yp_get_default_domain (&ypdomain) != YPERR_SUCCESS) if (yp_get_default_domain (&ypdomain) != YPERR_SUCCESS)
{ {
ent->netgroup = 0; ent->netgroup = 0;
@ -340,13 +382,176 @@ getpwent_next_netgr (struct passwd *result, ent_t *ent, char *group,
return NSS_STATUS_SUCCESS; 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 static enum nss_status
getpwent_next_nis (struct passwd *result, ent_t *ent, char *buffer, getpwent_next_nis (struct passwd *result, ent_t *ent, char *buffer,
size_t buflen) size_t buflen)
{ {
struct parser_data *data = (void *) buffer; struct parser_data *data = (void *) buffer;
char *domain, *outkey, *outval, *p, *p2; char *domain, *outkey, *outval, *p, *p2;
int outkeylen, outvallen; int outkeylen, outvallen, parse_res;
size_t p2len; size_t p2len;
if (yp_get_default_domain (&domain) != YPERR_SUCCESS) 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)) while (isspace (*p))
++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); copy_pwd_changes (result, &ent->pwd, p2, p2len);
if (!in_blacklist (result->pw_name, strlen (result->pw_name), ent)) return NSS_STATUS_SUCCESS;
return NSS_STATUS_SUCCESS;
else
return NSS_STATUS_NOTFOUND;
} }
/* 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 static enum nss_status
getpwent_next_file (struct passwd *result, ent_t *ent, 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; struct parser_data *data = (void *) buffer;
while (1) while (1)
{ {
char *p, *p2; char *p;
size_t p2len;
do do
{ {
@ -494,50 +777,16 @@ getpwent_next_file (struct passwd *result, ent_t *ent,
if (result->pw_name[0] == '+' && result->pw_name[1] != '\0' if (result->pw_name[0] == '+' && result->pw_name[1] != '\0'
&& result->pw_name[1] != '@') && result->pw_name[1] != '@')
{ {
char *domain; enum nss_status status;
char *outval;
int outvallen; status = getpwent_next_file_plususer (result, buffer, buflen);
struct passwd pwd; if (status == NSS_STATUS_SUCCESS) /* We found the entry. */
break;
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;
}
else else
{ if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */
/* Give buffer the old len back */ continue;
buflen += p2len; else
give_pwd_free (&pwd); return status;
}
} }
/* +:... */ /* +:... */
@ -547,7 +796,10 @@ getpwent_next_file (struct passwd *result, ent_t *ent,
ent->first = TRUE; ent->first = TRUE;
copy_pwd_changes (&ent->pwd, result, NULL, 0); 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; return status;
} }
else if (ent->nis) 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 else
return getpwent_next_file (pw, ent, buffer, buflen); 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); __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. */ /* Be prepared that the setpwent function was not called before. */
if (ext_ent.stream == NULL) if (ext_ent.stream == NULL)
status = internal_setpwent (&ext_ent); status = internal_setpwent (&ext_ent);
@ -602,13 +865,22 @@ enum nss_status
_nss_compat_getpwnam_r (const char *name, struct passwd *pwd, _nss_compat_getpwnam_r (const char *name, struct passwd *pwd,
char *buffer, size_t buflen) 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}}; {NULL, NULL, 0, 0, NULL, NULL, NULL}};
enum nss_status status; enum nss_status status;
if (name[0] == '-' || name[0] == '+') if (name[0] == '-' || name[0] == '+')
return NSS_STATUS_NOTFOUND; 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); status = internal_setpwent (&ent);
if (status != NSS_STATUS_SUCCESS) if (status != NSS_STATUS_SUCCESS)
@ -628,10 +900,20 @@ enum nss_status
_nss_compat_getpwuid_r (uid_t uid, struct passwd *pwd, _nss_compat_getpwuid_r (uid_t uid, struct passwd *pwd,
char *buffer, size_t buflen) 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}}; {NULL, NULL, 0, 0, NULL, NULL, NULL}};
enum nss_status status; 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); status = internal_setpwent (&ent);
if (status != NSS_STATUS_SUCCESS) if (status != NSS_STATUS_SUCCESS)
return status; 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. This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996. Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
@ -26,6 +26,15 @@
#include <libc-lock.h> #include <libc-lock.h>
#include <rpcsvc/yp.h> #include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.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. */ /* Get the declaration of the parser function. */
#define ENTNAME spent #define ENTNAME spent
@ -50,13 +59,17 @@ struct ent_t
bool_t first; bool_t first;
char *oldkey; char *oldkey;
int oldkeylen; int oldkeylen;
nis_result *result;
nis_name *names;
u_long names_nr;
FILE *stream; FILE *stream;
struct blacklist_t blacklist; struct blacklist_t blacklist;
struct spwd pwd; struct spwd pwd;
struct __netgrent netgrdata;
}; };
typedef struct ent_t 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, 0, 0, 0, 0, 0}}; {NULL, NULL, 0, 0, 0, 0, 0, 0, 0}};
/* Protect global state against multiple changers. */ /* Protect global state against multiple changers. */
@ -65,7 +78,8 @@ __libc_lock_define_initialized (static, lock)
/* Prototypes for local functions. */ /* Prototypes for local functions. */
static void blacklist_store_name (const char *, ent_t *); static void blacklist_store_name (const char *, ent_t *);
static int in_blacklist (const char *, int, 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 static void
give_spwd_free (struct spwd *pwd) give_spwd_free (struct spwd *pwd)
{ {
@ -130,6 +144,10 @@ internal_setspent (ent_t *ent)
ent->nis = ent->first = ent->netgroup = 0; 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) if (ent->oldkey != NULL)
{ {
free (ent->oldkey); free (ent->oldkey);
@ -137,6 +155,18 @@ internal_setspent (ent_t *ent)
ent->oldkeylen = 0; 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; ent->blacklist.current = 0;
if (ent->blacklist.data != NULL) if (ent->blacklist.data != NULL)
ent->blacklist.data[0] = '\0'; ent->blacklist.data[0] = '\0';
@ -164,6 +194,12 @@ _nss_compat_setspent (void)
__libc_lock_lock (lock); __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); result = internal_setspent (&ext_ent);
__libc_lock_unlock (lock); __libc_lock_unlock (lock);
@ -181,6 +217,9 @@ internal_endspent (ent_t *ent)
ent->stream = NULL; ent->stream = NULL;
} }
if (ent->netgroup)
__internal_endnetgrent (&ent->netgrdata);
ent->nis = ent->first = ent->netgroup = 0; ent->nis = ent->first = ent->netgroup = 0;
if (ent->oldkey != NULL) if (ent->oldkey != NULL)
@ -190,10 +229,22 @@ internal_endspent (ent_t *ent)
ent->oldkeylen = 0; 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; ent->blacklist.current = 0;
if (ent->blacklist.data != NULL) if (ent->blacklist.data != NULL)
ent->blacklist.data[0] = '\0'; ent->blacklist.data[0] = '\0';
give_spwd_free (&ent->pwd); give_spwd_free (&ent->pwd);
return NSS_STATUS_SUCCESS; return NSS_STATUS_SUCCESS;
@ -215,8 +266,8 @@ _nss_compat_endspent (void)
static enum nss_status static enum nss_status
getspent_next_netgr (struct spwd *result, ent_t *ent, char *group, getspent_next_nis_netgr (struct spwd *result, ent_t *ent, char *group,
char *buffer, size_t buflen) char *buffer, size_t buflen)
{ {
struct parser_data *data = (void *) buffer; struct parser_data *data = (void *) buffer;
char *ypdomain, *host, *user, *domain, *outval, *p, *p2; 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) if (ent->first == TRUE)
{ {
setnetgrent (group); bzero (&ent->netgrdata, sizeof (struct __netgrent));
__internal_setnetgrent (group, &ent->netgrdata);
ent->first = FALSE; ent->first = FALSE;
} }
while (1) 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; ent->netgroup = 0;
give_spwd_free (&ent->pwd); give_spwd_free (&ent->pwd);
return NSS_STATUS_RETURN; return NSS_STATUS_RETURN;
@ -280,13 +334,177 @@ getspent_next_netgr (struct spwd *result, ent_t *ent, char *group,
return NSS_STATUS_SUCCESS; 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 static enum nss_status
getspent_next_nis (struct spwd *result, ent_t *ent, getspent_next_nis (struct spwd *result, ent_t *ent,
char *buffer, size_t buflen) char *buffer, size_t buflen)
{ {
struct parser_data *data = (void *) buffer; struct parser_data *data = (void *) buffer;
char *domain, *outkey, *outval, *p, *p2; char *domain, *outkey, *outval, *p, *p2;
int outkeylen, outvallen; int outkeylen, outvallen, parse_res;
size_t p2len; size_t p2len;
if (yp_get_default_domain (&domain) != YPERR_SUCCESS) if (yp_get_default_domain (&domain) != YPERR_SUCCESS)
@ -344,17 +562,96 @@ getspent_next_nis (struct spwd *result, ent_t *ent,
while (isspace (*p)) while (isspace (*p))
++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); copy_spwd_changes (result, &ent->pwd, p2, p2len);
if (!in_blacklist (result->sp_namp, strlen (result->sp_namp), ent)) return NSS_STATUS_SUCCESS;
return NSS_STATUS_SUCCESS;
else
return NSS_STATUS_NOTFOUND;
} }
/* 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 static enum nss_status
getspent_next_file (struct spwd *result, ent_t *ent, 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' if (result->sp_namp[0] == '+' && result->sp_namp[1] != '\0'
&& result->sp_namp[1] != '@') && result->sp_namp[1] != '@')
{ {
char *domain; enum nss_status status;
char *outval;
int outvallen; status = getspent_next_file_plususer (result, buffer, buflen);
struct spwd pwd; if (status == NSS_STATUS_SUCCESS) /* We found the entry. */
break;
memset (&pwd, '\0', sizeof (struct spwd)); else
if (status == NSS_STATUS_RETURN) /* We couldn't parse the entry */
if (yp_get_default_domain (&domain) != YPERR_SUCCESS) continue;
/* XXX Should we regard this as an fatal error? I don't else
think so. Just continue working. --drepper@gnu */ return status;
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);
}
} }
/* +:... */ /* +:... */
@ -487,7 +750,10 @@ getspent_next_file (struct spwd *result, ent_t *ent,
ent->first = TRUE; ent->first = TRUE;
copy_spwd_changes (&ent->pwd, result, NULL, 0); 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; return status;
} }
else if (ent->nis) 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 else
return getspent_next_file (pw, ent, buffer, buflen); 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); __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. */ /* Be prepared that the setspent function was not called before. */
if (ext_ent.stream == NULL) if (ext_ent.stream == NULL)
status = internal_setspent (&ext_ent); status = internal_setspent (&ext_ent);
@ -541,13 +818,19 @@ enum nss_status
_nss_compat_getspnam_r (const char *name, struct spwd *pwd, _nss_compat_getspnam_r (const char *name, struct spwd *pwd,
char *buffer, size_t buflen) 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}}; {NULL, NULL, 0, 0, 0, 0, 0, 0, 0}};
enum nss_status status; enum nss_status status;
if (name[0] == '-' || name[0] == '+') if (name[0] == '-' || name[0] == '+')
return NSS_STATUS_NOTFOUND; 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); status = internal_setspent (&ent);
if (status != NSS_STATUS_SUCCESS) if (status != NSS_STATUS_SUCCESS)
return status; return status;
@ -619,3 +902,4 @@ in_blacklist (const char *name, int namelen, ent_t *ent)
stpcpy (stpcpy (stpcpy (buf, "|"), name), "|"); stpcpy (stpcpy (stpcpy (buf, "|"), name), "|");
return strstr (ent->blacklist.data, buf) != NULL; 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); free (result);
parse_res = _nss_files_parse_grent (p, grp, data, buflen); 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; return NSS_STATUS_TRYAGAIN;
free (oldkey); free (oldkey);
@ -130,7 +130,7 @@ internal_nis_getgrent_r (struct group *grp, char *buffer, size_t buflen)
oldkeylen = keylen; oldkeylen = keylen;
new_start = 0; new_start = 0;
} }
while (!parse_res); while (parse_res < 1);
return NSS_STATUS_SUCCESS; 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); parse_res = _nss_files_parse_grent (p, grp, data, buflen);
if (!parse_res) if (parse_res < 1)
{ {
if (errno == ERANGE) if (errno == ERANGE)
return NSS_STATUS_TRYAGAIN; 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); parse_res = _nss_files_parse_grent (p, grp, data, buflen);
if (!parse_res) if (parse_res < 1)
{ {
if (errno == ERANGE) if (errno == ERANGE)
return NSS_STATUS_TRYAGAIN; return NSS_STATUS_TRYAGAIN;

View File

@ -23,22 +23,24 @@
#include <string.h> #include <string.h>
#include <syslog.h> #include <syslog.h>
#include <libc-lock.h> #include <libc-lock.h>
#include <rpc/key_prot.h> #include <rpc/rpc.h>
#include <rpcsvc/yp.h> #include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.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" #include "nss-nis.h"
extern int xdecrypt (char *, char *); /* If we haven't found the entry, we give a SUCCESS and an empty key back. */
/* If we found the entry, we give a SUCCESS and an empty key back. */
enum nss_status enum nss_status
_nss_nis_getpublickey (const char *netname, char *pkey) _nss_nis_getpublickey (const char *netname, char *pkey)
{ {
enum nss_status retval; enum nss_status retval;
char *domain, *result; char *domain, *result;
int len; int len;
pkey[0] = 0; pkey[0] = 0;
if (netname == NULL) if (netname == NULL)
@ -75,6 +77,7 @@ _nss_nis_getpublickey (const char *netname, char *pkey)
enum nss_status enum nss_status
_nss_nis_getsecretkey (const char *netname, char *skey, char *passwd) _nss_nis_getsecretkey (const char *netname, char *skey, char *passwd)
{ {
#if defined (HAVE_SECURE_RPC)
enum nss_status retval; enum nss_status retval;
char buf[1024]; char buf[1024];
char *domain, *result; char *domain, *result;
@ -120,6 +123,9 @@ _nss_nis_getsecretkey (const char *netname, char *skey, char *passwd)
buf[HEXKEYBYTES] = 0; buf[HEXKEYBYTES] = 0;
strcpy (skey, buf); strcpy (skey, buf);
} }
#else
skey[0] = 0;
#endif
return NSS_STATUS_SUCCESS; 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) char *buffer, size_t buflen)
{ {
if (result == NULL) if (result == NULL)
return -1; return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) || if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
result->objects.objects_len != 1 || 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, strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
"mail_aliases") != 0 || "mail_aliases") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 2) result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 2)
return -1; return 0;
else else
{ {
char *first_unused = buffer + NISENTRYLEN(0, 1, result) + 1; 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. */ /* The line is too long for our buffer. */
no_more_room: no_more_room:
__set_errno (ERANGE); __set_errno (ERANGE);
return -1; return 0;
} }
else else
{ {

View File

@ -86,7 +86,7 @@ _nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether,
struct parser_data *data = (void *) buffer; struct parser_data *data = (void *) buffer;
if (result == NULL) if (result == NULL)
return -1; return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) || if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
result->objects.objects_len != 1 || 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, strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
"ethers_tbl") != 0 || "ethers_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 2) 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); 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) if (NISENTRYLEN (0, 0, result) +1 > room_left)
{ {
__set_errno (ERANGE); __set_errno (ERANGE);
return -1; return 0;
} }
strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result)); strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
room_left -= (NISENTRYLEN (0, 0, result) +1); 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) if (NISENTRYLEN (0, 1, result) +1 > room_left)
{ {
__set_errno (ERANGE); __set_errno (ERANGE);
return -1; return 0;
} }
strcat (p, "\t"); strcat (p, "\t");
strncat (p, NISENTRYVAL (0, 1, result), NISENTRYLEN (0, 1, result)); 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) \ #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) ((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 int
#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
_nss_nisplus_parse_grent (nis_result * result, struct group *gr, _nss_nisplus_parse_grent (nis_result * result, struct group *gr,
char *buffer, size_t buflen) 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; char *first_unused = buffer;
size_t room_left = buflen; size_t room_left = buflen;
char *line; char *line;
int count; int count;
if (result == NULL) if (result == NULL)
return -1; return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) || if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
result->objects.objects_len != 1 || result->objects.objects_len != 1 ||
result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ || 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, strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
"group_tbl") != 0 || "group_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 4) 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) if (NISENTRYLEN (0, 0, result) >= room_left)
{ {
/* The line is too long for our buffer. */ /* The line is too long for our buffer. */
no_more_room: no_more_room:
__set_errno (ERANGE); __set_errno (ERANGE);
return -1; return 0;
} }
strncpy (first_unused, NISENTRYVAL (0, 0, result), strncpy (first_unused, NISENTRYVAL (0, 0, result),
NISENTRYLEN (0, 0, result)); NISENTRYLEN (0, 0, result));
first_unused[NISENTRYLEN (0, 0, result)] = '\0'; 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]) if (line != gr->gr_mem[count])
{ {
*line = '\0'; if (*line != '\0')
++line; {
*line = '\0';
++line;
}
++count; ++count;
} }
else else
@ -171,59 +145,6 @@ _nss_nisplus_parse_grent (nis_result * result, struct group *gr,
gr->gr_mem[count] = NULL; gr->gr_mem[count] = NULL;
return 1; 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 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; struct parser_data *data = (void *) buffer;
if (result == NULL) if (result == NULL)
return -1; return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) || if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ || 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, strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
"hosts_tbl") != 0 || "hosts_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 4) 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); 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) if (NISENTRYLEN (0, 2, result) + 1 > room_left)
{ {
__set_errno (ERANGE); __set_errno (ERANGE);
return -1; return 0;
} }
strncpy (p, NISENTRYVAL (0, 2, result), strncpy (p, NISENTRYVAL (0, 2, result),
NISENTRYLEN (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) if (NISENTRYLEN (0, 0, result) + 1 > room_left)
{ {
__set_errno (ERANGE); __set_errno (ERANGE);
return -1; return 0;
} }
strcat (p, "\t"); strcat (p, "\t");
strncat (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result)); 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) if (NISENTRYLEN (i, 1, result) + 1 > room_left)
{ {
__set_errno (ERANGE); __set_errno (ERANGE);
return -1; return 0;
} }
strcat (p, " "); strcat (p, " ");
strcat (p, NISENTRYVAL (i, 1, result)); strcat (p, NISENTRYVAL (i, 1, result));

View File

@ -31,13 +31,9 @@
__libc_lock_define_initialized (static, lock) __libc_lock_define_initialized (static, lock)
static char *data = NULL; static nis_result *data = NULL;
static size_t data_size = 0; static unsigned long data_size = 0;
static char *cursor = NULL;; static unsigned long position = 0;
extern enum nss_status
_nss_netgroup_parseline (char **cursor, struct __netgrent *result,
char *buffer, size_t buflen);
#define NISENTRYVAL(idx,col,res) \ #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) ((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) \ #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) ((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 enum nss_status
_nss_nisplus_setnetgrent (char *group) _nss_nisplus_setnetgrent (char *group)
{ {
enum nss_status status; enum nss_status status;
nis_result *result;
char buf[strlen (group) + 30]; char buf[strlen (group) + 30];
int i;
size_t len;
if (group == NULL || group[0] == '\0') if (group == NULL || group[0] == '\0')
return NSS_STATUS_UNAVAIL; return NSS_STATUS_UNAVAIL;
@ -64,43 +148,27 @@ _nss_nisplus_setnetgrent (char *group)
if (data != NULL) if (data != NULL)
{ {
free (data); nis_freeresult (data);
data = NULL; data = NULL;
data_size = 0; data_size = 0;
cursor = NULL; position = 0;
} }
sprintf(buf, "[name=%s],netgroup.org_dir", group); 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) if (niserr2nss (data->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++)
{ {
strncat (data, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result)); status = niserr2nss (data->status);
strcat (data," ("); nis_freeresult (data);
strncat (data, NISENTRYVAL(i,2,result), NISENTRYLEN (i, 2, result)); data = NULL;
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, ") ");
} }
else
nis_freeresult (result); data_size = data->objects.objects_len;
__libc_lock_unlock (lock); __libc_lock_unlock (lock);
return status; return status;
} }
@ -111,10 +179,10 @@ _nss_nisplus_endnetgrent (void)
if (data != NULL) if (data != NULL)
{ {
free (data); nis_freeresult (data);
data = NULL; data = NULL;
data_size = 0; data_size = 0;
cursor = NULL; position = 0;
} }
__libc_lock_unlock (lock); __libc_lock_unlock (lock);
@ -128,12 +196,9 @@ _nss_nisplus_getnetgrent_r (struct __netgrent *result,
{ {
enum nss_status status; enum nss_status status;
if (cursor == NULL)
return NSS_STATUS_NOTFOUND;
__libc_lock_lock (lock); __libc_lock_lock (lock);
status = _nss_netgroup_parseline (&cursor, result, buffer, buflen); status = _nss_nisplus_parse_netgroup (result, buffer, buflen);
__libc_lock_unlock (lock); __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; struct parser_data *data = (void *) buffer;
if (result == NULL) if (result == NULL)
return -1; return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) || if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ || 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, strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
"networks_tbl") != 0 || "networks_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3) 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 */ /* Generate the network entry format and use the normal parser */
if (NISENTRYLEN (0, 0, result) +1 > room_left) if (NISENTRYLEN (0, 0, result) +1 > room_left)
{ {
__set_errno (ERANGE); __set_errno (ERANGE);
return -1; return 0;
} }
memset (p, '\0', room_left); 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) if (NISENTRYLEN (0, 2, result) +1 > room_left)
{ {
__set_errno (ERANGE); __set_errno (ERANGE);
return -1; return 0;
} }
strcat (p, "\t"); strcat (p, "\t");
strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result)); 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 */ /* + 1: We overwrite the last \0 */
for (i = 1; i < result->objects.objects_len; i++) 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) if (NISENTRYLEN (i, 1, result) +1 > room_left)
{ {
__set_errno (ERANGE); __set_errno (ERANGE);
return -1; return 0;
} }
strcat (p, " "); strcat (p, " ");
strncat (p, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result)); 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; struct parser_data *data = (void *) buffer;
if (result == NULL) if (result == NULL)
return -1; return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) || if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ || 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, strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
"protocols_tbl") != 0 || "protocols_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3) 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); 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) if (NISENTRYLEN (0, 0, result) + 1 > room_left)
{ {
__set_errno (ERANGE); __set_errno (ERANGE);
return -1; return 0;
} }
strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result)); strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
room_left -= (NISENTRYLEN (0, 0, result) + 1); 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) if (NISENTRYLEN (0, 2, result) + 1 > room_left)
{ {
__set_errno (ERANGE); __set_errno (ERANGE);
return -1; return 0;
} }
strcat (p, "\t"); strcat (p, "\t");
strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result)); 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) if (NISENTRYLEN (i, 1, result) + 1 > room_left)
{ {
__set_errno (ERANGE); __set_errno (ERANGE);
return -1; return 0;
} }
strcat (p, " "); strcat (p, " ");
strncat (p, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result)); strncat (p, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));

View File

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

View File

@ -38,7 +38,7 @@ static nis_name *names = NULL;
#define NISENTRYLEN(idx,col,res) \ #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) ((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, _nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
char *buffer, size_t buflen) char *buffer, size_t buflen)
{ {
@ -46,7 +46,7 @@ _nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
size_t room_left = buflen; size_t room_left = buflen;
if (result == NULL) if (result == NULL)
return -1; return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) || if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
result->objects.objects_len != 1 || 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, strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
"passwd_tbl") != 0 || "passwd_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 7) 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) if (NISENTRYLEN(0, 0, result) >= room_left)
{ {
/* The line is too long for our buffer. */ /* The line is too long for our buffer. */
no_more_room: no_more_room:
__set_errno (ERANGE); __set_errno (ERANGE);
return -1; return 0;
} }
strncpy (first_unused, NISENTRYVAL(0, 0, result), 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; struct parser_data *data = (void *) buffer;
if (result == NULL) if (result == NULL)
return -1; return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) || if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ || 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, strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
"rpc_tbl") != 0 || "rpc_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3) 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); 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) if (NISENTRYLEN (0, 0, result) +1 > room_left)
{ {
__set_errno (ERANGE); __set_errno (ERANGE);
return -1; return 0;
} }
strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result)); strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
room_left -= (NISENTRYLEN (0, 0, result) +1); 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) if (NISENTRYLEN (0, 2, result) +1 > room_left)
{ {
__set_errno (ERANGE); __set_errno (ERANGE);
return -1; return 0;
} }
strcat (p, "\t"); strcat (p, "\t");
strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result)); 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) if (NISENTRYLEN (i, 1, result) +1 > room_left)
{ {
__set_errno (ERANGE); __set_errno (ERANGE);
return -1; return 0;
} }
strcat (p, " "); strcat (p, " ");
strncat (p, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result)); 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; struct parser_data *data = (void *) buffer;
if (result == NULL) if (result == NULL)
return -1; return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) || if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ || 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, strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
"services_tbl") != 0 || "services_tbl") != 0 ||
result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 4) 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); 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) if (NISENTRYLEN (0, 0, result) + 1 > room_left)
{ {
__set_errno (ERANGE); __set_errno (ERANGE);
return -1; return 0;
} }
strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result)); strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
room_left -= (NISENTRYLEN (0, 0, result) + 1); 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) if (NISENTRYLEN (0, 3, result) + 1 > room_left)
{ {
__set_errno (ERANGE); __set_errno (ERANGE);
return -1; return 0;
} }
strcat (p, "\t"); strcat (p, "\t");
strncat (p, NISENTRYVAL (0, 3, result), NISENTRYLEN (0, 3, result)); 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) if (NISENTRYLEN (0, 2, result) + 1 > room_left)
{ {
__set_errno (ERANGE); __set_errno (ERANGE);
return -1; return 0;
} }
strcat (p, "/"); strcat (p, "/");
strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result)); 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) if (NISENTRYLEN (i, 1, result) + 1 > room_left)
{ {
__set_errno (ERANGE); __set_errno (ERANGE);
return -1; return 0;
} }
strcat (p, " "); strcat (p, " ");
strcat (p, NISENTRYVAL (i, 1, result)); strcat (p, NISENTRYVAL (i, 1, result));

View File

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

View File

@ -21,6 +21,7 @@
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <libc-lock.h> #include <libc-lock.h>
#include <rpc/rpc.h>
#include <rpcsvc/yp.h> #include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h> #include <rpcsvc/ypclnt.h>
#include <rpcsvc/ypupd.h> #include <rpcsvc/ypupd.h>
@ -781,7 +782,7 @@ int
yp_update (char *domain, char *map, unsigned ypop, yp_update (char *domain, char *map, unsigned ypop,
char *key, int keylen, char *data, int datalen) char *key, int keylen, char *data, int datalen)
{ {
#if 0 #if defined (HAVE_SECURE_RPC)
union union
{ {
ypupdate_args update_args; ypupdate_args update_args;
@ -847,8 +848,8 @@ yp_update (char *domain, char *map, unsigned ypop,
clnt->cl_auth = authunix_create_default (); clnt->cl_auth = authunix_create_default ();
again: again:
r = clnt_call (clnt, ypop, xdr_argument, &args, r = clnt_call (clnt, ypop, xdr_argument, (caddr_t) &args,
(xdrproc_t) xdr_u_int, &res, TIMEOUT); (xdrproc_t) xdr_u_int, (caddr_t) &res, TIMEOUT);
if (r == RPC_AUTHERROR) 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 */ /* Compute cubic root of double value.
/* Copyright (C) 1997 Free Software Foundation, Inc.
* ==================================================== This file is part of the GNU C Library.
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. Contributed by Dirk Alboth <dirka@uni-paderborn.de> and
* Ulrich Drepper <drepper@cygnus.com>, 1997.
* 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.
* ====================================================
*/
#if defined(LIBM_SCCS) && !defined(lint) The GNU C Library is free software; you can redistribute it and/or
static char rcsid[] = "$NetBSD: s_cbrt.c,v 1.8 1995/05/10 20:46:49 jtc Exp $"; modify it under the terms of the GNU Library General Public License as
#endif 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.h"
#include "math_private.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__ #define CBRT2 1.2599210498948731648 /* 2^(1/3) */
static const double #define SQR_CBRT2 1.5874010519681994748 /* 2^(2/3) */
#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 */
#ifdef __STDC__ static const double factor[5] =
double __cbrt(double x)
#else
double __cbrt(x)
double x;
#endif
{ {
int32_t hx; 1.0 / SQR_CBRT2,
double r,s,t=0.0,w; 1.0 / CBRT2,
u_int32_t sign; 1.0,
u_int32_t high,low; CBRT2,
SQR_CBRT2
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);
/* new cbrt to 23 bits, may be implemented in single precision */ double
r=t*t/x; __cbrt (double x)
s=C+r*t; {
t*=G+F/(s+E+D/s); double xm, ym, u, t2;
int xe;
/* chopped to 20 bits and make it larger than cbrt(x) */ /* Reduce X. XM now is an range 1.0 to 0.5. */
GET_HIGH_WORD(high,t); xm = __frexp (fabs (x), &xe);
INSERT_WORDS(t,high+0x00000001,0);
/* 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 */ u = (0.354895765043919860
s=t*t; /* t*t is exact */ + ((1.50819193781584896
r=x/s; + ((-2.11499494167371287
w=t+t; + ((2.44693122563534430
r=(r-t)/(w+r); /* r-s is exact */ + ((-1.83469277483613086
t=t+t*r; + (0.784932344976639262 - 0.145263899385486377 * xm) * xm)
* xm))
* xm))
* xm))
* xm));
/* retore the sign bit */ t2 = u * u * u;
GET_HIGH_WORD(high,t);
SET_HIGH_WORD(t,high|sign); ym = u * (t2 + 2.0 * xm) / (2.0 * t2 + xm) * factor[2 + xe % 3];
return(t);
return __ldexp (x > 0.0 ? ym : -ym, xe / 3);
} }
weak_alias (__cbrt, cbrt) weak_alias (__cbrt, cbrt)
#ifdef NO_LONG_DOUBLE #ifdef NO_LONG_DOUBLE

View File

@ -1,84 +1,62 @@
/* s_cbrtf.c -- float version of s_cbrt.c. /* Compute cubic root of float value.
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. 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
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
* 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.
* ====================================================
*/
#if defined(LIBM_SCCS) && !defined(lint) The GNU C Library is distributed in the hope that it will be useful,
static char rcsid[] = "$NetBSD: s_cbrtf.c,v 1.4 1995/05/10 20:46:51 jtc Exp $"; but WITHOUT ANY WARRANTY; without even the implied warranty of
#endif 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.h"
#include "math_private.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__ #define CBRT2 1.2599210498948731648 /* 2^(1/3) */
static const float #define SQR_CBRT2 1.5874010519681994748 /* 2^(2/3) */
#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 */
#ifdef __STDC__ static const double factor[5] =
float __cbrtf(float x)
#else
float __cbrtf(x)
float x;
#endif
{ {
float r,s,t; 1.0 / SQR_CBRT2,
int32_t hx; 1.0 / CBRT2,
u_int32_t sign; 1.0,
u_int32_t high; CBRT2,
SQR_CBRT2
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);
/* new cbrt to 23 bits */ float
r=t*t/x; __cbrtf (float x)
s=C+r*t; {
t*=G+F/(s+E+D/s); float xm, ym, u, t2;
int xe;
/* retore the sign bit */ /* Reduce X. XM now is an range 1.0 to 0.5. */
GET_FLOAT_WORD(high,t); xm = __frexpf (fabsf (x), &xe);
SET_FLOAT_WORD(t,high|sign);
return(t); /* 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) weak_alias (__cbrtf, cbrtf)

View File

@ -1,122 +1,76 @@
/* s_cbrtl.c -- long double version of s_cbrt.c. /* Compute cubic root of double value.
* Conversion to long double by Ulrich Drepper, Copyright (C) 1997 Free Software Foundation, Inc.
* Cygnus Support, drepper@cygnus.com. 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
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
* 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.
* ====================================================
*/
#if defined(LIBM_SCCS) && !defined(lint) The GNU C Library is distributed in the hope that it will be useful,
static char rcsid[] = "$NetBSD: $"; but WITHOUT ANY WARRANTY; without even the implied warranty of
#endif 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.h"
#include "math_private.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, #define CBRT2 1.2599210498948731648 /* 2^(1/3) */
B2_MANT = 0x7bc4b064; /* = Int(1.0-0.03306235651)*2**31 */ #define SQR_CBRT2 1.5874010519681994748 /* 2^(2/3) */
#ifdef __STDC__ /* We don't use long double values here since U need not be computed
static const long double with full precision. */
#else static const double factor[5] =
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
{ {
long double r,s,t=0.0,w; 1.0 / SQR_CBRT2,
u_int32_t sign, se, x0, x1; 1.0 / CBRT2,
1.0,
GET_LDOUBLE_WORDS(se,x0,x1,x); CBRT2,
sign=se&0x8000; /* sign= sign(x) */ SQR_CBRT2
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);
}
/* new cbrt to 23 bits, may be implemented in single precision */ long double
r=t*t/x; __cbrtl (long double x)
s=C+r*t; {
t*=G+F/(s+E+D/s); long double xm, ym, u, t2;
int xe;
/* chopped to 32 bits and make it larger than cbrt(x) */ /* Reduce X. XM now is an range 1.0 to 0.5. */
GET_LDOUBLE_WORDS(se,x0,x1,t); xm = __frexpl (fabs (x), &xe);
SET_LDOUBLE_WORDS(t,se,x0+1,0);
/* 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 */ u = (0.338058687610520237
s=t*t; /* t*t is exact */ + (1.67595307700780102
r=x/s; + (-2.82414939754975962
w=t+t; + (4.09559907378707839 +
r=(r-t)/(w+r); /* r-s is exact */ (-4.11151425200350531
t=t+t*r; + (2.65298938441952296 +
(-0.988553671195413709
+ 0.161617097923756032 * xm)
* xm)
* xm)
* xm)
* xm)
* xm)
*xm);
/* retore the sign bit */ t2 = u * u * u;
GET_LDOUBLE_EXP(se,t);
SET_LDOUBLE_EXP(t,se|sign); ym = u * (t2 + 2.0 * xm) / (2.0 * t2 + xm) * factor[2 + xe % 3];
return(t);
return __ldexpl (x > 0.0 ? ym : -ym, xe / 3);
} }
weak_alias (__cbrtl, cbrtl) weak_alias (__cbrtl, cbrtl)

View File

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

View File

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

View File

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

View File

@ -53,7 +53,7 @@ inhibit-siglist := yes
endif endif
ifeq ($(subdir),inet) 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/if_fddi.h netinet/if_tr.h netinet/igmp.h \
netinet/ip_fw.h netinet/ip_icmp.h sys/socketvar.h netinet/ip_fw.h netinet/ip_icmp.h sys/socketvar.h
endif endif

View File

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