]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Update.
authorUlrich Drepper <drepper@redhat.com>
Tue, 28 Jul 1998 16:26:04 +0000 (16:26 +0000)
committerUlrich Drepper <drepper@redhat.com>
Tue, 28 Jul 1998 16:26:04 +0000 (16:26 +0000)
1998-07-28  Ulrich Drepper  <drepper@cygnus.com>

* math/libm-test.c (tgamma_test): Remove redundant tests.

1998-07-28 16:20  Ulrich Drepper  <drepper@cygnus.com>

* sysdeps/generic/glob.c: Correct problems with */foo and GLOB_NOCHECK
where foo does not exist in any of the subdirectories.
Reported by Paul D. Smith <psmith@BayNetworks.COM>.

* posix/globtest.sh: Add test for this bug.

1998-07-28  Mark Kettenis  <kettenis@phys.uva.nl>

* io/sys/statfs.h: Fix typos.
* io/sys/statvfs.h: Fix typos.

1998-07-28  Ulrich Drepper  <drepper@cygnus.com>

* version.h (VERSION): Bump to 2.0.95.

* math/Makefile (libm-calls): Remove w_gamma, add w_tgamma.
* math/Versions [GLIBC_2.1]: Add tgamma, tgammaf, and tgammal.
* math/libm-test.c: Split old gamma_test and move half of it in new
function tgamma_test.
* math/bits/mathcalls.h: Add declaration of tgamma.
* sysdeps/libm-ieee754/k_standard.c: Change gamma errors into
tgamma errors.
* sysdeps/libm-ieee754/w_gamma.c: Remove lgamma compatibility code
and rename to ...
* sysdeps/libm-ieee754/w_tgamma.c: ... this.  New file.
* sysdeps/libm-ieee754/w_gammaf.c: Remove lgammaf compatibility code
and rename to ...
* sysdeps/libm-ieee754/w_tgammaf.c: ... this.  New file.
* sysdeps/libm-ieee754/w_gammal.c: Remove lgammal compatibility code
and rename to ...
* sysdeps/libm-ieee754/w_tgammal.c: ... this.  New file.
* sysdeps/libm-ieee754/w_lgamma.c: Add gamma as weak alias.
* sysdeps/libm-ieee754/w_lgammaf.c: Likewise.
* sysdeps/libm-ieee754/w_lgammal.c: Likewise.

* stgdio-common/printf-parse.h: Implement handling of j, t, and z
modifiers.
* stdio-common/vfprintf.c: Likewise.
* stdio-common/vfscanf.c: Likewise.
* manual/stdio.texi: Document new printf/scanf modifiers.

* sysdeps/unix/sysv/linux/recvmsg.c: Remove alias __recvmsg.
* sysdeps/unix/sysv/linux/sendmsg.c: Remove alias __sendmsg.

1998-07-28  Thorsten Kukuk  <kukuk@vt.uni-paderborn.de>

* sunrpc/Makefile (routines): Add clnt_unix and svc_unix.
* sunrpc/Versions: Add new *unix_create functions.
* sunrpc/clnt_gen.c: Add support for RPC over AF_UNIX.
* sunrpc/clnt_unix.c: New, client side of RPC over AF_UNIX.
* sunrpc/key_call.c: Use RPC over AF_UNIX for communication
with keyserv daemon.
* sunrpc/rpc/clnt.h: Add AF_UNIX based RPC function prototypes.
* sunrpc/rpc/svc.h: Likewise.
* sunrpc/svc_authux.c: Copy internal auth flavor if none is given.
* sunrpc/svc_tcp.c: Fix typos.
* sunrpc/svc_unix.c: New, server side of AF_UNIX based RPC.

* nis/Makefile: Remove currently not working cache functions.
* nis/Versions: Add __nisbind_* functions for rpc.nisd.
* nis/nis_call.c: Rewrite binding to a NIS+ server to reuse
CLIENT handles.
* nis/nis_file.c: Fix memory leaks.
* nis/nis_intern.h: Move internal structs from here ...
* nis/rpcsvc/nislib.h: ... to here for NIS+ server and tools.
* nis/nis_lookup.c: Try at first if last client handle works.
* nis/nis_table.c: Likewise.
* nis/nis_checkpoint.c: Adjust __do_niscall2 parameters.
* nis/nis_mkdir.c: Likewise.
* nis/nis_ping.c: Likewise.
* nis/nis_rmdir.c: Likewise.
* nis/nis_server.c: Likewise.
* nis/nis_util.c: Likewise.
* nis/nis_findserv.c (__nis_findfastest): Little optimization.

1998-07-28  Andreas Jaeger  <aj@arthur.rhein-neckar.de>

* stdlib/strtol.c (STRTOL_LONG_MAX): Correct typo in last patch -
define as LONG_MAX.

1998-07-28 09:31  Ulrich Drepper  <drepper@cygnus.com>

* nscd/connections.c (gr_send_answer): Deal with missing UIO_MAXIOV.
Correct test whether writev send all data.
* nscd/nscd_getgr_r.c (__nscd_getgr_r): Correct test whether readv
received all data.

1998-07-28  Mark Kettenis  <kettenis@phys.uva.nl>

* nscd/nscd_getgr_r.c (__nscd_getgr_r): Deal with missing UIO_MAXIOV.

1998-07-28  Mark Kettenis  <kettenis@phys.uva.nl>

* sysdeps/mach/hurd/dl-sysdep.c (open_file): Change assert call to
allow mode to be 0.
(__xstat): New function.
(__fxstat): New function.
(_dl_sysdep_read_whole_file): Removed.  The implementation in
`elf/dl-misc.c' now also works for the Hurd.

54 files changed:
ChangeLog
manual/math.texi
manual/stdio.texi
math/Makefile
math/Versions
math/bits/mathcalls.h
math/libm-test.c
nis/Banner
nis/Makefile
nis/Versions
nis/nis_call.c
nis/nis_checkpoint.c
nis/nis_file.c
nis/nis_findserv.c
nis/nis_intern.h
nis/nis_lookup.c
nis/nis_mkdir.c
nis/nis_ping.c
nis/nis_rmdir.c
nis/nis_server.c
nis/nis_table.c
nis/nis_util.c
nis/rpcsvc/nislib.h
nscd/connections.c
nscd/nscd_getgr_r.c
posix/globtest.sh
stdio-common/printf-parse.h
stdio-common/vfprintf.c
stdio-common/vfscanf.c
stdlib/strtol.c
sunrpc/Makefile
sunrpc/Versions
sunrpc/clnt_gen.c
sunrpc/clnt_unix.c [new file with mode: 0644]
sunrpc/key_call.c
sunrpc/rpc/clnt.h
sunrpc/rpc/svc.h
sunrpc/svc_authux.c
sunrpc/svc_tcp.c
sunrpc/svc_unix.c [new file with mode: 0644]
sysdeps/generic/glob.c
sysdeps/libm-ieee754/k_standard.c
sysdeps/libm-ieee754/w_gammaf.c [deleted file]
sysdeps/libm-ieee754/w_gammal.c [deleted file]
sysdeps/libm-ieee754/w_lgamma.c
sysdeps/libm-ieee754/w_lgammaf.c
sysdeps/libm-ieee754/w_lgammal.c
sysdeps/libm-ieee754/w_tgamma.c [moved from sysdeps/libm-ieee754/w_gamma.c with 50% similarity]
sysdeps/libm-ieee754/w_tgammaf.c [new file with mode: 0644]
sysdeps/libm-ieee754/w_tgammal.c [new file with mode: 0644]
sysdeps/mach/hurd/dl-sysdep.c
sysdeps/unix/sysv/linux/recvmsg.c
sysdeps/unix/sysv/linux/sendmsg.c
version.h

index 98f052420f8bffdc5fc6e09e32b9f4d84cc9b731..3ada1541006ca731340f2ad0376ac0e2eb7639f7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,109 @@
+1998-07-28  Ulrich Drepper  <drepper@cygnus.com>
+
+       * math/libm-test.c (tgamma_test): Remove redundant tests.
+
+1998-07-28 16:20  Ulrich Drepper  <drepper@cygnus.com>
+
+       * sysdeps/generic/glob.c: Correct problems with */foo and GLOB_NOCHECK
+       where foo does not exist in any of the subdirectories.
+       Reported by Paul D. Smith <psmith@BayNetworks.COM>.
+
+       * posix/globtest.sh: Add test for this bug.
+
+1998-07-28  Mark Kettenis  <kettenis@phys.uva.nl>
+
+       * io/sys/statfs.h: Fix typos.
+       * io/sys/statvfs.h: Fix typos.
+
+1998-07-28  Ulrich Drepper  <drepper@cygnus.com>
+
+       * version.h (VERSION): Bump to 2.0.95.
+
+       * math/Makefile (libm-calls): Remove w_gamma, add w_tgamma.
+       * math/Versions [GLIBC_2.1]: Add tgamma, tgammaf, and tgammal.
+       * math/libm-test.c: Split old gamma_test and move half of it in new
+       function tgamma_test.
+       * math/bits/mathcalls.h: Add declaration of tgamma.
+       * sysdeps/libm-ieee754/k_standard.c: Change gamma errors into
+       tgamma errors.
+       * sysdeps/libm-ieee754/w_gamma.c: Remove lgamma compatibility code
+       and rename to ...
+       * sysdeps/libm-ieee754/w_tgamma.c: ... this.  New file.
+       * sysdeps/libm-ieee754/w_gammaf.c: Remove lgammaf compatibility code
+       and rename to ...
+       * sysdeps/libm-ieee754/w_tgammaf.c: ... this.  New file.
+       * sysdeps/libm-ieee754/w_gammal.c: Remove lgammal compatibility code
+       and rename to ...
+       * sysdeps/libm-ieee754/w_tgammal.c: ... this.  New file.
+       * sysdeps/libm-ieee754/w_lgamma.c: Add gamma as weak alias.
+       * sysdeps/libm-ieee754/w_lgammaf.c: Likewise.
+       * sysdeps/libm-ieee754/w_lgammal.c: Likewise.
+
+       * stgdio-common/printf-parse.h: Implement handling of j, t, and z
+       modifiers.
+       * stdio-common/vfprintf.c: Likewise.
+       * stdio-common/vfscanf.c: Likewise.
+       * manual/stdio.texi: Document new printf/scanf modifiers.
+
+       * sysdeps/unix/sysv/linux/recvmsg.c: Remove alias __recvmsg.
+       * sysdeps/unix/sysv/linux/sendmsg.c: Remove alias __sendmsg.
+
+1998-07-28  Thorsten Kukuk  <kukuk@vt.uni-paderborn.de>
+
+       * sunrpc/Makefile (routines): Add clnt_unix and svc_unix.
+       * sunrpc/Versions: Add new *unix_create functions.
+       * sunrpc/clnt_gen.c: Add support for RPC over AF_UNIX.
+       * sunrpc/clnt_unix.c: New, client side of RPC over AF_UNIX.
+       * sunrpc/key_call.c: Use RPC over AF_UNIX for communication
+       with keyserv daemon.
+       * sunrpc/rpc/clnt.h: Add AF_UNIX based RPC function prototypes.
+       * sunrpc/rpc/svc.h: Likewise.
+       * sunrpc/svc_authux.c: Copy internal auth flavor if none is given.
+       * sunrpc/svc_tcp.c: Fix typos.
+       * sunrpc/svc_unix.c: New, server side of AF_UNIX based RPC.
+
+       * nis/Makefile: Remove currently not working cache functions.
+       * nis/Versions: Add __nisbind_* functions for rpc.nisd.
+       * nis/nis_call.c: Rewrite binding to a NIS+ server to reuse
+       CLIENT handles.
+       * nis/nis_file.c: Fix memory leaks.
+       * nis/nis_intern.h: Move internal structs from here ...
+       * nis/rpcsvc/nislib.h: ... to here for NIS+ server and tools.
+       * nis/nis_lookup.c: Try at first if last client handle works.
+       * nis/nis_table.c: Likewise.
+       * nis/nis_checkpoint.c: Adjust __do_niscall2 parameters.
+       * nis/nis_mkdir.c: Likewise.
+       * nis/nis_ping.c: Likewise.
+       * nis/nis_rmdir.c: Likewise.
+       * nis/nis_server.c: Likewise.
+       * nis/nis_util.c: Likewise.
+       * nis/nis_findserv.c (__nis_findfastest): Little optimization.
+
+1998-07-28  Andreas Jaeger  <aj@arthur.rhein-neckar.de>
+
+       * stdlib/strtol.c (STRTOL_LONG_MAX): Correct typo in last patch -
+       define as LONG_MAX.
+
+1998-07-28 09:31  Ulrich Drepper  <drepper@cygnus.com>
+
+       * nscd/connections.c (gr_send_answer): Deal with missing UIO_MAXIOV.
+       Correct test whether writev send all data.
+       * nscd/nscd_getgr_r.c (__nscd_getgr_r): Correct test whether readv
+       received all data.
+
+1998-07-28  Mark Kettenis  <kettenis@phys.uva.nl>
+
+       * nscd/nscd_getgr_r.c (__nscd_getgr_r): Deal with missing UIO_MAXIOV.
+
+1998-07-28  Mark Kettenis  <kettenis@phys.uva.nl>
+
+       * sysdeps/mach/hurd/dl-sysdep.c (open_file): Change assert call to
+       allow mode to be 0.
+       (__xstat): New function.
+       (__fxstat): New function.
+       (_dl_sysdep_read_whole_file): Removed.  The implementation in
+       `elf/dl-misc.c' now also works for the Hurd.
+
 1998-07-27 22:25  Ulrich Drepper  <drepper@cygnus.com>
 
        * sysdeps/generic/glob.c: Handle ~ and ~NAME case correctly.
index 4386c2fefcd0aec72bb2806443382e468d4bfe2a..e1d597d06aa96174ce9975d4e10a224a32e49c0f 100644 (file)
@@ -857,7 +857,8 @@ The sign of the gamma function is stored in the global variable
 the intermediate result was positive or zero, and, @code{-1} if it was
 negative.
 
-You can compute the actual gamma function as follows:
+To compute the real gamma function you can use the @code{tgamma}
+function or you can compute the values as follows:
 @smallexample
 lgam = lgamma(x);
 gam  = signgam*exp(lgam);
@@ -878,15 +879,35 @@ the intermediate result in the variable pointed to by @var{signp}
 instead of in the @var{signgam} global.
 @end deftypefun
 
-@ignore
 @comment math.h
 @comment SVID
 @deftypefun double gamma (double @var{x})
 @deftypefunx float gammaf (float @var{x})
 @deftypefunx {long double} gammal (long double @var{x})
-??? _not_ exp(lgamma())*signgam - historical?
+These functions exist for compatibility reasons.  They are equivalent to
+@code{lgamma} etc.  It is better to use @code{lgamma} since for one the
+name reflect better the actual computation and @code{lgamma} is also
+standardized in @w{ISO C 9x} while @code{gamma} is not.
+@end deftypefun
+
+@comment math.h
+@comment XPG
+@deftypefun double tgamma (double @var{x})
+@deftypefunx float tgammaf (float @var{x})
+@deftypefunx {long double} tgammal (long double @var{x})
+@code{tgamma} applies the gamma function to @var{x}.  The gamma
+function is defined as
+@tex
+$$\Gamma(x) = \int_0^\infty t^{x-1} e^{-t} \hbox{d}t$$
+@end tex
+@ifnottex
+@smallexample
+gamma (x) = integral from 0 to @infinity{} of t^(x-1) e^-t dt
+@end smallexample
+@end ifnottex
+
+This function was introduced in @w{ISO C 9x}.
 @end deftypefun
-@end ignore
 
 @comment math.h
 @comment SVID
index c9304712205c3d5962f1f91901f39caacf822897..531717c81ff16fd9fcd5c0dd501c950175ff6769 100644 (file)
@@ -1190,6 +1190,8 @@ char}, as appropriate.  A @code{char} argument is converted to an
 anyway, but the @samp{h} modifier says to convert it back to a
 @code{char} again.
 
+This modifier was introduced in @w{ISO C 9x}.
+
 @item h
 Specifies that the argument is a @code{short int} or @code{unsigned
 short int}, as appropriate.  A @code{short} argument is converted to an
@@ -1197,6 +1199,12 @@ short int}, as appropriate.  A @code{short} argument is converted to an
 anyway, but the @samp{h} modifier says to convert it back to a
 @code{short} again.
 
+@item j
+Specifies that the argument is a @code{intmax_t} or @code{uintmax_t}, as
+appropriate.
+
+This modifier was introduced in @w{ISO C 9x}.
+
 @item l
 Specifies that the argument is a @code{long int} or @code{unsigned long
 int}, as appropriate.  Two @samp{l} characters is like the @samp{L}
@@ -1213,8 +1221,17 @@ The @samp{q} modifier is another name for the same thing, which comes
 from 4.4 BSD; a @w{@code{long long int}} is sometimes called a ``quad''
 @code{int}.
 
-@item Z
-Specifies that the argument is a @code{size_t}.  This is a GNU extension.
+@item t
+Specifies that the argument is a @code{ptrdiff_t}.
+
+This modifier was introduced in @w{ISO C 9x}.
+
+@item z
+@itemx Z
+Specifies that the argument is a @code{size_t}.
+
+@samp{z} was introduced in @w{ISO C 9x}.  @samp{Z} is a GNU extension
+predating this addition and should not be used anymore in new code.
 @end table
 
 Here is an example.  Using the template string:
@@ -2653,10 +2670,17 @@ specify other sizes of integer:
 Specifies that the argument is a @code{signed char *} or @code{unsigned
 char *}.
 
+This modifier was introduced in @w{ISO C 9x}.
+
 @item h
 Specifies that the argument is a @code{short int *} or @code{unsigned
 short int *}.
 
+@item j
+Specifies that the argument is a @code{intmax_t *} or @code{uintmax_t *}.
+
+This modifier was introduced in @w{ISO C 9x}.
+
 @item l
 Specifies that the argument is a @code{long int *} or @code{unsigned
 long int *}.  Two @samp{l} characters is like the @samp{L} modifier, below.
@@ -2672,6 +2696,16 @@ is the same as @code{long int}.)
 The @samp{q} modifier is another name for the same thing, which comes
 from 4.4 BSD; a @w{@code{long long int}} is sometimes called a ``quad''
 @code{int}.
+
+@item t
+Specifies that the argument is a @code{ptrdiff_t *}.
+
+This modifier was introduced in @w{ISO C 9x}.
+
+@item z
+Specifies that the argument is a @code{size_t *}.
+
+This modifier was introduced in @w{ISO C 9x}.
 @end table
 
 All of the @samp{%e}, @samp{%f}, @samp{%g}, @samp{%E}, and @samp{%G}
index 9f2d3367e5ea27a06ad92cf3db8c649c6cf67a5d..4bd958008440baa014ef78af78f0491317899b42 100644 (file)
@@ -49,7 +49,7 @@ libm-calls = e_acos e_acosh e_asin e_atan2 e_atanh e_cosh e_exp e_fmod        \
             s_modf s_nextafter s_nextafterx s_rint s_scalbn s_scalbln  \
             s_significand s_sin s_tan s_tanh w_acos w_acosh w_asin     \
             w_atan2 w_atanh w_cosh w_drem w_exp w_exp2 w_exp10 w_fmod  \
-            w_gamma w_hypot w_j0 w_j1 w_jn w_lgamma w_lgamma_r         \
+            w_tgamma w_hypot w_j0 w_j1 w_jn w_lgamma w_lgamma_r        \
             w_log w_log10 w_pow w_remainder w_scalb w_sinh w_sqrt      \
             s_signbit s_fpclassify s_fmax s_fmin s_fdim s_nan s_trunc  \
             s_remquo s_log2 s_exp2 s_round s_nearbyint s_sincos        \
index 8864ef1b8756c90c9ca702affe91d1d4b064fbea..580fa253aa4009765ce53248b9bfd4ccc9289133 100644 (file)
@@ -111,6 +111,7 @@ libm {
     scalbln; scalblnf; scalblnl;
     sincos; sincosf; sincosl;
     trunc; truncf; truncl;
+    tgamma; tgammaf; tgammal;
 
     # complex functions
     cabs; cabsf; cabsl;
index 30bbb7c0aad8d1791156a2a46d1ed90c57052f31..a94707ffe31479b8e3aa993895f4ba33df9b42f8 100644 (file)
@@ -224,8 +224,12 @@ __MATHCALL (yn,, (int, _Mdouble_));
 /* Error, gamma, and Bessel functions.  */
 __MATHCALL (erf,, (_Mdouble_));
 __MATHCALL (erfc,, (_Mdouble_));
-__MATHCALL (gamma,, (_Mdouble_));
 __MATHCALL (lgamma,, (_Mdouble_));
+__MATHCALL (tgamma,, (_Mdouble_));
+#endif
+
+#if defined __USE_MISC || defined __USE_XOPEN
+__MATHCALL (gamma,, (_Mdouble_));
 #endif
 
 #ifdef __USE_MISC
index 52358d5b3460e7f482640343276623c6479cf859..95d285e1c70f056c172eb24c3b239a121700bc83 100644 (file)
@@ -51,7 +51,7 @@
    modf, nearbyint, nextafter,
    pow, remainder, remquo, rint, lrint, llrint,
    round, lround, llround,
-   scalb, scalbn, signbit, sin, sincos, sinh, sqrt, tan, tanh, trunc
+   scalb, scalbn, signbit, sin, sincos, sinh, sqrt, tan, tanh, tgamma, trunc
 
    and for the following complex math functions:
    cabs, cacos, cacosh, carg, casin, casinh, catan, catanh,
@@ -1413,15 +1413,9 @@ signbit_test (void)
 }
 
 
-/*
-   gamma has different semantics depending on _LIB_VERSION:
-   if _LIB_VERSION is _SVID, gamma is just an alias for lgamma,
-   otherwise gamma is the real gamma function as definied in ISO C 9X.
-*/
 static void
 gamma_test (void)
 {
-  int save_lib_version = _LIB_VERSION;
   errno = 0;
   FUNC(gamma) (1);
   if (errno == ENOSYS)
@@ -1430,14 +1424,12 @@ gamma_test (void)
   feclearexcept (FE_ALL_EXCEPT);
 
 
-  _LIB_VERSION = _SVID_;
-
   check_isinfp ("gamma (+inf) == +inf", FUNC(gamma) (plus_infty));
-  check_exc ("gamma (0) == HUGE plus divide by zero exception",
-            FUNC(gamma) (0), HUGE, DIVIDE_BY_ZERO_EXCEPTION);
+  check_isinfp_exc ("gamma (0) == +inf plus divide by zero exception",
+                   FUNC(gamma) (0), DIVIDE_BY_ZERO_EXCEPTION);
 
-  check_exc ("gamma (x) == HUGE plus divide by zero exception for integer x <= 0",
-            FUNC(gamma) (-3), HUGE, DIVIDE_BY_ZERO_EXCEPTION);
+  check_isinfp_exc ("gamma (x) == +inf plus divide by zero exception for integer x <= 0",
+                   FUNC(gamma) (-3), DIVIDE_BY_ZERO_EXCEPTION);
   check_isnan_exc ("gamma (-inf) == NaN plus invalid exception",
                    FUNC(gamma) (minus_infty), INVALID_EXCEPTION);
 
@@ -1459,39 +1451,43 @@ gamma_test (void)
              FUNC(log) (2*FUNC(sqrt) (M_PIl)), CHOOSE (0, 1e-15, 0));
 
   check_int ("gamma (-0.5) sets signgam to -1", signgam, -1);
+}
 
 
-  _LIB_VERSION = _IEEE_;
+static void
+tgamma_test (void)
+{
+  errno = 0;
+  FUNC(tgamma) (1);
+  if (errno == ENOSYS)
+    /* Function not implemented.  */
+    return;
+  feclearexcept (FE_ALL_EXCEPT);
 
-  check_isinfp ("gamma (+inf) == +inf", FUNC(gamma) (plus_infty));
-  check_isnan_exc ("gamma (0) == NaN plus invalid exception",
-                    FUNC(gamma) (0), INVALID_EXCEPTION);
 
-  check_isnan_exc_ext ("gamma (x) == NaN plus invalid exception for integer x <= 0",
-                        FUNC(gamma) (-2), INVALID_EXCEPTION, -2);
-  check_isnan_exc ("gamma (-inf) == NaN plus invalid exception",
-                   FUNC(gamma) (minus_infty), INVALID_EXCEPTION);
+  check_isinfp ("tgamma (+inf) == +inf", FUNC(tgamma) (plus_infty));
+  check_isnan_exc ("tgamma (0) == NaN plus invalid exception",
+                    FUNC(tgamma) (0), INVALID_EXCEPTION);
+
+  check_isnan_exc_ext ("tgamma (x) == NaN plus invalid exception for integer x <= 0",
+                        FUNC(tgamma) (-2), INVALID_EXCEPTION, -2);
+  check_isnan_exc ("tgamma (-inf) == NaN plus invalid exception",
+                   FUNC(tgamma) (minus_infty), INVALID_EXCEPTION);
 
 #ifdef TODO
-  check_eps ("gamma (0.5) == sqrt(pi)", FUNC(gamma) (0.5), FUNC(sqrt) (M_PIl),
-            CHOOSE (0, 5e-16, 2e-7));
+  check_eps ("tgamma (0.5) == sqrt(pi)", FUNC(tgamma) (0.5),
+            FUNC(sqrt) (M_PIl), CHOOSE (0, 5e-16, 2e-7));
 #endif
-  check_eps ("gamma (-0.5) == -2*sqrt(pi)", FUNC(gamma) (-0.5),
+  check_eps ("tgamma (-0.5) == -2*sqrt(pi)", FUNC(tgamma) (-0.5),
             -2*FUNC(sqrt) (M_PIl), CHOOSE (0, 5e-16, 3e-7));
 
-  check ("gamma (1) == 1", FUNC(gamma) (1), 1);
-  check ("gamma (4) == 6", FUNC(gamma) (4), 6);
+  check ("tgamma (1) == 1", FUNC(tgamma) (1), 1);
+  check ("tgamma (4) == 6", FUNC(tgamma) (4), 6);
 
-  check_eps ("gamma (0.7) == 1.29805...", FUNC(gamma) (0.7),
+  check_eps ("tgamma (0.7) == 1.29805...", FUNC(tgamma) (0.7),
             1.29805533264755778568L, CHOOSE(0, 3e-16, 2e-7));
-  check ("gamma (1.2) == 0.91816...", FUNC(gamma) (1.2), 0.91816874239976061064L);
-
-  check_isnan_exc ("gamma (0.0) == NaN plus invalid exception",
-                  FUNC(gamma) (0.0), INVALID_EXCEPTION);
-  check_isnan_exc ("gamma (-1.0) == NaN plus invalid exception",
-                  FUNC(gamma) (-1.0), INVALID_EXCEPTION);
-
-  _LIB_VERSION = save_lib_version;
+  check ("tgamma (1.2) == 0.91816...", FUNC(tgamma) (1.2),
+        0.91816874239976061064L);
 }
 
 
@@ -6012,6 +6008,7 @@ main (int argc, char *argv[])
   erf_test ();
   erfc_test ();
   gamma_test ();
+  tgamma_test ();
   lgamma_test ();
 
   /* nearest integer functions */
index 478c9b996ebff15da94ccaa4c99cc026248dfe9e..1df3a1652b7324fc4553f5613aee1bc19708b69c 100644 (file)
@@ -1 +1 @@
-NIS(YP)/NIS+ NSS modules 0.17 by Thorsten Kukuk
+NIS(YP)/NIS+ NSS modules 0.18 by Thorsten Kukuk
index c736b5a59a1aeef55ba79c941bd9205a4e11e117..78fdd072ec553130237a9f3a4dc73f7676288e10 100644 (file)
@@ -23,7 +23,7 @@ subdir        := nis
 
 headers                        := $(wildcard rpcsvc/*.[hx])
 distribute             := nss-nis.h nss-nisplus.h nis_intern.h Banner \
-                       nisplus-parser.h nis_cache2.h nis_xdr.h
+                       nisplus-parser.h nis_xdr.h
 
 # These are the databases available for the nis (and perhaps later nisplus)
 # service.  This must be a superset of the services in nss.
@@ -44,8 +44,8 @@ vpath %.c $(subdir-dirs)
 
 libnsl-routines = yp_xdr ypclnt ypupdate_xdr \
                   nis_subr nis_local_names nis_free nis_file \
-                  nis_print nis_error nis_call nis_lookup nis_cache\
-                  nis_table nis_xdr nis_server nis_ping nis_cache2_xdr\
+                  nis_print nis_error nis_call nis_lookup\
+                  nis_table nis_xdr nis_server nis_ping \
                  nis_checkpoint nis_mkdir nis_rmdir nis_getservlist\
                  nis_verifygroup nis_ismember nis_addmember nis_util\
                  nis_removemember nis_creategroup nis_destroygroup\
index aa2df3a0485d3dfaded24e322535d78921a00112..d26cba75b33a353b14aa93fa6fbd84a4ef5b5113 100644 (file)
@@ -48,9 +48,10 @@ libnsl {
 
     # This functions are needed by the NIS+ tools and rpc.nisd,
     # they should never be used in a normal user program !
-    __do_niscall2;        __free_fdresult;     __nis_default_access;
-    __nis_default_group;  __nis_default_owner; __nis_default_ttl;
-    __nis_finddirectory;  __nis_hash;
+    __free_fdresult;      __nis_default_access; __nis_default_group;  
+    __nis_default_owner;  __nis_default_ttl;   __nis_finddirectory;  
+    __nis_hash;           __nisbind_connect;   __nisbind_create;
+    __nisbind_destroy;    __nisbind_next;
     readColdStartFile;    writeColdStartFile;
   }
 }
index 94144d50eac0ac756b838685800b60e6c7e768f8..ce7607f4e16af19fb445040503a57671f864ca4f 100644 (file)
@@ -60,8 +60,8 @@ inetstr2int (const char *str)
   return inet_addr (buffer);
 }
 
-static void
-__bind_destroy (dir_binding *bind)
+void
+__nisbind_destroy (dir_binding *bind)
 {
   if (bind->clnt != NULL)
     {
@@ -71,8 +71,8 @@ __bind_destroy (dir_binding *bind)
     }
 }
 
-static nis_error
-__bind_next (dir_binding *bind)
+nis_error
+__nisbind_next (dir_binding *bind)
 {
   u_int j;
 
@@ -91,8 +91,7 @@ __bind_next (dir_binding *bind)
        j < bind->server_val[bind->server_used].ep.ep_len; ++j)
     if (strcmp (bind->server_val[bind->server_used].ep.ep_val[j].family,
                "inet") == 0)
-      if (strcmp (bind->server_val[bind->server_used].ep.ep_val[j].proto,
-                 "-") == 0)
+      if (bind->server_val[bind->server_used].ep.ep_val[j].proto[0] == '-')
        {
          bind->current_ep = j;
          return NIS_SUCCESS;
@@ -115,8 +114,8 @@ __bind_next (dir_binding *bind)
   return NIS_FAIL;
 }
 
-static nis_error
-__bind_connect (dir_binding *dbp)
+nis_error
+__nisbind_connect (dir_binding *dbp)
 {
   nis_server *serv;
 
@@ -157,7 +156,7 @@ __bind_connect (dir_binding *dbp)
 
   if (dbp->use_auth)
     {
-      if (serv->key_type == NIS_PK_DH && key_secretkey_is_set ())
+      if (serv->key_type == NIS_PK_DH)
        {
          char netname[MAXNETNAMELEN+1];
          char *p;
@@ -180,9 +179,9 @@ __bind_connect (dir_binding *dbp)
   return NIS_SUCCESS;
 }
 
-static nis_error
-__bind_create (dir_binding *dbp, const nis_server *serv_val, u_int serv_len,
-              u_long flags, cache2_info *cinfo)
+nis_error
+__nisbind_create (dir_binding *dbp, const nis_server *serv_val, u_int serv_len,
+                 u_long flags)
 {
   dbp->clnt = NULL;
 
@@ -208,54 +207,34 @@ __bind_create (dir_binding *dbp, const nis_server *serv_val, u_int serv_len,
   dbp->trys = 1;
 
   dbp->class = -1;
-  if (cinfo != NULL && cinfo->server_used >= 0)
-    {
-      dbp->server_used = cinfo->server_used;
-      dbp->current_ep = cinfo->current_ep;
-      dbp->class = cinfo->class;
-    }
-  else if (__nis_findfastest (dbp) < 1)
+  if (__nis_findfastest (dbp) < 1)
     {
-      __bind_destroy (dbp);
+      __nisbind_destroy (dbp);
       return NIS_NAMEUNREACHABLE;
     }
 
   return NIS_SUCCESS;
 }
 
+/* __nisbind_connect (dbp) must be run before calling this function !
+   So we could use the same binding twice */
 nis_error
-__do_niscall2 (const nis_server *server, u_int server_len, u_long prog,
-              xdrproc_t xargs, caddr_t req, xdrproc_t xres, caddr_t resp,
-              u_long flags, nis_cb *cb, cache2_info *cinfo)
+__do_niscall3 (dir_binding *dbp, u_long prog, xdrproc_t xargs, caddr_t req,
+              xdrproc_t xres, caddr_t resp, u_long flags, nis_cb *cb)
 {
   enum clnt_stat result;
   nis_error retcode;
-  dir_binding dbp;
 
-  if (flags & MASTER_ONLY)
-    server_len = 1;
-
-  if (__bind_create (&dbp, server, server_len, flags, cinfo) != NIS_SUCCESS)
+  if (dbp == NULL)
     return NIS_NAMEUNREACHABLE;
-  while (__bind_connect (&dbp) != NIS_SUCCESS)
-    {
-      if (__bind_next (&dbp) != NIS_SUCCESS)
-       {
-         __bind_destroy (&dbp);
-         return NIS_NAMEUNREACHABLE;
-       }
-    }
 
   do
     {
     again:
-      result = clnt_call (dbp.clnt, prog, xargs, req, xres, resp, RPCTIMEOUT);
+      result = clnt_call (dbp->clnt, prog, xargs, req, xres, resp, RPCTIMEOUT);
 
       if (result != RPC_SUCCESS)
-       {
-         __bind_destroy (&dbp);
-         retcode = NIS_RPCERROR;
-       }
+       retcode = NIS_RPCERROR;
       else
        {
          switch (prog)
@@ -264,11 +243,11 @@ __do_niscall2 (const nis_server *server, u_int server_len, u_long prog,
              if ((((nis_result *)resp)->status == NIS_CBRESULTS) &&
                  (cb != NULL))
                {
-                 __nis_do_callback(&dbp, &((nis_result *)resp)->cookie, cb);
+                 __nis_do_callback(dbp, &((nis_result *)resp)->cookie, cb);
                  break;
                }
-             /* Yes, this is correct. If we doesn't have to start
-                a callback, look if we have to search another server */
+             /* Yes, the missing break is correct. If we doesn't have to
+                start a callback, look if we have to search another server */
            case NIS_LOOKUP:
            case NIS_ADD:
            case NIS_MODIFY:
@@ -278,19 +257,16 @@ __do_niscall2 (const nis_server *server, u_int server_len, u_long prog,
            case NIS_IBREMOVE:
            case NIS_IBFIRST:
            case NIS_IBNEXT:
-             if ((((nis_result *)resp)->status == NIS_NOTFOUND) ||
+             if ((((nis_result *)resp)->status == NIS_SYSTEMERROR) ||
                  (((nis_result *)resp)->status == NIS_NOSUCHNAME) ||
                  (((nis_result *)resp)->status == NIS_NOT_ME))
                {
-                 if (__bind_next (&dbp) == NIS_SUCCESS)
+                 if (__nisbind_next (dbp) == NIS_SUCCESS)
                    {
-                     while (__bind_connect (&dbp) != NIS_SUCCESS)
+                     while (__nisbind_connect (dbp) != NIS_SUCCESS)
                        {
-                         if (__bind_next (&dbp) != NIS_SUCCESS)
-                           {
-                             __bind_destroy (&dbp);
+                         if (__nisbind_next (dbp) != NIS_SUCCESS)
                              return NIS_SUCCESS;
-                           }
                        }
                    }
                  else
@@ -299,19 +275,16 @@ __do_niscall2 (const nis_server *server, u_int server_len, u_long prog,
                }
              break;
            case NIS_FINDDIRECTORY:
-             if ((((fd_result *)resp)->status == NIS_NOTFOUND) ||
+             if ((((fd_result *)resp)->status == NIS_SYSTEMERROR) ||
                  (((fd_result *)resp)->status == NIS_NOSUCHNAME) ||
                  (((fd_result *)resp)->status == NIS_NOT_ME))
                {
-                 if (__bind_next (&dbp) == NIS_SUCCESS)
+                 if (__nisbind_next (dbp) == NIS_SUCCESS)
                    {
-                     while (__bind_connect (&dbp) != NIS_SUCCESS)
+                     while (__nisbind_connect (dbp) != NIS_SUCCESS)
                        {
-                         if (__bind_next (&dbp) != NIS_SUCCESS)
-                           {
-                             __bind_destroy (&dbp);
-                             return NIS_SUCCESS;
-                           }
+                         if (__nisbind_next (dbp) != NIS_SUCCESS)
+                           return NIS_SUCCESS;
                        }
                    }
                  else
@@ -321,19 +294,16 @@ __do_niscall2 (const nis_server *server, u_int server_len, u_long prog,
              break;
            case NIS_DUMPLOG: /* log_result */
            case NIS_DUMP:
-             if ((((log_result *)resp)->lr_status == NIS_NOTFOUND) ||
+             if ((((log_result *)resp)->lr_status == NIS_SYSTEMERROR) ||
                  (((log_result *)resp)->lr_status == NIS_NOSUCHNAME) ||
                  (((log_result *)resp)->lr_status == NIS_NOT_ME))
                {
-                 if (__bind_next (&dbp) == NIS_SUCCESS)
+                 if (__nisbind_next (dbp) == NIS_SUCCESS)
                    {
-                     while (__bind_connect (&dbp) != NIS_SUCCESS)
+                     while (__nisbind_connect (dbp) != NIS_SUCCESS)
                        {
-                         if (__bind_next (&dbp) != NIS_SUCCESS)
-                           {
-                             __bind_destroy (&dbp);
-                             return NIS_SUCCESS;
-                           }
+                         if (__nisbind_next (dbp) != NIS_SUCCESS)
+                           return NIS_SUCCESS;
                        }
                    }
                  else
@@ -344,7 +314,6 @@ __do_niscall2 (const nis_server *server, u_int server_len, u_long prog,
            default:
              break;
            }
-         __bind_destroy (&dbp);
          retcode = NIS_SUCCESS;
        }
     }
@@ -353,9 +322,37 @@ __do_niscall2 (const nis_server *server, u_int server_len, u_long prog,
   return retcode;
 }
 
+nis_error
+__do_niscall2 (const nis_server *server, u_int server_len, u_long prog,
+              xdrproc_t xargs, caddr_t req, xdrproc_t xres, caddr_t resp,
+              u_long flags, nis_cb *cb)
+{
+  dir_binding dbp;
+  nis_error status;
+
+  if (flags & MASTER_ONLY)
+    server_len = 1;
+
+  status = __nisbind_create (&dbp, server, server_len, flags);
+  if (status != NIS_SUCCESS)
+    return status;
+
+  while (__nisbind_connect (&dbp) != NIS_SUCCESS)
+    {
+      if (__nisbind_next (&dbp) != NIS_SUCCESS)
+       return NIS_NAMEUNREACHABLE;
+    }
+
+  status = __do_niscall3 (&dbp, prog, xargs, req, xres, resp, flags, cb);
+
+  __nisbind_destroy (&dbp);
+
+  return status;
+
+}
+
 static directory_obj *
-rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags,
-              nis_error *status)
+rec_dirsearch (const_nis_name name, directory_obj *dir, nis_error *status)
 {
   fd_result *fd_res;
   XDR xdrs;
@@ -396,7 +393,7 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags,
            /* We have found a NIS+ server serving ndomain, now
               let us search for "name" */
            nis_free_directory (dir);
-           return rec_dirsearch (name, obj, flags, status);
+           return rec_dirsearch (name, obj, status);
          }
        else
          {
@@ -461,7 +458,7 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags,
            /* We have found a NIS+ server serving ndomain, now
               let us search for "name" */
            nis_free_directory (dir);
-           return rec_dirsearch (name, obj, flags, status);
+           return rec_dirsearch (name, obj, status);
          }
       }
     break;
@@ -478,7 +475,7 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags,
 /* We try to query the current server for the searched object,
    maybe he know about it ? */
 static directory_obj *
-first_shoot (const_nis_name name, directory_obj *dir, u_long flags)
+first_shoot (const_nis_name name, directory_obj *dir)
 {
   directory_obj *obj;
   fd_result *fd_res;
@@ -516,51 +513,57 @@ first_shoot (const_nis_name name, directory_obj *dir, u_long flags)
 }
 
 nis_error
-__do_niscall (const_nis_name name, u_long prog, xdrproc_t xargs,
-             caddr_t req, xdrproc_t xres, caddr_t resp, u_long flags,
-             nis_cb *cb)
+__nisfind_server (const_nis_name name, directory_obj **dir)
 {
-  nis_error retcode;
-  directory_obj *dir = NULL;
-  nis_server *server;
-  u_int server_len;
-  cache2_info cinfo = {-1, -1, -1};
-  int saved_errno = errno;
-
   if (name == NULL)
     return NIS_BADNAME;
 
+#if 0
   /* Search in local cache. In the moment, we ignore the fastest server */
   if (!(flags & NO_CACHE))
     dir = __nis_cache_search (name, flags, &cinfo);
+#endif
 
-  if (dir == NULL)
+  if (*dir == NULL)
     {
       nis_error status;
       directory_obj *obj;
 
-      dir = readColdStartFile ();
-      if (dir == NULL) /* No /var/nis/NIS_COLD_START->no NIS+ installed */
-       {
-         __set_errno (saved_errno);
-         return NIS_UNAVAIL;
-       }
+      *dir = readColdStartFile ();
+      if (*dir == NULL) /* No /var/nis/NIS_COLD_START->no NIS+ installed */
+       return NIS_UNAVAIL;
 
       /* Try at first, if servers in "dir" know our object */
-      obj = first_shoot (name, dir, flags);
+      obj = first_shoot (name, *dir);
       if (obj == NULL)
        {
-         dir = rec_dirsearch (name, dir, flags, &status);
-         if (dir == NULL)
-           {
-             __set_errno (saved_errno);
-             return status;
-           }
+         *dir = rec_dirsearch (name, *dir, &status);
+         if (*dir == NULL)
+           return status;
        }
       else
-       dir = obj;
+       *dir = obj;
     }
 
+  return NIS_SUCCESS;
+}
+
+nis_error
+__do_niscall (const_nis_name name, u_long prog, xdrproc_t xargs,
+             caddr_t req, xdrproc_t xres, caddr_t resp, u_long flags,
+             nis_cb *cb)
+{
+  nis_error retcode;
+  dir_binding bptr;
+  directory_obj *dir = NULL;
+  nis_server *server;
+  u_int server_len;
+  int saved_errno = errno;
+
+  retcode = __nisfind_server (name, &dir);
+  if (retcode != NIS_SUCCESS)
+    return retcode;
+
   if (flags & MASTER_ONLY)
     {
       server = dir->do_servers.do_servers_val;
@@ -572,9 +575,22 @@ __do_niscall (const_nis_name name, u_long prog, xdrproc_t xargs,
       server_len = dir->do_servers.do_servers_len;
     }
 
+  retcode = __nisbind_create (&bptr, server, server_len, flags);
+  if (retcode == NIS_SUCCESS)
+    {
+      while (__nisbind_connect (&bptr) != NIS_SUCCESS)
+       {
+         if (__nisbind_next (&bptr) != NIS_SUCCESS)
+           {
+             nis_free_directory (dir);
+             __nisbind_destroy (&bptr);
+             return NIS_NAMEUNREACHABLE;
+           }
+       }
+      retcode = __do_niscall3 (&bptr, prog, xargs, req, xres, resp, flags, cb);
 
-  retcode = __do_niscall2 (server, server_len, prog, xargs, req, xres, resp,
-                          flags, cb, &cinfo);
+      __nisbind_destroy (&bptr);
+    }
 
   nis_free_directory (dir);
 
index f1e860f7b88f47bf010eaad0a4e6dd01d8494e48..15bae8be221570267153033611101ed4a83a4d88 100644 (file)
@@ -58,7 +58,7 @@ nis_checkpoint(const_nis_name dirname)
          if (__do_niscall2 (&NIS_RES_OBJECT(res2)->DI_data.do_servers.do_servers_val[i],
                             1, NIS_CHECKPOINT, (xdrproc_t) _xdr_nis_name,
                             (caddr_t) &dirname, (xdrproc_t) _xdr_cp_result,
-                            (caddr_t) &cpres, 0, NULL, NULL) != NIS_SUCCESS)
+                            (caddr_t) &cpres, 0, NULL) != NIS_SUCCESS)
            NIS_RES_STATUS (res) = NIS_RPCERROR;
          else
            {
index 94fa4eb86586bea1b43e5351661826b33411db25..0ffac68fe263f20f90cb6c9068a8e40ca9718aa4 100644 (file)
@@ -31,18 +31,26 @@ readColdStartFile (void)
   XDR xdrs;
   FILE *in;
   bool_t status;
-  directory_obj obj;
+  directory_obj *obj = calloc (1, sizeof (directory_obj));
+
+  if (obj == NULL)
+    return NULL;
 
   in = fopen (cold_start_file, "rb");
   if (in == NULL)
     return NULL;
-  memset (&obj, '\0', sizeof (obj));
   xdrstdio_create (&xdrs, in, XDR_DECODE);
-  status = _xdr_directory_obj (&xdrs, &obj);
+  status = _xdr_directory_obj (&xdrs, obj);
   xdr_destroy (&xdrs);
   fclose (in);
 
-  return status ? nis_clone_directory (&obj, NULL) : NULL;
+  if (status)
+    return obj;
+  else
+    {
+      nis_free_directory (obj);
+      return NULL;
+    }
 }
 
 bool_t
@@ -70,19 +78,27 @@ nis_read_obj (const char *name)
   XDR xdrs;
   FILE *in;
   bool_t status;
-  nis_object obj;
+  nis_object *obj = calloc (1, sizeof (nis_object));
+
+  if (obj == NULL)
+    return NULL;
 
   in = fopen (name, "rb");
   if (in == NULL)
     return NULL;
 
-  memset (&obj, '\0', sizeof (obj));
   xdrstdio_create (&xdrs, in, XDR_DECODE);
-  status =_xdr_nis_object (&xdrs, &obj);
+  status =_xdr_nis_object (&xdrs, obj);
   xdr_destroy (&xdrs);
   fclose (in);
 
-  return status ? nis_clone_object (&obj, NULL) : NULL;
+  if (status)
+    return obj;
+  else
+    {
+      nis_free_object (obj);
+      return NULL;
+    }
 }
 
 bool_t
index 832b6a541dead02805effb6e484eac2873e2822f..5b6a74981c25a0bcf4669ec3cb323801a2fe941d 100644 (file)
@@ -110,8 +110,25 @@ struct findserv_req
 };
 
 long
-__nis_findfastest (dir_binding * bind)
+__nis_findfastest (dir_binding *bind)
 {
+#if 0
+  unsigned long i, j;
+
+  for (i = 0; i < bind->server_len; i++)
+    for (j = 0; j < bind->server_val[i].ep.ep_len; ++j)
+      if (strcmp (bind->server_val[i].ep.ep_val[j].family, "inet") == 0)
+       if ((bind->server_val[i].ep.ep_val[j].proto == NULL) ||
+           (bind->server_val[i].ep.ep_val[j].proto[0] ==  '-') ||
+           (bind->server_val[i].ep.ep_val[j].proto[0] == '\0'))
+         {
+           bind->server_used = i;
+           bind->current_ep = j;
+           return 1;
+         }
+
+  return 0;
+#else
   const struct timeval TIMEOUT50 = {5, 0};
   const struct timeval TIMEOUT00 = {0, 0};
   struct findserv_req **pings;
@@ -137,7 +154,7 @@ __nis_findfastest (dir_binding * bind)
     for (j = 0; j < bind->server_val[i].ep.ep_len; ++j)
       if (strcmp (bind->server_val[i].ep.ep_val[j].family, "inet") == 0)
        if ((bind->server_val[i].ep.ep_val[j].proto == NULL) ||
-           (strcmp (bind->server_val[i].ep.ep_val[j].proto, "-") == 0) ||
+           (bind->server_val[i].ep.ep_val[j].proto[0] == '-') ||
            (bind->server_val[i].ep.ep_val[j].proto[0] == '\0'))
          {
            sin.sin_addr.s_addr =
@@ -228,4 +245,5 @@ __nis_findfastest (dir_binding * bind)
   free (pings);
 
   return found;
+#endif
 }
index bea4e272ce39562784735f425c94d92b2c0c5984..9f515bb46006bf1491f59e33af833514d6114942 100644 (file)
 
 __BEGIN_DECLS
 
-struct dir_binding
-{
-  CLIENT *clnt;                  /* RPC CLIENT handle */
-  nis_server *server_val;        /* List of servers */
-  u_int server_len;              /* # of servers */
-  u_int server_used;             /* Which server we are bind in the moment ? */
-  u_int current_ep;              /* Which endpoint of the server are in use? */
-  u_int trys;                    /* How many server have we tried ? */
-  u_int class;                   /* From which class is server_val ? */
-  bool_t master_only;            /* Is only binded to the master */
-  bool_t use_auth;               /* Do we use AUTH ? */
-  bool_t use_udp;                /* Do we use UDP ? */
-  struct sockaddr_in addr;       /* Server's IP address */
-  int socket;                    /* Server's local socket */
-};
-typedef struct dir_binding dir_binding;
-
-struct cache2_info
-{
-  long server_used;
-  long current_ep;
-  long class;
-};
-typedef struct cache2_info cache2_info;
-
 struct nis_cb
   {
     nis_server *serv;
@@ -66,8 +41,7 @@ extern long __nis_findfastest __P ((dir_binding *bind));
 extern nis_error __do_niscall2 __P ((const nis_server *serv, u_int serv_len,
                                     u_long prog, xdrproc_t xargs, caddr_t req,
                                     xdrproc_t xres, caddr_t resp,
-                                    u_long flags, nis_cb *cb,
-                                    cache2_info *cinfo));
+                                    u_long flags, nis_cb *cb));
 extern nis_error __do_niscall __P ((const_nis_name name, u_long prog,
                                    xdrproc_t xargs, caddr_t req,
                                    xdrproc_t xres, caddr_t resp,
@@ -81,13 +55,6 @@ extern struct nis_cb *__nis_create_callback
            const void *userdata, u_long flags));
 extern nis_error __nis_destroy_callback __P ((struct nis_cb *cb));
 
-#ifdef _LIBC
-/* NIS+ Cache functions */
-extern directory_obj *__nis_cache_search __P ((const_nis_name name,
-                                              u_long flags,
-                                              cache2_info *cinfo));
-#endif
-
 __END_DECLS
 
 #endif
index 6a2198ac2147eb2744dfcc28d62d9260e2862933..df16cceeac469d1fc07618d19120930eab682dfc 100644 (file)
 nis_result *
 nis_lookup (const_nis_name name, const u_long flags)
 {
-  nis_result *res;
+  nis_result *res = calloc (1, sizeof (nis_result));
   struct ns_request req;
   nis_name *names;
   nis_error status;
+  int link_first_try = 0;
   int count_links = 0;  /* We will follow only 16 links in the deep */
   int done = 0;
   int name_nr = 0;
   nis_name namebuf[2] = {NULL, NULL};
 
-  res = calloc (1, sizeof (nis_result));
   if (res == NULL)
     return NULL;
 
-  if (flags & EXPAND_NAME)
+  if ((flags & EXPAND_NAME) && (name[strlen (name) - 1] != '.'))
     {
       names = nis_getnames (name);
       if (names == NULL)
@@ -56,51 +56,141 @@ nis_lookup (const_nis_name name, const u_long flags)
   req.ns_name = names[0];
   while (!done)
     {
+      dir_binding bptr;
+      directory_obj *dir = NULL;
       req.ns_object.ns_object_len = 0;
       req.ns_object.ns_object_val = NULL;
-      memset (res, '\0', sizeof (nis_result));
 
-      status = __do_niscall (req.ns_name, NIS_LOOKUP,
-                            (xdrproc_t) _xdr_ns_request,
-                            (caddr_t) & req,
-                            (xdrproc_t) _xdr_nis_result,
-                            (caddr_t) res, flags, NULL);
+      status = __nisfind_server (req.ns_name, &dir);
       if (status != NIS_SUCCESS)
-       NIS_RES_STATUS (res) = status;
+       {
+         NIS_RES_STATUS (res) = status;
+         return res;
+       }
 
-      switch (NIS_RES_STATUS (res))
+      status = __nisbind_create (&bptr, dir->do_servers.do_servers_val,
+                                dir->do_servers.do_servers_len, flags);
+      if (status != NIS_SUCCESS)
        {
-       case NIS_PARTIAL:
-       case NIS_SUCCESS:
-       case NIS_S_SUCCESS:
-         if (__type_of(NIS_RES_OBJECT (res)) == NIS_LINK_OBJ &&
-             flags & FOLLOW_LINKS) /* We are following links */
+         NIS_RES_STATUS (res) = status;
+         nis_free_directory (dir);
+         return res;
+       }
+
+      while (__nisbind_connect (&bptr) != NIS_SUCCESS)
+       {
+         if (__nisbind_next (&bptr) != NIS_SUCCESS)
+           {
+             __nisbind_destroy (&bptr);
+             nis_free_directory (dir);
+             NIS_RES_STATUS (res) = NIS_NAMEUNREACHABLE;
+             return res;
+           }
+       }
+
+      do
+       {
+         static struct timeval RPCTIMEOUT = {10, 0};
+         enum clnt_stat result;
+
+       again:
+         result = clnt_call (bptr.clnt, NIS_LOOKUP,
+                             (xdrproc_t) _xdr_ns_request,
+                             (caddr_t) &req, (xdrproc_t) _xdr_nis_result,
+                             (caddr_t) res, RPCTIMEOUT);
+
+         if (result != RPC_SUCCESS)
+           status = NIS_RPCERROR;
+         else
            {
-             /* if we hit the link limit, bail */
-             if (count_links > NIS_MAXLINKS)
+             if (NIS_RES_STATUS (res) == NIS_SUCCESS)
                {
-                 NIS_RES_STATUS (res) = NIS_LINKNAMEERROR;
-                 ++done;
-                 break;
+                   if (__type_of(NIS_RES_OBJECT (res)) == NIS_LINK_OBJ &&
+                       flags & FOLLOW_LINKS) /* We are following links */
+                     {
+                       if (count_links)
+                         free (req.ns_name);
+                       /* if we hit the link limit, bail */
+                       if (count_links > NIS_MAXLINKS)
+                         {
+                           NIS_RES_STATUS (res) = NIS_LINKNAMEERROR;
+                           break;
+                         }
+                       ++count_links;
+                       req.ns_name =
+                         strdup (NIS_RES_OBJECT (res)->LI_data.li_name);
+                       nis_freeresult (res);
+                       res = calloc (1, sizeof (nis_result));
+                       if (res == NULL)
+                         {
+                           __nisbind_destroy (&bptr);
+                           nis_free_directory (dir);
+                           return NULL;
+                         }
+                       link_first_try = 1; /* Try at first the old binding */
+                       goto again;
+                     }
                }
-             if (count_links)
-               free (req.ns_name);
-             ++count_links;
-             req.ns_name = strdup (NIS_RES_OBJECT (res)->LI_data.li_name);
-             nis_freeresult (res);
-             res = calloc (1, sizeof (nis_result));
-             if (res == NULL)
-               return NULL;
+             else
+               if ((NIS_RES_STATUS (res) == NIS_SYSTEMERROR) ||
+                   (NIS_RES_STATUS (res) == NIS_NOSUCHNAME) ||
+                   (NIS_RES_STATUS (res) == NIS_NOT_ME))
+                 {
+                   if (link_first_try)
+                     {
+                       __nisbind_destroy (&bptr);
+                       nis_free_directory (dir);
+
+                       if (__nisfind_server (req.ns_name, &dir) != NIS_SUCCESS)
+                         return res;
+
+                       if (__nisbind_create (&bptr,
+                                             dir->do_servers.do_servers_val,
+                                             dir->do_servers.do_servers_len,
+                                             flags) != NIS_SUCCESS)
+                         {
+                           nis_free_directory (dir);
+                           return res;
+                         }
+                     }
+                   else
+                     if (__nisbind_next (&bptr) != NIS_SUCCESS)
+                       break; /* No more servers to search */
+
+                   while (__nisbind_connect (&bptr) != NIS_SUCCESS)
+                     {
+                       if (__nisbind_next (&bptr) != NIS_SUCCESS)
+                         {
+                           __nisbind_destroy (&bptr);
+                           nis_free_directory (dir);
+                           return res;
+                         }
+                     }
+                   goto again;
+                 }
+             break;
            }
-         else
-           ++done;
-         break;
-       case NIS_CBRESULTS:
-         /* The callback is handled in __do_niscall2 */
-         ++done;
-         break;
-       case NIS_UNAVAIL:
-         /* NIS+ is not installed, or all servers are down */
+         link_first_try = 0; /* Set it back */
+         status= NIS_SUCCESS;
+       }
+      while ((flags & HARD_LOOKUP) && status == NIS_RPCERROR);
+
+      __nisbind_destroy (&bptr);
+      nis_free_directory (dir);
+
+      if (status != NIS_SUCCESS)
+       {
+         NIS_RES_STATUS (res) = status;
+         return res;
+       }
+
+      switch (NIS_RES_STATUS (res))
+       {
+       case NIS_PARTIAL:
+       case NIS_SUCCESS:
+       case NIS_S_SUCCESS:
+       case NIS_LINKNAMEERROR: /* We follow to max links */
+       case NIS_UNAVAIL: /* NIS+ is not installed, or all servers are down */
          ++done;
          break;
        default:
index 71fc4ba877ba80d0c9db519216f48ab863ab521a..5d40daebc5966cf38f8c157941dc7cd655ed964b 100644 (file)
@@ -35,7 +35,7 @@ nis_mkdir (const_nis_name dir, const nis_server *server)
     res2 = __do_niscall2 (server, 1, NIS_MKDIR,
                          (xdrproc_t) _xdr_nis_name,
                          (caddr_t) &dir, (xdrproc_t) _xdr_nis_error,
-                         (caddr_t) &res, 0, NULL, NULL);
+                         (caddr_t) &res, 0, NULL);
   if (res2 != NIS_SUCCESS)
     return res2;
 
index 1becd4bf895dd906af170f5ca486450d0f81c678..3fc87551f5861c201f4de22773fcc1de3fd393ac 100644 (file)
@@ -62,7 +62,7 @@ nis_ping (const_nis_name dirname, u_long utime, const nis_object *dirobj)
     __do_niscall2 (&obj->DI_data.do_servers.do_servers_val[i], 1,
                   NIS_PING, (xdrproc_t) _xdr_ping_args,
                   (caddr_t) &args, (xdrproc_t) xdr_void,
-                  (caddr_t) NULL, 0, NULL, NULL);
+                  (caddr_t) NULL, 0, NULL);
   if (res)
     nis_freeresult (res);
 }
index 1f3e91874ce05a8870624958c77ce66af3e13819..0cd4458091a376999c9e9b78a94f9e66a27d2ec0 100644 (file)
@@ -33,7 +33,7 @@ nis_rmdir (const_nis_name dir, const nis_server *server)
   res2 = __do_niscall2 (server, 1, NIS_RMDIR,
                        (xdrproc_t) _xdr_nis_name,
                        (caddr_t) &dir, (xdrproc_t) _xdr_nis_error,
-                       (caddr_t) &res, 0, NULL, NULL);
+                       (caddr_t) &res, 0, NULL);
   if (res2 != NIS_SUCCESS)
     return res2;
 
index aa0f05eb392cb3affc236572c24ae8bbe0788aff..84cd5fb827efc389d52c46a5b931ba71207a3497 100644 (file)
@@ -41,7 +41,7 @@ nis_servstate (const nis_server *serv, const nis_tag *tags,
 
   if (__do_niscall2 (serv, 1, NIS_SERVSTATE, (xdrproc_t) _xdr_nis_taglist,
                     (caddr_t) &taglist, (xdrproc_t) _xdr_nis_taglist,
-                    (caddr_t) &tagres, 0, NULL, NULL) != RPC_SUCCESS)
+                    (caddr_t) &tagres, 0, NULL) != RPC_SUCCESS)
     return NIS_RPCERROR;
 
   *result = tagres.tags.tags_val;
@@ -67,7 +67,7 @@ nis_stats (const nis_server *serv, const nis_tag *tags,
 
   if (__do_niscall2 (serv, 1, NIS_STATUS, (xdrproc_t) _xdr_nis_taglist,
                     (caddr_t) &taglist, (xdrproc_t) _xdr_nis_taglist,
-                    (caddr_t) &tagres, 0, NULL, NULL) != RPC_SUCCESS)
+                    (caddr_t) &tagres, 0, NULL) != RPC_SUCCESS)
     return NIS_RPCERROR;
 
   *result = tagres.tags.tags_val;
index ed4b3740ddef1756741331c3a3e3992cde79d72a..e0885ca02478462e405fd88d9489c21f93b65959 100644 (file)
@@ -110,6 +110,40 @@ __create_ib_request (const_nis_name name, u_long flags)
   return ibreq;
 }
 
+static struct timeval RPCTIMEOUT = {10, 0};
+
+static char *
+__get_tablepath (char *name, dir_binding *bptr)
+{
+  enum clnt_stat result;
+  nis_result *res = calloc (1, sizeof (nis_result));
+  struct ns_request req;
+
+  if (res == NULL)
+    return NULL;
+
+  req.ns_name = name;
+  req.ns_object.ns_object_len = 0;
+  req.ns_object.ns_object_val = NULL;
+
+  result = clnt_call (bptr->clnt, NIS_LOOKUP, (xdrproc_t) _xdr_ns_request,
+                     (caddr_t) &req, (xdrproc_t) _xdr_nis_result,
+                     (caddr_t) res, RPCTIMEOUT);
+
+  if (result == RPC_SUCCESS && NIS_RES_STATUS (res) == NIS_SUCCESS &&
+      __type_of (NIS_RES_OBJECT (res)) == NIS_TABLE_OBJ)
+    {
+      char *cptr = strdup (NIS_RES_OBJECT (res)->TA_data.ta_path);
+      nis_freeresult (res);
+      return cptr;
+    }
+  else
+    {
+      nis_freeresult (res);
+      return strdup ("");
+    }
+}
+
 nis_result *
 nis_list (const_nis_name name, u_long flags,
          int (*callback) (const_nis_name name,
@@ -120,12 +154,16 @@ nis_list (const_nis_name name, u_long flags,
   nis_result *res = NULL;
   ib_request *ibreq;
   int status;
+  enum clnt_stat clnt_status;
   int count_links = 0;         /* We will only follow NIS_MAXLINKS links! */
   int done = 0;
   nis_name *names;
   nis_name namebuf[2] = {NULL, NULL};
   int name_nr = 0;
   nis_cb *cb = NULL;
+  char *tableptr, *tablepath = NULL;
+  int have_tablepath = 0;
+  int first_try = 0; /* Do we try the old binding at first ? */
 
   res = calloc (1, sizeof (nis_result));
   if (res == NULL)
@@ -164,189 +202,230 @@ nis_list (const_nis_name name, u_long flags,
 
   cb = NULL;
 
-  if (flags & FOLLOW_PATH || flags & ALL_RESULTS)
+  while (!done)
     {
-      nis_result *lres;
-      u_long newflags = flags & ~FOLLOW_PATH & ~ALL_RESULTS;
-      char table_path[NIS_MAXPATH + 3];
-      char *ntable, *p;
-      u_long done = 0, failures = 0;
-
-      while (names[name_nr] != NULL && !done)
-       {
-         lres = nis_lookup (names[name_nr], newflags | NO_AUTHINFO);
-         if (lres == NULL || NIS_RES_STATUS (lres) != NIS_SUCCESS)
-           {
-             NIS_RES_STATUS (res) = NIS_RES_STATUS (lres);
-             nis_freeresult (lres);
-             ++name_nr;
-             continue;
-           }
-
-         /* nis_lookup handles FOLLOW_LINKS,
-            so we must have a table object.*/
-         if (__type_of (NIS_RES_OBJECT (lres)) != NIS_TABLE_OBJ)
-           {
-             nis_freeresult (lres);
-             NIS_RES_STATUS (res) = NIS_INVALIDOBJ;
-             break;
-           }
+      dir_binding bptr;
+      directory_obj *dir = NULL;
 
-         /* Save the path, discard everything else.  */
-         p = __stpncpy (table_path, names[name_nr], NIS_MAXPATH);
-         *p++ = ':';
-         p = __stpncpy (p, NIS_RES_OBJECT (lres)->TA_data.ta_path,
-                        NIS_MAXPATH - (p - table_path));
-         *p = '\0';
-         nis_freeresult (lres);
-         free (res);
-         res = NULL;
+      memset (res, '\0', sizeof (nis_result));
 
-         p = table_path;
+      status = __nisfind_server (ibreq->ibr_name, &dir);
+      if (status != NIS_SUCCESS)
+        {
+          NIS_RES_STATUS (res) = status;
+          return res;
+        }
 
-         while (((ntable = strsep (&p, ":")) != NULL) && !done)
-           {
-             char *c;
+      status = __nisbind_create (&bptr, dir->do_servers.do_servers_val,
+                                 dir->do_servers.do_servers_len, flags);
+      if (status != NIS_SUCCESS)
+        {
+          NIS_RES_STATUS (res) = status;
+          nis_free_directory (dir);
+          return res;
+        }
 
-             if (res != NULL)
-               nis_freeresult (res);
+      while (__nisbind_connect (&bptr) != NIS_SUCCESS)
+       if (__nisbind_next (&bptr) != NIS_SUCCESS)
+         {
+           __nisbind_destroy (&bptr);
+           nis_free_directory (dir);
+           NIS_RES_STATUS (res) = NIS_NAMEUNREACHABLE;
+           return res;
+         }
 
-             /* Do the job recursive here!  */
-             if ((c = strchr(name, ']')) != NULL)
-               {
-                 /* Have indexed name ! */
-                 int index_len = c - name + 2;
-                 char buf[index_len + strlen (ntable) + 1];
-
-                 c = __stpncpy (buf, name, index_len);
-                 strcpy (c, ntable);
-                 res = nis_list (buf, newflags, callback,userdata);
-               }
-             else
-               res = nis_list (ntable, newflags, callback, userdata);
-             if (res == NULL)
-               return NULL;
-             switch (NIS_RES_STATUS (res))
-               {
-               case NIS_SUCCESS:
-               case NIS_CBRESULTS:
-                 if (!(flags & ALL_RESULTS))
-                   done = 1;
-                 break;
-               case NIS_PARTIAL: /* The table is correct, we doesn't found
-                                    the entry */
-                 break;
-               default:
-                 if (flags & ALL_RESULTS)
-                   ++failures;
-                 else
-                   done = 1;
-                 break;
-               }
-           }
-         if (NIS_RES_STATUS (res) == NIS_SUCCESS && failures)
-           NIS_RES_STATUS (res) = NIS_S_SUCCESS;
-         if (NIS_RES_STATUS (res) == NIS_NOTFOUND && failures)
-           NIS_RES_STATUS (res) = NIS_S_NOTFOUND;
-         break;
-       }
-    }
-  else
-    {
       if (callback != NULL)
        {
          cb = __nis_create_callback (callback, userdata, flags);
          ibreq->ibr_cbhost.ibr_cbhost_len = 1;
          ibreq->ibr_cbhost.ibr_cbhost_val = cb->serv;
-         }
-
-      while (!done)
-       {
-         memset (res, '\0', sizeof (nis_result));
-
-         status = __do_niscall (ibreq->ibr_name, NIS_IBLIST,
-                                (xdrproc_t) _xdr_ib_request,
-                                (caddr_t) ibreq, (xdrproc_t) _xdr_nis_result,
-                                (caddr_t) res, flags, cb);
-         if (status != NIS_SUCCESS)
-           NIS_RES_STATUS (res) = status;
+       }
 
-         switch (NIS_RES_STATUS (res))
-           {
-           case NIS_PARTIAL:
-           case NIS_SUCCESS:
-           case NIS_S_SUCCESS:
-             if (__type_of (NIS_RES_OBJECT (res)) == NIS_LINK_OBJ &&
-                 flags & FOLLOW_LINKS)         /* We are following links.  */
-               {
-                 /* If we hit the link limit, bail.  */
-                 if (count_links > NIS_MAXLINKS)
+    again:
+      clnt_status = clnt_call (bptr.clnt, NIS_IBLIST,
+                              (xdrproc_t) _xdr_ib_request, (caddr_t) ibreq,
+                              (xdrproc_t) _xdr_nis_result,
+                              (caddr_t) res, RPCTIMEOUT);
+
+      if (clnt_status != RPC_SUCCESS)
+       NIS_RES_STATUS (res) = NIS_RPCERROR;
+      else
+       switch (NIS_RES_STATUS (res))
+         { /* start switch */
+         case NIS_PARTIAL:
+         case NIS_SUCCESS:
+         case NIS_S_SUCCESS:
+           if (__type_of (NIS_RES_OBJECT (res)) == NIS_LINK_OBJ &&
+               flags & FOLLOW_LINKS)           /* We are following links.  */
+             {
+               free (ibreq->ibr_name);
+               /* If we hit the link limit, bail.  */
+               if (count_links > NIS_MAXLINKS)
+                 {
+                   NIS_RES_STATUS (res) = NIS_LINKNAMEERROR;
+                   ++done;
+                   break;
+                 }
+               ++count_links;
+               ibreq->ibr_name =
+                 strdup (NIS_RES_OBJECT (res)->LI_data.li_name);
+               if (NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_len)
+                 if (ibreq->ibr_srch.ibr_srch_len == 0)
                    {
-                     NIS_RES_STATUS (res) = NIS_LINKNAMEERROR;
-                     ++done;
-                     break;
+                     ibreq->ibr_srch.ibr_srch_len =
+                       NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_len;
+                     ibreq->ibr_srch.ibr_srch_val =
+                       NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_val;
                    }
-                 if (count_links)
-                   free (ibreq->ibr_name);
-                 ++count_links;
-                 free (ibreq->ibr_name);
-                 ibreq->ibr_name =
-                   strdup (NIS_RES_OBJECT (res)->LI_data.li_name);
-                 if (NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_len)
-                   if (ibreq->ibr_srch.ibr_srch_len == 0)
+               nis_freeresult (res);
+               res = calloc (1, sizeof (nis_result));
+               if (res == NULL)
+                 {
+                   if (have_tablepath)
+                     free (tablepath);
+                   __nisbind_destroy (&bptr);
+                   nis_free_directory (dir);
+                   return NULL;
+                 }
+               first_try = 1; /* Try at first the old binding */
+               goto again;
+             }
+           else if ((flags & FOLLOW_PATH) &&
+                    NIS_RES_STATUS (res) == NIS_PARTIAL)
+             {
+               if (!have_tablepath)
+                 {
+                   tablepath = __get_tablepath (ibreq->ibr_name, &bptr);
+                   tableptr = tablepath;
+                   have_tablepath = 1;
+                 }
+               if (tableptr == NULL)
+                 {
+                   ++done;
+                   break;
+                 }
+               free (ibreq->ibr_name);
+               ibreq->ibr_name = strsep (&tableptr, ":");
+               if (ibreq->ibr_name == NULL || ibreq->ibr_name[0] == '\0')
+                 {
+                   ibreq->ibr_name = strdup ("");
+                   ++done;
+                 }
+               else
+                 {
+                   ibreq->ibr_name = strdup (ibreq->ibr_name);
+                   nis_freeresult (res);
+                   res = calloc (1, sizeof (nis_result));
+                   if (res == NULL)
                      {
-                       ibreq->ibr_srch.ibr_srch_len =
-                         NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_len;
-                       ibreq->ibr_srch.ibr_srch_val =
-                         NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_val;
+                       if (have_tablepath)
+                         free (tablepath);
+                       __nisbind_destroy (&bptr);
+                       nis_free_directory (dir);
+                       return NULL;
                      }
-                 nis_freeresult (res);
-                 res = calloc (1, sizeof (nis_result));
-               }
-             else
-               ++done;
-             break;
-           case NIS_CBRESULTS:
-             /* Calback is handled in nis_call.c (__do_niscall2),
-                but we have to change the error code */
-             NIS_RES_STATUS (res) = cb->result;
+                   first_try = 1;
+                   goto again;
+                 }
+             }
+           else
              ++done;
-             break;
-           case NIS_UNAVAIL:
-             /* NIS+ is not installed, or all servers are down.  */
-             ++done;
-             break;
-           default:
-             /* Try the next domainname if we don't follow a link.  */
-             if (count_links)
-               {
-                 free (ibreq->ibr_name);
-                 NIS_RES_STATUS (res) = NIS_LINKNAMEERROR;
-                 ++done;
-                 break;
-               }
-             ++name_nr;
-             if (names[name_nr] == NULL)
-               {
+           break;
+         case NIS_CBRESULTS:
+           if (cb != NULL)
+             {
+               __nis_do_callback (&bptr, &res->cookie, cb);
+               NIS_RES_STATUS (res) = cb->result;
+
+               if (!(flags & ALL_RESULTS))
                  ++done;
-                 break;
-               }
-             ibreq->ibr_name = names[name_nr];
-             break;
-           }
+               else
+                 {
+                   if (!have_tablepath)
+                     {
+                       tablepath = __get_tablepath (ibreq->ibr_name, &bptr);
+                       tableptr = tablepath;
+                       have_tablepath = 1;
+                     }
+                   if (tableptr == NULL)
+                     {
+                       ++done;
+                       break;
+                     }
+                   free (ibreq->ibr_name);
+                   ibreq->ibr_name = strsep (&tableptr, ":");
+                   if (ibreq->ibr_name == NULL || ibreq->ibr_name[0] == '\0')
+                     {
+                       ibreq->ibr_name = strdup ("");
+                       ++done;
+                     }
+                   else
+                     ibreq->ibr_name = strdup (ibreq->ibr_name);
+                 }
+             }
+           break;
+         case NIS_SYSTEMERROR:
+         case NIS_NOSUCHNAME:
+         case NIS_NOT_ME:
+           /* If we had first tried the old binding, do nothing, but
+              get a new binding */
+           if (!first_try)
+             {
+               if (__nisbind_next (&bptr) != NIS_SUCCESS)
+                 {
+                   ++done;
+                   break; /* No more servers to search */
+                 }
+               while (__nisbind_connect (&bptr) != NIS_SUCCESS)
+                 {
+                   if (__nisbind_next (&bptr) != NIS_SUCCESS)
+                     {
+                       ++done;
+                       break; /* No more servers to search */
+                     }
+                 }
+               goto again;
+             }
+           break;
+         default:
+           if (!first_try)
+             {
+               /* Try the next domainname if we don't follow a link.  */
+               if (count_links)
+                 {
+                   free (ibreq->ibr_name);
+                   NIS_RES_STATUS (res) = NIS_LINKNAMEERROR;
+                   ++done;
+                   break;
+                 }
+               ++name_nr;
+               if (names[name_nr] == NULL)
+                 {
+                   ++done;
+                   break;
+                 }
+               ibreq->ibr_name = names[name_nr];
+               first_try = 1; /* Try old binding at first */
+               goto again;
+             }
+           break;
+         }
+      first_try = 0;
+
+      if (cb)
+       {
+         __nis_destroy_callback (cb);
+         ibreq->ibr_cbhost.ibr_cbhost_len = 0;
+         ibreq->ibr_cbhost.ibr_cbhost_val = NULL;
        }
-    }                          /* End of not FOLLOW_PATH.  */
+
+      __nisbind_destroy (&bptr);
+      nis_free_directory (dir);
+    }
 
   if (names != namebuf)
     nis_freenames (names);
 
-  if (cb)
-    {
-      __nis_destroy_callback (cb);
-      ibreq->ibr_cbhost.ibr_cbhost_len = 0;
-      ibreq->ibr_cbhost.ibr_cbhost_val = NULL;
-    }
-
   nis_free_request (ibreq);
 
   return res;
index 656b1a48c1d2a295f97e747facae24ddc2cbea30..2b351e73397039ed9d6eb3f52e0c086c5cc6d608 100644 (file)
@@ -38,7 +38,7 @@ __nis_finddirectory (directory_obj *dir, const_nis_name name)
                          dir->do_servers.do_servers_len,
                          NIS_FINDDIRECTORY, (xdrproc_t) _xdr_fd_args,
                          (caddr_t) &fd_args, (xdrproc_t) _xdr_fd_result,
-                         (caddr_t) fd_res, NO_AUTHINFO|USE_DGRAM, NULL, NULL);
+                         (caddr_t) fd_res, NO_AUTHINFO|USE_DGRAM, NULL);
   if (status != NIS_SUCCESS)
     fd_res->status = status;
 
index 016bedc769c1c9644a600f4c13b0f6c070540d57..60bf8923d8831e05d686dde03921bf437b491359 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
 
@@ -247,6 +247,35 @@ extern u_long __nis_hash __P ((const void *keyarg, register size_t len));
 extern int __nis_lock_cache __P ((void));
 extern int __nis_unlock_cache __P ((void));
 
+/* (XXX INTERNAL FUNCTIONS, ONLY FOR rpc.nisd AND glibc !!) */
+#if defined (NIS_INTERNAL) || defined (_LIBC)
+
+struct dir_binding
+{
+  CLIENT *clnt;                  /* RPC CLIENT handle */
+  nis_server *server_val;        /* List of servers */
+  u_int server_len;              /* # of servers */
+  u_int server_used;             /* Which server we are bind in the moment ? */
+  u_int current_ep;              /* Which endpoint of the server are in use? */
+  u_int trys;                    /* How many server have we tried ? */
+  u_int class;                   /* From which class is server_val ? */
+  bool_t master_only;            /* Is only binded to the master */
+  bool_t use_auth;               /* Do we use AUTH ? */
+  bool_t use_udp;                /* Do we use UDP ? */
+  struct sockaddr_in addr;       /* Server's IP address */
+  int socket;                    /* Server's local socket */
+};
+typedef struct dir_binding dir_binding;
+
+extern nis_error __nisbind_create __P ((dir_binding *, const nis_server *,
+                                       u_int, u_long));
+extern nis_error __nisbind_connect __P ((dir_binding *));
+extern nis_error __nisbind_next __P ((dir_binding *));
+extern void __nisbind_destroy __P ((dir_binding *));
+extern nis_error __nisfind_server __P ((const_nis_name, directory_obj **));
+
+#endif
+
 __END_DECLS
 
 #endif /* __RPCSVC_NISLIB_H__ */
index 582a6cf8f09c330bc633dc32b56f6392f1d256d3..4cf397d2011af17c87a65f41ebfa3e055ca7a2d9 100644 (file)
@@ -427,8 +427,9 @@ gr_send_answer (int conn, struct group *grp)
   struct iovec *vec;
   size_t *len;
   gr_response_header resp;
-  size_t total_len;
+  size_t total_len, sum;
   int nblocks;
+  size_t maxiov;
 
   resp.version = NSCD_VERSION;
   if (grp != NULL)
@@ -501,16 +502,21 @@ gr_send_answer (int conn, struct group *grp)
        }
     }
 
+#ifdef UIO_MAXIOV
+  maxiov = UIO_MAXIOV;
+#else
+  maxiov = sysconf (_SC_UIO_MAXIOV);
+#endif
+
   /* Send all the data.  */
-  while (nblocks > UIO_MAXIOV)
+  sum = 0;
+  while (nblocks > maxiov)
     {
-      if (writev (sock[conn], vec, UIO_MAXIOV) != total_len)
-       dbg_log (_("write incomplete on send group answer: %s"),
-                strerror (errno));
-      vec += UIO_MAXIOV;
-      nblocks -= UIO_MAXIOV;
+      sum += writev (sock[conn], vec, maxiov);
+      vec += maxiov;
+      nblocks -= maxiov;
     }
-  if (writev (sock[conn], vec, nblocks) != total_len)
+  if (sum + writev (sock[conn], vec, nblocks) != total_len)
     dbg_log (_("write incomplete on send group answer: %s"),
             strerror (errno));
 }
index 85ebb0dc60959ae560c2615b2ddadec24847c024..ec4f5a12973c2095a5f56c92ae99fa8ed0a1ce58 100644 (file)
@@ -99,6 +99,8 @@ __nscd_getgr_r (const char *key, request_type type, struct group *resultbuf,
   request_header req;
   gr_response_header gr_resp;
   ssize_t nbytes;
+  size_t maxiov;
+  size_t sum;
 
   if (sock == -1)
     {
@@ -232,18 +234,21 @@ __nscd_getgr_r (const char *key, request_type type, struct group *resultbuf,
              *p++ = '\0';
            }
 
-         while (i > UIO_MAXIOV)
+#ifdef UIO_MAXIOV
+         maxiov = UIO_MAXIOV;
+#else
+         maxiov = sysconf (_SC_UIO_MAXIOV);
+#endif
+
+         sum = 0;
+         while (i > maxiov)
            {
-             if (__readv (sock, vec, UIO_MAXIOV) != total_len)
-               {
-                 __close (sock);
-                 return -1;
-               }
-             vec += UIO_MAXIOV;
-             i -= UIO_MAXIOV;
+             sum += __readv (sock, vec, maxiov);
+             vec += maxiov;
+             i -= maxiov;
            }
 
-         if (__readv (sock, vec, i) != total_len)
+         if (sum + __readv (sock, vec, i) != total_len)
            {
              __close (sock);
              return -1;
index 919c584b59db502a005eaebb30c613efff55fe58..ba41fc489647e148f4594e075e0084c9d40bc4bf 100755 (executable)
@@ -267,6 +267,15 @@ cat <<"EOF" | cmp - $testout || result=1
 `file1'
 EOF
 
+# Test NOCHECK with non-existing file in subdir.
+${elf_objpfx}${rtld_installed_name} --library-path ${library_path} \
+${common_objpfx}posix/globtest -c "$testdir" "*/blahblah" |
+sort > $testout
+cat <<"EOF" | cmp - $testout || result=1
+`dir1/blahblah'
+`dir2/blahblah'
+EOF
+
 if test $result -eq 0; then
     rm -fr $testdir $testout
 fi
index 036b3b4dfe04106e36a0178df6cf643b51ce7364..61468ebdd33c1dafed0e5a6448b431f7ee670ec7 100644 (file)
@@ -19,8 +19,9 @@
 
 #include <ctype.h>
 #include <printf.h>
-#include <string.h>
+#include <stdint.h>
 #include <stddef.h>
+#include <string.h>
 
 #define NDEBUG 1
 #include <assert.h>
@@ -271,7 +272,8 @@ parse_one_spec (const UCHAR_T *format, size_t posn, struct printf_spec *spec,
   spec->info.is_char = 0;
 
   if (*format == L_('h') || *format == L_('l') || *format == L_('L') ||
-      *format == L_('Z') || *format == L_('q'))
+      *format == L_('Z') || *format == L_('q') || *format == L_('z') ||
+      *format == L_('t') || *format == L_('j'))
     switch (*format++)
       {
       case L_('h'):
@@ -297,11 +299,24 @@ parse_one_spec (const UCHAR_T *format, size_t posn, struct printf_spec *spec,
        /* 4.4 uses this for long long.  */
        spec->info.is_long_double = 1;
        break;
+      case L_('z'):
       case L_('Z'):
        /* int's are size_t's.  */
-       assert (sizeof(size_t) <= sizeof(unsigned long long int));
-       spec->info.is_longlong = sizeof(size_t) > sizeof(unsigned long int);
-       spec->info.is_long = sizeof(size_t) > sizeof(unsigned int);
+       assert (sizeof (size_t) <= sizeof (unsigned long long int));
+       spec->info.is_longlong = sizeof (size_t) > sizeof (unsigned long int);
+       spec->info.is_long = sizeof (size_t) > sizeof (unsigned int);
+       break;
+      case L_('t'):
+       assert (sizeof (ptrdiff_t) <= sizeof (unsigned long long int));
+       spec->info.is_longlong = (sizeof (ptrdiff_t)
+                                 > sizeof (unsigned long int));
+       spec->info.is_long = sizeof (ptrdiff_t) > sizeof (unsigned int);
+       break;
+      case L_('j'):
+       assert (sizeof (intmax_t) <= sizeof (unsigned long long int));
+       spec->info.is_longlong = (sizeof (intmax_t)
+                                 > sizeof (unsigned long int));
+       spec->info.is_long = sizeof (intmax_t) > sizeof (unsigned int);
        break;
       }
 
index a40acb75d4c1fd55f3b1dc3e8b18699bc9a844dd..a3281c2e0ea0f026fcce6a3832cc94da78ee2db6 100644 (file)
@@ -20,6 +20,7 @@
 #include <limits.h>
 #include <printf.h>
 #include <stdarg.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <wchar.h>
@@ -250,14 +251,14 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
               0,            0,            0,            0,
               0, /* 'a' */ 26,            0, /* 'c' */ 20,
     /* 'd' */ 15, /* 'e' */ 19, /* 'f' */ 19, /* 'g' */ 19,
-    /* 'h' */ 10, /* 'i' */ 15,            0,            0,
+    /* 'h' */ 10, /* 'i' */ 15, /* 'j' */ 28,            0,
     /* 'l' */ 11, /* 'm' */ 24, /* 'n' */ 23, /* 'o' */ 17,
     /* 'p' */ 22, /* 'q' */ 12,            0, /* 's' */ 21,
-              0, /* 'u' */ 16,            0,            0,
-    /* 'x' */ 18
+    /* 't' */ 27, /* 'u' */ 16,            0,            0,
+    /* 'x' */ 18,            0, /* 'z' */ 13
   };
 
-#define NOT_IN_JUMP_RANGE(Ch) ((Ch) < ' ' || (Ch) > 'x')
+#define NOT_IN_JUMP_RANGE(Ch) ((Ch) < ' ' || (Ch) > 'z')
 #define CHAR_CLASS(Ch) (jump_table[(int) (Ch) - ' '])
 #define JUMP(ChExpr, table)                                                  \
       do                                                                     \
@@ -272,7 +273,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
 
 #define STEP0_3_TABLE                                                        \
     /* Step 0: at the beginning.  */                                         \
-    static const void *step0_jumps[27] =                                     \
+    static const void *step0_jumps[29] =                                     \
     {                                                                        \
       REF (form_unknown),                                                    \
       REF (flag_space),                /* for ' ' */                                 \
@@ -287,7 +288,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
       REF (mod_half),          /* for 'h' */                                 \
       REF (mod_long),          /* for 'l' */                                 \
       REF (mod_longlong),      /* for 'L', 'q' */                            \
-      REF (mod_size_t),                /* for 'Z' */                                 \
+      REF (mod_size_t),                /* for 'z', 'Z' */                            \
       REF (form_percent),      /* for '%' */                                 \
       REF (form_integer),      /* for 'd', 'i' */                            \
       REF (form_unsigned),     /* for 'u' */                                 \
@@ -300,10 +301,12 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
       REF (form_number),       /* for 'n' */                                 \
       REF (form_strerror),     /* for 'm' */                                 \
       REF (form_wcharacter),   /* for 'C' */                                 \
-      REF (form_floathex)      /* for 'A', 'a' */                            \
+      REF (form_floathex),     /* for 'A', 'a' */                            \
+      REF (mod_ptrdiff_t),      /* for 't' */                                \
+      REF (mod_intmax_t),       /* for 'j' */                                \
     };                                                                       \
     /* Step 1: after processing width.  */                                   \
-    static const void *step1_jumps[27] =                                     \
+    static const void *step1_jumps[29] =                                     \
     {                                                                        \
       REF (form_unknown),                                                    \
       REF (form_unknown),      /* for ' ' */                                 \
@@ -318,7 +321,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
       REF (mod_half),          /* for 'h' */                                 \
       REF (mod_long),          /* for 'l' */                                 \
       REF (mod_longlong),      /* for 'L', 'q' */                            \
-      REF (mod_size_t),                /* for 'Z' */                                 \
+      REF (mod_size_t),                /* for 'z', 'Z' */                            \
       REF (form_percent),      /* for '%' */                                 \
       REF (form_integer),      /* for 'd', 'i' */                            \
       REF (form_unsigned),     /* for 'u' */                                 \
@@ -331,10 +334,12 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
       REF (form_number),       /* for 'n' */                                 \
       REF (form_strerror),     /* for 'm' */                                 \
       REF (form_wcharacter),   /* for 'C' */                                 \
-      REF (form_floathex)      /* for 'A', 'a' */                            \
+      REF (form_floathex),     /* for 'A', 'a' */                            \
+      REF (mod_ptrdiff_t),      /* for 't' */                                \
+      REF (mod_intmax_t)        /* for 'j' */                                \
     };                                                                       \
     /* Step 2: after processing precision.  */                               \
-    static const void *step2_jumps[27] =                                     \
+    static const void *step2_jumps[29] =                                     \
     {                                                                        \
       REF (form_unknown),                                                    \
       REF (form_unknown),      /* for ' ' */                                 \
@@ -349,7 +354,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
       REF (mod_half),          /* for 'h' */                                 \
       REF (mod_long),          /* for 'l' */                                 \
       REF (mod_longlong),      /* for 'L', 'q' */                            \
-      REF (mod_size_t),                /* for 'Z' */                                 \
+      REF (mod_size_t),                /* for 'z', 'Z' */                            \
       REF (form_percent),      /* for '%' */                                 \
       REF (form_integer),      /* for 'd', 'i' */                            \
       REF (form_unsigned),     /* for 'u' */                                 \
@@ -362,10 +367,12 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
       REF (form_number),       /* for 'n' */                                 \
       REF (form_strerror),     /* for 'm' */                                 \
       REF (form_wcharacter),   /* for 'C' */                                 \
-      REF (form_floathex)      /* for 'A', 'a' */                            \
+      REF (form_floathex),     /* for 'A', 'a' */                            \
+      REF (mod_ptrdiff_t),      /* for 't' */                                \
+      REF (mod_intmax_t)        /* for 'j' */                                \
     };                                                                       \
     /* Step 3a: after processing first 'h' modifier.  */                     \
-    static const void *step3a_jumps[27] =                                    \
+    static const void *step3a_jumps[29] =                                    \
     {                                                                        \
       REF (form_unknown),                                                    \
       REF (form_unknown),      /* for ' ' */                                 \
@@ -380,7 +387,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
       REF (mod_halfhalf),      /* for 'h' */                                 \
       REF (form_unknown),      /* for 'l' */                                 \
       REF (form_unknown),      /* for 'L', 'q' */                            \
-      REF (form_unknown),      /* for 'Z' */                                 \
+      REF (form_unknown),      /* for 'z', 'Z' */                            \
       REF (form_percent),      /* for '%' */                                 \
       REF (form_integer),      /* for 'd', 'i' */                            \
       REF (form_unsigned),     /* for 'u' */                                 \
@@ -393,10 +400,12 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
       REF (form_number),       /* for 'n' */                                 \
       REF (form_unknown),      /* for 'm' */                                 \
       REF (form_unknown),      /* for 'C' */                                 \
-      REF (form_unknown)       /* for 'A', 'a' */                            \
+      REF (form_unknown),      /* for 'A', 'a' */                            \
+      REF (form_unknown),       /* for 't' */                                \
+      REF (form_unknown)        /* for 'j' */                                \
     };                                                                       \
     /* Step 3b: after processing first 'l' modifier.  */                     \
-    static const void *step3b_jumps[27] =                                    \
+    static const void *step3b_jumps[29] =                                    \
     {                                                                        \
       REF (form_unknown),                                                    \
       REF (form_unknown),      /* for ' ' */                                 \
@@ -411,7 +420,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
       REF (form_unknown),      /* for 'h' */                                 \
       REF (mod_longlong),      /* for 'l' */                                 \
       REF (form_unknown),      /* for 'L', 'q' */                            \
-      REF (form_unknown),      /* for 'Z' */                                 \
+      REF (form_unknown),      /* for 'z', 'Z' */                            \
       REF (form_percent),      /* for '%' */                                 \
       REF (form_integer),      /* for 'd', 'i' */                            \
       REF (form_unsigned),     /* for 'u' */                                 \
@@ -424,12 +433,14 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
       REF (form_number),       /* for 'n' */                                 \
       REF (form_strerror),     /* for 'm' */                                 \
       REF (form_wcharacter),   /* for 'C' */                                 \
-      REF (form_floathex)      /* for 'A', 'a' */                            \
+      REF (form_floathex),     /* for 'A', 'a' */                            \
+      REF (form_unknown),       /* for 't' */                                \
+      REF (form_unknown)        /* for 'j' */                                \
     }
 
 #define STEP4_TABLE                                                          \
     /* Step 4: processing format specifier.  */                                      \
-    static const void *step4_jumps[27] =                                     \
+    static const void *step4_jumps[29] =                                     \
     {                                                                        \
       REF (form_unknown),                                                    \
       REF (form_unknown),      /* for ' ' */                                 \
@@ -444,7 +455,7 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
       REF (form_unknown),      /* for 'h' */                                 \
       REF (form_unknown),      /* for 'l' */                                 \
       REF (form_unknown),      /* for 'L', 'q' */                            \
-      REF (form_unknown),      /* for 'Z' */                                 \
+      REF (form_unknown),      /* for 'z', 'Z' */                            \
       REF (form_percent),      /* for '%' */                                 \
       REF (form_integer),      /* for 'd', 'i' */                            \
       REF (form_unsigned),     /* for 'u' */                                 \
@@ -457,7 +468,9 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
       REF (form_number),       /* for 'n' */                                 \
       REF (form_strerror),     /* for 'm' */                                 \
       REF (form_wcharacter),   /* for 'C' */                                 \
-      REF (form_floathex)      /* for 'A', 'a' */                            \
+      REF (form_floathex),     /* for 'A', 'a' */                            \
+      REF (form_unknown),       /* for 't' */                                \
+      REF (form_unknown)        /* for 'j' */                                \
     }
 
 
@@ -1178,6 +1191,16 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap)
       is_long = sizeof (size_t) > sizeof (unsigned int);
       JUMP (*++f, step4_jumps);
 
+    LABEL (mod_ptrdiff_t):
+      is_longlong = sizeof (ptrdiff_t) > sizeof (unsigned long int);
+      is_long = sizeof (ptrdiff_t) > sizeof (unsigned int);
+      JUMP (*++f, step4_jumps);
+
+    LABEL (mod_intmax_t):
+      is_longlong = sizeof (intmax_t) > sizeof (unsigned long int);
+      is_long = sizeof (intmax_t) > sizeof (unsigned int);
+      JUMP (*++f, step4_jumps);
+
       /* Process current format.  */
       while (1)
        {
index bd167b9a5bc83ea1296f10476806ed56aa144d7e..ce5e5125f701c0084a46734289da4dd4ca78746c 100644 (file)
@@ -21,6 +21,7 @@
 #include <ctype.h>
 #include <stdarg.h>
 #include <stdio.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 #include <wctype.h>
@@ -407,7 +408,8 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
        width = -1;
 
       /* Check for type modifiers.  */
-      while (*f == 'h' || *f == 'l' || *f == 'L' || *f == 'a' || *f == 'q')
+      while (*f == 'h' || *f == 'l' || *f == 'L' || *f == 'a' || *f == 'q'
+            || *f == 'z' || *f == 't' || *f == 'j')
        switch (*f++)
          {
          case 'h':
@@ -459,6 +461,30 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
               arg and fill it in with a malloc'd pointer.  */
            flags |= MALLOC;
            break;
+         case 'z':
+           if (flags & (SHORT|LONGDBL|CHAR))
+             conv_error ();
+           if (sizeof (size_t) > sizeof (unsigned long int))
+             flags |= LONGDBL;
+           else if (sizeof (size_t) > sizeof (unsigned int))
+             flags |= LONG;
+           break;
+         case 'j':
+           if (flags & (SHORT|LONGDBL|CHAR))
+             conv_error ();
+           if (sizeof (intmax_t) > sizeof (unsigned long int))
+             flags |= LONGDBL;
+           else if (sizeof (intmax_t) > sizeof (unsigned int))
+             flags |= LONG;
+           break;
+         case 't':
+           if (flags & (SHORT|LONGDBL|CHAR))
+             conv_error ();
+           if (sizeof (ptrdiff_t) > sizeof (unsigned long int))
+             flags |= LONGDBL;
+           else if (sizeof (ptrdiff_t) > sizeof (unsigned int))
+             flags |= LONG;
+           break;
          }
 
       /* End of the format string?  */
index 8db108c2debd27db5ec249257729786ecc96b8b0..2a750d7dc23cbda8a1669d9a0e0796d0d01b8459 100644 (file)
@@ -147,7 +147,7 @@ extern int errno;
 #  define LONG_MAX ((long int) (ULONG_MAX >> 1))
 # endif
 # define STRTOL_LONG_MIN LONG_MIN
-# define STRTOL_LONG_MAX ULONG_MAX
+# define STRTOL_LONG_MAX LONG_MAX
 # define STRTOL_ULONG_MAX ULONG_MAX
 #endif
 
index 2ab2577f088cb41ec6189ef170704b19c4270e84..2dac9937f37d266a664e5d3d08448eb678237570 100644 (file)
@@ -66,7 +66,8 @@ routines := auth_none auth_unix authuxprot bindrsvprt \
            svc_tcp svc_udp xdr xdr_array xdr_float xdr_mem \
            xdr_rec xdr_ref xdr_stdio publickey xdr_sizeof \
            auth_des authdes_prot des_crypt des_impl des_soft \
-           key_call key_prot netname openchild rtime svcauth_des xcrypt
+           key_call key_prot netname openchild rtime svcauth_des xcrypt\
+           clnt_unix svc_unix
 
 others := rpcinfo
 install-bin := rpcgen
index d956486f9f8bac07bd5e2525106550bcf235d87f..98dfbbc79f7527d705732f803370751c996e1e16 100644 (file)
@@ -59,7 +59,7 @@ libc {
     authdes_create; authdes_getucred; authdes_pk_create;
 
     # c*
-    cbc_crypt;
+    cbc_crypt; clntunix_create;
 
     # d*
     des_setparity;
@@ -87,6 +87,9 @@ libc {
     # r*
     rtime;
 
+    # s*
+    svcunix_create; svcunixfd_create;
+
     # u*
     user2netname;
 
index b1b35ca50a7283e980b018ef791621f1d7849fa0..f62618bdaccd06f1fdad40f736a974d0c388423b 100644 (file)
@@ -57,11 +57,27 @@ clnt_create (const char *hostname, u_long prog, u_long vers,
   size_t prtbuflen;
   char *prttmpbuf;
   struct sockaddr_in sin;
+  struct sockaddr_un sun;
   int sock;
   struct timeval tv;
   CLIENT *client;
   int herr;
 
+  if (strcmp (proto, "unix") == 0)
+    {
+      __bzero ((char *)&sun, sizeof (sun));
+      sun.sun_family = AF_UNIX;
+      strcpy (sun.sun_path, hostname);
+      sock = RPC_ANYSOCK;
+      client = clntunix_create (&sun, prog, vers, &sock, 0, 0);
+      if (client == NULL)
+       return NULL;
+      tv.tv_sec = 25;
+      tv.tv_usec = 0;
+      clnt_control (client, CLSET_TIMEOUT, (char *)&tv);
+      return client;
+    }
+
   hstbuflen = 1024;
   hsttmpbuf = __alloca (hstbuflen);
   while (__gethostbyname_r (hostname, &hostbuf, hsttmpbuf, hstbuflen,
diff --git a/sunrpc/clnt_unix.c b/sunrpc/clnt_unix.c
new file mode 100644 (file)
index 0000000..848b752
--- /dev/null
@@ -0,0 +1,573 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * clnt_unix.c, Implements a TCP/IP based, client side RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * TCP based RPC supports 'batched calls'.
+ * A sequence of calls may be batched-up in a send buffer.  The rpc call
+ * return immediately to the client even though the call was not necessarily
+ * sent.  The batching occurs if the results' xdr routine is NULL (0) AND
+ * the rpc timeout value is zero (see clnt.h, rpc).
+ *
+ * Clients should NOT casually batch calls that in fact return results; that is,
+ * the server side should be aware that a call is batched and not produce any
+ * return message.  Batched calls that produce many result messages can
+ * deadlock (netlock) the client and the server....
+ *
+ * Now go hang yourself.
+ */
+
+#include <netdb.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <sys/uio.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <rpc/pmap_clnt.h>
+
+#define MCALL_MSG_SIZE 24
+
+struct ct_data
+  {
+    int ct_sock;
+    bool_t ct_closeit;
+    struct timeval ct_wait;
+    bool_t ct_waitset;         /* wait set by clnt_control? */
+    struct sockaddr_un ct_addr;
+    struct rpc_err ct_error;
+    char ct_mcall[MCALL_MSG_SIZE];     /* marshalled callmsg */
+    u_int ct_mpos;             /* pos after marshal */
+    XDR ct_xdrs;
+  };
+
+static int readunix (char *, char *, int);
+static int writeunix (char *, char *, int);
+
+static enum clnt_stat clntunix_call (CLIENT *, u_long, xdrproc_t, caddr_t,
+                                   xdrproc_t, caddr_t, struct timeval);
+static void clntunix_abort (void);
+static void clntunix_geterr (CLIENT *, struct rpc_err *);
+static bool_t clntunix_freeres (CLIENT *, xdrproc_t, caddr_t);
+static bool_t clntunix_control (CLIENT *, int, char *);
+static void clntunix_destroy (CLIENT *);
+
+static struct clnt_ops unix_ops =
+{
+  clntunix_call,
+  clntunix_abort,
+  clntunix_geterr,
+  clntunix_freeres,
+  clntunix_destroy,
+  clntunix_control
+};
+
+/*
+ * Create a client handle for a tcp/ip connection.
+ * If *sockp<0, *sockp is set to a newly created TCP socket and it is
+ * connected to raddr.  If *sockp non-negative then
+ * raddr is ignored.  The rpc/tcp package does buffering
+ * similar to stdio, so the client must pick send and receive buffer sizes,];
+ * 0 => use the default.
+ * If raddr->sin_port is 0, then a binder on the remote machine is
+ * consulted for the right port number.
+ * NB: *sockp is copied into a private area.
+ * NB: It is the clients responsibility to close *sockp.
+ * NB: The rpch->cl_auth is set null authentication.  Caller may wish to set this
+ * something more useful.
+ */
+CLIENT *
+clntunix_create (struct sockaddr_un *raddr, u_long prog, u_long vers,
+                int *sockp, u_int sendsz, u_int recvsz)
+{
+  CLIENT *h;
+  struct ct_data *ct = (struct ct_data *) mem_alloc (sizeof (*ct));
+  struct timeval now;
+  struct rpc_msg call_msg;
+  int len;
+
+  h = (CLIENT *) mem_alloc (sizeof (*h));
+  if (h == NULL)
+    {
+      (void) fputs (_("clntunix_create: out of memory\n"), stderr);
+      rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+      rpc_createerr.cf_error.re_errno = errno;
+      goto fooy;
+    }
+  /*  ct = (struct ct_data *) mem_alloc (sizeof (*ct)); */
+  if (ct == NULL)
+    {
+      (void) fputs (_("clntunix_create: out of memory\n"), stderr);
+      rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+      rpc_createerr.cf_error.re_errno = errno;
+      goto fooy;
+    }
+
+  /*
+   * If no socket given, open one
+   */
+  if (*sockp < 0)
+    {
+      *sockp = __socket (AF_UNIX, SOCK_STREAM, 0);
+      len = strlen (raddr->sun_path) + sizeof (raddr->sun_family) + 1;
+      if (*sockp < 0
+         || __connect (*sockp, (struct sockaddr *) raddr, len) < 0)
+       {
+         rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+         rpc_createerr.cf_error.re_errno = errno;
+         if (*sockp != -1)
+           __close (*sockp);
+         goto fooy;
+       }
+      ct->ct_closeit = TRUE;
+    }
+  else
+    {
+      ct->ct_closeit = FALSE;
+    }
+
+  /*
+   * Set up private data struct
+   */
+  ct->ct_sock = *sockp;
+  ct->ct_wait.tv_usec = 0;
+  ct->ct_waitset = FALSE;
+  ct->ct_addr = *raddr;
+
+  /*
+   * Initialize call message
+   */
+  __gettimeofday (&now, (struct timezone *) 0);
+  call_msg.rm_xid = __getpid () ^ now.tv_sec ^ now.tv_usec;
+  call_msg.rm_direction = CALL;
+  call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+  call_msg.rm_call.cb_prog = prog;
+  call_msg.rm_call.cb_vers = vers;
+
+  /*
+   * pre-serialize the static part of the call msg and stash it away
+   */
+  xdrmem_create (&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE, XDR_ENCODE);
+  if (!xdr_callhdr (&(ct->ct_xdrs), &call_msg))
+    {
+      if (ct->ct_closeit)
+       __close (*sockp);
+      goto fooy;
+    }
+  ct->ct_mpos = XDR_GETPOS (&(ct->ct_xdrs));
+  XDR_DESTROY (&(ct->ct_xdrs));
+
+  /*
+   * Create a client handle which uses xdrrec for serialization
+   * and authnone for authentication.
+   */
+  xdrrec_create (&(ct->ct_xdrs), sendsz, recvsz,
+                (caddr_t) ct, readunix, writeunix);
+  h->cl_ops = &unix_ops;
+  h->cl_private = (caddr_t) ct;
+  h->cl_auth = authnone_create ();
+  return h;
+
+fooy:
+  /*
+   * Something goofed, free stuff and barf
+   */
+  mem_free ((caddr_t) ct, sizeof (struct ct_data));
+  mem_free ((caddr_t) h, sizeof (CLIENT));
+  return (CLIENT *) NULL;
+}
+
+static enum clnt_stat
+clntunix_call (h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
+     CLIENT *h;
+     u_long proc;
+     xdrproc_t xdr_args;
+     caddr_t args_ptr;
+     xdrproc_t xdr_results;
+     caddr_t results_ptr;
+     struct timeval timeout;
+{
+  struct ct_data *ct = (struct ct_data *) h->cl_private;
+  XDR *xdrs = &(ct->ct_xdrs);
+  struct rpc_msg reply_msg;
+  u_long x_id;
+  u_int32_t *msg_x_id = (u_int32_t *) (ct->ct_mcall);  /* yuk */
+  bool_t shipnow;
+  int refreshes = 2;
+
+  if (!ct->ct_waitset)
+    {
+      ct->ct_wait = timeout;
+    }
+
+  shipnow =
+    (xdr_results == (xdrproc_t) 0 && timeout.tv_sec == 0
+     && timeout.tv_usec == 0) ? FALSE : TRUE;
+
+call_again:
+  xdrs->x_op = XDR_ENCODE;
+  ct->ct_error.re_status = RPC_SUCCESS;
+  x_id = ntohl (--(*msg_x_id));
+  if ((!XDR_PUTBYTES (xdrs, ct->ct_mcall, ct->ct_mpos)) ||
+      (!XDR_PUTLONG (xdrs, (long *) &proc)) ||
+      (!AUTH_MARSHALL (h->cl_auth, xdrs)) ||
+      (!(*xdr_args) (xdrs, args_ptr)))
+    {
+      if (ct->ct_error.re_status == RPC_SUCCESS)
+       ct->ct_error.re_status = RPC_CANTENCODEARGS;
+      (void) xdrrec_endofrecord (xdrs, TRUE);
+      return ct->ct_error.re_status;
+    }
+  if (!xdrrec_endofrecord (xdrs, shipnow))
+    return ct->ct_error.re_status = RPC_CANTSEND;
+  if (!shipnow)
+    return RPC_SUCCESS;
+  /*
+   * Hack to provide rpc-based message passing
+   */
+  if (timeout.tv_sec == 0 && timeout.tv_usec == 0)
+    return ct->ct_error.re_status = RPC_TIMEDOUT;
+
+
+  /*
+   * Keep receiving until we get a valid transaction id
+   */
+  xdrs->x_op = XDR_DECODE;
+  while (TRUE)
+    {
+      reply_msg.acpted_rply.ar_verf = _null_auth;
+      reply_msg.acpted_rply.ar_results.where = NULL;
+      reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void;
+      if (!xdrrec_skiprecord (xdrs))
+       return ct->ct_error.re_status;
+      /* now decode and validate the response header */
+      if (!xdr_replymsg (xdrs, &reply_msg))
+       {
+         if (ct->ct_error.re_status == RPC_SUCCESS)
+           continue;
+         return ct->ct_error.re_status;
+       }
+      if (reply_msg.rm_xid == x_id)
+       break;
+    }
+
+  /*
+   * process header
+   */
+  _seterr_reply (&reply_msg, &(ct->ct_error));
+  if (ct->ct_error.re_status == RPC_SUCCESS)
+    {
+      if (!AUTH_VALIDATE (h->cl_auth, &reply_msg.acpted_rply.ar_verf))
+       {
+         ct->ct_error.re_status = RPC_AUTHERROR;
+         ct->ct_error.re_why = AUTH_INVALIDRESP;
+       }
+      else if (!(*xdr_results) (xdrs, results_ptr))
+       {
+         if (ct->ct_error.re_status == RPC_SUCCESS)
+           ct->ct_error.re_status = RPC_CANTDECODERES;
+       }
+      /* free verifier ... */
+      if (reply_msg.acpted_rply.ar_verf.oa_base != NULL)
+       {
+         xdrs->x_op = XDR_FREE;
+         (void) xdr_opaque_auth (xdrs, &(reply_msg.acpted_rply.ar_verf));
+       }
+    }                          /* end successful completion */
+  else
+    {
+      /* maybe our credentials need to be refreshed ... */
+      if (refreshes-- && AUTH_REFRESH (h->cl_auth))
+       goto call_again;
+    }                          /* end of unsuccessful completion */
+  return ct->ct_error.re_status;
+}
+
+static void
+clntunix_geterr (CLIENT *h, struct rpc_err *errp)
+{
+  struct ct_data *ct = (struct ct_data *) h->cl_private;
+
+  *errp = ct->ct_error;
+}
+
+static bool_t
+clntunix_freeres (cl, xdr_res, res_ptr)
+     CLIENT *cl;
+     xdrproc_t xdr_res;
+     caddr_t res_ptr;
+{
+  struct ct_data *ct = (struct ct_data *) cl->cl_private;
+  XDR *xdrs = &(ct->ct_xdrs);
+
+  xdrs->x_op = XDR_FREE;
+  return (*xdr_res) (xdrs, res_ptr);
+}
+
+static void
+clntunix_abort ()
+{
+}
+
+static bool_t
+clntunix_control (CLIENT *cl, int request, char *info)
+{
+  struct ct_data *ct = (struct ct_data *) cl->cl_private;
+
+
+  switch (request)
+    {
+    case CLSET_FD_CLOSE:
+      ct->ct_closeit = TRUE;
+      break;
+    case CLSET_FD_NCLOSE:
+      ct->ct_closeit = FALSE;
+      break;
+    case CLSET_TIMEOUT:
+      ct->ct_wait = *(struct timeval *) info;
+      break;
+    case CLGET_TIMEOUT:
+      *(struct timeval *) info = ct->ct_wait;
+      break;
+    case CLGET_SERVER_ADDR:
+      *(struct sockaddr_un *) info = ct->ct_addr;
+      break;
+    case CLGET_FD:
+      *(int *)info = ct->ct_sock;
+      break;
+    case CLGET_XID:
+      /*
+       * use the knowledge that xid is the
+       * first element in the call structure *.
+       * This will get the xid of the PREVIOUS call
+       */
+      *(u_long *) info = ntohl (*(u_long *)ct->ct_mcall);
+      break;
+    case CLSET_XID:
+      /* This will set the xid of the NEXT call */
+      *(u_long *) ct->ct_mcall =  htonl (*(u_long *)info - 1);
+      /* decrement by 1 as clntunix_call() increments once */
+    case CLGET_VERS:
+      /*
+       * This RELIES on the information that, in the call body,
+       * the version number field is the fifth field from the
+       * begining of the RPC header. MUST be changed if the
+       * call_struct is changed
+       */
+      *(u_long *) info = ntohl (*(u_long *) (ct->ct_mcall
+                                            + 4 * BYTES_PER_XDR_UNIT));
+      break;
+    case CLSET_VERS:
+      *(u_long *) (ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT)
+       = htonl (*(u_long *) info);
+      break;
+    case CLGET_PROG:
+      /*
+       * This RELIES on the information that, in the call body,
+       * the program number field is the  field from the
+       * begining of the RPC header. MUST be changed if the
+       * call_struct is changed
+       */
+      *(u_long *) info = ntohl (*(u_long *) (ct->ct_mcall
+                                            + 3 * BYTES_PER_XDR_UNIT));
+      break;
+    case CLSET_PROG:
+      *(u_long *) (ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT)
+       = htonl(*(u_long *) info);
+      break;
+    /* The following are only possible with TI-RPC */
+    case CLGET_RETRY_TIMEOUT:
+    case CLSET_RETRY_TIMEOUT:
+    case CLGET_SVC_ADDR:
+    case CLSET_SVC_ADDR:
+    case CLSET_PUSH_TIMOD:
+    case CLSET_POP_TIMOD:
+    default:
+      return FALSE;
+    }
+  return TRUE;
+}
+
+
+static void
+clntunix_destroy (CLIENT *h)
+{
+  struct ct_data *ct =
+  (struct ct_data *) h->cl_private;
+
+  if (ct->ct_closeit)
+    {
+      (void) close (ct->ct_sock);
+    }
+  XDR_DESTROY (&(ct->ct_xdrs));
+  mem_free ((caddr_t) ct, sizeof (struct ct_data));
+  mem_free ((caddr_t) h, sizeof (CLIENT));
+}
+
+struct cmessage {
+  struct cmsghdr cmsg;
+  struct cmsgcred cmcred;
+};
+
+static int
+__msgread (int sock, void *buf, size_t cnt)
+{
+  struct iovec iov[1];
+  struct msghdr msg;
+  struct cmessage cm;
+  int on = 1;
+
+  iov[0].iov_base = buf;
+  iov[0].iov_len = cnt;
+
+  msg.msg_iov = iov;
+  msg.msg_iovlen = 1;
+  msg.msg_name = NULL;
+  msg.msg_namelen = 0;
+  msg.msg_control = (caddr_t)&cm;
+  msg.msg_controllen = sizeof(struct cmessage);
+  msg.msg_flags = 0;
+
+  setsockopt (sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on));
+
+  return recvmsg (sock, &msg, 0);
+}
+
+static int
+__msgwrite (int sock, void *buf, size_t cnt)
+{
+#ifndef SCM_CRED
+  /* We cannot implement this reliably.  */
+  __set_errno (ENOSYS);
+#else
+  struct iovec iov[1];
+  struct msghdr msg;
+  struct cmessage cm;
+  int len;
+
+  iov[0].iov_base = buf;
+  iov[0].iov_len = cnt;
+
+  cm.cmsg.cmsg_type = SCM_CREDS;
+  cm.cmsg.cmsg_level = SOL_SOCKET;
+  cm.cmsg.cmsg_len = sizeof (struct cmessage);
+  /* XXX I'm not sure, if gete?id() is always correct, or if we should use
+     get?id(). But since keyserv needs geteuid(), we have no other chance.
+     It would be much better, if the kernel could pass both to the server. */
+  cm.cmcred.cmcred_pid = __getpid ();
+  cm.cmcred.cmcred_uid = __geteuid ();
+  cm.cmcred.cmcred_gid = __getegid ();
+
+  msg.msg_iov = iov;
+  msg.msg_iovlen = 1;
+  msg.msg_name = NULL;
+  msg.msg_namelen = 0;
+  msg.msg_control = (caddr_t) &cm;
+  msg.msg_controllen = sizeof (struct cmessage);
+  msg.msg_flags = 0;
+
+  return sendmsg (sock, &msg, 0);
+#endif
+}
+
+
+/*
+ * Interface between xdr serializer and unix connection.
+ * Behaves like the system calls, read & write, but keeps some error state
+ * around for the rpc level.
+ */
+static int
+readunix (char *ctptr, char *buf, int len)
+{
+  struct ct_data *ct = (struct ct_data *) ctptr;
+  struct pollfd fd;
+  int milliseconds = ((ct->ct_wait.tv_sec * 1000)
+                     + (ct->ct_wait.tv_usec / 1000));
+
+  if (len == 0)
+    return 0;
+
+  fd.fd = ct->ct_sock;
+  fd.events = POLLIN;
+  while (TRUE)
+    {
+      switch (__poll (&fd, 1, milliseconds))
+        {
+        case 0:
+          ct->ct_error.re_status = RPC_TIMEDOUT;
+          return -1;
+
+        case -1:
+          if (errno == EINTR)
+            continue;
+          ct->ct_error.re_status = RPC_CANTRECV;
+          ct->ct_error.re_errno = errno;
+          return -1;
+        }
+      break;
+    }
+  switch (len = __msgread (ct->ct_sock, buf, len))
+    {
+
+    case 0:
+      /* premature eof */
+      ct->ct_error.re_errno = ECONNRESET;
+      ct->ct_error.re_status = RPC_CANTRECV;
+      len = -1;                        /* it's really an error */
+      break;
+
+    case -1:
+      ct->ct_error.re_errno = errno;
+      ct->ct_error.re_status = RPC_CANTRECV;
+      break;
+    }
+  return len;
+}
+
+static int
+writeunix (char *ctptr, char *buf, int len)
+{
+  int i, cnt;
+  struct ct_data *ct = (struct ct_data *) ctptr;
+
+  for (cnt = len; cnt > 0; cnt -= i, buf += i)
+    {
+      if ((i = __msgwrite (ct->ct_sock, buf, cnt)) == -1)
+       {
+         ct->ct_error.re_errno = errno;
+         ct->ct_error.re_status = RPC_CANTSEND;
+         return -1;
+       }
+    }
+  return len;
+}
index e59a8b7a378a3d06b8e4133534c4912062a4f146..0219eaf5ad0ad777fffe91f75ab28c1f17e1d194 100644 (file)
@@ -38,6 +38,7 @@
 
 #include <stdio.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <signal.h>
 #include <unistd.h>
 #include <string.h>
@@ -47,6 +48,7 @@
 #include <sys/param.h>
 #include <sys/socket.h>
 #include <rpc/key_prot.h>
+#include <bits/libc-lock.h>
 
 #define KEY_TIMEOUT    5       /* per-try timeout in seconds */
 #define KEY_NRETRY     12      /* number of retries */
@@ -268,8 +270,8 @@ des_block *(*__key_gendes_LOCAL) (uid_t, char *) = 0;
 
 static int
 internal_function
-key_call (u_long proc, xdrproc_t xdr_arg, char *arg,
-         xdrproc_t xdr_rslt, char *rslt)
+key_call_keyenvoy (u_long proc, xdrproc_t xdr_arg, char *arg,
+                  xdrproc_t xdr_rslt, char *rslt)
 {
   XDR xdrargs;
   XDR xdrrslt;
@@ -283,28 +285,6 @@ key_call (u_long proc, xdrproc_t xdr_arg, char *arg,
   uid_t euid;
   static char MESSENGER[] = "/usr/etc/keyenvoy";
 
-  if (proc == KEY_ENCRYPT_PK && __key_encryptsession_pk_LOCAL)
-    {
-      cryptkeyres *res;
-      res = (*__key_encryptsession_pk_LOCAL) (__geteuid (), arg);
-      *(cryptkeyres *) rslt = *res;
-      return 1;
-    }
-  else if (proc == KEY_DECRYPT_PK && __key_decryptsession_pk_LOCAL)
-    {
-      cryptkeyres *res;
-      res = (*__key_decryptsession_pk_LOCAL) (__geteuid (), arg);
-      *(cryptkeyres *) rslt = *res;
-      return 1;
-    }
-  else if (proc == KEY_GEN && __key_gendes_LOCAL)
-    {
-      des_block *res;
-      res = (*__key_gendes_LOCAL) (__geteuid (), 0);
-      *(des_block *) rslt = *res;
-      return 1;
-    }
-
   success = 1;
   sigemptyset (&mask);
   sigaddset (&mask, SIGCHLD);
@@ -365,3 +345,175 @@ key_call (u_long proc, xdrproc_t xdr_arg, char *arg,
 
   return success;
 }
+
+struct  key_call_private {
+  CLIENT  *client;        /* Client handle */
+  pid_t   pid;            /* process-id at moment of creation */
+  uid_t   uid;            /* user-id at last authorization */
+};
+static struct key_call_private *key_call_private_main = NULL;
+__libc_lock_define_initialized (static, keycall_lock)
+
+/*
+ * Keep the handle cached.  This call may be made quite often.
+ */
+static CLIENT *
+getkeyserv_handle (int vers)
+{
+  struct key_call_private *kcp = key_call_private_main;
+  struct timeval wait_time;
+  int fd;
+  struct sockaddr_un name;
+  int namelen = sizeof(struct sockaddr_un);
+
+#define TOTAL_TIMEOUT   30      /* total timeout talking to keyserver */
+#define TOTAL_TRIES     5       /* Number of tries */
+
+  if (kcp == (struct key_call_private *)NULL)
+    {
+      kcp = (struct key_call_private *)malloc (sizeof (*kcp));
+      if (kcp == (struct key_call_private *)NULL)
+       return (CLIENT *) NULL;
+
+      key_call_private_main = kcp;
+      kcp->client = NULL;
+    }
+
+  /* if pid has changed, destroy client and rebuild */
+  if (kcp->client != NULL && kcp->pid != __getpid ())
+    {
+      clnt_destroy (kcp->client);
+      kcp->client = NULL;
+    }
+
+  if (kcp->client != NULL)
+    {
+      /* if other side closed socket, build handle again */
+      clnt_control (kcp->client, CLGET_FD, (char *)&fd);
+      if (getpeername (fd,(struct sockaddr *)&name,&namelen) == -1)
+       {
+         auth_destroy (kcp->client->cl_auth);
+         clnt_destroy (kcp->client);
+         kcp->client = NULL;
+       }
+    }
+
+  if (kcp->client != NULL)
+    {
+      /* if uid has changed, build client handle again */
+      if (kcp->uid != __geteuid ())
+       {
+        kcp->uid = __geteuid ();
+        auth_destroy (kcp->client->cl_auth);
+        kcp->client->cl_auth =
+          authunix_create ((char *)"", kcp->uid, 0, 0, NULL);
+        if (kcp->client->cl_auth == NULL)
+          {
+            clnt_destroy (kcp->client);
+            kcp->client = NULL;
+            return ((CLIENT *) NULL);
+          }
+       }
+      /* Change the version number to the new one */
+      clnt_control (kcp->client, CLSET_VERS, (void *)&vers);
+      return kcp->client;
+    }
+
+  if ((kcp->client == (CLIENT *) NULL))
+    /* Use the AF_UNIX transport */
+    kcp->client = clnt_create ("/var/run/keyservsock", KEY_PROG, vers, "unix");
+
+  if (kcp->client == (CLIENT *) NULL)
+    return (CLIENT *) NULL;
+
+  kcp->uid = __geteuid ();
+  kcp->pid = __getpid ();
+  kcp->client->cl_auth = authunix_create ((char *)"", kcp->uid, 0, 0, NULL);
+  if (kcp->client->cl_auth == NULL)
+    {
+      clnt_destroy (kcp->client);
+      kcp->client = NULL;
+      return (CLIENT *) NULL;
+    }
+
+  wait_time.tv_sec = TOTAL_TIMEOUT/TOTAL_TRIES;
+  wait_time.tv_usec = 0;
+  clnt_control (kcp->client, CLSET_RETRY_TIMEOUT,
+               (char *)&wait_time);
+  if (clnt_control (kcp->client, CLGET_FD, (char *)&fd))
+    fcntl (fd, F_SETFD, 1);  /* make it "close on exec" */
+
+  return kcp->client;
+}
+
+/* returns  0 on failure, 1 on success */
+static int
+internal_function
+key_call_socket (u_long proc, xdrproc_t xdr_arg, char *arg,
+               xdrproc_t xdr_rslt, char *rslt)
+{
+  CLIENT *clnt;
+  struct timeval wait_time;
+  int result = 0;
+
+  __libc_lock_lock (keycall_lock);
+  if ((proc == KEY_ENCRYPT_PK) || (proc == KEY_DECRYPT_PK) ||
+      (proc == KEY_NET_GET) || (proc == KEY_NET_PUT) ||
+      (proc == KEY_GET_CONV))
+    clnt = getkeyserv_handle(2); /* talk to version 2 */
+  else
+    clnt = getkeyserv_handle(1); /* talk to version 1 */
+
+  if (clnt != NULL)
+    {
+      wait_time.tv_sec = TOTAL_TIMEOUT;
+      wait_time.tv_usec = 0;
+
+      if (clnt_call (clnt, proc, xdr_arg, arg, xdr_rslt, rslt,
+                    wait_time) == RPC_SUCCESS)
+       result = 1;
+    }
+
+  __libc_lock_unlock (keycall_lock);
+
+  return result;
+}
+
+/* returns  0 on failure, 1 on success */
+static int
+internal_function
+key_call (u_long proc, xdrproc_t xdr_arg, char *arg,
+         xdrproc_t xdr_rslt, char *rslt)
+{
+  static int use_keyenvoy = 0;
+
+  if (proc == KEY_ENCRYPT_PK && __key_encryptsession_pk_LOCAL)
+    {
+      cryptkeyres *res;
+      res = (*__key_encryptsession_pk_LOCAL) (__geteuid (), arg);
+      *(cryptkeyres *) rslt = *res;
+      return 1;
+    }
+  else if (proc == KEY_DECRYPT_PK && __key_decryptsession_pk_LOCAL)
+    {
+      cryptkeyres *res;
+      res = (*__key_decryptsession_pk_LOCAL) (__geteuid (), arg);
+      *(cryptkeyres *) rslt = *res;
+      return 1;
+    }
+  else if (proc == KEY_GEN && __key_gendes_LOCAL)
+    {
+      des_block *res;
+      res = (*__key_gendes_LOCAL) (__geteuid (), 0);
+      *(des_block *) rslt = *res;
+      return 1;
+    }
+
+  if (!use_keyenvoy)
+    {
+      if (key_call_socket (proc, xdr_arg, arg, xdr_rslt, rslt))
+       return 1;
+      use_keyenvoy = 1;
+    }
+  return key_call_keyenvoy (proc, xdr_arg, arg, xdr_rslt, rslt);
+}
index 1570cba4c205c3e05e00f5ae39f84d493b03d40a..b3852927a3e16a9d2512e96e97df170caff8823f 100644 (file)
@@ -41,6 +41,7 @@
 #include <sys/types.h>
 #include <rpc/types.h>
 #include <rpc/auth.h>
+#include <sys/un.h>
 
 __BEGIN_DECLS
 
@@ -282,7 +283,8 @@ extern CLIENT *clntraw_create __P ((__const u_long __prog,
 
 
 /*
- * Generic client creation routine. Supported protocols are "udp" and "tcp"
+ * Generic client creation routine. Supported protocols are "udp", "tcp" and
+ * "unix"
  * CLIENT *
  * clnt_create(host, prog, vers, prot)
  *     char *host;     -- hostname
@@ -341,6 +343,24 @@ extern CLIENT *clntudp_bufcreate __P ((struct sockaddr_in *__raddr,
                                       int *__sockp, u_int __sendsz,
                                       u_int __recvsz));
 
+
+/*
+ * AF_UNIX based rpc
+ * CLIENT *
+ * clntunix_create(raddr, prog, vers, sockp, sendsz, recvsz)
+ *      struct sockaddr_un *raddr;
+ *      u_long prog;
+ *      u_long version;
+ *      register int *sockp;
+ *      u_int sendsz;
+ *      u_int recvsz;
+ */
+extern CLIENT *clntunix_create  __P ((struct sockaddr_un *__raddr,
+                                     u_long __program, u_long __version,
+                                     int *__sockp, u_int __sendsz,
+                                     u_int __recvsz));
+
+
 extern int callrpc __P ((__const char *__host, __const u_long __prognum,
                         __const u_long __versnum, __const u_long __procnum,
                         __const xdrproc_t __inproc, __const char *__in,
index a53bc1015f4d77f2bd0d5288231ed4b381ad3303..4ac2a5cdf0b38339b355921c2b569ce2dc09fe95 100644 (file)
@@ -305,6 +305,13 @@ extern SVCXPRT *svctcp_create __P ((int __sock, u_int __sendsize,
                                    u_int __recvsize));
 
 
+/*
+ * Unix based rpc.
+ */
+extern SVCXPRT *svcunix_create __P ((int __sock, u_int __sendsize,
+                                    u_int __recvsize, char *__path));
+
+
 __END_DECLS
 
 #endif /* rpc/svc.h */
index 04cff9c53aea703f36776091d4d8fb8e6e95d0c8..627b7e3faf5f1cad213889b7bc7561fb24985ccd 100644 (file)
@@ -120,8 +120,22 @@ _svcauth_unix (struct svc_req *rqst, struct rpc_msg *msg)
       stat = AUTH_BADCRED;
       goto done;
     }
-  rqst->rq_xprt->xp_verf.oa_flavor = AUTH_NULL;
-  rqst->rq_xprt->xp_verf.oa_length = 0;
+
+  /* get the verifier */
+  if ((u_int)msg->rm_call.cb_verf.oa_length)
+    {
+      rqst->rq_xprt->xp_verf.oa_flavor =
+       msg->rm_call.cb_verf.oa_flavor;
+      rqst->rq_xprt->xp_verf.oa_base =
+       msg->rm_call.cb_verf.oa_base;
+      rqst->rq_xprt->xp_verf.oa_length =
+       msg->rm_call.cb_verf.oa_length;
+    }
+  else
+    {
+      rqst->rq_xprt->xp_verf.oa_flavor = AUTH_NULL;
+      rqst->rq_xprt->xp_verf.oa_length = 0;
+    }
   stat = AUTH_OK;
 done:
   XDR_DESTROY (&xdrs);
index 75fa8705b60a621a8ba0a5778fa9e63ac14f41fe..0c2ce9650ad7bb9af39d974b1965362272fb9a13 100644 (file)
@@ -141,7 +141,7 @@ svctcp_create (int sock, u_int sendsize, u_int recvsize)
     {
       if ((sock = __socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
        {
-         perror (_("svctcp_.c - udp socket creation problem"));
+         perror (_("svc_tcp.c - tcp socket creation problem"));
          return (SVCXPRT *) NULL;
        }
       madesock = TRUE;
@@ -156,7 +156,7 @@ svctcp_create (int sock, u_int sendsize, u_int recvsize)
   if ((getsockname (sock, (struct sockaddr *) &addr, &len) != 0) ||
       (listen (sock, 2) != 0))
     {
-      perror (_("svctcp_.c - cannot getsockname or listen"));
+      perror (_("svc_tcp.c - cannot getsockname or listen"));
       if (madesock)
        (void) __close (sock);
       return (SVCXPRT *) NULL;
diff --git a/sunrpc/svc_unix.c b/sunrpc/svc_unix.c
new file mode 100644 (file)
index 0000000..59ae7a5
--- /dev/null
@@ -0,0 +1,496 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * svc_unix.c, Server side for TCP/IP based RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * Actually implements two flavors of transporter -
+ * a unix rendezvouser (a listener and connection establisher)
+ * and a record/unix stream.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/*
+ * Ops vector for AF_UNIX based rpc service handle
+ */
+static bool_t svcunix_recv (SVCXPRT *, struct rpc_msg *);
+static enum xprt_stat svcunix_stat (SVCXPRT *);
+static bool_t svcunix_getargs (SVCXPRT *, xdrproc_t, caddr_t);
+static bool_t svcunix_reply (SVCXPRT *, struct rpc_msg *);
+static bool_t svcunix_freeargs (SVCXPRT *, xdrproc_t, caddr_t);
+static void svcunix_destroy (SVCXPRT *);
+
+static const struct xp_ops svcunix_op =
+{
+  svcunix_recv,
+  svcunix_stat,
+  svcunix_getargs,
+  svcunix_reply,
+  svcunix_freeargs,
+  svcunix_destroy
+};
+
+/*
+ * Ops vector for AF_UNIX rendezvous handler
+ */
+static bool_t rendezvous_request (SVCXPRT *, struct rpc_msg *);
+static enum xprt_stat rendezvous_stat (SVCXPRT *);
+
+static const struct xp_ops svcunix_rendezvous_op =
+{
+  rendezvous_request,
+  rendezvous_stat,
+  (bool_t (*) (SVCXPRT *, xdrproc_t, caddr_t)) abort,
+  (bool_t (*) (SVCXPRT *, struct rpc_msg *)) abort,
+  (bool_t (*) (SVCXPRT *, xdrproc_t, caddr_t)) abort,
+  svcunix_destroy
+};
+
+static int readunix (char*, char *, int);
+static int writeunix (char *, char *, int);
+static SVCXPRT *makefd_xprt (int, u_int, u_int) internal_function;
+
+struct unix_rendezvous {        /* kept in xprt->xp_p1 */
+  u_int sendsize;
+  u_int recvsize;
+};
+
+struct unix_conn {             /* kept in xprt->xp_p1 */
+  enum xprt_stat strm_stat;
+  u_long x_id;
+  XDR xdrs;
+  char verf_body[MAX_AUTH_BYTES];
+};
+
+/*
+ * Usage:
+ *      xprt = svcunix_create(sock, send_buf_size, recv_buf_size);
+ *
+ * Creates, registers, and returns a (rpc) unix based transporter.
+ * Once *xprt is initialized, it is registered as a transporter
+ * see (svc.h, xprt_register).  This routine returns
+ * a NULL if a problem occurred.
+ *
+ * If sock<0 then a socket is created, else sock is used.
+ * If the socket, sock is not bound to a port then svcunix_create
+ * binds it to an arbitrary port.  The routine then starts a unix
+ * listener on the socket's associated port.  In any (successful) case,
+ * xprt->xp_sock is the registered socket number and xprt->xp_port is the
+ * associated port number.
+ *
+ * Since unix streams do buffered io similar to stdio, the caller can specify
+ * how big the send and receive buffers are via the second and third parms;
+ * 0 => use the system default.
+ */
+SVCXPRT *
+svcunix_create (int sock, u_int sendsize, u_int recvsize, char *path)
+{
+  bool_t madesock = FALSE;
+  SVCXPRT *xprt;
+  struct unix_rendezvous *r;
+  struct sockaddr_un addr;
+  socklen_t len = sizeof (struct sockaddr_in);
+
+  if (sock == RPC_ANYSOCK)
+    {
+      if ((sock = __socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
+       {
+         perror (_("svc_unix.c - AF_UNIX socket creation problem"));
+         return (SVCXPRT *) NULL;
+       }
+      madesock = TRUE;
+    }
+  memset (&addr, '\0', sizeof (addr));
+  addr.sun_family = AF_UNIX;
+  len = strlen (addr.sun_path) + 1;
+  memcpy (addr.sun_path, path, len);
+  len += sizeof (addr.sun_family);
+
+  bind (sock, (struct sockaddr *) &addr, len);
+
+  if (getsockname (sock, (struct sockaddr *) &addr, &len) != 0
+      || listen (sock, 2) != 0)
+    {
+      perror (_("svc_unix.c - cannot getsockname or listen"));
+      if (madesock)
+       __close (sock);
+      return (SVCXPRT *) NULL;
+    }
+
+  r = (struct unix_rendezvous *) mem_alloc (sizeof (*r));
+  if (r == NULL)
+    {
+      fputs (_("svcunix_create: out of memory\n"), stderr);
+      return NULL;
+    }
+  r->sendsize = sendsize;
+  r->recvsize = recvsize;
+  xprt = (SVCXPRT *) mem_alloc (sizeof (SVCXPRT));
+  if (xprt == NULL)
+    {
+      fputs (_("svcunix_create: out of memory\n"), stderr);
+      return NULL;
+    }
+  xprt->xp_p2 = NULL;
+  xprt->xp_p1 = (caddr_t) r;
+  xprt->xp_verf = _null_auth;
+  xprt->xp_ops = &svcunix_rendezvous_op;
+  xprt->xp_port = -1;
+  xprt->xp_sock = sock;
+  xprt_register (xprt);
+  return xprt;
+}
+
+/*
+ * Like svunix_create(), except the routine takes any *open* UNIX file
+ * descriptor as its first input.
+ */
+SVCXPRT *
+svcunixfd_create (int fd, u_int sendsize, u_int recvsize)
+{
+  return makefd_xprt (fd, sendsize, recvsize);
+}
+
+static SVCXPRT *
+internal_function
+makefd_xprt (int fd, u_int sendsize, u_int recvsize)
+{
+  SVCXPRT *xprt;
+  struct unix_conn *cd;
+
+  xprt = (SVCXPRT *) mem_alloc (sizeof (SVCXPRT));
+  if (xprt == (SVCXPRT *) NULL)
+    {
+      (void) fputs (_("svc_unix: makefd_xprt: out of memory\n"), stderr);
+      goto done;
+    }
+  cd = (struct unix_conn *) mem_alloc (sizeof (struct unix_conn));
+  if (cd == (struct unix_conn *) NULL)
+    {
+      (void) fputs (_("svc_unix: makefd_xprt: out of memory\n"), stderr);
+      mem_free ((char *) xprt, sizeof (SVCXPRT));
+      xprt = (SVCXPRT *) NULL;
+      goto done;
+    }
+  cd->strm_stat = XPRT_IDLE;
+  xdrrec_create (&(cd->xdrs), sendsize, recvsize,
+                (caddr_t) xprt, readunix, writeunix);
+  xprt->xp_p2 = NULL;
+  xprt->xp_p1 = (caddr_t) cd;
+  xprt->xp_verf.oa_base = cd->verf_body;
+  xprt->xp_addrlen = 0;
+  xprt->xp_ops = &svcunix_op;  /* truly deals with calls */
+  xprt->xp_port = 0;           /* this is a connection, not a rendezvouser */
+  xprt->xp_sock = fd;
+  xprt_register (xprt);
+done:
+  return xprt;
+}
+
+static bool_t
+rendezvous_request (SVCXPRT *xprt, struct rpc_msg *errmsg)
+{
+  int sock;
+  struct unix_rendezvous *r;
+  struct sockaddr_un addr;
+  struct sockaddr_in in_addr;
+  socklen_t len;
+
+  r = (struct unix_rendezvous *) xprt->xp_p1;
+again:
+  len = sizeof (struct sockaddr_un);
+  if ((sock = accept (xprt->xp_sock, (struct sockaddr *) &addr, &len)) < 0)
+    {
+      if (errno == EINTR)
+       goto again;
+      return FALSE;
+    }
+  /*
+   * make a new transporter (re-uses xprt)
+   */
+  memset (&in_addr, '\0', sizeof (in_addr));
+  in_addr.sin_family = AF_UNIX;
+  xprt = makefd_xprt (sock, r->sendsize, r->recvsize);
+  xprt->xp_raddr = in_addr;
+  xprt->xp_addrlen = len;
+  return FALSE;                /* there is never an rpc msg to be processed */
+}
+
+static enum xprt_stat
+rendezvous_stat (SVCXPRT *xprt)
+{
+  return XPRT_IDLE;
+}
+
+static void
+svcunix_destroy (SVCXPRT *xprt)
+{
+  struct unix_conn *cd = (struct unix_conn *) xprt->xp_p1;
+
+  xprt_unregister (xprt);
+  __close (xprt->xp_sock);
+  if (xprt->xp_port != 0)
+    {
+      /* a rendezvouser socket */
+      xprt->xp_port = 0;
+    }
+  else
+    {
+      /* an actual connection socket */
+      XDR_DESTROY (&(cd->xdrs));
+    }
+  mem_free ((caddr_t) cd, sizeof (struct unix_conn));
+  mem_free ((caddr_t) xprt, sizeof (SVCXPRT));
+}
+
+struct cmessage {
+  struct cmsghdr cmsg;
+  struct cmsgcred cmcred;
+};
+
+/* XXX This is not thread safe, but since the main functions in svc.c
+   and the rpcgen generated *_svc functions for the daemon are also not
+   thread safe and uses static global variables, it doesn't matter. */
+static struct cmessage cm;
+
+static int
+__msgread (int sock, void *buf, size_t cnt)
+{
+  struct iovec iov[1];
+  struct msghdr msg;
+  int len, on = 1;
+
+  iov[0].iov_base = buf;
+  iov[0].iov_len = cnt;
+
+  msg.msg_iov = iov;
+  msg.msg_iovlen = 1;
+  msg.msg_name = NULL;
+  msg.msg_namelen = 0;
+  msg.msg_control = (caddr_t) &cm;
+  msg.msg_controllen = sizeof (struct cmessage);
+  msg.msg_flags = 0;
+
+  setsockopt (sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on));
+
+  return recvmsg (sock, &msg, 0);
+}
+
+static int
+__msgwrite (int sock, void *buf, size_t cnt)
+{
+#ifndef SCM_CRED
+  /* We cannot implement this reliably.  */
+  __set_errno (ENOSYS);
+#else
+  struct iovec iov[1];
+  struct msghdr msg;
+  int len;
+
+  iov[0].iov_base = buf;
+  iov[0].iov_len = cnt;
+
+  cm.cmsg.cmsg_type = SCM_CREDS;
+  cm.cmsg.cmsg_level = SOL_SOCKET;
+  cm.cmsg.cmsg_len = sizeof (struct cmessage);
+  /* XXX I'm not sure, if we really should use gete?id(), or get?id().
+     It would be much better, if the kernel could pass both to the
+     client. */
+  cm.cmcred.cmcred_pid = __getpid ();
+  cm.cmcred.cmcred_uid = __geteuid ();
+  cm.cmcred.cmcred_gid = __getegid ();
+
+  msg.msg_iov = iov;
+  msg.msg_iovlen = 1;
+  msg.msg_name = NULL;
+  msg.msg_namelen = 0;
+  msg.msg_control = (caddr_t) &cm;
+  msg.msg_controllen = sizeof (struct cmessage);
+  msg.msg_flags = 0;
+
+  return sendmsg (sock, &msg, 0);
+#endif
+}
+
+/*
+ * All read operations timeout after 35 seconds.
+ * A timeout is fatal for the connection.
+ */
+static struct timeval wait_per_try = {35, 0};
+
+/*
+ * reads data from the unix connection.
+ * any error is fatal and the connection is closed.
+ * (And a read of zero bytes is a half closed stream => error.)
+ */
+static int
+readunix (char *xprtptr, char *buf, int len)
+{
+  SVCXPRT *xprt = (SVCXPRT *) xprtptr;
+  int sock = xprt->xp_sock;
+#ifdef FD_SETSIZE
+  fd_set readfds;
+#else
+  int mask = 1 << sock;
+  int readfds;
+#endif /* def FD_SETSIZE */
+  while (1)
+    {
+      struct timeval timeout = wait_per_try;
+      readfds = svc_fdset;
+#ifdef FD_SETSIZE
+      FD_SET (sock, &readfds);
+#else
+      readfds |= (1 << sock);
+#endif /* def FD_SETSIZE */
+      if (__select (_rpc_dtablesize (), &readfds, (fd_set *) NULL,
+                   (fd_set *) NULL, &timeout) <= 0)
+       {
+         if (errno == EINTR)
+           continue;
+         goto fatal_err;
+       }
+
+#ifdef FD_SETSIZE
+      if (FD_ISSET (sock, &readfds))
+#else
+      if (readfds == mask)
+#endif /* def FD_SETSIZE */
+       break;
+
+      svc_getreqset (&readfds);
+    }
+
+  if ((len = __msgread (sock, buf, len)) > 0)
+    return len;
+
+ fatal_err:
+  ((struct unix_conn *) (xprt->xp_p1))->strm_stat = XPRT_DIED;
+  return -1;
+}
+
+/*
+ * writes data to the unix connection.
+ * Any error is fatal and the connection is closed.
+ */
+static int
+writeunix (char *xprtptr, char * buf, int len)
+{
+  SVCXPRT *xprt = (SVCXPRT *) xprtptr;
+  int i, cnt;
+
+  for (cnt = len; cnt > 0; cnt -= i, buf += i)
+    {
+      if ((i = __msgwrite (xprt->xp_sock, buf, cnt)) < 0)
+       {
+         ((struct unix_conn *) (xprt->xp_p1))->strm_stat = XPRT_DIED;
+         return -1;
+       }
+    }
+  return len;
+}
+
+static enum xprt_stat
+svcunix_stat (SVCXPRT *xprt)
+{
+  struct unix_conn *cd =
+  (struct unix_conn *) (xprt->xp_p1);
+
+  if (cd->strm_stat == XPRT_DIED)
+    return XPRT_DIED;
+  if (!xdrrec_eof (&(cd->xdrs)))
+    return XPRT_MOREREQS;
+  return XPRT_IDLE;
+}
+
+static bool_t
+svcunix_recv (SVCXPRT *xprt, struct rpc_msg *msg)
+{
+  struct unix_conn *cd = (struct unix_conn *) (xprt->xp_p1);
+  XDR *xdrs = &(cd->xdrs);
+
+  xdrs->x_op = XDR_DECODE;
+  xdrrec_skiprecord (xdrs);
+  if (xdr_callmsg (xdrs, msg))
+    {
+      cd->x_id = msg->rm_xid;
+      /* set up verifiers */
+      msg->rm_call.cb_verf.oa_flavor = AUTH_UNIX;
+      msg->rm_call.cb_verf.oa_base = (caddr_t) &cm;
+      msg->rm_call.cb_verf.oa_length = sizeof (cm);
+      return TRUE;
+    }
+  cd->strm_stat = XPRT_DIED;   /* XXXX */
+  return FALSE;
+}
+
+static bool_t
+svcunix_getargs (SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr)
+{
+  return (*xdr_args) (&(((struct unix_conn *) (xprt->xp_p1))->xdrs),
+                     args_ptr);
+}
+
+static bool_t
+svcunix_freeargs (xprt, xdr_args, args_ptr)
+     SVCXPRT *xprt;
+     xdrproc_t xdr_args;
+     caddr_t args_ptr;
+{
+  XDR *xdrs = &(((struct unix_conn *) (xprt->xp_p1))->xdrs);
+
+  xdrs->x_op = XDR_FREE;
+  return (*xdr_args) (xdrs, args_ptr);
+}
+
+static bool_t
+svcunix_reply (xprt, msg)
+     SVCXPRT *xprt;
+     struct rpc_msg *msg;
+{
+  struct unix_conn *cd = (struct unix_conn *) (xprt->xp_p1);
+  XDR *xdrs = &(cd->xdrs);
+  bool_t stat;
+
+  xdrs->x_op = XDR_ENCODE;
+  msg->rm_xid = cd->x_id;
+  stat = xdr_replymsg (xdrs, msg);
+  (void) xdrrec_endofrecord (xdrs, TRUE);
+  return stat;
+}
index 5f96554bf21c88e8bf598eb361375a30ce054423..c9744fc46f4b59995ba35f4cc6e8aac943ffa6cb 100644 (file)
@@ -808,26 +808,29 @@ glob (pattern, flags, errfunc, pglob)
 
       flags |= GLOB_MAGCHAR;
 
+      /* We have ignored the GLOB_NOCHECK flag in the `glob_in_dir' calls.
+        But if we have not found any matching entry and thie GLOB_NOCHECK
+        flag was set we must return the list consisting of the disrectory
+        names followed by the filename.  */
       if (pglob->gl_pathc == oldcount)
        /* No matches.  */
        if (flags & GLOB_NOCHECK)
          {
-           size_t len = strlen (pattern) + 1;
-           char *patcopy = (char *) malloc (len);
-           if (patcopy == NULL)
-             return GLOB_NOSPACE;
-           memcpy (patcopy, pattern, len);
+           size_t filename_len = strlen (filename) + 1;
+           char **new_pathv;
+           struct stat st;
 
+           /* This is an pessimistic guess about the size.  */
            pglob->gl_pathv
              = (char **) realloc (pglob->gl_pathv,
                                   (pglob->gl_pathc +
                                    ((flags & GLOB_DOOFFS) ?
                                     pglob->gl_offs : 0) +
-                                   1 + 1) *
+                                   dirs.gl_pathc + 1) *
                                   sizeof (char *));
            if (pglob->gl_pathv == NULL)
              {
-               free (patcopy);
+               globfree (&dirs);
                return GLOB_NOSPACE;
              }
 
@@ -835,12 +838,54 @@ glob (pattern, flags, errfunc, pglob)
              while (pglob->gl_pathc < pglob->gl_offs)
                pglob->gl_pathv[pglob->gl_pathc++] = NULL;
 
-           pglob->gl_pathv[pglob->gl_pathc++] = patcopy;
+           for (i = 0; i < dirs.gl_pathc; ++i)
+             {
+               const char *dir = dirs.gl_pathv[i];
+               size_t dir_len = strlen (dir);
+
+               /* First check whether this really is a directory.  */
+               if (((flags & GLOB_ALTDIRFUNC)
+                    ? (*pglob->gl_stat) (dir, &st) : __stat (dir, &st)) != 0
+                   || !S_ISDIR (st.st_mode))
+                 /* No directory, ignore this entry.  */
+                 continue;
+
+               pglob->gl_pathv[pglob->gl_pathc] = malloc (dir_len + 1
+                                                          + filename_len);
+               if (pglob->gl_pathv[pglob->gl_pathc] == NULL)
+                 {
+                   globfree (&dirs);
+                   globfree (pglob);
+                   return GLOB_NOSPACE;
+                 }
+
+#ifdef HAVE_MEMPCPY
+               mempcpy (mempcpy (mempcpy (pglob->gl_pathv[pglob->gl_pathc],
+                                          dir, dir_len),
+                                 "/", 1),
+                        filename, filename_len);
+#else
+               memcpy (pglob->gl_pathv[pglob->gl_pathc], dir, dir_len);
+               pglob->gl_pathv[pglob->gl_pathc][dir_len] = '/';
+               memcpy (&pglob->gl_pathv[pglob->gl_pathc][dir_len + 1],
+                       filename, filename_len);
+#endif
+               ++pglob->gl_pathc;
+             }
+
            pglob->gl_pathv[pglob->gl_pathc] = NULL;
            pglob->gl_flags = flags;
+
+           /* Now we know how large the gl_pathv vector must be.  */
+           new_pathv = realloc (pglob->gl_pathv,
+                                (pglob->gl_pathc + 1) * sizeof (char *));
+           if (new_pathv != NULL)
+             pglob->gl_pathv = new_pathv;
          }
        else
          return GLOB_NOMATCH;
+
+      globfree (&dirs);
     }
   else
     {
index 82cfbe467a7b7f40226d1261251edefb2c066c77..42ecca9980883e3bb86f3bc4bd90313035973067 100644 (file)
@@ -77,8 +77,8 @@ static double zero = 0.0;     /* used as const */
  *     37-- y1(x>X_TLOSS)
  *     38-- jn(|x|>X_TLOSS, n)
  *     39-- yn(x>X_TLOSS, n)
- *     40-- gamma(finite) overflow
- *     41-- gamma(-integer)
+ *     40-- tgamma(finite) overflow
+ *     41-- tgamma(-integer)
  *     42-- pow(NaN,0.0)
  *     43-- +0**neg
  *     44-- exp2 overflow
@@ -829,8 +829,8 @@ static double zero = 0.0;   /* used as const */
            case 240:
                /* gamma(finite) overflow */
                exc.type = OVERFLOW;
-               exc.name = type < 100 ? "gamma" : (type < 200
-                                                  ? "gammaf" : "gammal");
+               exc.name = type < 100 ? "tgamma" : (type < 200
+                                                  ? "tgammaf" : "tgammal");
                exc.retval = HUGE_VAL;
                 if (_LIB_VERSION == _POSIX_)
                  __set_errno (ERANGE);
@@ -843,14 +843,14 @@ static double zero = 0.0; /* used as const */
            case 241:
                /* gamma(-integer) or gamma(0) */
                exc.type = SING;
-               exc.name = type < 100 ? "gamma" : (type < 200
-                                                  ? "gammaf" : "gammal");
+               exc.name = type < 100 ? "tgamma" : (type < 200
+                                                  ? "tgammaf" : "tgammal");
                exc.retval = NAN;
                if (_LIB_VERSION == _POSIX_)
                  __set_errno (EDOM);
                else if (!matherr(&exc)) {
                  if (_LIB_VERSION == _SVID_) {
-                       (void) WRITE2("gamma: SING error\n", 18);
+                       (void) WRITE2("tgamma: SING error\n", 18);
                        exc.retval = HUGE_VAL;
                      }
                  __set_errno (EDOM);
diff --git a/sysdeps/libm-ieee754/w_gammaf.c b/sysdeps/libm-ieee754/w_gammaf.c
deleted file mode 100644 (file)
index bc251b3..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/* w_gammaf.c -- float version of w_gamma.c.
- * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: w_gammaf.c,v 1.4 1995/11/20 22:06:48 jtc Exp $";
-#endif
-
-#include "math.h"
-#include "math_private.h"
-
-#ifdef __STDC__
-       float __gammaf(float x)
-#else
-       float __gammaf(x)
-       float x;
-#endif
-{
-        float y;
-#ifndef _IEEE_LIBM
-       if (_LIB_VERSION == _SVID_)
-         {
-           y = __ieee754_lgammaf_r(x,&signgam);
-
-           if(!__finitef(y)&&__finitef(x)) {
-             if(__floorf(x)==x&&x<=(float)0.0)
-               /* lgammaf pole */
-               return (float)__kernel_standard((double)x,(double)x,115);
-             else
-               /* lgammaf overflow */
-               return (float)__kernel_standard((double)x,(double)x,114);
-           }
-         }
-       else
-         {
-#endif
-           int local_signgam;
-           y = __ieee754_gammaf_r(x,&local_signgam);
-           if (local_signgam < 0) y = -y;
-#ifdef _IEEE_LIBM
-           return y;
-#else
-           if(_LIB_VERSION == _IEEE_) return y;
-
-           if(!__finitef(y)&&__finitef(x)) {
-             if(__floorf(x)==x&&x<=(float)0.0)
-               /* gammaf pole */
-               return (float)__kernel_standard((double)x,(double)x,141);
-             else
-               /* gammaf overflow */
-               return (float)__kernel_standard((double)x,(double)x,140);
-           }
-         }
-       return y;
-#endif
-}
-weak_alias (__gammaf, gammaf)
diff --git a/sysdeps/libm-ieee754/w_gammal.c b/sysdeps/libm-ieee754/w_gammal.c
deleted file mode 100644 (file)
index 68328f6..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/* w_gammal.c -- long double version of w_gamma.c.
- * Conversion to long double by Ulrich Drepper,
- * Cygnus Support, drepper@cygnus.com.
- */
-
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-#if defined(LIBM_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: $";
-#endif
-
-/* long double gammal(double x)
- * Return the Gamma function of x.
- */
-
-#include "math.h"
-#include "math_private.h"
-
-#ifdef __STDC__
-       long double __gammal(long double x)
-#else
-       long double __gammal(x)
-       long double x;
-#endif
-{
-        long double y;
-#ifndef _IEEE_LIBM
-       if (_LIB_VERSION == _SVID_)
-         {
-           y = __ieee754_lgammal_r(x,&signgam);
-
-           if(!__finitel(y)&&__finitel(x)) {
-             if(__floorl(x)==x&&x<=(long double)0.0)
-               /* lgamma pole */
-               return (long double)__kernel_standard((double)x,(double)x,15);
-             else
-               /* lgamma overflow */
-               return (long double)__kernel_standard((double)x,(double)x,14);
-           }
-         }
-       else
-         {
-#endif
-           int local_signgam;
-           y = __ieee754_gammal_r(x,&local_signgam);
-           if (local_signgam < 0) y = -y;
-#ifdef _IEEE_LIBM
-           return y;
-#else
-           if(_LIB_VERSION == _IEEE_) return y;
-
-           if(!__finitel(y)&&__finitel(x)) {
-             if(__floorl(x)==x&&x<=0.0)
-                return __kernel_standard(x,x,241); /* gamma pole */
-             else
-                return __kernel_standard(x,x,240); /* gamma overflow */
-           }
-         }
-       return y;
-#endif
-}
-weak_alias (__gammal, gammal)
index bbb53f53e873aa9254ab488b4354b1d498e488ad..0cc62a17847ef80da869ca7b3114e44d81844d4b 100644 (file)
@@ -50,7 +50,11 @@ static char rcsid[] = "$NetBSD: w_lgamma.c,v 1.6 1995/05/10 20:49:24 jtc Exp $";
 #endif
 }
 weak_alias (__lgamma, lgamma)
+strong_alias (__lgamma, __gamma)
+weak_alias (__gamma, gamma)
 #ifdef NO_LONG_DOUBLE
 strong_alias (__lgamma, __lgammal)
 weak_alias (__lgamma, lgammal)
+strong_alias (__gamma, __gammal)
+weak_alias (__gamma, gammal)
 #endif
index 369dee6749513477feb7887a924aa22781ec59fd..4c64aa4130b55b5813567a3448bcbabd36ed0a2c 100644 (file)
@@ -49,3 +49,5 @@ static char rcsid[] = "$NetBSD: w_lgammaf.c,v 1.3 1995/05/10 20:49:30 jtc Exp $"
 #endif
 }
 weak_alias (__lgammaf, lgammaf)
+strong_alias (__lgammaf, __gammaf)
+weak_alias (__gammaf, gammaf)
index 9db2ce26931a7a1dfb11f255f4603597463f5d92..41104e47e4e49fc9e4eb799fe24ebed9850eb3e4 100644 (file)
@@ -54,3 +54,5 @@ static char rcsid[] = "$NetBSD: $";
 #endif
 }
 weak_alias (__lgammal, lgammal)
+strong_alias (__lgammal, __gammal)
+weak_alias (__gammal, gammal)
similarity index 50%
rename from sysdeps/libm-ieee754/w_gamma.c
rename to sysdeps/libm-ieee754/w_tgamma.c
index 3511b67d779658035b6bf4f6e16f51bc772c2986..2adbc2e14d8b390b3242c90400c7cb1d40ea5a2a 100644 (file)
@@ -23,50 +23,32 @@ static char rcsid[] = "$NetBSD: w_gamma.c,v 1.7 1995/11/20 22:06:43 jtc Exp $";
 #include "math_private.h"
 
 #ifdef __STDC__
-       double __gamma(double x)
+       double __tgamma(double x)
 #else
-       double __gamma(x)
+       double __tgamma(x)
        double x;
 #endif
 {
         double y;
-#ifndef _IEEE_LIBM
-       if (_LIB_VERSION == _SVID_)
-         {
-           y = __ieee754_lgamma_r(x,&signgam);
-
-           if(!__finite(y)&&__finite(x)) {
-             if(__floor(x)==x&&x<=(double)0.0)
-               /* lgamma pole */
-               return __kernel_standard(x,x,15);
-             else
-               /* lgamma overflow */
-               return __kernel_standard(x,x,14);
-           }
-         }
-       else
-         {
-#endif
-           int local_signgam;
-           y = __ieee754_gamma_r(x,&local_signgam);
-           if (local_signgam < 0) y = -y;
+       int local_signgam;
+       y = __ieee754_gamma_r(x,&local_signgam);
+       if (local_signgam < 0) y = -y;
 #ifdef _IEEE_LIBM
-           return y;
+       return y;
 #else
-           if(_LIB_VERSION == _IEEE_) return y;
+       if(_LIB_VERSION == _IEEE_) return y;
 
-           if(!__finite(y)&&__finite(x)) {
-             if(__floor(x)==x&&x<=0.0)
-                return __kernel_standard(x,x,41); /* gamma pole */
-             else
-                return __kernel_standard(x,x,40); /* gamma overflow */
-           }
-         }
+       if(!__finite(y)&&__finite(x)) {
+         if(__floor(x)==x&&x<=0.0)
+           return __kernel_standard(x,x,41); /* tgamma pole */
+         else
+           return __kernel_standard(x,x,40); /* tgamma overflow */
+       }
        return y;
 #endif
 }
-weak_alias (__gamma, gamma)
+weak_alias (__tgamma, tgamma)
 #ifdef NO_LONG_DOUBLE
-strong_alias (__gamma, __gammal)
-weak_alias (__gamma, gammal)
+strong_alias (__tgamma, __tgammal)
+weak_alias (__tgamma, tgammal)
 #endif
diff --git a/sysdeps/libm-ieee754/w_tgammaf.c b/sysdeps/libm-ieee754/w_tgammaf.c
new file mode 100644 (file)
index 0000000..152f4be
--- /dev/null
@@ -0,0 +1,50 @@
+/* w_gammaf.c -- float version of w_gamma.c.
+ * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: w_gammaf.c,v 1.4 1995/11/20 22:06:48 jtc Exp $";
+#endif
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+       float __tgammaf(float x)
+#else
+       float __tgammaf(x)
+       float x;
+#endif
+{
+        float y;
+       int local_signgam;
+       y = __ieee754_gammaf_r(x,&local_signgam);
+       if (local_signgam < 0) y = -y;
+#ifdef _IEEE_LIBM
+       return y;
+#else
+       if(_LIB_VERSION == _IEEE_) return y;
+
+       if(!__finitef(y)&&__finitef(x)) {
+         if(__floorf(x)==x&&x<=(float)0.0)
+           /* tgammaf pole */
+           return (float)__kernel_standard((double)x,(double)x,141);
+         else
+           /* tgammaf overflow */
+           return (float)__kernel_standard((double)x,(double)x,140);
+       }
+       return y;
+#endif
+}
+weak_alias (__tgammaf, tgammaf)
diff --git a/sysdeps/libm-ieee754/w_tgammal.c b/sysdeps/libm-ieee754/w_tgammal.c
new file mode 100644 (file)
index 0000000..9efce2b
--- /dev/null
@@ -0,0 +1,53 @@
+/* w_gammal.c -- long double version of w_gamma.c.
+ * Conversion to long double by Ulrich Drepper,
+ * Cygnus Support, drepper@cygnus.com.
+ */
+
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#if defined(LIBM_SCCS) && !defined(lint)
+static char rcsid[] = "$NetBSD: $";
+#endif
+
+/* long double gammal(double x)
+ * Return the Gamma function of x.
+ */
+
+#include "math.h"
+#include "math_private.h"
+
+#ifdef __STDC__
+       long double __tgammal(long double x)
+#else
+       long double __tgammal(x)
+       long double x;
+#endif
+{
+        long double y;
+       int local_signgam;
+       y = __ieee754_gammal_r(x,&local_signgam);
+       if (local_signgam < 0) y = -y;
+#ifdef _IEEE_LIBM
+       return y;
+#else
+       if(_LIB_VERSION == _IEEE_) return y;
+
+       if(!__finitel(y)&&__finitel(x)) {
+         if(__floorl(x)==x&&x<=0.0)
+           return __kernel_standard(x,x,241); /* tgamma pole */
+         else
+           return __kernel_standard(x,x,240); /* tgamma overflow */
+       }
+       return y;
+#endif
+}
+weak_alias (__tgammal, tgammal)
index 8edde693379ed6ae0580ef52f576519592790e45..abaf0b26769f52e25dc246b1ba497c49145beba9 100644 (file)
@@ -240,7 +240,7 @@ open_file (const char *file_name, int mode,
   int nloops;
   error_t err;
 
-  assert (mode == O_RDONLY);
+  assert (!(mode & ~O_READ));
 
   startdir = _dl_hurd_data->portarray[file_name[0] == '/' ?
                                      INIT_PORT_CRDIR : INIT_PORT_CWDIR];
@@ -558,6 +558,38 @@ __mmap (__ptr_t addr, size_t len, int prot, int flags, int fd, off_t offset)
   return err ? (__ptr_t) __hurd_fail (err) : (__ptr_t) mapaddr;
 }
 
+int weak_function
+__fxstat (int vers, int fd, struct stat *buf)
+{
+  error_t err;
+  
+  assert (vers == _STAT_VER);
+  
+  err = __io_stat ((mach_port_t) fd, buf);
+  if (err)
+    return __hurd_fail (err);
+
+  return 0;
+  
+}
+
+int weak_function
+__xstat (int vers, const char *file, struct stat *buf)
+{
+  error_t err;
+  mach_port_t port;
+  
+  assert (vers == _STAT_VER);
+
+  err = open_file (file, 0, &port, buf);
+  if (err)
+    return __hurd_fail (err);
+
+  __mach_port_deallocate (__mach_task_self (), port);
+
+  return 0;
+}
+
 void weak_function
 _exit (int status)
 {
@@ -567,37 +599,6 @@ _exit (int status)
     __mach_task_self_ = (__mach_task_self) ();
 }
 \f
-/* Read the whole contents of FILE into new mmap'd space with given
-   protections.  The size of the file is returned in SIZE.  */
-void *
-weak_function
-_dl_sysdep_read_whole_file (const char *file, size_t *size, int prot)
-{
-  struct stat stat;
-  mach_port_t memobj_rd;
-  void *contents;
-  error_t err = open_file (file, O_RDONLY, &memobj_rd, &stat);
-
-  if (! err)
-    {
-      /* Map a copy of the file contents.  */
-      contents = __mmap (0, stat.st_size, prot, MAP_COPY, memobj_rd, 0);
-      if (contents == (void *)-1)
-       contents = 0;
-      else
-       *size = stat.st_size;
-
-      __mach_port_deallocate (__mach_task_self (), memobj_rd);
-    }
-  else
-    {
-      __hurd_fail (err);
-      contents = 0;
-    }
-
-  return contents;
-}
-\f
 /* This function is called by interruptible RPC stubs.  For initial
    dynamic linking, just use the normal mach_msg.  Since this defn is
    weak, the real defn in libc.so will override it if we are linked into
index 3795d91b908e0d20b9bc830f8b00fc6495d181bc..66970bcb89899eb84be9ba12c345794c7a311c0d 100644 (file)
@@ -89,5 +89,4 @@ __libc_recvmsg (int fd, struct msghdr *message, int flags)
   return ret;
 }
 
-weak_alias (__libc_recvmsg, __recvmsg)
 weak_alias (__libc_recvmsg, recvmsg)
index c0f009d0ac42fc3e4687e6e28402be4abd1c9b5c..304aa6e2a16d76d03e3448c0e2a59b5bf3eade86 100644 (file)
@@ -121,5 +121,4 @@ __libc_sendmsg (int fd, const struct msghdr *message, int flags)
   return __syscall_sendmsg (fd, message, flags);
 }
 
-weak_alias (__libc_sendmsg, __sendmsg)
 weak_alias (__libc_sendmsg, sendmsg)
index 7223b3a99bdf3f5bd764a75dea1f7ae5fdcb0c1a..9bc6abc9727693e9b06ecd8c2b7f35f4c63d0345 100644 (file)
--- a/version.h
+++ b/version.h
@@ -1,4 +1,4 @@
 /* This file just defines the current version number of libc.  */
 
 #define RELEASE "experimental"
-#define VERSION "2.0.94"
+#define VERSION "2.0.95"