update. cvs/libc-ud-970710
authorUlrich Drepper <drepper@redhat.com>
Fri, 11 Jul 1997 01:19:07 +0000 (01:19 +0000)
committerUlrich Drepper <drepper@redhat.com>
Fri, 11 Jul 1997 01:19:07 +0000 (01:19 +0000)
1997-07-11 03:00  Ulrich Drepper  <drepper@cygnus.com>

* inet/inet_ntoa.c: Prevent looking for thread data key if we found
one.

* signal/sigandset.c: Include stddef.h to get NULL defined.
* signal/sigisempty.c: Likewise.
* signal/sigorset.c: Likewise.
* sysdeps/stub/if_index.h: Likewise.
* wcsmbs/wcstod_l.c: Include locale.h to get __locale_t defined.
* wcsmbs/wcstof_l.c: Likewise.
* wcsmbs/wcstol_l.c: Likewise.
* wcsmbs/wcstold_l.c: Likewise.
* wcsmbs/wcstoll_l.c: Likewise.
* wcsmbs/wcstoul_l.c: Likewise.
* wcsmbs/wcstoull_l.c: Likewise.
Reported by Marcus G. Daniels <marcus@cathcart.sysc.pdx.edu>.

* stdio-common/snprintf.c: Use ISO C function definition form.

* sysdeps/stub/libc-lock.h: Don't define __libc_key_create and
__libc_setspecific as empty macros since they are used as
function with return value.
Reported by Andreas Jaeger.

1997-07-10  Marcus G. Daniels  <marcus@cathcart.sysc.pdx.edu>

* sysdeps/mach/hurd/select.c (__select): Need bit count for
MACH_MSG_TYPE_INTEGER_T.

1997-07-08 10:12  Fila Kolodny  <fila@ibi.com>

* sysdeps/i370/Implies: New file for i370-ibm-mvs port.
* sysdeps/mvs/Implies: Likewise.

1997-07-09 23:06  Thorsten Kukuk  <kukuk@vt.uni-paderborn.de>

* nis/Makefile: Add new source files.

* nis/nis_intern.h: Add new internal functions.
* nis/rpcsvc/nislib.h: Likewise.

* nis/lckcache.c: New.
* nis/nis_cache.c: New, dummy functions in the moment.
* nis/nis_util.c: New.
* nis/nisplus-parser.h: New.
* nis/nss_nisplus/nisplus-parser.c: New.
* nis/rpcsvc/nis_cache.h: New.
* nis/rpcsvc/nis_cache.x: New.

* nis/nss_compat/compat-grp.c: Matches Solaris behaviour now.
* nis/nss_compat/compat-pwd.c: Likewise.
* nis/nss_compat/compat-spwd.c: Likewise.
* nis/nss_nisplus/nisplus-alias.c: Likewise.
* nis/nss_nisplus/nisplus-ethers.c: Likewise.
* nis/nss_nisplus/nisplus-grp.c: Likewise.
* nis/nss_nisplus/nisplus-hosts.c: Likewise.
* nis/nss_nisplus/nisplus-netgrp.c: Likewise.
* nis/nss_nisplus/nisplus-network.c: Likewise.
* nis/nss_nisplus/nisplus-proto.c: Likewise.
* nis/nss_nisplus/nisplus-publickey.c: Likewise.
* nis/nss_nisplus/nisplus-pwd.c: Likewise.
* nis/nss_nisplus/nisplus-rpc.c: Likewise.
* nis/nss_nisplus/nisplus-service.c: Likewise.
* nis/nss_nisplus/nisplus-spwd.c: Likewise.

* nis/nss_nis/nis-publickey.c: Remove libc-lock.h include.

* nis/nis_intern.c: Removed.

* nis/nis_call.c: Complete rewrite.
* nis/nis_lookup.c: Likewise.
* nis/nis_table.c: Likewise.

* nis/libnsl.map: Add missing symbols.

* nis/nis_print.c: Fix nis_print_link.
* nis/nis_subr.c: Fix nis_getnames.

1997-07-09 07:19  H.J. Lu  <hjl@gnu.ai.mit.edu>

* posix/execvp.c (execvp): Handle ESTALE.

1997-07-10 13:54  Ulrich Drepper  <drepper@cygnus.com>

* posix/regex.c: Make CHAR_SET_SIZE definition always available,
even if SYNTAX_TABLE is defined.
Patch by Akim Demaille <demaille@inf.enst.fr>.

1997-07-09 08:16  H.J. Lu  <hjl@gnu.ai.mit.edu>

* libio/fileops.c (_IO_file_underflow): Adjust pointers
before calling _IO_SYSREAD ().

1997-07-07 22:54  Zack Weinberg  <zack@rabi.phys.columbia.edu>

* sysdeps/sparc/divrem.m4: Eliminate use of "DEFS.h"
(sysdep.h does the same job).
* sysdeps/sparc/alloca.S: Likewise.
* sysdeps/sparc/dotmul.S: Likewise.
* sysdeps/sparc/udiv_qrnnd.S: Likewise.

* sysdeps/sparc/rem.S: Regenerated.
* sysdeps/sparc/sdiv.S: Regenerated.
* sysdeps/sparc/udiv.S: Regenerated.
* sysdeps/sparc/urem.S: Regenerated.

* sysdeps/sparc/DEFS.h: Removed.
* sysdeps/sparc/elf/DEFS.h: Removed.
* sysdeps/sparc/Dist: Don't distribute DEFS.h.

* sysdeps/unix/sparc/sysdep.h: Use 4 byte alignment. Add .type
directive #ifdef HAVE_ELF.  Minor format changes.

* sysdeps/alpha/DEFS.h: Removed.
* sysdeps/alpha/Dist: Don't distribute DEFS.h.

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

* math/test-fenv.c (feenv_nomask_test): Move
fesetenv (FE_NOMASK_ENV) after fork () to work with
SMP.

* sysdeps/i386/fpu_control.h (_FPU_IEEE): Fix comment.

1997-07-08  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

* libc.map: Add _IO_peekc_locked.

1997-07-07 15:45  Fila Kolodny  <fila@ibi.com>

* Makeconfig: Add dbobjdir to rpath-link analogous to nssobjdir.

1997-07-08  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

* sysdeps/m68k/fpu/feholdexcpt.c: Shift the exception mask in the
right position.
* sysdeps/m68k/fpu/fesetenv.c (fesetenv): Likewise.

1997-07-08 13:59  Ulrich Drepper  <drepper@cygnus.com>

* time/strftime.c (spaces, zeroes): Handle broken SGI compiler.
Patch by Richard Stallman <rms@gnu.ai.mit.edu>.

78 files changed:
ChangeLog
Makeconfig
inet/inet_ntoa.c
libc.map
libio/fileops.c
manual/texinfo.tex
math/test-fenv.c
nis/Banner
nis/Makefile
nis/TODO
nis/lckcache.c [new file with mode: 0644]
nis/libnsl.map
nis/nis_cache.c [new file with mode: 0644]
nis/nis_call.c
nis/nis_intern.c [deleted file]
nis/nis_intern.h
nis/nis_lookup.c
nis/nis_print.c
nis/nis_subr.c
nis/nis_table.c
nis/nis_util.c [new file with mode: 0644]
nis/nisplus-parser.h [new file with mode: 0644]
nis/nss_compat/compat-grp.c
nis/nss_compat/compat-pwd.c
nis/nss_compat/compat-spwd.c
nis/nss_nis/nis-publickey.c
nis/nss_nisplus/nisplus-alias.c
nis/nss_nisplus/nisplus-ethers.c
nis/nss_nisplus/nisplus-grp.c
nis/nss_nisplus/nisplus-hosts.c
nis/nss_nisplus/nisplus-netgrp.c
nis/nss_nisplus/nisplus-network.c
nis/nss_nisplus/nisplus-parser.c [new file with mode: 0644]
nis/nss_nisplus/nisplus-proto.c
nis/nss_nisplus/nisplus-publickey.c
nis/nss_nisplus/nisplus-pwd.c
nis/nss_nisplus/nisplus-rpc.c
nis/nss_nisplus/nisplus-service.c
nis/nss_nisplus/nisplus-spwd.c
nis/rpcsvc/nis_cache.h [new file with mode: 0644]
nis/rpcsvc/nis_cache.x [new file with mode: 0644]
nis/rpcsvc/nislib.h
posix/execvp.c
posix/regex.c
signal/sigandset.c
signal/sigisempty.c
signal/sigorset.c
stdio-common/snprintf.c
sysdeps/alpha/DEFS.h [deleted file]
sysdeps/alpha/Dist
sysdeps/i370/Implies [new file with mode: 0644]
sysdeps/i386/fpu_control.h
sysdeps/m68k/fpu/feholdexcpt.c
sysdeps/m68k/fpu/fesetenv.c
sysdeps/mach/hurd/select.c
sysdeps/mvs/Implies [new file with mode: 0644]
sysdeps/sparc/DEFS.h [deleted file]
sysdeps/sparc/Dist
sysdeps/sparc/alloca.S
sysdeps/sparc/divrem.m4
sysdeps/sparc/dotmul.S
sysdeps/sparc/elf/DEFS.h [deleted file]
sysdeps/sparc/rem.S
sysdeps/sparc/sdiv.S
sysdeps/sparc/udiv.S
sysdeps/sparc/udiv_qrnnd.S
sysdeps/sparc/urem.S
sysdeps/stub/bits/libc-lock.h
sysdeps/stub/if_index.c
sysdeps/unix/sparc/sysdep.h
time/strftime.c
wcsmbs/wcstod_l.c
wcsmbs/wcstof_l.c
wcsmbs/wcstol_l.c
wcsmbs/wcstold_l.c
wcsmbs/wcstoll_l.c
wcsmbs/wcstoul_l.c
wcsmbs/wcstoull_l.c

index 5d0901b..67048cc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,147 @@
+1997-07-11 03:00  Ulrich Drepper  <drepper@cygnus.com>
+
+       * inet/inet_ntoa.c: Prevent looking for thread data key if we found
+       one.
+
+       * signal/sigandset.c: Include stddef.h to get NULL defined.
+       * signal/sigisempty.c: Likewise.
+       * signal/sigorset.c: Likewise.
+       * sysdeps/stub/if_index.h: Likewise.
+       * wcsmbs/wcstod_l.c: Include locale.h to get __locale_t defined.
+       * wcsmbs/wcstof_l.c: Likewise.
+       * wcsmbs/wcstol_l.c: Likewise.
+       * wcsmbs/wcstold_l.c: Likewise.
+       * wcsmbs/wcstoll_l.c: Likewise.
+       * wcsmbs/wcstoul_l.c: Likewise.
+       * wcsmbs/wcstoull_l.c: Likewise.
+       Reported by Marcus G. Daniels <marcus@cathcart.sysc.pdx.edu>.
+
+       * stdio-common/snprintf.c: Use ISO C function definition form.
+
+       * sysdeps/stub/libc-lock.h: Don't define __libc_key_create and
+       __libc_setspecific as empty macros since they are used as
+       function with return value.
+       Reported by Andreas Jaeger.
+
+1997-07-10  Marcus G. Daniels  <marcus@cathcart.sysc.pdx.edu>
+
+       * sysdeps/mach/hurd/select.c (__select): Need bit count for
+       MACH_MSG_TYPE_INTEGER_T.
+
+1997-07-08 10:12  Fila Kolodny  <fila@ibi.com>
+
+       * sysdeps/i370/Implies: New file for i370-ibm-mvs port.
+       * sysdeps/mvs/Implies: Likewise.
+
+1997-07-09 23:06  Thorsten Kukuk  <kukuk@vt.uni-paderborn.de>
+
+       * nis/Makefile: Add new source files.
+
+       * nis/nis_intern.h: Add new internal functions.
+       * nis/rpcsvc/nislib.h: Likewise.
+
+       * nis/lckcache.c: New.
+       * nis/nis_cache.c: New, dummy functions in the moment.
+       * nis/nis_util.c: New.
+       * nis/nisplus-parser.h: New.
+       * nis/nss_nisplus/nisplus-parser.c: New.
+       * nis/rpcsvc/nis_cache.h: New.
+       * nis/rpcsvc/nis_cache.x: New.
+
+       * nis/nss_compat/compat-grp.c: Matches Solaris behaviour now.
+       * nis/nss_compat/compat-pwd.c: Likewise.
+       * nis/nss_compat/compat-spwd.c: Likewise.
+       * nis/nss_nisplus/nisplus-alias.c: Likewise.
+       * nis/nss_nisplus/nisplus-ethers.c: Likewise.
+       * nis/nss_nisplus/nisplus-grp.c: Likewise.
+       * nis/nss_nisplus/nisplus-hosts.c: Likewise.
+       * nis/nss_nisplus/nisplus-netgrp.c: Likewise.
+       * nis/nss_nisplus/nisplus-network.c: Likewise.
+       * nis/nss_nisplus/nisplus-proto.c: Likewise.
+       * nis/nss_nisplus/nisplus-publickey.c: Likewise.
+       * nis/nss_nisplus/nisplus-pwd.c: Likewise.
+       * nis/nss_nisplus/nisplus-rpc.c: Likewise.
+       * nis/nss_nisplus/nisplus-service.c: Likewise.
+       * nis/nss_nisplus/nisplus-spwd.c: Likewise.
+
+       * nis/nss_nis/nis-publickey.c: Remove libc-lock.h include.
+
+       * nis/nis_intern.c: Removed.
+
+       * nis/nis_call.c: Complete rewrite.
+       * nis/nis_lookup.c: Likewise.
+       * nis/nis_table.c: Likewise.
+
+       * nis/libnsl.map: Add missing symbols.
+
+       * nis/nis_print.c: Fix nis_print_link.
+       * nis/nis_subr.c: Fix nis_getnames.
+
+1997-07-09 07:19  H.J. Lu  <hjl@gnu.ai.mit.edu>
+
+       * posix/execvp.c (execvp): Handle ESTALE.
+
+1997-07-10 13:54  Ulrich Drepper  <drepper@cygnus.com>
+
+       * posix/regex.c: Make CHAR_SET_SIZE definition always available,
+       even if SYNTAX_TABLE is defined.
+       Patch by Akim Demaille <demaille@inf.enst.fr>.
+
+1997-07-09 08:16  H.J. Lu  <hjl@gnu.ai.mit.edu>
+
+       * libio/fileops.c (_IO_file_underflow): Adjust pointers
+       before calling _IO_SYSREAD ().
+
+1997-07-07 22:54  Zack Weinberg  <zack@rabi.phys.columbia.edu>
+
+       * sysdeps/sparc/divrem.m4: Eliminate use of "DEFS.h"
+       (sysdep.h does the same job).
+       * sysdeps/sparc/alloca.S: Likewise.
+       * sysdeps/sparc/dotmul.S: Likewise.
+       * sysdeps/sparc/udiv_qrnnd.S: Likewise.
+
+       * sysdeps/sparc/rem.S: Regenerated.
+       * sysdeps/sparc/sdiv.S: Regenerated.
+       * sysdeps/sparc/udiv.S: Regenerated.
+       * sysdeps/sparc/urem.S: Regenerated.
+
+       * sysdeps/sparc/DEFS.h: Removed.
+       * sysdeps/sparc/elf/DEFS.h: Removed.
+       * sysdeps/sparc/Dist: Don't distribute DEFS.h.
+
+       * sysdeps/unix/sparc/sysdep.h: Use 4 byte alignment. Add .type
+       directive #ifdef HAVE_ELF.  Minor format changes.
+
+       * sysdeps/alpha/DEFS.h: Removed.
+       * sysdeps/alpha/Dist: Don't distribute DEFS.h.
+
+1997-07-07 19:03  H.J. Lu  <hjl@gnu.ai.mit.edu>
+
+       * math/test-fenv.c (feenv_nomask_test): Move
+       fesetenv (FE_NOMASK_ENV) after fork () to work with
+       SMP.
+
+       * sysdeps/i386/fpu_control.h (_FPU_IEEE): Fix comment.
+
+1997-07-08  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+       * libc.map: Add _IO_peekc_locked.
+
+1997-07-07 15:45  Fila Kolodny  <fila@ibi.com>
+
+       * Makeconfig: Add dbobjdir to rpath-link analogous to nssobjdir.
+
+1997-07-08  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+       * sysdeps/m68k/fpu/feholdexcpt.c: Shift the exception mask in the
+       right position.
+       * sysdeps/m68k/fpu/fesetenv.c (fesetenv): Likewise.
+
+1997-07-08 13:59  Ulrich Drepper  <drepper@cygnus.com>
+
+       * time/strftime.c (spaces, zeroes): Handle broken SGI compiler.
+       Patch by Richard Stallman <rms@gnu.ai.mit.edu>.
+
 1997-07-08 02:18  Ulrich Drepper  <drepper@cygnus.com>
 
        * io/lockf.c (lockf): Clear fl before using.
index 8f5313f..0756d91 100644 (file)
@@ -372,10 +372,11 @@ else
 default-rpath = $(libdir)
 endif
 # This is how to find at build-time things that will be installed there.
-rpath-link = $(common-objdir):$(mathobjdir):$(elfobjdir):$(nssobjdir)
+rpath-link = $(common-objdir):$(mathobjdir):$(elfobjdir):$(nssobjdir):$(dbobjdir)
 mathobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)math)
 elfobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)elf)
 nssobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)nss)
+dbobjdir := $(patsubst ../$(subdir),.,$(common-objpfx)db)
 else
 link-libc = $(common-objpfx)libc.a $(gnulib) $(common-objpfx)libc.a
 endif
index 3e9636c..9e4b2af 100644 (file)
@@ -57,6 +57,9 @@ inet_ntoa (struct in_addr in)
               really went wrong.  In any case use a static buffer
               which is better than nothing.  */
            buffer = static_buf;
+         else
+           /* We have a key.  */
+           initialized = 1;
        }
 
       __libc_lock_unlock (lock);
index 8ce6160..fec1c49 100644 (file)
--- a/libc.map
+++ b/libc.map
@@ -80,6 +80,7 @@ GLIBC_2.0 {
     _IO_seekmark; _IO_unsave_markers; _IO_str_overflow;
     _IO_str_underflow; _IO_str_init_static; _IO_str_init_readonly;
     _IO_str_seekoff; _IO_str_pbackfail; _IO_list_all; _IO_file_jumps;
+    _IO_peekc_locked;
     _rpc_dtablesize;
 
     # all functions and variables in the normal name space
index 3d494e3..afba972 100644 (file)
@@ -291,6 +291,15 @@ DEFUN(_IO_file_underflow, (fp),
 
   _IO_switch_to_get_mode(fp);
 
+  /* This is very tricky. We have to adjust those
+     pointers before we call _IO_SYSREAD () since
+     we may longjump () out while waiting for
+     input. Those pointers may be screwed up. H.J. */
+  fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base;
+  fp->_IO_read_end = fp->_IO_buf_base;
+  fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
+    = fp->_IO_buf_base;
+
   count = _IO_SYSREAD (fp, fp->_IO_buf_base,
                       fp->_IO_buf_end - fp->_IO_buf_base);
   if (count <= 0)
@@ -300,10 +309,7 @@ DEFUN(_IO_file_underflow, (fp),
       else
        fp->_flags |= _IO_ERR_SEEN, count = 0;
   }
-  fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base;
-  fp->_IO_read_end = fp->_IO_buf_base + count;
-  fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
-    = fp->_IO_buf_base;
+  fp->_IO_read_end += count;
   if (count == 0)
     return EOF;
   if (fp->_offset != _IO_pos_BAD)
index ee40bc8..cef4466 100644 (file)
@@ -1,5 +1,5 @@
 %% TeX macros to handle Texinfo files.
-%% $Id: texinfo.tex,v 2.207 1997/07/07 13:08:20 drepper Exp $
+%% $Id: texinfo.tex,v 2.208 1997/07/11 01:01:45 drepper Exp $
 
 %  Copyright (C) 1985, 86, 88, 90, 91, 92, 93,
 %                94, 95, 96, 97 Free Software Foundation, Inc.
@@ -36,7 +36,7 @@
 
 % This automatically updates the version number based on RCS.
 \def\deftexinfoversion$#1: #2 ${\def\texinfoversion{#2}}
-\deftexinfoversion$Revision: 2.207 $
+\deftexinfoversion$Revision: 2.208 $
 \message{Loading texinfo package [Version \texinfoversion]:}
 
 % If in a .fmt file, print the version number
 \hyphenation{ap-pen-dix}
 \hyphenation{mini-buf-fer mini-buf-fers}
 \hyphenation{eshell}
+\hyphenation{white-space}
 
 % Margin to add to right of even pages, to left of odd pages.
 \newdimen \bindingoffset
@@ -1235,6 +1236,7 @@ where each line of input produces a line of output.}
   \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy
   \let\tenttsl=\titlettsl
   \resetmathfonts \setleading{25pt}}
+\def\titlefont#1{{\titlefonts #1}}
 \def\chapfonts{%
   \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
   \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
@@ -3298,7 +3300,9 @@ width0pt\relax} \fi
    \unnumbchapmacro{#1}\def\thischapter{}%
    \begingroup                  % Set up to handle contents files properly.
       \catcode`\\=0  \catcode`\{=1  \catcode`\}=2  \catcode`\@=11
-      \catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi
+      % We can't do this, because then an actual ^ in a section
+      % title fails, e.g., @chapter ^ -- exponentiation.  --karl, 9jul97.
+      %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi
       \raggedbottom             % Worry more about breakpoints than the bottom.
       \advance\hsize by -\contentsrightmargin % Don't use the full line length.
 }
index 62a148b..9161c33 100644 (file)
@@ -227,10 +227,10 @@ feenv_nomask_test (const char *flag_name, int fe_exc)
 
   printf ("Test: after fesetenv (FE_NOMASK_ENV) processes will abort\n");
   printf ("      when feraiseexcept (%s) is called.\n", flag_name);
-  fesetenv (FE_NOMASK_ENV);
   pid = fork  ();
   if (pid == 0)
     {
+      fesetenv (FE_NOMASK_ENV);
       feraiseexcept (fe_exc);
       exit (2);
     }
@@ -270,10 +270,10 @@ feenv_mask_test (const char *flag_name, int fe_exc)
 
   printf ("Test: after fesetenv (FE_DFL_ENV) processes will not abort\n");
   printf ("      when feraiseexcept (%s) is called.\n", flag_name);
-  fesetenv (FE_DFL_ENV);
   pid = fork ();
   if (pid == 0)
     {
+      fesetenv (FE_DFL_ENV);
       feraiseexcept (fe_exc);
       exit (2);
     }
index b5aedc2..77ab77e 100644 (file)
@@ -1 +1 @@
-NIS(YP)/NIS+ NSS modules 0.11 by Thorsten Kukuk
+NIS(YP)/NIS+ NSS modules 0.12 by Thorsten Kukuk
index 23a7144..c10c175 100644 (file)
 # Boston, MA 02111-1307, USA.
 
 #
-#      Makefile for NIS part.
+#      Makefile for NIS/NIS+ part.
 #
 subdir := nis
 
 headers                        := $(wildcard rpcsvc/*.[hx])
-distribute             := nss-nis.h nss-nisplus.h nis_intern.h Banner
+distribute             := nss-nis.h nss-nisplus.h nis_intern.h Banner \
+                       nisplus-parser.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,15 +45,15 @@ 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_clone\
-                  nis_table nis_xdr nis_intern nis_server nis_ping\
+                  nis_cache nis_table nis_xdr nis_server nis_ping\
                  nis_checkpoint nis_mkdir nis_rmdir nis_getservlist\
-                 nis_verifygroup nis_ismember nis_addmember \
+                 nis_verifygroup nis_ismember nis_addmember nis_util\
                  nis_removemember nis_creategroup nis_destroygroup\
                  nis_print_group_entry nis_domain_of nis_domain_of_r\
-                 nis_modify nis_remove nis_add nis_defaults
+                 nis_modify nis_remove nis_add nis_defaults lckcache
 libnsl-map     = libnsl.map
 
-libnss_compat-routines := $(addprefix compat-,grp pwd spwd)
+libnss_compat-routines := $(addprefix compat-,grp pwd spwd) nisplus-parser
 libnss_compat-inhibit-o        = $(filter-out .so,$(object-suffixes))
 libnss_compat-map      := libnss_compat.map
 
@@ -60,16 +61,14 @@ libnss_nis-routines := $(addprefix nis-,$(databases))
 libnss_nis-inhibit-o   = $(filter-out .so,$(object-suffixes))
 libnss_nis-map         := libnss_nis.map
 
-libnss_nisplus-routines        := $(addprefix nisplus-,$(databases))
+libnss_nisplus-routines        := $(addprefix nisplus-,$(databases)) nisplus-parser
 libnss_nisplus-inhibit-o = $(filter-out .so,$(object-suffixes))
 libnss_nisplus-map     := libnss_nisplus.map
 
 include ../Rules
 
 
-$(objpfx)libnss_compat.so: $(objpfx)libnsl.so$(libnsl.so-version) \
-                          $(common-objpfx)nss/libnss_files.so \
-                          $(common-objpfx)nis/libnss_nisplus.so
+$(objpfx)libnss_compat.so: $(objpfx)libnsl.so$(libnsl.so-version)
 $(objpfx)libnss_nis.so: $(objpfx)libnsl.so$(libnsl.so-version) \
                        $(common-objpfx)nss/libnss_files.so
 $(objpfx)libnss_nisplus.so: $(objpfx)libnsl.so$(libnsl.so-version)
index f6d6959..0fe695d 100644 (file)
--- a/nis/TODO
+++ b/nis/TODO
@@ -2,8 +2,6 @@
  * nis_addmember: Where checks for duplicate group members ? nisgrpadm or
                  nis_addmember ?
 
- * nss_nisplus: When using parser form nss_files, rewrite parser
-
  * nis_table.c: nis_list(): 
        Missing flags: FOLLOW_PATH, ALL_RESULTS
        callback: Don't simulate it, use server callback thread
diff --git a/nis/lckcache.c b/nis/lckcache.c
new file mode 100644 (file)
index 0000000..ead5773
--- /dev/null
@@ -0,0 +1,181 @@
+/* Handle locking of NIS+ cache file.
+   Copyright (C) 1996 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <fcntl.h>
+#include <bits/libc-lock.h>
+#include <shadow.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/file.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+#include <rpcsvc/nis_cache.h>
+
+/* How long to wait for getting the lock before returning with an
+   error.  */
+#define TIMEOUT 15 /* sec */
+
+
+/* File descriptor for lock file.  */
+static int lock_fd = -1;
+
+/* Prevent problems in multithreaded program by using mutex.  */
+__libc_lock_define_initialized (static, lock)
+
+
+/* Prototypes for local functions.  */
+static void noop_handler __P ((int __sig));
+
+
+/* We cannot simply return in error cases.  We have to close the file
+   and perhaps restore the signal handler.  */
+#define RETURN_CLOSE_FD(code)                                                \
+  do {                                                                       \
+    if ((code) < 0 && lock_fd >= 0)                                          \
+      {                                                                              \
+       close (lock_fd);                                                      \
+       lock_fd = -1;                                                         \
+      }                                                                              \
+    __libc_lock_unlock (lock);                                               \
+    return (code);                                                           \
+  } while (0)
+
+#define RETURN_RESTORE_HANDLER(code)                                         \
+  do {                                                                       \
+    /* Restore old action handler for alarm.  We don't need to know          \
+       about the current one.  */                                            \
+    sigaction (SIGALRM, &saved_act, NULL);                                   \
+    RETURN_CLOSE_FD (code);                                                  \
+  } while (0)
+
+#define RETURN_CLEAR_ALARM(code)                                             \
+  do {                                                                       \
+    /* Clear alarm.  */                                                              \
+    alarm (0);                                                               \
+    /* Restore old set of handled signals.  We don't need to know            \
+       about the current one.*/                                                      \
+    sigprocmask (SIG_SETMASK, &saved_set, NULL);                             \
+    RETURN_RESTORE_HANDLER (code);                                           \
+  } while (0)
+
+
+int
+__nis_lock_cache (void)
+{
+  int flags;
+  sigset_t saved_set;                  /* Saved set of caught signals.  */
+  struct sigaction saved_act;          /* Saved signal action.  */
+  sigset_t new_set;                    /* New set of caught signals.  */
+  struct sigaction new_act;            /* New signal action.  */
+  struct flock fl;                     /* Information struct for locking.  */
+  int result;
+
+  if (lock_fd != -1)
+    /* Still locked by own process.  */
+    return -1;
+
+  /* Prevent problems caused by multiple threads.  */
+  __libc_lock_lock (lock);
+
+  lock_fd = open (CACHELOCK, O_RDONLY|O_CREAT, 0666);
+  if (lock_fd == -1)
+    /* Cannot create lock file.  */
+    RETURN_CLOSE_FD (-1);
+
+  /* Make sure file gets correctly closed when process finished.  */
+  flags = fcntl (lock_fd, F_GETFD, 0);
+  if (flags == -1)
+    /* Cannot get file flags.  */
+    RETURN_CLOSE_FD (-1);
+  flags |= FD_CLOEXEC;         /* Close on exit.  */
+  if (fcntl (lock_fd, F_SETFD, flags) < 0)
+    /* Cannot set new flags.  */
+    RETURN_CLOSE_FD (-1);
+
+  /* Now we have to get exclusive write access.  Since multiple
+     process could try this we won't stop when it first fails.
+     Instead we set a timeout for the system call.  Once the timer
+     expires it is likely that there are some problems which cannot be
+     resolved by waiting.
+
+     It is important that we don't change the signal state.  We must
+     restore the old signal behaviour.  */
+  memset (&new_act, '\0', sizeof (struct sigaction));
+  new_act.sa_handler = noop_handler;
+  sigfillset (&new_act.sa_mask);
+  new_act.sa_flags = 0ul;
+
+  /* Install new action handler for alarm and save old.  */
+  if (sigaction (SIGALRM, &new_act, &saved_act) < 0)
+    /* Cannot install signal handler.  */
+    RETURN_CLOSE_FD (-1);
+
+  /* Now make sure the alarm signal is not blocked.  */
+  sigemptyset (&new_set);
+  sigaddset (&new_set, SIGALRM);
+  if (sigprocmask (SIG_UNBLOCK, &new_set, &saved_set) < 0)
+    RETURN_RESTORE_HANDLER (-1);
+
+  /* Start timer.  If we cannot get the lock in the specified time we
+     get a signal.  */
+  alarm (TIMEOUT);
+
+  /* Try to get the lock.  */
+  memset (&fl, '\0', sizeof (struct flock));
+  fl.l_type = F_RDLCK;
+  fl.l_whence = SEEK_SET;
+  result = fcntl (lock_fd, F_SETLK, &fl);
+
+  RETURN_CLEAR_ALARM (result);
+}
+
+
+int
+__nis_unlock_cache ()
+{
+  int result;
+
+  if (lock_fd == -1)
+    /* There is no lock set.  */
+    result = -1;
+  else
+    {
+      /* Prevent problems caused by multiple threads.  */
+      __libc_lock_lock (lock);
+
+      result = close (lock_fd);
+
+      /* Mark descriptor as unused.  */
+      lock_fd = -1;
+
+      /* Clear mutex.  */
+      __libc_lock_unlock (lock);
+    }
+
+  return result;
+}
+
+
+static void
+noop_handler (sig)
+     int sig;
+{
+  /* We simply return which makes the `fcntl' call return with an error.  */
+}
index 36bb857..cf22d27 100644 (file)
@@ -1,7 +1,10 @@
 GLIBC_2.0 {
   global:
     __nis_default_access; __nis_default_group; __nis_default_owner;
-    __nis_default_ttl;    __yp_check;          nis_add;
+    __nis_default_ttl;    __nis_finddirectory; __nis_lock_cache;
+    __nis_unlock_cache;   __nis_hash;
+
+    nis_add;
     nis_add_entry;        nis_addmember;       nis_checkpoint;
     nis_clone_directory;  nis_clone_entry;     nis_clone_group;
     nis_clone_link;       nis_clone_nis_attr;  nis_clone_objdata;
@@ -51,6 +54,7 @@ GLIBC_2.0 {
     xdr_ypresp_xfr;       xdr_ypstat;          xdr_ypupdate_args;
     xdr_ypxfrstat;        xdr_zotypes;
 
+    __yp_check;          
     yp_all;               yp_bind;             yp_first;
     yp_get_default_domain; yp_maplist;         yp_master;
     yp_match;             yp_next;             yp_order;
diff --git a/nis/nis_cache.c b/nis/nis_cache.c
new file mode 100644 (file)
index 0000000..8e1d583
--- /dev/null
@@ -0,0 +1,44 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+#include <rpcsvc/nis_cache.h>
+#include <bits/libc-lock.h>
+
+#include "nis_intern.h"
+
+/* XXX Only dummy functions in the moment. The real implementation
+       will follow, if we have a working nis_cachemgr */
+directory_obj *
+__cache_search (const_nis_name name)
+{
+  return NULL;
+}
+
+nis_error 
+__cache_add (fd_result *fd)
+{
+  return NIS_FAIL;
+}
index 08a20ac..f25b801 100644 (file)
@@ -17,6 +17,7 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
+#include <fcntl.h>
 #include <string.h>
 #include <rpc/rpc.h>
 #include <rpc/auth.h>
 #include <arpa/inet.h>
 #include "nis_intern.h"
 
-static struct timeval TIMEOUT = {25, 0};
-static int const MAXTRIES = 3;
+static struct timeval TIMEOUT = {10, 0};
+
+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 trys;                    /* How many server have we tried ? */
+  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 ? */
+  time_t create;                 /* Binding creation time */
+  struct sockaddr_in addr;       /* Server's IP address */
+  int socket;                    /* Server's local socket */
+  unsigned short port;           /* Local port */
+};
+typedef struct dir_binding dir_binding;
+
+static inline u_int
+__nis_ping (const nis_server *serv, u_int serv_len)
+{
+  return 0;
+}
 
 static unsigned long
 inetstr2int (const char *str)
@@ -53,110 +76,217 @@ inetstr2int (const char *str)
   return inet_addr (buffer);
 }
 
-static CLIENT *
-__nis_dobind (const nis_server *server, u_long flags)
+static void
+__bind_destroy (dir_binding *bind)
 {
-  struct sockaddr_in clnt_saddr;
-  int clnt_sock;
-  size_t i;
-  CLIENT *client = NULL;
-
-  memset (&clnt_saddr, '\0', sizeof clnt_saddr);
-  clnt_saddr.sin_family = AF_INET;
-  for (i = 0; i < server->ep.ep_len; i++)
+  if (bind->clnt != NULL)
     {
-      if (strcmp (server->ep.ep_val[i].family, "loopback") == 0)
+      if (bind->use_auth)
+       auth_destroy (bind->clnt->cl_auth);
+      clnt_destroy (bind->clnt);
+    }
+  free (bind->server_val);
+  free (bind);
+}
+
+static nis_error
+__bind_next (dir_binding *bind)
+{
+  if (bind->trys >= bind->server_len)
+    return NIS_FAIL;
+  
+  bind->server_used++;
+  if (bind->server_used >= bind->server_len)
+    bind->server_used = 0;
+
+  if (bind->clnt != NULL)
+    {
+      if (bind->use_auth)
+       auth_destroy (bind->clnt->cl_auth);
+      clnt_destroy (bind->clnt);
+      bind->clnt = NULL;
+    }
+  
+  return NIS_SUCCESS;
+}
+
+static nis_error
+__bind_connect (dir_binding *dbp)
+{
+  struct sockaddr_in check;
+  nis_server *serv;
+  int checklen;
+  u_int i;
+
+  if (dbp == NULL)
+    return NIS_FAIL;
+
+  serv = &dbp->server_val[dbp->server_used];
+
+  memset (&dbp->addr, '\0', sizeof (dbp->addr));
+  dbp->addr.sin_family = AF_INET;
+  for (i = 0; i < serv->ep.ep_len; ++i)
+    {
+      if (strcmp (serv->ep.ep_val[i].family, "inet") == 0)
        {
-         if (server->ep.ep_val[i].uaddr[i] == '-')
-           clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+         if (dbp->use_udp)
+           {
+             if (strcmp (serv->ep.ep_val[i].proto, "udp") == 0)
+               dbp->addr.sin_addr.s_addr =
+                 inetstr2int (serv->ep.ep_val[i].uaddr);
+             else
+               continue;
+           }
          else
-           if (strcmp (server->ep.ep_val[i].proto, "udp") == 0)
-             {
-               if ((flags & USE_DGRAM) == USE_DGRAM)
-                 clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
-               else
-                 continue;
-             }
-           else
-             if (strcmp (server->ep.ep_val[i].proto, "tcp") == 0)
-               {
-                 if ((flags & USE_DGRAM) == USE_DGRAM)
-                   continue;
-                 else
-                   clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
-               }
+           if (strcmp (serv->ep.ep_val[i].proto, "tcp") == 0)
+             dbp->addr.sin_addr.s_addr =
+               inetstr2int (serv->ep.ep_val[i].uaddr);
        }
       else
-       if (strcmp (server->ep.ep_val[i].family, "inet") == 0)
-         {
-           if (server->ep.ep_val[i].uaddr[i] == '-')
-             clnt_saddr.sin_addr.s_addr =
-               inetstr2int (server->ep.ep_val[i].uaddr);
-           else
-             if (strcmp (server->ep.ep_val[i].proto, "udp") == 0)
-               {
-                 if ((flags & USE_DGRAM) == USE_DGRAM)
-                   clnt_saddr.sin_addr.s_addr =
-                     inetstr2int (server->ep.ep_val[i].uaddr);
-                 else
-                   continue;
-               }
-             else
-               if (strcmp (server->ep.ep_val[i].proto, "tcp") == 0)
-                 {
-                   if ((flags & USE_DGRAM) == USE_DGRAM)
-                     continue;
-                   else
-                     clnt_saddr.sin_addr.s_addr =
-                       inetstr2int (server->ep.ep_val[i].uaddr);
-                 }
-         }
-       else
-         continue;
-
-      clnt_sock = RPC_ANYSOCK;
-      if ((flags & USE_DGRAM) == USE_DGRAM)
-       client = clntudp_create (&clnt_saddr, NIS_PROG, NIS_VERSION,
-                                TIMEOUT, &clnt_sock);
-      else
-       client = clnttcp_create (&clnt_saddr, NIS_PROG, NIS_VERSION,
-                                &clnt_sock, 0, 0);
-
-      if (client == NULL)
        continue;
-      if (clnt_call (client, 0, (xdrproc_t) xdr_void, NULL,
-                    (xdrproc_t) xdr_void, NULL, TIMEOUT) != RPC_SUCCESS)
+    }
+  if (dbp->addr.sin_addr.s_addr == 0)
+    return NIS_FAIL;
+
+  dbp->socket = RPC_ANYSOCK;
+  if (dbp->use_udp)
+    dbp->clnt = clntudp_create (&dbp->addr, NIS_PROG, NIS_VERSION,
+                                TIMEOUT, &dbp->socket);
+  else
+    dbp->clnt = clnttcp_create (&dbp->addr, NIS_PROG, NIS_VERSION,
+                                &dbp->socket, 0, 0);
+  
+  if (dbp->clnt == NULL)
+    return NIS_RPCERROR;
+  
+  clnt_control (dbp->clnt, CLSET_TIMEOUT, (caddr_t)&TIMEOUT);
+  /* If the program exists, close the socket */
+  if (fcntl (dbp->socket, F_SETFD, 1) == -1)
+    perror (_("fcntl: F_SETFD"));
+  
+  if (dbp->use_auth)
+    {
+#if defined(HAVE_SECURE_RPC)
+      if (serv->key_type == NIS_PK_DH)
        {
-         clnt_destroy (client);
-         continue;
+         char netname[MAXNETNAMELEN+1];
+         char *p;
+         
+         p = stpcpy (netname, "unix.");
+         strncpy (p, serv->name,MAXNETNAMELEN-5);
+         netname[MAXNETNAMELEN] = '\0';
+         p = strchr (netname, '.');
+         *p = '@';
+         dbp->clnt->cl_auth =
+           authdes_pk_create (netname, &serv->pkey, 300, NULL, NULL);
+         if (!dbp->clnt->cl_auth)
+           dbp->clnt->cl_auth = authunix_create_default ();
        }
+      else
+#endif
+       dbp->clnt->cl_auth = authunix_create_default ();
+      dbp->use_auth = TRUE;
+    }
+  
+  /* Get port for sanity checks later */
+  checklen = sizeof (struct sockaddr_in);
+  memset (&check, 0, checklen);
+  if (dbp->use_udp)
+    bind (dbp->socket, (struct sockaddr *)&check, checklen);
+  check.sin_family = AF_INET;
+  if (!getsockname (dbp->socket, (struct sockaddr *)&check, &checklen))
+    dbp->port = check.sin_port;
+
+  dbp->create = time (NULL);
+
+  return NIS_SUCCESS;
+}
 
-      if ((flags & NO_AUTHINFO) != NO_AUTHINFO)
+static dir_binding *
+__bind_create (const nis_server *serv_val, u_int serv_len, u_long flags)
+{
+  dir_binding *dbp;
+  u_int i;
+  
+  dbp = calloc (1, sizeof (dir_binding));
+  if (dbp == NULL)
+    return NULL;
+  
+  dbp->server_len = serv_len;
+  dbp->server_val = calloc (1, sizeof (nis_server) * serv_len);
+  if (dbp->server_val == NULL)
+    {
+      free (dbp);
+      return NULL;
+    }
+  
+  for (i = 0; i < serv_len; ++i)
+    {
+      if (serv_val[i].name != NULL)
+       dbp->server_val[i].name = strdup (serv_val[i].name);
+      
+      dbp->server_val[i].ep.ep_len = serv_val[i].ep.ep_len;
+      if (dbp->server_val[i].ep.ep_len > 0)
        {
-#if defined(HAVE_SECURE_RPC)
-         if (server->key_type == NIS_PK_DH && getenv ("NO_SECURE_RPC") == NULL)
+         unsigned long j;
+         
+         dbp->server_val[i].ep.ep_val =
+           malloc (serv_val[i].ep.ep_len * sizeof (endpoint));
+         for (j = 0; j < dbp->server_val[i].ep.ep_len; ++j)
            {
-             char netname[MAXNETNAMELEN+1];
-             char *p;
-
-             p = stpcpy (netname, "unix.");
-             strncpy (p, server->name,MAXNETNAMELEN-5);
-             netname[MAXNETNAMELEN] = '\0';
-             p = strchr (netname, '.');
-             *p = '@';
-             client->cl_auth =
-               authdes_pk_create (netname, &server->pkey, 300, NULL, NULL);
-             if (!client->cl_auth)
-               client->cl_auth = authunix_create_default ();
+             if (serv_val[i].ep.ep_val[j].uaddr)
+               dbp->server_val[i].ep.ep_val[j].uaddr =
+                 strdup (serv_val[i].ep.ep_val[j].uaddr);
+             else
+               dbp->server_val[i].ep.ep_val[j].uaddr = NULL;
+             if (serv_val[i].ep.ep_val[j].family)
+               dbp->server_val[i].ep.ep_val[j].family =
+                 strdup (serv_val[i].ep.ep_val[j].family);
+             else
+               dbp->server_val[i].ep.ep_val[j].family = NULL;
+             if (serv_val[i].ep.ep_val[j].proto)
+               dbp->server_val[i].ep.ep_val[j].proto =
+                 strdup (serv_val[i].ep.ep_val[j].proto);
+             else
+               dbp->server_val[i].ep.ep_val[j].proto = NULL;
            }
-         else
-#endif
-           client->cl_auth = authunix_create_default ();
        }
-      return client;
+      else
+       dbp->server_val[i].ep.ep_val = NULL;
+      dbp->server_val[i].key_type = serv_val[i].key_type;
+      dbp->server_val[i].pkey.n_len = serv_val[i].pkey.n_len;
+      if (serv_val[i].pkey.n_len > 0)
+       {
+         dbp->server_val[i].pkey.n_bytes =
+           malloc (serv_val[i].pkey.n_len);
+         if (dbp->server_val[i].pkey.n_bytes == NULL)
+           return NULL;
+         memcpy (dbp->server_val[i].pkey.n_bytes, serv_val[i].pkey.n_bytes,
+                 serv_val[i].pkey.n_len);
+       }
+      else
+       dbp->server_val[i].pkey.n_bytes = NULL;
     }
+  
+  dbp->server_used = __nis_ping (dbp->server_val, dbp->server_len);
+  if (flags & USE_DGRAM)
+    dbp->use_udp = TRUE;
+  else
+    dbp->use_udp = FALSE;
 
-  return NULL;
+  if (flags & NO_AUTHINFO)
+    dbp->use_auth = FALSE;
+  else
+    dbp->use_auth = TRUE;
+
+  if (flags & MASTER_ONLY)
+    dbp->master_only = TRUE;
+  else
+    dbp->master_only = FALSE;
+
+  dbp->trys = 1;
+
+  return dbp;
 }
 
 nis_error
@@ -164,89 +294,84 @@ __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)
 {
-  CLIENT *clnt;
-  int try, result;
-
-  try = 0;
-  result = NIS_NAMEUNREACHABLE;
-
-  if (((flags & MASTER_ONLY) == MASTER_ONLY) && server_len > 1)
-    server_len = 1; /* The first entry is the master */
-
-  while (try < MAXTRIES && result != RPC_SUCCESS)
+  enum clnt_stat result;
+  nis_error retcode;
+  dir_binding *dbp;
+
+  if (flags & MASTER_ONLY) 
+    server_len = 1;
+  
+  dbp = __bind_create (server, server_len, flags);
+  while (__bind_connect (dbp) != NIS_SUCCESS)
     {
-      unsigned int i;
-
-      if ((flags & HARD_LOOKUP) == 0)
-       ++try;
-
-      for (i = 0; i < server_len; i++)
+      if (__bind_next (dbp) != NIS_SUCCESS)
        {
-         if ((clnt = __nis_dobind (&server[i], flags)) == NULL)
-           continue;
-
-         result = clnt_call (clnt, prog, xargs, req, xres, resp, TIMEOUT);
-
-         if (result != RPC_SUCCESS)
-           {
-             clnt_perror (clnt, "do_niscall: clnt_call");
-             clnt_destroy (clnt);
-             result = NIS_RPCERROR;
-           }
-         else
-           clnt_destroy (clnt);
+         __bind_destroy (dbp);
+         return NIS_NAMEUNREACHABLE;
        }
     }
 
-  return result;
-}
-
-static directory_obj *
-dir_lookup (const_nis_name name, nis_server *serv, u_long flags)
-{
-  CLIENT *clnt;
-  int try, result;
-  nis_result *res;
-  struct ns_request req;
-  directory_obj *dir;
-
-  res = calloc (1, sizeof (nis_result));
-  req.ns_name = (char *)name;
-  req.ns_object.ns_object_len = 0;
-  req.ns_object.ns_object_val = NULL;
-  try = 0;
-  result = NIS_NAMEUNREACHABLE;
-
-  while (try < MAXTRIES && result != RPC_SUCCESS)
+  do
     {
-      if ((clnt = __nis_dobind (serv, flags)) == NULL)
-       continue;
-
-      result = clnt_call (clnt, NIS_LOOKUP, (xdrproc_t) xdr_ns_request,
-                         (caddr_t) &req, (xdrproc_t) xdr_nis_result,
-                         (caddr_t) res, TIMEOUT);
-
+    again:
+      result = clnt_call (dbp->clnt, prog, xargs, req, xres, resp, TIMEOUT);
+      
       if (result != RPC_SUCCESS)
        {
-         clnt_perror (clnt, "do_niscall: clnt_call");
-         clnt_destroy (clnt);
-         result = NIS_RPCERROR;
+         clnt_perror (dbp->clnt, "__do_niscall2: clnt_call");
+         __bind_destroy (dbp);
+         retcode = NIS_RPCERROR;
        }
       else
-       clnt_destroy (clnt);
+       {
+         switch (prog)
+           {
+           case NIS_LOOKUP:
+           case NIS_ADD:
+           case NIS_MODIFY:
+           case NIS_REMOVE:
+           case NIS_IBLIST:
+           case NIS_IBADD:
+           case NIS_IBMODIFY:
+           case NIS_IBREMOVE:
+           case NIS_IBFIRST:
+           case NIS_IBNEXT:
+             if ((((nis_result *)xres)->status != NIS_SUCCESS) &&
+                 (((nis_result *)xres)->status != NIS_S_SUCCESS))
+               if (__bind_next (dbp) == NIS_SUCCESS)
+                 goto again;
+           case NIS_FINDDIRECTORY:
+             if (((fd_result *)xres)->status != NIS_SUCCESS)
+               if (__bind_next (dbp) == NIS_SUCCESS)
+                 goto again;
+             break;
+#if 0
+           case NIS_STATUS: /* nis_taglist */
+           case NIS_SERVSTATE:
+             break;
+           case NIS_DUMPLOG: /* log_result */
+           case NIS_DUMP:
+             break;
+           case NIS_CHECKPOINT: /* cp_result */
+             break;
+#endif
+           default:
+             break;
+           }
+         __bind_destroy (dbp);
+         retcode = NIS_SUCCESS;
+       }
     }
-  if (result != RPC_SUCCESS || res->status != NIS_SUCCESS)
-    return NULL;
-
-  dir = nis_clone_directory (&res->objects.objects_val->DI_data, NULL);
-  nis_freeresult (res);
-
-  return dir;
+  while ((flags & HARD_LOOKUP) && retcode == NIS_RPCERROR);
+  
+  return retcode; 
 }
 
 static directory_obj *
 rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags)
 {
+  fd_result *fd_res;
+  XDR xdrs;
   char domain [strlen (name) + 3];
 
   nis_domain_of_r (name, domain, sizeof (domain));
@@ -287,8 +412,20 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags)
        /* The root server of our domain is a replica of the parent
           domain ! (Now I understand why a root server must be a
           replica of the parent domain) */
-       obj = dir_lookup (ndomain, dir->do_servers.do_servers_val,
-                         flags);
+       fd_res = __nis_finddirectory (dir, ndomain);
+       if (fd_res->status != NIS_SUCCESS)
+         {
+           nis_free_directory (dir);
+           xdr_free((xdrproc_t)xdr_fd_result, (caddr_t)fd_res);
+           return NULL;
+         }
+       __cache_add (fd_res);
+       obj = calloc(1, sizeof(directory_obj));
+       xdrmem_create(&xdrs, fd_res->dir_data.dir_data_val,
+                     fd_res->dir_data.dir_data_len, XDR_DECODE);
+       xdr_directory_obj(&xdrs, obj);
+       xdr_destroy(&xdrs);
+       xdr_free((xdrproc_t)xdr_fd_result, (caddr_t)fd_res);
        if (obj != NULL)
          {
            /* We have found a NIS+ server serving ndomain, now
@@ -303,15 +440,14 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags)
            return NULL;
          }
       }
-      break;
+    break;
     case LOWER_NAME:
       {
        directory_obj *obj;
        char leaf [strlen (name) + 3];
        char ndomain [strlen (name) + 3];
-       u_int i;
        char *cp;
-
+       
        do
          {
            if (strlen (domain) == 0)
@@ -327,21 +463,30 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags)
        cp = strchr (leaf, '\0');
        *cp++ = '.';
        strcpy (cp, domain);
-
-       for (i = 0; i < dir->do_servers.do_servers_len; ++i)
+       
+       fd_res = __nis_finddirectory (dir, leaf);
+       if (fd_res->status != NIS_SUCCESS)
          {
-           obj = dir_lookup (leaf, &dir->do_servers.do_servers_val[i],
-                             flags);
-           if (obj != NULL)
-             {
-               /* We have found a NIS+ server serving ndomain, now
-                  let us search for "name" */
-               nis_free_directory (dir);
-               return rec_dirsearch (name, obj, flags);
-             }
+           nis_free_directory (dir);
+           xdr_free((xdrproc_t)xdr_fd_result, (caddr_t)fd_res);
+           return NULL;
+         }
+       __cache_add (fd_res);
+       obj = calloc(1, sizeof(directory_obj));
+       xdrmem_create(&xdrs, fd_res->dir_data.dir_data_val,
+                     fd_res->dir_data.dir_data_len, XDR_DECODE);
+       xdr_directory_obj(&xdrs, obj);
+       xdr_destroy(&xdrs);
+       xdr_free((xdrproc_t)xdr_fd_result, (caddr_t)fd_res);
+       if (obj != NULL)
+         {
+           /* We have found a NIS+ server serving ndomain, now
+              let us search for "name" */
+           nis_free_directory (dir);
+           return rec_dirsearch (name, obj, flags);
          }
       }
-      break;
+    break;
     case BAD_NAME:
       nis_free_directory (dir);
       return NULL;
@@ -354,37 +499,44 @@ 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_error result;
+  nis_error retcode;
   directory_obj *dir = NULL;
-  const nis_server *server;
+  nis_server *server;
   u_int server_len;
 
+  if (name == NULL)
+    return NIS_BADNAME;
 
-  dir = readColdStartFile ();
-  if (dir == NULL) /* No /var/nis/NIS_COLD_START -> no NIS+ installed */
-    return NIS_UNAVAIL;
-
-  if (name != NULL)
+  if ((flags & NO_CACHE) !=  NO_CACHE)
+    dir = __cache_search (name);
+  
+  if (dir == NULL)
     {
+      dir = readColdStartFile ();
+      if (dir == NULL) /* No /var/nis/NIS_COLD_START->no NIS+ installed */
+       return NIS_UNAVAIL;
+      
       dir = rec_dirsearch (name, dir, flags);
       if (dir == NULL)
-       {
-         if (nis_dir_cmp (nis_local_directory(), name) == NOT_SEQUENTIAL)
-           return NIS_NAMEUNREACHABLE;
-         else
-           return NIS_NOTFOUND;
-       }
+       return NIS_NOTFOUND;
     }
-  server = dir->do_servers.do_servers_val;
-  server_len = dir->do_servers.do_servers_len;
 
-  if (((flags & MASTER_ONLY) == MASTER_ONLY) && server_len > 1)
-    server_len = 1; /* The first entry is the master */
-
-  result = __do_niscall2 (server, server_len, prog, xargs, req, xres,
-                         resp, flags);
-  if (dir != NULL)
-    nis_free_directory (dir);
+  if (flags & MASTER_ONLY) 
+    {
+      server = dir->do_servers.do_servers_val;
+      server_len = 1;
+    }
+  else
+    {
+      server = dir->do_servers.do_servers_val;
+      server_len = dir->do_servers.do_servers_len;
+    }
+  
+  
+  retcode = __do_niscall2 (server, server_len, prog, xargs, req, xres, resp,
+                          flags);
+  
+  nis_free_directory (dir);
 
-  return result;
+  return retcode;
 }
diff --git a/nis/nis_intern.c b/nis/nis_intern.c
deleted file mode 100644 (file)
index 7bfa263..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/* Copyright (c) 1997 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-#include <string.h>
-#include <rpcsvc/nis.h>
-#include <rpcsvc/nislib.h>
-#include "nis_intern.h"
-
-/* Nearly the same as nis_getnames, but nis_getnames stopped
-   when 2 points left */
-nis_name *
-__nis_expandname (const char *name)
-{
-  nis_name *getnames = NULL;
-  char local_domain[NIS_MAXNAMELEN + 1];
-  char *path, *cp;
-  int count, pos;
-
-  strncpy (local_domain, nis_local_directory (), NIS_MAXNAMELEN);
-  local_domain[NIS_MAXNAMELEN] = '\0';
-
-  count = 1;
-  if ((getnames = malloc ((count + 1) * sizeof (char *))) == NULL)
-    return NULL;
-
-  /* Do we have a fully qualified NIS+ name ? If yes, give it back */
-  if (name[strlen (name) - 1] == '.')
-    {
-      if ((getnames[0] = strdup (name)) == NULL)
-       {
-         free (getnames);
-         return NULL;
-       }
-      getnames[1] = NULL;
-
-      return getnames;
-    }
-
-  /* Get the search path, where we have to search "name" */
-  path = getenv ("NIS_PATH");
-  if (path == NULL)
-    path = strdupa ("$");
-  else
-    path = strdupa (path);
-
-  pos = 0;
-
-  cp = strtok (path, ":");
-  while (cp)
-    {
-      if (strcmp (cp, "$") == 0)
-       {
-         char *cptr = local_domain;
-         char *tmp;
-
-         while (*cptr != '\0')
-           {
-             if (pos >= count)
-               {
-                 count += 5;
-                 getnames = realloc (getnames, (count + 1) * sizeof (char *));
-               }
-             tmp = malloc (strlen (cptr) + strlen (local_domain) +
-                           strlen (name) + 2);
-             if (tmp == NULL)
-               return NULL;
-
-             getnames[pos] = tmp;
-             tmp = stpcpy (tmp, name);
-             if (*cptr != '.')
-               *tmp++ = '.';
-             stpcpy (tmp, cptr);
-
-             ++pos;
-
-             ++cptr;
-             while ((*cptr != '\0') && (*cptr != '.'))
-               ++cptr;
-
-             if ((*cptr == '.') && (cptr[1] != '\0'))
-               ++cptr;
-           }
-       }
-      else
-       {
-         char *tmp;
-
-         if (cp[strlen (cp) - 1] == '$')
-           {
-             tmp = malloc (strlen (cp) + strlen (local_domain) +
-                           strlen (name) + 2);
-             if (tmp == NULL)
-               return NULL;
-
-             getnames[pos] = tmp;
-             tmp = stpcpy (tmp, name);
-             *tmp++ = '.';
-             tmp = stpcpy (tmp, cp);
-             --tmp;
-             if (tmp[- 1] != '.')
-               *tmp++ = '.';
-             stpcpy (tmp, local_domain);
-           }
-         else
-           {
-             tmp = malloc (strlen (cp) + strlen (name) + 2);
-             if (tmp == NULL)
-               return NULL;
-
-             tmp = stpcpy (tmp, name);
-             *tmp++ = '.';
-             stpcpy (tmp, cp);
-           }
-
-         if (pos > count)
-           {
-             count += 5;
-             getnames = realloc (getnames, (count + 1) * sizeof (char *));
-           }
-         getnames[pos] = tmp;
-         pos++;
-       }
-      cp = strtok (NULL, ":");
-    }
-
-  getnames[pos] = NULL;
-
-  return getnames;
-}
index 25c88a2..a7cb785 100644 (file)
 
 __BEGIN_DECLS
 
-extern 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);
-extern 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);
+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));
+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,
+                                   u_long flags));
 #if defined (HAVE_SECURE_RPC)
-extern AUTH *authdes_pk_create (const char *, const netobj *, u_int,
-                               struct sockaddr *, des_block *);
+extern AUTH *authdes_pk_create __P ((const char *, const netobj *, u_int,
+                                    struct sockaddr *, des_block *));
 #endif
-extern nis_name *__nis_expandname (const char *);
+
+/* NIS+ cache */
+extern directory_obj *__cache_search __P ((const_nis_name name));
+extern nis_error __cache_add __P ((fd_result *));
 
 __END_DECLS
 
index 6f5b12b..82db7b0 100644 (file)
@@ -30,128 +30,94 @@ nis_lookup (const_nis_name name, const u_long flags)
   struct ns_request req;
   nis_name *names;
   nis_error status;
-  int is_link = 1;      /* We should go at least once in the while loop */
   int count_links = 0;  /* We will follow only 16 links in the deep */
-  int i;
+  int done = 0;
+  int name_nr = 0;
+  nis_name namebuf[2] = {NULL, NULL};
 
   res = calloc (1, sizeof (nis_result));
 
   if (flags & EXPAND_NAME)
     {
-      names = __nis_expandname (name);
+      names = nis_getnames (name);
       if (names == NULL)
        {
          res->status = NIS_NAMEUNREACHABLE;
          return res;
        }
-
-      i = 0;
-      while (names[i] != NULL && (i == 0 || res->status > 1))
-       {
-         req.ns_name = names[i];
-
-         while (is_link)
-           {
-             req.ns_object.ns_object_len = 0;
-             req.ns_object.ns_object_val = NULL;
-             memset (res, '\0', sizeof (nis_result));
-
-             if ((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)) != RPC_SUCCESS)
-               {
-                 res->status = status;
-                 nis_freenames (names);
-                 return res;
-               }
-
-             if ((res->status == NIS_SUCCESS || res->status == NIS_S_SUCCESS)
-                 && (res->objects.objects_len > 0 &&
-                     res->objects.objects_val->zo_data.zo_type == LINK_OBJ))
-               is_link = 1;
-             else
-               is_link = 0;
-
-             if (is_link)
-               {
-                 if ((flags & FOLLOW_LINKS) == FOLLOW_LINKS)
-                   {
-                     if (count_links == 16)
-                       {
-                         res->status = NIS_LINKNAMEERROR;
-                         return res;
-                       }
-                     else
-                       ++count_links;
-
-                     req.ns_name = res->objects.objects_val->LI_data.li_name;
-                   }
-                 else
-                   {
-                     res->status = NIS_NOTSEARCHABLE;
-                     return res;
-                   }
-               }
-           }
-
-         ++i;
-         if (res->status == NIS_NOT_ME)
-           res->status = NIS_NOSUCHNAME;
-       }
-
-      nis_freenames (names);
     }
   else
     {
-      req.ns_name = (char *)name;
+      names = namebuf;
+      names[0] = (nis_name) name;
+    }
 
-      while (is_link)
+  req.ns_name = names[0];
+  while (!done)
+    {
+      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);
+      if (status != NIS_SUCCESS)
+       res->status = status;
+
+      switch (res->status)
        {
-         req.ns_object.ns_object_len = 0;
-         req.ns_object.ns_object_val = NULL;
-         memset (res, '\0', sizeof (nis_result));
-
-         if ((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)) != RPC_SUCCESS)
+       case NIS_PARTIAL:
+       case NIS_SUCCESS:
+       case NIS_S_SUCCESS:
+         if (__type_of(NIS_RES_OBJECT (res)) == LINK_OBJ &&
+             flags & FOLLOW_LINKS) /* We are following links */
            {
-             res->status = status;
-             return res;
+             /* if we hit the link limit, bail */
+             if (count_links > NIS_MAXLINKS)
+               {
+                 res->status = NIS_LINKNAMEERROR;
+                 ++done;
+                 break;
+               }
+             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->status == NIS_SUCCESS || res->status == NIS_S_SUCCESS) &&
-             (res->objects.objects_len > 0 &&
-              res->objects.objects_val->zo_data.zo_type == LINK_OBJ))
-           is_link = 1;
          else
-           is_link = 0;
-
-         if (is_link)
+           ++done;
+         break;
+       case NIS_CBRESULTS:
+         /* XXX Implement CALLBACK here ! */
+         ++done;
+         break;
+       default:
+         /* Try the next domainname if we don't follow a link */
+         if (count_links)
            {
-             if ((flags & FOLLOW_LINKS) == FOLLOW_LINKS)
-               {
-                 if (count_links == 16)
-                   {
-                     res->status = NIS_LINKNAMEERROR;
-                     return res;
-                   }
-                 else
-                   ++count_links;
-
-                 req.ns_name = res->objects.objects_val->LI_data.li_name;
-               }
-             else
-               {
-                 res->status = NIS_NOTSEARCHABLE;
-                 return res;
-               }
+             free (req.ns_name);
+             res->status = NIS_LINKNAMEERROR;
+             ++done;
+             break;
            }
+         ++name_nr;
+         if (names[name_nr] == NULL)
+           {
+             ++done;
+             break;
+           }
+         req.ns_name = names[name_nr];
+         break;
        }
     }
 
+  if (names != namebuf)
+    nis_freenames (names);
+
   return res;
 }
index f829994..1914840 100644 (file)
@@ -77,6 +77,41 @@ nis_flags2str (const u_long flags)
   return buf;
 }
 
+static void
+nis_print_objtype (enum zotypes type)
+{
+  switch (type)
+    {
+    case BOGUS_OBJ:
+      fputs (_("BOGUS OBJECT\n"), stdout);
+      break;
+    case NO_OBJ:
+      fputs (_("NO OBJECT\n"), stdout);
+      break;
+    case DIRECTORY_OBJ:
+      fputs (_("DIRECTORY\n"), stdout);
+      break;
+    case GROUP_OBJ:
+      fputs (_("GROUP\n"), stdout);
+      break;
+    case TABLE_OBJ:
+      fputs (_("TABLE\n"), stdout);
+      break;
+    case ENTRY_OBJ:
+      fputs (_("ENTRY\n"), stdout);
+      break;
+    case LINK_OBJ:
+      fputs (_("LINK\n"), stdout);
+      break;
+    case PRIVATE_OBJ:
+      fputs (_("PRIVATE\n"), stdout);
+      break;
+    default:
+      fputs (_("(Unknown object)\n"), stdout);
+      break;
+    }
+}
+
 void
 nis_print_rights (const u_long access)
 {
@@ -218,9 +253,10 @@ nis_print_table (const table_obj *obj)
 void
 nis_print_link (const link_obj *obj)
 {
-  printf (_("Type : %d\n"), obj->li_rtype);
-  printf (_("Name : %s\n"), obj->li_name);
-  printf (_("Attributes : %d\n"), obj->li_attrs.li_attrs_len);
+  fputs (_("Linked Object Type : "), stdout);
+  nis_print_objtype (obj->li_rtype);
+  printf (_("Linked to : %s\n"), obj->li_name);
+  /* XXX Print the attributs here, if they exists */
 }
 
 void
@@ -255,41 +291,29 @@ nis_print_object (const nis_object * obj)
   printf (_("Creation Time : %s"), ctime (&obj->zo_oid.ctime));
   printf (_("Mod. Time     : %s"), ctime (&obj->zo_oid.mtime));
   fputs (_("Object Type   : "), stdout);
+  nis_print_objtype (obj->zo_data.zo_type);
   switch (obj->zo_data.zo_type)
     {
-    case BOGUS_OBJ:
-      fputs (_("BOGUS OBJECT\n"), stdout);
-      break;
-    case NO_OBJ:
-      fputs (_("NO OBJECT\n"), stdout);
-      break;
     case DIRECTORY_OBJ:
-      fputs (_("DIRECTORY\n"), stdout);
       nis_print_directory (&obj->zo_data.objdata_u.di_data);
       break;
     case GROUP_OBJ:
-      fputs (_("GROUP\n"), stdout);
       nis_print_group (&obj->zo_data.objdata_u.gr_data);
       break;
     case TABLE_OBJ:
-      fputs (_("TABLE\n"), stdout);
       nis_print_table (&obj->zo_data.objdata_u.ta_data);
       break;
     case ENTRY_OBJ:
-      fputs (_("ENTRY\n"), stdout);
       nis_print_entry (&obj->zo_data.objdata_u.en_data);
       break;
     case LINK_OBJ:
-      fputs (_("LINK\n"), stdout);
       nis_print_link (&obj->zo_data.objdata_u.li_data);
       break;
     case PRIVATE_OBJ:
-      fputs (_("PRIVATE\n"), stdout);
       printf (_("    Data Length = %u\n"),
              obj->zo_data.objdata_u.po_data.po_data_len);
       break;
     default:
-      fputs (_("(Unknown object)\n"), stdout);
       break;
     }
 }
index 780c27f..fcd1903 100644 (file)
@@ -116,8 +116,7 @@ nis_getnames (const_nis_name name)
   nis_name *getnames = NULL;
   char local_domain[NIS_MAXNAMELEN + 1];
   char *path, *cp;
-  int count, pos;
-
+  int count, pos, have_point;
 
   strncpy (local_domain, nis_local_directory (), NIS_MAXNAMELEN);
   local_domain[NIS_MAXNAMELEN] = '\0';
@@ -146,6 +145,8 @@ nis_getnames (const_nis_name name)
   else
     path = strdupa (path);
 
+  have_point = (strchr (name, '.') != NULL);
+
   pos = 0;
 
   cp = strtok (path, ":");
@@ -156,7 +157,7 @@ nis_getnames (const_nis_name name)
          char *cptr = local_domain;
          char *tmp;
 
-         while (count_dots (cptr) >= 2)
+         while ((have_point && *cptr != '\0') || (count_dots (cptr) >= 2))
            {
              if (pos >= count)
                {
@@ -171,13 +172,18 @@ nis_getnames (const_nis_name name)
              getnames[pos] = tmp;
              tmp = stpcpy (tmp, name);
              *tmp++ = '.';
-             stpcpy (tmp, cptr);
+             if (cptr[1] != '\0')
+               stpcpy (tmp, cptr);
+             else
+               ++cptr;
 
              ++pos;
 
-             while (*cptr != '.')
+             while (*cptr != '.' && *cptr != '\0')
+               ++cptr;
+             if (cptr[0] != '\0' && cptr[1] != '\0')
+               /* If we have only ".", don't remove the "." */
                ++cptr;
-             ++cptr;
            }
        }
       else
@@ -186,31 +192,35 @@ nis_getnames (const_nis_name name)
 
          if (cp[strlen (cp) - 1] == '$')
            {
+             char *p;
+
              tmp = malloc (strlen (cp) + strlen (local_domain) +
                            strlen (name) + 2);
              if (tmp == NULL)
                return NULL;
 
-             tmp = stpcpy (tmp, name);
-             *tmp++ = '.';
-             tmp = stpcpy (tmp, cp);
-             --tmp;
-             if (tmp[-1] != '.')
-               *tmp++ = '.';
-             stpcpy (tmp, local_domain);
+             p = stpcpy (tmp, name);
+             *p++ = '.';
+             p = stpcpy (p, cp);
+             --p;
+             if (p[-1] != '.')
+               *p++ = '.';
+             stpcpy (p, local_domain);
            }
          else
            {
+             char *p;
+
              tmp = malloc (strlen (cp) + strlen (name) + 2);
              if (tmp == NULL)
                return NULL;
 
-             tmp = stpcpy (tmp, name);
-             *tmp++ = '.';
-             stpcpy (tmp, cp);
+             p = stpcpy (tmp, name);
+             *p++ = '.';
+             stpcpy (p, cp);
            }
 
-         if (pos > count)
+         if (pos >= count)
            {
              count += 5;
              getnames = realloc (getnames, (count + 1) * sizeof (char *));
index 4cfd734..16fd1e6 100644 (file)
@@ -145,18 +145,6 @@ __create_ib_request (const_nis_name name, struct ib_request *ibreq,
             &ibreq->ibr_srch.ibr_srch_val);
   if (ibreq->ibr_name == NULL)
     return NULL;
-  if ((flags & EXPAND_NAME) == EXPAND_NAME)
-    {
-      nis_name *names;
-
-      names = __nis_expandname (ibreq->ibr_name);
-      free (ibreq->ibr_name);
-      ibreq->ibr_name = NULL;
-      if (names == NULL)
-       return NULL;
-      ibreq->ibr_name = strdup (names[0]);
-      nis_freenames (names);
-    }
 
   ibreq->ibr_flags = (flags & (RETURN_RESULT | ADD_OVERWRITE | REM_MULTIPLE |
                               MOD_SAMEOBJ | ADD_RESERVED | REM_RESERVED |
@@ -181,9 +169,12 @@ nis_list (const_nis_name name, u_long flags,
 {
   nis_result *res = NULL;
   struct ib_request ibreq;
-  int result;
-  int count_links = 0;         /* We will only follow 16 links! */
-  int is_link = 1;             /* We should go at least once in the while loop */
+  int status;
+  int count_links = 0;     /* We will only follow 16 links! */
+  int done = 0;
+  nis_name *names;
+  nis_name namebuf[2] = {NULL, NULL};
+  int name_nr = 0;
 
   res = calloc (1, sizeof (nis_result));
 
@@ -193,56 +184,95 @@ nis_list (const_nis_name name, u_long flags,
       return res;
     }
 
-  while (is_link)
+  if (flags & EXPAND_NAME)
     {
-      memset (res, '\0', sizeof (nis_result));
-
-      if ((result = __do_niscall (ibreq.ibr_name, NIS_IBLIST,
-                                 (xdrproc_t) xdr_ib_request,
-                                 (caddr_t) &ibreq, (xdrproc_t) xdr_nis_result,
-                                 (caddr_t) res, flags)) != RPC_SUCCESS)
+      names = nis_getnames (ibreq.ibr_name);
+      free (ibreq.ibr_name);
+      ibreq.ibr_name = NULL;
+      if (names == NULL)
        {
-         res->status = result;
-         nis_free_request (&ibreq);
+         res->status = NIS_BADNAME;
          return res;
        }
+      ibreq.ibr_name = strdup (names[name_nr]);
+    }
+  else
+    names = namebuf;
 
-      nis_free_request (&ibreq);
+  while (!done)
+    {
+      memset (res, '\0', sizeof (nis_result));
 
-      if ((res->status == NIS_SUCCESS || res->status == NIS_S_SUCCESS) &&
-         (res->objects.objects_len > 0 &&
-          res->objects.objects_val->zo_data.zo_type == LINK_OBJ))
-       is_link = 1;
-      else
-       is_link = 0;
+      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);
+      if (status != NIS_SUCCESS)
+       res->status = status;
 
-      if (is_link)
+      switch (res->status)
        {
-         if ((flags & FOLLOW_LINKS) == FOLLOW_LINKS)
+       case NIS_PARTIAL:
+       case NIS_SUCCESS:
+       case NIS_S_SUCCESS:
+         if (__type_of(NIS_RES_OBJECT (res)) == LINK_OBJ &&
+             flags & FOLLOW_LINKS) /* We are following links */
            {
-             if (count_links == 16)
+             /* if we hit the link limit, bail */
+             if (count_links > NIS_MAXLINKS)
                {
                  res->status = NIS_LINKNAMEERROR;
-                 return res;
-               }
-             else
-               ++count_links;
-
-             if (__create_ib_request (res->objects.objects_val->LI_data.li_name,
-                                      &ibreq, flags) == NULL)
-               {
-                 res->status = NIS_BADNAME;
-                 return res;
+                 ++done;
+                 break;
                }
+             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)
+                 {
+                   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;
+                 }
+             nis_freeresult (res);
+             res = calloc (1, sizeof (nis_result));
            }
          else
+           ++done;
+         break;
+       case NIS_CBRESULTS:
+         /* XXX Implement CALLBACK here ! */
+         ++done;
+         break;
+       default:
+         /* Try the next domainname if we don't follow a link */
+         if (count_links)
+           {
+             free (ibreq.ibr_name);
+             res->status = NIS_LINKNAMEERROR;
+             ++done;
+             break;
+           }
+         ++name_nr;
+         if (names[name_nr] == NULL)
            {
-             res->status = NIS_NOTSEARCHABLE;
-             return res;
+             ++done;
+             break;
            }
+         ibreq.ibr_name = names[name_nr];
+         break;
        }
     }
 
+  if (names != namebuf)
+    nis_freenames (names);
+
+  nis_free_request (&ibreq);
+
   if (callback != NULL &&
       (res->status == NIS_SUCCESS || res->status == NIS_S_SUCCESS))
     {
@@ -279,34 +309,34 @@ nis_add_entry (const_nis_name name, const nis_object *obj,
   ibreq.ibr_obj.ibr_obj_val = nis_clone_object (obj, NULL);
   ibreq.ibr_obj.ibr_obj_len = 1;
 
-  p1 = ibreq.ibr_obj.ibr_obj_val[0].zo_name;
+  p1 = ibreq.ibr_obj.ibr_obj_val->zo_name;
   if (p1 == NULL || strlen (p1) == 0)
-    ibreq.ibr_obj.ibr_obj_val[0].zo_name =
+    ibreq.ibr_obj.ibr_obj_val->zo_name =
       nis_leaf_of_r (name, buf1, sizeof (buf1));
 
-  p2 = ibreq.ibr_obj.ibr_obj_val[0].zo_owner;
+  p2 = ibreq.ibr_obj.ibr_obj_val->zo_owner;
   if (p2 == NULL || strlen (p2) == 0)
-    ibreq.ibr_obj.ibr_obj_val[0].zo_owner = nis_local_principal ();
+    ibreq.ibr_obj.ibr_obj_val->zo_owner = nis_local_principal ();
 
-  p3 = ibreq.ibr_obj.ibr_obj_val[0].zo_group;
+  p3 = ibreq.ibr_obj.ibr_obj_val->zo_group;
   if (p3 == NULL || strlen (p3) == 0)
-    ibreq.ibr_obj.ibr_obj_val[0].zo_group = nis_local_group ();
+    ibreq.ibr_obj.ibr_obj_val->zo_group = nis_local_group ();
 
-  p4 = ibreq.ibr_obj.ibr_obj_val[0].zo_domain;
-  ibreq.ibr_obj.ibr_obj_val[0].zo_domain =
+  p4 = ibreq.ibr_obj.ibr_obj_val->zo_domain;
+  ibreq.ibr_obj.ibr_obj_val->zo_domain =
     nis_domain_of_r (name, buf4, sizeof (buf4));
 
   if ((status = __do_niscall (ibreq.ibr_name, NIS_IBADD,
                              (xdrproc_t) xdr_ib_request,
                              (caddr_t) &ibreq,
                              (xdrproc_t) xdr_nis_result,
-                             (caddr_t) res, 0)) != RPC_SUCCESS)
+                             (caddr_t) res, 0)) != NIS_SUCCESS)
     res->status = status;
 
-  ibreq.ibr_obj.ibr_obj_val[0].zo_name = p1;
-  ibreq.ibr_obj.ibr_obj_val[0].zo_owner = p2;
-  ibreq.ibr_obj.ibr_obj_val[0].zo_group = p3;
-  ibreq.ibr_obj.ibr_obj_val[0].zo_domain = p4;
+  ibreq.ibr_obj.ibr_obj_val->zo_name = p1;
+  ibreq.ibr_obj.ibr_obj_val->zo_owner = p2;
+  ibreq.ibr_obj.ibr_obj_val->zo_group = p3;
+  ibreq.ibr_obj.ibr_obj_val->zo_domain = p4;
 
   nis_free_request (&ibreq);
 
@@ -336,33 +366,33 @@ nis_modify_entry (const_nis_name name, const nis_object *obj,
   ibreq.ibr_obj.ibr_obj_val = nis_clone_object (obj, NULL);
   ibreq.ibr_obj.ibr_obj_len = 1;
 
-  p1 = ibreq.ibr_obj.ibr_obj_val[0].zo_name;
+  p1 = ibreq.ibr_obj.ibr_obj_val->zo_name;
   if (p1 == NULL || strlen (p1) == 0)
-    ibreq.ibr_obj.ibr_obj_val[0].zo_name =
+    ibreq.ibr_obj.ibr_obj_val->zo_name =
       nis_leaf_of_r (name, buf1, sizeof (buf1));
 
-  p2 = ibreq.ibr_obj.ibr_obj_val[0].zo_owner;
+  p2 = ibreq.ibr_obj.ibr_obj_val->zo_owner;
   if (p2 == NULL || strlen (p2) == 0)
-    ibreq.ibr_obj.ibr_obj_val[0].zo_owner = nis_local_principal ();
+    ibreq.ibr_obj.ibr_obj_val->zo_owner = nis_local_principal ();
 
-  p3 = ibreq.ibr_obj.ibr_obj_val[0].zo_group;
+  p3 = ibreq.ibr_obj.ibr_obj_val->zo_group;
   if (p3 == NULL || strlen (p3) == 0)
-    ibreq.ibr_obj.ibr_obj_val[0].zo_group = nis_local_group ();
+    ibreq.ibr_obj.ibr_obj_val->zo_group = nis_local_group ();
 
-  p4 = ibreq.ibr_obj.ibr_obj_val[0].zo_domain;
-  ibreq.ibr_obj.ibr_obj_val[0].zo_domain =
+  p4 = ibreq.ibr_obj.ibr_obj_val->zo_domain;
+  ibreq.ibr_obj.ibr_obj_val->zo_domain =
     nis_domain_of_r (name, buf4, sizeof (buf4));
 
   if ((status = __do_niscall (ibreq.ibr_name, NIS_IBMODIFY,
                              (xdrproc_t) xdr_ib_request,
                              (caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
-                             (caddr_t) res, 0)) != RPC_SUCCESS)
+                             (caddr_t) res, 0)) != NIS_SUCCESS)
     res->status = status;
 
-  ibreq.ibr_obj.ibr_obj_val[0].zo_name = p1;
-  ibreq.ibr_obj.ibr_obj_val[0].zo_owner = p2;
-  ibreq.ibr_obj.ibr_obj_val[0].zo_group = p3;
-  ibreq.ibr_obj.ibr_obj_val[0].zo_domain = p4;
+  ibreq.ibr_obj.ibr_obj_val->zo_name = p1;
+  ibreq.ibr_obj.ibr_obj_val->zo_owner = p2;
+  ibreq.ibr_obj.ibr_obj_val->zo_group = p3;
+  ibreq.ibr_obj.ibr_obj_val->zo_domain = p4;
 
   nis_free_request (&ibreq);
 
@@ -395,7 +425,7 @@ nis_remove_entry (const_nis_name name, const nis_object *obj,
   if ((status = __do_niscall (ibreq.ibr_name, NIS_IBREMOVE,
                              (xdrproc_t) xdr_ib_request,
                              (caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
-                             (caddr_t) res, 0)) != RPC_SUCCESS)
+                             (caddr_t) res, 0)) != NIS_SUCCESS)
     res->status = status;
 
   nis_free_request (&ibreq);
@@ -421,7 +451,7 @@ nis_first_entry (const_nis_name name)
   if ((status = __do_niscall (ibreq.ibr_name, NIS_IBFIRST,
                              (xdrproc_t) xdr_ib_request,
                              (caddr_t) &ibreq, (xdrproc_t) xdr_nis_result,
-                             (caddr_t) res, 0)) != RPC_SUCCESS)
+                             (caddr_t) res, 0)) != NIS_SUCCESS)
     res->status = status;
 
   nis_free_request (&ibreq);
@@ -460,7 +490,7 @@ nis_next_entry (const_nis_name name, const netobj *cookie)
   if ((status = __do_niscall (ibreq.ibr_name, NIS_IBNEXT,
                              (xdrproc_t) xdr_ib_request,
                              (caddr_t) &ibreq, (xdrproc_t) xdr_nis_result,
-                             (caddr_t) res, 0)) != RPC_SUCCESS)
+                             (caddr_t) res, 0)) != NIS_SUCCESS)
     res->status = status;
 
   nis_free_request (&ibreq);
diff --git a/nis/nis_util.c b/nis/nis_util.c
new file mode 100644 (file)
index 0000000..4e39d6f
--- /dev/null
@@ -0,0 +1,99 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <string.h>
+#include <rpcsvc/nis.h>
+#include "nis_intern.h"
+
+fd_result *
+__nis_finddirectory (directory_obj *dir, const_nis_name name)
+{
+  fd_args fd_args;
+  fd_result *fd_res;
+
+  fd_args.dir_name = strdup (name);
+  fd_args.requester = nis_local_host();
+  fd_res = calloc (1, sizeof (fd_result));
+      
+  if (__do_niscall2 (dir->do_servers.do_servers_val, 
+                    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) != NIS_SUCCESS)
+    fd_res->status = NIS_RPCERROR;
+  
+  return fd_res;
+}
+
+/* This is from libc/db/hash/hash_func.c, hash3 is static there */
+/*
+ * This is INCREDIBLY ugly, but fast.  We break the string up into 8 byte
+ * units.  On the first time through the loop we get the "leftover bytes"
+ * (strlen % 8).  On every other iteration, we perform 8 HASHC's so we handle
+ * all 8 bytes.  Essentially, this saves us 7 cmp & branch instructions.  If
+ * this routine is heavily used enough, it's worth the ugly coding.
+ *
+ * OZ's original sdbm hash
+ */
+unsigned long
+__nis_hash (const void *keyarg, register size_t len)
+{
+  register const u_char *key;
+  register size_t loop;
+  register u_int32_t h;
+  
+#define HASHC   h = *key++ + 65599 * h
+  
+  h = 0;
+  key = keyarg;
+  if (len > 0) 
+    {
+      loop = (len + 8 - 1) >> 3;
+      switch (len & (8 - 1)) 
+       {
+       case 0:
+         do {
+           HASHC;
+           /* FALLTHROUGH */
+         case 7:
+           HASHC;
+           /* FALLTHROUGH */
+         case 6:
+           HASHC;
+           /* FALLTHROUGH */
+         case 5:
+           HASHC;
+           /* FALLTHROUGH */
+         case 4:
+           HASHC;
+           /* FALLTHROUGH */
+         case 3:
+           HASHC;
+           /* FALLTHROUGH */
+         case 2:
+           HASHC;
+           /* FALLTHROUGH */
+         case 1:
+           HASHC;
+         } while (--loop);
+       }
+    }
+  return (h);
+}
+
diff --git a/nis/nisplus-parser.h b/nis/nisplus-parser.h
new file mode 100644 (file)
index 0000000..b24ca46
--- /dev/null
@@ -0,0 +1,34 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef __NISPLUS_PARSER_H_
+#define __NISPLUS_PARSER_H_ 1
+
+#include <pwd.h>
+#include <grp.h>
+#include <shadow.h>
+
+extern int _nss_nisplus_parse_pwent (nis_result *, struct passwd *,
+                                    char *, size_t);
+extern int _nss_nisplus_parse_grent (nis_result *, u_long, struct group *,
+                                    char *, size_t);
+extern int _nss_nisplus_parse_spent (nis_result *, struct spwd *,
+                                    char *, size_t);
+
+#endif
index 40a190e..59165ea 100644 (file)
 #include <nsswitch.h>
 
 #include "nss-nisplus.h"
+#include "nisplus-parser.h"
 
 static service_user *ni = NULL;
 static bool_t use_nisplus = FALSE; /* default: group_compat: nis */
+static nis_name grptable = NULL; /* Name of the group table */
+static size_t grptablelen = 0;
 
 /* Get the declaration of the parser function.  */
 #define ENTNAME grent
@@ -57,14 +60,12 @@ struct ent_t
     char *oldkey;
     int oldkeylen;
     nis_result *result;
-    nis_name *names;
-    u_long names_nr;
     FILE *stream;
     struct blacklist_t blacklist;
 };
 typedef struct ent_t ent_t;
 
-static ent_t ext_ent = {0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0}};
+static ent_t ext_ent = {0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0}};
 
 /* Protect global state against multiple changers.  */
 __libc_lock_define_initialized (static, lock)
@@ -72,8 +73,31 @@ __libc_lock_define_initialized (static, lock)
 /* Prototypes for local functions.  */
 static void blacklist_store_name (const char *, ent_t *);
 static int in_blacklist (const char *, int, ent_t *);
-extern int _nss_nisplus_parse_grent (nis_result *, struct group *,
-                                    char *, size_t);
+
+static enum nss_status
+_nss_first_init (void)
+{
+  if (ni == NULL)
+    {
+      __nss_database_lookup ("group_compat", NULL, "nis", &ni);
+      use_nisplus = (strcmp (ni->name, "nisplus") == 0);
+    }
+
+  if (grptable == NULL)
+    {
+      char buf [20 + strlen (nis_local_directory ())];
+      char *p;
+
+      p = stpcpy (buf, "group.org_dir.");
+      p = stpcpy (p, nis_local_directory ());
+      grptable = strdup (buf);
+      if (grptable == NULL)
+        return NSS_STATUS_TRYAGAIN;
+      grptablelen = strlen (grptable);
+    }
+
+  return NSS_STATUS_SUCCESS;
+}
 
 static enum nss_status
 internal_setgrent (ent_t *ent)
@@ -82,6 +106,9 @@ internal_setgrent (ent_t *ent)
 
   ent->nis = ent->nis_first = 0;
 
+  if (_nss_first_init () != NSS_STATUS_SUCCESS)
+    return NSS_STATUS_UNAVAIL;
+
   if (ent->oldkey != NULL)
     {
       free (ent->oldkey);
@@ -95,12 +122,6 @@ internal_setgrent (ent_t *ent)
       ent->result = NULL;
     }
 
-  if (ent->names != NULL)
-    {
-      nis_freenames (ent->names);
-      ent->names = NULL;
-    }
-  ent->names_nr = 0;
   ent->blacklist.current = 0;
   if (ent->blacklist.data != NULL)
     ent->blacklist.data[0] = '\0';
@@ -126,12 +147,6 @@ _nss_compat_setgrent (void)
 
   __libc_lock_lock (lock);
 
-  if (ni == NULL)
-    {
-      __nss_database_lookup ("group_compat", NULL, "nis", &ni);
-      use_nisplus = (strcmp (ni->name, "nisplus") == 0);
-    }
-
   result = internal_setgrent (&ext_ent);
 
   __libc_lock_unlock (lock);
@@ -164,12 +179,6 @@ internal_endgrent (ent_t *ent)
       ent->result = NULL;
     }
 
-  if (ent->names != NULL)
-    {
-      nis_freenames (ent->names);
-      ent->names = NULL;
-    }
-  ent->names_nr = 0;
   ent->blacklist.current = 0;
   if (ent->blacklist.data != NULL)
     ent->blacklist.data[0] = '\0';
@@ -263,22 +272,11 @@ getgrent_next_nisplus (struct group *result, ent_t *ent, char *buffer,
 {
   int parse_res;
 
-  if (ent->names == NULL)
-    {
-      ent->names = nis_getnames ("group.org_dir");
-      if (ent->names == NULL || ent->names[0] == NULL)
-        {
-          ent->nis = 0;
-          return NSS_STATUS_UNAVAIL;
-        }
-    }
-
   do
     {
       if (ent->nis_first)
         {
-       next_name:
-          ent->result = nis_first_entry(ent->names[ent->names_nr]);
+          ent->result = nis_first_entry(grptable);
           if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
             {
               ent->nis = 0;
@@ -290,27 +288,16 @@ getgrent_next_nisplus (struct group *result, ent_t *ent, char *buffer,
         {
           nis_result *res;
 
-          res = nis_next_entry(ent->names[ent->names_nr],
-                               &ent->result->cookie);
+          res = nis_next_entry(grptable, &ent->result->cookie);
           nis_freeresult (ent->result);
           ent->result = res;
           if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
             {
-              if ((ent->result->status == NIS_NOTFOUND) &&
-                  ent->names[ent->names_nr + 1] != NULL)
-                {
-                  nis_freeresult (ent->result);
-                  ent->names_nr += 1;
-                  goto next_name;
-                }
-              else
-                {
-                  ent->nis = 0;
-                  return niserr2nss (ent->result->status);
-                }
+             ent->nis = 0;
+             return niserr2nss (ent->result->status);
             }
         }
-      parse_res = _nss_nisplus_parse_grent (ent->result, result, buffer,
+      parse_res = _nss_nisplus_parse_grent (ent->result, 0, result, buffer,
                                             buflen);
       if (parse_res &&
           in_blacklist (result->gr_name, strlen (result->gr_name), ent))
@@ -332,11 +319,10 @@ getgrent_next_file_plusgroup (struct group *result, char *buffer,
   if (use_nisplus) /* Do the NIS+ query here */
     {
       nis_result *res;
-      char buf[strlen (result->gr_name) + 24];
+      char buf[strlen (result->gr_name) + 24 + grptablelen];
 
-      sprintf(buf, "[name=%s],group.org_dir",
-              &result->gr_name[1]);
-      res = nis_list(buf, EXPAND_NAME, NULL, NULL);
+      sprintf(buf, "[name=%s],%s", &result->gr_name[1], grptable);
+      res = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
       if (niserr2nss (res->status) != NSS_STATUS_SUCCESS)
         {
           enum nss_status status =  niserr2nss (res->status);
@@ -344,7 +330,7 @@ getgrent_next_file_plusgroup (struct group *result, char *buffer,
           nis_freeresult (res);
           return status;
         }
-      parse_res = _nss_nisplus_parse_grent (res, result, buffer, buflen);
+      parse_res = _nss_nisplus_parse_grent (res, 0, result, buffer, buflen);
       nis_freeresult (res);
     }
   else /* Use NIS */
@@ -470,12 +456,6 @@ _nss_compat_getgrent_r (struct group *grp, char *buffer, size_t buflen)
 
   __libc_lock_lock (lock);
 
-  if (ni == NULL)
-    {
-      __nss_database_lookup ("group_compat", NULL, "nis", &ni);
-      use_nisplus = (strcmp (ni->name, "nisplus") == 0);
-    }
-
   /* Be prepared that the setgrent function was not called before.  */
   if (ext_ent.stream == NULL)
     status = internal_setgrent (&ext_ent);
@@ -493,7 +473,7 @@ enum nss_status
 _nss_compat_getgrnam_r (const char *name, struct group *grp,
                        char *buffer, size_t buflen)
 {
-  ent_t ent = {0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0}};
+  ent_t ent = {0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0}};
   enum nss_status status;
 
   if (name[0] == '-' || name[0] == '+')
@@ -501,15 +481,10 @@ _nss_compat_getgrnam_r (const char *name, struct group *grp,
 
   __libc_lock_lock (lock);
 
-  if (ni == NULL)
-    {
-      __nss_database_lookup ("group_compat", NULL, "nis", &ni);
-      use_nisplus = (strcmp (ni->name, "nisplus") == 0);
-    }
+  status = internal_setgrent (&ent);
 
   __libc_lock_unlock (lock);
 
-  status = internal_setgrent (&ent);
   if (status != NSS_STATUS_SUCCESS)
     return status;
 
@@ -527,20 +502,15 @@ enum nss_status
 _nss_compat_getgrgid_r (gid_t gid, struct group *grp,
                        char *buffer, size_t buflen)
 {
-  ent_t ent = {0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0}};
+  ent_t ent = {0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0}};
   enum nss_status status;
 
   __libc_lock_lock (lock);
 
-  if (ni == NULL)
-    {
-      __nss_database_lookup ("group_compat", NULL, "nis", &ni);
-      use_nisplus = (strcmp (ni->name, "nisplus") == 0);
-    }
+  status = internal_setgrent (&ent);
 
   __libc_lock_unlock (lock);
 
-  status = internal_setgrent (&ent);
   if (status != NSS_STATUS_SUCCESS)
     return status;
 
index d0d230b..0d0f2a6 100644 (file)
 
 #include "netgroup.h"
 #include "nss-nisplus.h"
+#include "nisplus-parser.h"
 
 static service_user *ni = NULL;
 static bool_t use_nisplus = FALSE; /* default: passwd_compat: nis */
+static nis_name pwdtable = NULL; /* Name of the pwd table */
+static size_t pwdtablelen = 0;
 
 /* Get the declaration of the parser function.  */
 #define ENTNAME pwent
@@ -60,8 +63,6 @@ struct ent_t
     char *oldkey;
     int oldkeylen;
     nis_result *result;
-    nis_name *names;
-    u_long names_nr;
     FILE *stream;
     struct blacklist_t blacklist;
     struct passwd pwd;
@@ -69,7 +70,7 @@ struct ent_t
   };
 typedef struct ent_t ent_t;
 
-static ent_t ext_ent = {0, 0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0},
+static ent_t ext_ent = {0, 0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0},
                        {NULL, NULL, 0, 0, NULL, NULL, NULL}};
 
 /* Protect global state against multiple changers.  */
@@ -78,8 +79,7 @@ __libc_lock_define_initialized (static, lock)
 /* Prototypes for local functions.  */
 static void blacklist_store_name (const char *, ent_t *);
 static int in_blacklist (const char *, int, ent_t *);
-extern int _nss_nisplus_parse_pwent (nis_result *, struct passwd *,
-                                    char *, size_t);
+
 static void
 give_pwd_free (struct passwd *pwd)
 {
@@ -209,12 +209,19 @@ internal_setpwent (ent_t *ent)
       ent->result = NULL;
     }
 
-  if (ent->names != NULL)
+  if (pwdtable == NULL)
     {
-      nis_freenames (ent->names);
-      ent->names = NULL;
+      char buf [20 + strlen (nis_local_directory ())];
+      char *p;
+
+      p = stpcpy (buf, "passwd.org_dir.");
+      p = stpcpy (p, nis_local_directory ());
+      pwdtable = strdup (buf);
+      if (pwdtable == NULL)
+       return NSS_STATUS_TRYAGAIN;
+      pwdtablelen = strlen (pwdtable);
     }
-  ent->names_nr = 0;
+
   ent->blacklist.current = 0;
   if (ent->blacklist.data != NULL)
     ent->blacklist.data[0] = '\0';
@@ -280,13 +287,6 @@ internal_endpwent (ent_t *ent)
       ent->result = NULL;
     }
 
-  if (ent->names != NULL)
-    {
-      nis_freenames (ent->names);
-      ent->names = NULL;
-    }
-  ent->names_nr = 0;
-
   ent->blacklist.current = 0;
   if (ent->blacklist.data != NULL)
     ent->blacklist.data[0] = '\0';
@@ -435,9 +435,9 @@ getpwent_next_nisplus_netgr (struct passwd *result, ent_t *ent, char *group,
       p2 = buffer + (buflen - p2len);
       buflen -= p2len;
       {
-       char buf[strlen (user) + 30];
-       sprintf(buf, "[name=%s],passwd.org_dir", user);
-       nisres = nis_list(buf, EXPAND_NAME, NULL, NULL);
+       char buf[strlen (user) + 30 + pwdtablelen];
+       sprintf(buf, "[name=%s],%s", user, pwdtable);
+       nisres = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
       }
       if (niserr2nss (nisres->status) != NSS_STATUS_SUCCESS)
        {
@@ -475,16 +475,6 @@ getpwent_next_nisplus (struct passwd *result, ent_t *ent, char *buffer,
   size_t p2len;
   char *p2;
 
-  if (ent->names == NULL)
-    {
-      ent->names = nis_getnames ("passwd.org_dir");
-      if (ent->names == NULL || ent->names[0] == NULL)
-       {
-         ent->nis = 0;
-         return NSS_STATUS_UNAVAIL;
-       }
-    }
-
   p2len = pwd_need_buflen (&ent->pwd);
   if (p2len > buflen)
     {
@@ -497,8 +487,7 @@ getpwent_next_nisplus (struct passwd *result, ent_t *ent, char *buffer,
     {
       if (ent->first)
        {
-       next_name:
-         ent->result = nis_first_entry(ent->names[ent->names_nr]);
+         ent->result = nis_first_entry(pwdtable);
           if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
            {
              ent->nis = 0;
@@ -511,25 +500,14 @@ getpwent_next_nisplus (struct passwd *result, ent_t *ent, char *buffer,
        {
          nis_result *res;
 
-         res = nis_next_entry(ent->names[ent->names_nr],
-                              &ent->result->cookie);
+         res = nis_next_entry(pwdtable, &ent->result->cookie);
          nis_freeresult (ent->result);
          ent->result = res;
          if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
            {
-             if ((ent->result->status == NIS_NOTFOUND) &&
-                 ent->names[ent->names_nr + 1] != NULL)
-               {
-                 nis_freeresult (ent->result);
-                 ent->names_nr += 1;
-                 goto next_name;
-               }
-             else
-               {
-                 ent->nis = 0;
-                 give_pwd_free (&ent->pwd);
-                 return niserr2nss (ent->result->status);
-               }
+             ent->nis = 0;
+             give_pwd_free (&ent->pwd);
+             return niserr2nss (ent->result->status);
            }
        }
       parse_res = _nss_nisplus_parse_pwent (ent->result, result, buffer,
@@ -648,11 +626,10 @@ getpwent_next_file_plususer (struct passwd *result, char *buffer,
   if (use_nisplus) /* Do the NIS+ query here */
     {
       nis_result *res;
-      char buf[strlen (result->pw_name) + 24];
+      char buf[strlen (result->pw_name) + 24 + pwdtablelen];
 
-      sprintf(buf, "[name=%s],passwd.org_dir",
-             &result->pw_name[1]);
-      res = nis_list(buf, EXPAND_NAME, NULL, NULL);
+      sprintf(buf, "[name=%s],%s", &result->pw_name[1], pwdtable);
+      res = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
       if (niserr2nss (res->status) != NSS_STATUS_SUCCESS)
        {
          enum nss_status status =  niserr2nss (res->status);
@@ -869,7 +846,7 @@ enum nss_status
 _nss_compat_getpwnam_r (const char *name, struct passwd *pwd,
                        char *buffer, size_t buflen)
 {
-  ent_t ent = {0, 0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0},
+  ent_t ent = {0, 0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0},
               {NULL, NULL, 0, 0, NULL, NULL, NULL}};
   enum nss_status status;
 
@@ -904,7 +881,7 @@ enum nss_status
 _nss_compat_getpwuid_r (uid_t uid, struct passwd *pwd,
                        char *buffer, size_t buflen)
 {
-  ent_t ent = {0, 0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0},
+  ent_t ent = {0, 0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0},
               {NULL, NULL, 0, 0, NULL, NULL, NULL}};
   enum nss_status status;
 
index 066f707..4199baf 100644 (file)
 
 #include "netgroup.h"
 #include "nss-nisplus.h"
+#include "nisplus-parser.h"
 
 static service_user *ni = NULL;
 static bool_t use_nisplus = FALSE; /* default: passwd_compat: nis */
+static nis_name pwdtable = NULL; /* Name of the password table */
+static size_t pwdtablelen = 0;
 
 /* Get the declaration of the parser function.  */
 #define ENTNAME spent
@@ -60,8 +63,6 @@ struct ent_t
     char *oldkey;
     int oldkeylen;
     nis_result *result;
-    nis_name *names;
-    u_long names_nr;
     FILE *stream;
     struct blacklist_t blacklist;
     struct spwd pwd;
@@ -69,7 +70,7 @@ struct ent_t
   };
 typedef struct ent_t ent_t;
 
-static ent_t ext_ent = {0, 0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0},
+static ent_t ext_ent = {0, 0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0},
                        {NULL, NULL, 0, 0, 0, 0, 0, 0, 0}};
 
 /* Protect global state against multiple changers.  */
@@ -78,8 +79,7 @@ __libc_lock_define_initialized (static, lock)
 /* Prototypes for local functions.  */
 static void blacklist_store_name (const char *, ent_t *);
 static int in_blacklist (const char *, int, ent_t *);
-extern int _nss_nisplus_parse_spent (nis_result *, struct spwd *,
-                                    char *, size_t);
+
 static void
 give_spwd_free (struct spwd *pwd)
 {
@@ -160,12 +160,19 @@ internal_setspent (ent_t *ent)
       nis_freeresult (ent->result);
       ent->result = NULL;
     }
-  if (ent->names != NULL)
+
+  if (pwdtable == NULL)
     {
-      nis_freenames (ent->names);
-      ent->names = NULL;
+      char buf [20 + strlen (nis_local_directory ())];
+      char *p;
+
+      p = stpcpy (buf, "passwd.org_dir.");
+      p = stpcpy (p, nis_local_directory ());
+      pwdtable = strdup (buf);
+      if (pwdtable == NULL)
+        return NSS_STATUS_TRYAGAIN;
+      pwdtablelen = strlen (pwdtable);
     }
-  ent->names_nr = 0;
 
   ent->blacklist.current = 0;
   if (ent->blacklist.data != NULL)
@@ -234,12 +241,6 @@ internal_endspent (ent_t *ent)
       nis_freeresult (ent->result);
       ent->result = NULL;
     }
-  if (ent->names != NULL)
-    {
-      nis_freenames (ent->names);
-      ent->names = NULL;
-    }
-  ent->names_nr = 0;
 
   ent->blacklist.current = 0;
   if (ent->blacklist.data != NULL)
@@ -387,9 +388,9 @@ getspent_next_nisplus_netgr (struct spwd *result, ent_t *ent, char *group,
       p2 = buffer + (buflen - p2len);
       buflen -= p2len;
       {
-        char buf[strlen (user) + 30];
-        sprintf(buf, "[name=%s],passwd.org_dir", user);
-        nisres = nis_list(buf, EXPAND_NAME, NULL, NULL);
+        char buf[strlen (user) + 30 + pwdtablelen];
+        sprintf(buf, "[name=%s],%s", user, pwdtable);
+        nisres = nis_list(buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
       }
       if (niserr2nss (nisres->status) != NSS_STATUS_SUCCESS)
         {
@@ -427,16 +428,6 @@ getspent_next_nisplus (struct spwd *result, ent_t *ent, char *buffer,
   size_t p2len;
   char *p2;
 
-  if (ent->names == NULL)
-    {
-      ent->names = nis_getnames ("passwd.org_dir");
-      if (ent->names == NULL || ent->names[0] == NULL)
-        {
-          ent->nis = 0;
-          return NSS_STATUS_UNAVAIL;
-        }
-    }
-
   p2len = spwd_need_buflen (&ent->pwd);
   if (p2len > buflen)
     {
@@ -449,8 +440,7 @@ getspent_next_nisplus (struct spwd *result, ent_t *ent, char *buffer,
     {
       if (ent->first)
         {
-        next_name:
-          ent->result = nis_first_entry(ent->names[ent->names_nr]);
+          ent->result = nis_first_entry(pwdtable);
           if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
             {
               ent->nis = 0;
@@ -463,25 +453,14 @@ getspent_next_nisplus (struct spwd *result, ent_t *ent, char *buffer,
         {
           nis_result *res;
 
-          res = nis_next_entry(ent->names[ent->names_nr],
-                               &ent->result->cookie);
+          res = nis_next_entry(pwdtable, &ent->result->cookie);
           nis_freeresult (ent->result);
           ent->result = res;
           if (niserr2nss (ent->result->status) != NSS_STATUS_SUCCESS)
             {
-              if ((ent->result->status == NIS_NOTFOUND) &&
-                  ent->names[ent->names_nr + 1] != NULL)
-                {
-                  nis_freeresult (ent->result);
-                  ent->names_nr += 1;
-                  goto next_name;
-                }
-              else
-                {
-                  ent->nis = 0;
-                  give_spwd_free (&ent->pwd);
-                  return niserr2nss (ent->result->status);
-                }
+             ent->nis = 0;
+             give_spwd_free (&ent->pwd);
+             return niserr2nss (ent->result->status);
             }
         }
       parse_res = _nss_nisplus_parse_spent (ent->result, result, buffer,
@@ -601,11 +580,10 @@ getspent_next_file_plususer (struct spwd *result, char *buffer,
   if (use_nisplus) /* Do the NIS+ query here */
     {
       nis_result *res;
-      char buf[strlen (result->sp_namp) + 24];
+      char buf[strlen (result->sp_namp) + 24 + pwdtablelen];
 
-      sprintf(buf, "[name=%s],passwd.org_dir",
-              &result->sp_namp[1]);
-      res = nis_list(buf, EXPAND_NAME, NULL, NULL);
+      sprintf(buf, "[name=%s],%s", &result->sp_namp[1], pwdtable);
+      res = nis_list(buf, 0, NULL, NULL);
       if (niserr2nss (res->status) != NSS_STATUS_SUCCESS)
         {
           enum nss_status status =  niserr2nss (res->status);
@@ -821,7 +799,7 @@ enum nss_status
 _nss_compat_getspnam_r (const char *name, struct spwd *pwd,
                        char *buffer, size_t buflen)
 {
-  ent_t ent = {0, 0, 0, NULL, 0, NULL, NULL, 0, NULL, {NULL, 0, 0},
+  ent_t ent = {0, 0, 0, NULL, 0, NULL, NULL, {NULL, 0, 0},
               {NULL, NULL, 0, 0, 0, 0, 0, 0, 0}};
   enum nss_status status;
 
index 52d1783..ade09c4 100644 (file)
@@ -22,7 +22,6 @@
 #include <errno.h>
 #include <string.h>
 #include <syslog.h>
-#include <bits/libc-lock.h>
 #include <rpc/rpc.h>
 #include <rpcsvc/yp.h>
 #include <rpcsvc/ypclnt.h>
@@ -40,7 +39,7 @@ _nss_nis_getpublickey (const char *netname, char *pkey)
   enum nss_status retval;
   char *domain, *result;
   int len;
-
+  
   pkey[0] = 0;
 
   if (netname == NULL)
index 1784778..660ba3c 100644 (file)
 __libc_lock_define_initialized (static, lock)
 
 static nis_result *result = NULL;
-static nis_name *names = NULL;
+static u_long next_entry = 0;
+static nis_name tablename_val = NULL;
+static u_long tablename_len = 0;
 
 #define NISENTRYVAL(idx,col,res) \
-        ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
+        ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
 
 #define NISENTRYLEN(idx,col,res) \
-        ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
+        ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
+
+static enum nss_status
+_nss_create_tablename (void)
+{
+  if (tablename_val == NULL)
+    {
+      char buf [40 + strlen (nis_local_directory ())];
+      char *p;
+
+      p = stpcpy (buf, "mail_aliases.org_dir.");
+      p = stpcpy (p, nis_local_directory ());
+      tablename_val = strdup (buf);
+      if (tablename_val == NULL)
+        return NSS_STATUS_TRYAGAIN;
+      tablename_len = strlen (tablename_val);
+    }
+  return NSS_STATUS_SUCCESS;
+}
 
 static int
-_nss_nisplus_parse_aliasent (nis_result *result, struct aliasent *alias,
-                         char *buffer, size_t buflen)
+_nss_nisplus_parse_aliasent (nis_result *result, unsigned long entry,
+                            struct aliasent *alias, char *buffer,
+                            size_t buflen)
 {
   if (result == NULL)
     return 0;
 
   if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
-      result->objects.objects_len != 1 ||
-      result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
-      strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+      __type_of (&result->objects.objects_val[entry]) != ENTRY_OBJ ||
+      strcmp(result->objects.objects_val[entry].EN_data.en_type,
             "mail_aliases") != 0 ||
-      result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 2)
+      result->objects.objects_val[entry].EN_data.en_cols.en_cols_len < 2)
     return 0;
   else
     {
@@ -62,7 +82,7 @@ _nss_nisplus_parse_aliasent (nis_result *result, struct aliasent *alias,
       char *line;
       char *cp;
 
-      if (NISENTRYLEN(0, 1, result) >= buflen)
+      if (NISENTRYLEN(entry, 1, result) >= buflen)
        {
          /* The line is too long for our buffer.  */
        no_more_room:
@@ -71,19 +91,20 @@ _nss_nisplus_parse_aliasent (nis_result *result, struct aliasent *alias,
        }
       else
        {
-         strncpy (buffer, NISENTRYVAL(0, 1, result), NISENTRYLEN(0, 1, result));
-         buffer[NISENTRYLEN(0, 1, result)] = '\0';
+         strncpy (buffer, NISENTRYVAL(entry, 1, result),
+                  NISENTRYLEN(entry, 1, result));
+         buffer[NISENTRYLEN(entry, 1, result)] = '\0';
        }
 
-      if (NISENTRYLEN(0, 0, result) >= room_left)
+      if (NISENTRYLEN(entry, 0, result) >= room_left)
        goto no_more_room;
 
       alias->alias_local = 0;
       alias->alias_members_len = 0;
       *first_unused = '\0';
       ++first_unused;
-      strcpy (first_unused, NISENTRYVAL(0, 0, result));
-      first_unused[NISENTRYLEN(0, 0, result)] = '\0';
+      strcpy (first_unused, NISENTRYVAL(entry, 0, result));
+      first_unused[NISENTRYLEN(entry, 0, result)] = '\0';
       alias->alias_name = first_unused;
 
       /* Terminate the line for any case.  */
@@ -129,23 +150,38 @@ _nss_nisplus_parse_aliasent (nis_result *result, struct aliasent *alias,
     }
 }
 
-enum nss_status
-_nss_nisplus_setaliasent (void)
+static enum nss_status
+internal_setaliasent (void)
 {
-  __libc_lock_lock (lock);
-
   if (result)
     nis_freeresult (result);
   result = NULL;
-  if (names)
+
+  if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+    return NSS_STATUS_UNAVAIL;
+
+  next_entry = 0;
+  result = nis_list(tablename_val, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
+  if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
     {
-      nis_freenames (names);
-      names = NULL;
+      nis_freeresult (result);
+      result = NULL;
     }
+  return niserr2nss (result->status);
+}
+
+enum nss_status
+_nss_nisplus_setaliasent (void)
+{
+  enum nss_status status;
+
+  __libc_lock_lock (lock);
+
+  status = internal_setaliasent ();
 
   __libc_lock_unlock (lock);
 
-  return NSS_STATUS_SUCCESS;
+  return status;
 }
 
 enum nss_status
@@ -156,11 +192,7 @@ _nss_nisplus_endaliasent (void)
   if (result)
     nis_freeresult (result);
   result = NULL;
-  if (names)
-    {
-      nis_freenames (names);
-      names = NULL;
-    }
+  next_entry = 0;
 
   __libc_lock_unlock (lock);
 
@@ -173,31 +205,18 @@ internal_nisplus_getaliasent_r (struct aliasent *alias,
 {
   int parse_res;
 
+  if (result == NULL)
+    internal_setaliasent ();
+
   /* Get the next entry until we found a correct one. */
   do
     {
-      if (result == NULL)
-       {
-         names = nis_getnames("mail_aliases.org_dir");
-         if (names == NULL || names[0] == NULL)
-           return NSS_STATUS_UNAVAIL;
-
-         result = nis_first_entry(names[0]);
-         if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
-           return niserr2nss (result->status);
-       }
-      else
-       {
-         nis_result *res2;
-
-         res2 = nis_next_entry(names[0], &result->cookie);
-         nis_freeresult (result);
-         result = res2;
-         if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
-           return niserr2nss (result->status);
-       }
+      if (next_entry >= result->objects.objects_len)
+       return NSS_STATUS_NOTFOUND;
 
-      parse_res = _nss_nisplus_parse_aliasent (result, alias, buffer, buflen);
+      parse_res = _nss_nisplus_parse_aliasent (result, next_entry, alias,
+                                              buffer, buflen);
+      ++next_entry;
     } while (!parse_res);
 
   return NSS_STATUS_SUCCESS;
@@ -224,21 +243,26 @@ _nss_nisplus_getaliasbyname_r (const char *name, struct aliasent *alias,
 {
   int parse_res;
 
+  if (tablename_val == NULL)
+    if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
+      return NSS_STATUS_UNAVAIL;
+
   if (name == NULL || strlen(name) > 8)
     return NSS_STATUS_NOTFOUND;
   else
     {
       nis_result *result;
-      char buf[strlen (name) + 30];
+      char buf[strlen (name) + 30 + tablename_len];
 
-      sprintf(buf, "[name=%s],mail_aliases.org_dir", name);
+      sprintf(buf, "[name=%s],%s", name, tablename_val);
 
-      result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+      result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
       if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
        return niserr2nss (result->status);
 
-      parse_res = _nss_nisplus_parse_aliasent (result, alias, buffer, buflen);
+      parse_res = _nss_nisplus_parse_aliasent (result, 0, alias,
+                                              buffer, buflen);
 
       if (parse_res)
        return NSS_STATUS_SUCCESS;
index d83c7b2..7c07833 100644 (file)
@@ -33,7 +33,8 @@
 __libc_lock_define_initialized (static, lock)
 
 static nis_result *result = NULL;
-static nis_name *names = NULL;
+static nis_name tablename_val = NULL;
+static u_long tablename_len = 0;
 
 /* Because the `ethers' lookup does not fit so well in the scheme so
    we define a dummy struct here which helps us to use the available
@@ -45,32 +46,6 @@ struct etherent
 };
 struct etherent_data {};
 
-#define ENTNAME         etherent
-#define DATABASE        "ethers"
-#include "../../nss/nss_files/files-parse.c"
-LINE_PARSER
-("#",
- /* Read the ethernet address: 6 x 8bit hexadecimal number.  */
- {
-   size_t cnt;
-
-   for (cnt = 0; cnt < 6; ++cnt)
-     {
-       unsigned int number;
-
-       if (cnt < 5)
-         INT_FIELD (number, ISCOLON , 0, 16, (unsigned int))
-       else
-         INT_FIELD (number, isspace, 0, 16, (unsigned int))
-
-       if (number > 0xff)
-         return 0;
-       result->e_addr.ether_addr_octet[cnt] = number;
-     }
- };
- STRING_FIELD (result->e_name, isspace, 1);
- )
-
 #define NISENTRYVAL(idx,col,res) \
         ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
 
@@ -83,21 +58,18 @@ _nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether,
 {
   char *p = buffer;
   size_t room_left = buflen;
-  struct parser_data *data = (void *) buffer;
 
   if (result == NULL)
     return 0;
 
   if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
       result->objects.objects_len != 1 ||
-      result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
-      strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+      __type_of (NIS_RES_OBJECT (result)) != ENTRY_OBJ ||
+      strcmp(NIS_RES_OBJECT (result)->EN_data.en_type,
              "ethers_tbl") != 0 ||
-      result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 2)
+      NIS_RES_OBJECT(result)->EN_data.en_cols.en_cols_len < 2)
     return 0;
 
-  memset (p, '\0', room_left);
-
   /* Generate the ether entry format and use the normal parser */
   if (NISENTRYLEN (0, 0, result) +1 > room_left)
     {
@@ -106,32 +78,47 @@ _nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether,
     }
   strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
   room_left -= (NISENTRYLEN (0, 0, result) +1);
+  ether->e_name = p;
+
+  ether->e_addr = *ether_aton (NISENTRYVAL (0, 1, result));
+
+  return 1;
+}
 
-  if (NISENTRYLEN (0, 1, result) +1 > room_left)
+static enum nss_status
+_nss_create_tablename (void)
+{
+  if (tablename_val == NULL)
     {
-      __set_errno (ERANGE);
-      return 0;
-    }
-  strcat (p, "\t");
-  strncat (p, NISENTRYVAL (0, 1, result), NISENTRYLEN (0, 1, result));
-  room_left -= (NISENTRYLEN (0, 1, result) + 1);
+      char buf [40 + strlen (nis_local_directory ())];
+      char *p;
 
-  return _nss_files_parse_etherent (p,ether, data, buflen);
+      p = stpcpy (buf, "ethers.org_dir.");
+      p = stpcpy (p, nis_local_directory ());
+      tablename_val = strdup (buf);
+      if (tablename_val == NULL)
+        return NSS_STATUS_TRYAGAIN;
+      tablename_len = strlen (tablename_val);
+    }
+  return NSS_STATUS_SUCCESS;
 }
 
+
 enum nss_status
 _nss_nisplus_setetherent (void)
 {
+  enum nss_status status;
+
+  status = NSS_STATUS_SUCCESS;
+
   __libc_lock_lock (lock);
 
   if (result)
     nis_freeresult (result);
   result = NULL;
-  if (names)
-    {
-      nis_freenames (names);
-      names = NULL;
-    }
+
+  if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+    status = NSS_STATUS_UNAVAIL;
 
   __libc_lock_unlock (lock);
 
@@ -146,11 +133,6 @@ _nss_nisplus_endetherent (void)
   if (result)
     nis_freeresult (result);
   result = NULL;
-  if (names)
-    {
-      nis_freenames (names);
-      names = NULL;
-    }
 
   __libc_lock_unlock (lock);
 
@@ -163,16 +145,16 @@ internal_nisplus_getetherent_r (struct etherent *ether, char *buffer,
 {
   int parse_res;
 
+  if (tablename_val == NULL)
+    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+      return NSS_STATUS_UNAVAIL;
+
   /* Get the next entry until we found a correct one. */
   do
     {
       if (result == NULL)
        {
-         names = nis_getnames("ethers.org_dir");
-         if (names == NULL || names[0] == NULL)
-           return NSS_STATUS_UNAVAIL;
-
-         result = nis_first_entry(names[0]);
+         result = nis_first_entry(tablename_val);
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
            return niserr2nss (result->status);
        }
@@ -180,7 +162,7 @@ internal_nisplus_getetherent_r (struct etherent *ether, char *buffer,
        {
          nis_result *res2;
 
-         res2 = nis_next_entry(names[0], &result->cookie);
+         res2 = nis_next_entry(tablename_val, &result->cookie);
          nis_freeresult (result);
          result = res2;
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
@@ -214,16 +196,20 @@ _nss_nisplus_gethostton_r (const char *name, struct etherent *eth,
 {
   int parse_res;
 
+  if (tablename_val == NULL)
+    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+      return NSS_STATUS_UNAVAIL;
+
   if (name == NULL)
     return NSS_STATUS_NOTFOUND;
   else
     {
       nis_result *result;
-      char buf[strlen (name) + 255];
+      char buf[strlen (name) + 40 + tablename_len];
 
-      sprintf(buf, "[name=%s],ethers.org_dir", name);
+      sprintf(buf, "[name=%s],%s", name, tablename_val);
 
-      result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+      result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
       if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
         return niserr2nss (result->status);
@@ -245,34 +231,40 @@ _nss_nisplus_getntohost_r (const struct ether_addr *addr,
                           struct etherent *eth,
                           char *buffer, size_t buflen)
 {
-  int parse_res;
-  nis_result *result;
-  char buf[255];
+  if (tablename_val == NULL)
+    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+      return NSS_STATUS_UNAVAIL;
 
   if (addr == NULL)
     {
       __set_errno (EINVAL);
       return NSS_STATUS_UNAVAIL;
     }
+  else
+    {
+      int parse_res;
+      nis_result *result;
+      char buf[255 + tablename_len];
 
-  memset (&buf, '\0', sizeof (buf));
-  snprintf(buf, sizeof (buf), "[addr=%x:%x:%x:%x:%x:%x],ethers.org_dir",
-          addr->ether_addr_octet[0], addr->ether_addr_octet[1],
-          addr->ether_addr_octet[2], addr->ether_addr_octet[3],
-          addr->ether_addr_octet[4], addr->ether_addr_octet[5]);
+      memset (&buf, '\0', sizeof (buf));
+      snprintf(buf, sizeof (buf), "[addr=%x:%x:%x:%x:%x:%x],ethers.org_dir",
+              addr->ether_addr_octet[0], addr->ether_addr_octet[1],
+              addr->ether_addr_octet[2], addr->ether_addr_octet[3],
+              addr->ether_addr_octet[4], addr->ether_addr_octet[5]);
 
-  result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+      result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
-  if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
-    return niserr2nss (result->status);
+      if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+       return niserr2nss (result->status);
 
-  parse_res = _nss_nisplus_parse_etherent (result, eth, buffer, buflen);
+      parse_res = _nss_nisplus_parse_etherent (result, eth, buffer, buflen);
 
-  if (parse_res)
-    return NSS_STATUS_SUCCESS;
+      if (parse_res)
+       return NSS_STATUS_SUCCESS;
 
-  if (!parse_res && errno == ERANGE)
-    return NSS_STATUS_TRYAGAIN;
-  else
-    return NSS_STATUS_NOTFOUND;
+      if (!parse_res && errno == ERANGE)
+       return NSS_STATUS_TRYAGAIN;
+      else
+       return NSS_STATUS_NOTFOUND;
+    }
 }
index bf851e0..f759f61 100644 (file)
 #include <rpcsvc/nislib.h>
 
 #include "nss-nisplus.h"
+#include "nisplus-parser.h"
 
 __libc_lock_define_initialized (static, lock);
 
 static nis_result *result = NULL;
-static nis_name *names = NULL;
+static unsigned long next_entry = 0;
+static nis_name tablename_val = NULL;
+static u_long tablename_len = 0;
 
-#define NISENTRYVAL(idx,col,res) \
-((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
-
-#define NISENTRYLEN(idx,col,res) \
-  ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
-
-int
-_nss_nisplus_parse_grent (nis_result * result, struct group *gr,
-                         char *buffer, size_t buflen)
+static enum nss_status
+_nss_create_tablename (void)
 {
-  char *first_unused = buffer;
-  size_t room_left = buflen;
-  char *line;
-  int count;
-
-  if (result == NULL)
-    return 0;
-
-  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
-      result->objects.objects_len != 1 ||
-      result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
-      strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
-             "group_tbl") != 0 ||
-      result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 4)
-    return 0;
-
-  if (NISENTRYLEN (0, 0, result) >= room_left)
+  if (tablename_val == NULL)
     {
-      /* The line is too long for our buffer.  */
-    no_more_room:
-      __set_errno (ERANGE);
-      return 0;
+      char buf [40 + strlen (nis_local_directory ())];
+      char *p;
+
+      p = stpcpy (buf, "group.org_dir.");
+      p = stpcpy (p, nis_local_directory ());
+      tablename_val = strdup (buf);
+      if (tablename_val == NULL)
+        return NSS_STATUS_TRYAGAIN;
+      tablename_len = strlen (tablename_val);
     }
+  return NSS_STATUS_SUCCESS;
+}
 
-  strncpy (first_unused, NISENTRYVAL (0, 0, result),
-          NISENTRYLEN (0, 0, result));
-  first_unused[NISENTRYLEN (0, 0, result)] = '\0';
-  gr->gr_name = first_unused;
-  room_left -= (strlen (first_unused) + 1);
-  first_unused += strlen (first_unused) + 1;
-
-  if (NISENTRYLEN (0, 1, result) >= room_left)
-    goto no_more_room;
-
-  strncpy (first_unused, NISENTRYVAL (0, 1, result),
-          NISENTRYLEN (0, 1, result));
-  first_unused[NISENTRYLEN (0, 1, result)] = '\0';
-  gr->gr_passwd = first_unused;
-  room_left -= (strlen (first_unused) + 1);
-  first_unused += strlen (first_unused) + 1;
-
-  if (NISENTRYLEN (0, 2, result) >= room_left)
-    goto no_more_room;
-
-  strncpy (first_unused, NISENTRYVAL (0, 2, result),
-          NISENTRYLEN (0, 2, result));
-  first_unused[NISENTRYLEN (0, 2, result)] = '\0';
-  gr->gr_gid = atoi (first_unused);
-  room_left -= (strlen (first_unused) + 1);
-  first_unused += strlen (first_unused) + 1;
-
-  if (NISENTRYLEN (0, 3, result) >= room_left)
-    goto no_more_room;
-
-  strncpy (first_unused, NISENTRYVAL (0, 3, result),
-          NISENTRYLEN (0, 3, result));
-  first_unused[NISENTRYLEN (0, 3, result)] = '\0';
-  line = first_unused;
-  room_left -= (strlen (line) + 1);
-  first_unused += strlen (line) + 1;
-  /* Adjust the pointer so it is aligned for
-     storing pointers.  */
-  first_unused += __alignof__ (char *) - 1;
-  first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *));
-  gr->gr_mem = (char **) first_unused;
-
-  count = 0;
-  while (*line != '\0')
-    {
-      /* Skip leading blanks.  */
-      while (isspace (*line))
-       ++line;
-
-      if (*line == '\0')
-       break;
-
-      if (room_left < sizeof (char *))
-         goto no_more_room;
-      room_left -= sizeof (char *);
-      gr->gr_mem[count] = line;
+static enum nss_status
+internal_setgrent (void)
+{
+  if (result)
+    nis_freeresult (result);
+  result = NULL;
+  next_entry = 0;
 
-      while (*line != '\0' && *line != ',' && !isspace(*line))
-       ++line;
+  if (tablename_val == NULL)
+    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+      return NSS_STATUS_UNAVAIL;
 
-      if (line != gr->gr_mem[count])
-       {
-         if (*line != '\0')
-           {
-             *line = '\0';
-             ++line;
-           }
-         ++count;
-       }
-      else
-       gr->gr_mem[count] = NULL;
+  result = nis_list (tablename_val, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
+  if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+    {
+      nis_freeresult (result);
+      result = NULL;
     }
-  if (room_left < sizeof (char *))
-      goto no_more_room;
-  room_left -= sizeof (char *);
-  gr->gr_mem[count] = NULL;
-
-  return 1;
+  return niserr2nss (result->status);
 }
 
 enum nss_status
 _nss_nisplus_setgrent (void)
 {
+  enum nss_status status;
+
   __libc_lock_lock (lock);
 
-  if (result)
-    nis_freeresult (result);
-  result = NULL;
-  if (names)
-    {
-      nis_freenames (names);
-      names = NULL;
-    }
+  status = internal_setgrent ();
 
   __libc_lock_unlock (lock);
 
-  return NSS_STATUS_SUCCESS;
+  return status;
 }
 
 enum nss_status
@@ -174,11 +97,6 @@ _nss_nisplus_endgrent (void)
   if (result)
     nis_freeresult (result);
   result = NULL;
-  if (names)
-    {
-      nis_freenames (names);
-      names = NULL;
-    }
 
   __libc_lock_unlock (lock);
 
@@ -190,31 +108,18 @@ internal_nisplus_getgrent_r (struct group *gr, char *buffer, size_t buflen)
 {
   int parse_res;
 
+  if (result == NULL)
+    internal_setgrent ();
+
   /* Get the next entry until we found a correct one. */
   do
     {
-      if (result == NULL)
-       {
-         names = nis_getnames ("group.org_dir");
-         if (names == NULL || names[0] == NULL)
-           return NSS_STATUS_UNAVAIL;
-
-         result = nis_first_entry (names[0]);
-         if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
-           return niserr2nss (result->status);
-       }
-      else
-       {
-         nis_result *res;
-
-         res = nis_next_entry (names[0], &result->cookie);
-         nis_freeresult (result);
-         result = res;
-         if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
-           return niserr2nss (result->status);
-       }
+      if (next_entry >= result->objects.objects_len)
+       return NSS_STATUS_NOTFOUND;
 
-      parse_res = _nss_nisplus_parse_grent (result, gr, buffer, buflen);
+      parse_res = _nss_nisplus_parse_grent (result, next_entry, gr,
+                                           buffer, buflen);
+      ++next_entry;
     }
   while (!parse_res);
 
@@ -241,16 +146,20 @@ _nss_nisplus_getgrnam_r (const char *name, struct group *gr,
 {
   int parse_res;
 
+  if (tablename_val == NULL)
+    if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
+      return NSS_STATUS_UNAVAIL;
+
   if (name == NULL || strlen (name) > 8)
     return NSS_STATUS_NOTFOUND;
   else
     {
       nis_result *result;
-      char buf[strlen (name) + 24];
+      char buf[strlen (name) + 24 + tablename_len];
 
-      sprintf (buf, "[name=%s],group.org_dir", name);
+      sprintf (buf, "[name=%s],%s", name, tablename_val);
 
-      result = nis_list (buf, EXPAND_NAME, NULL, NULL);
+      result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
 
       if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
        {
@@ -260,7 +169,7 @@ _nss_nisplus_getgrnam_r (const char *name, struct group *gr,
          return status;
        }
 
-      parse_res = _nss_nisplus_parse_grent (result, gr, buffer, buflen);
+      parse_res = _nss_nisplus_parse_grent (result, 0, gr, buffer, buflen);
 
       nis_freeresult (result);
 
@@ -278,31 +187,37 @@ enum nss_status
 _nss_nisplus_getgrgid_r (const gid_t gid, struct group *gr,
                         char *buffer, size_t buflen)
 {
-  int parse_res;
-  nis_result *result;
-  char buf[36];
+  if (tablename_val == NULL)
+    if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
+      return NSS_STATUS_UNAVAIL;
 
-  sprintf (buf, "[gid=%d],group.org_dir", gid);
+  {
+    int parse_res;
+    nis_result *result;
+    char buf[36 + tablename_len];
 
-  result = nis_list (buf, EXPAND_NAME, NULL, NULL);
+    sprintf (buf, "[gid=%d],%s", gid, tablename_val);
 
-  if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
-    {
-      enum nss_status status = niserr2nss (result->status);
+    result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
-      nis_freeresult (result);
-      return status;
-    }
+    if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+      {
+       enum nss_status status = niserr2nss (result->status);
+
+       nis_freeresult (result);
+       return status;
+      }
 
-  parse_res = _nss_nisplus_parse_grent (result, gr, buffer, buflen);
+    parse_res = _nss_nisplus_parse_grent (result, 0, gr, buffer, buflen);
 
-  nis_freeresult (result);
+    nis_freeresult (result);
 
-  if (parse_res)
-    return NSS_STATUS_SUCCESS;
+    if (parse_res)
+      return NSS_STATUS_SUCCESS;
 
-  if (!parse_res && errno == ERANGE)
-    return NSS_STATUS_TRYAGAIN;
-  else
-    return NSS_STATUS_NOTFOUND;
+    if (!parse_res && errno == ERANGE)
+      return NSS_STATUS_TRYAGAIN;
+    else
+      return NSS_STATUS_NOTFOUND;
+  }
 }
index ee87a78..19f9161 100644 (file)
 __libc_lock_define_initialized (static, lock)
 
 static nis_result *result = NULL;
-static nis_name *names = NULL;
+static nis_name tablename_val = NULL;
+static u_long tablename_len = 0;
 
 #define NISENTRYVAL(idx,col,res) \
-        ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
+        ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
 
 #define NISENTRYLEN(idx,col,res) \
-        ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
+        ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
 
 /* Get implementation for some internal functions. */
 #include "../../resolv/mapv4v6addr.h"
@@ -57,10 +58,10 @@ _nss_nisplus_parse_hostent (nis_result *result, int af, struct hostent *host,
     return 0;
 
   if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
-      result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
-      strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
-             "hosts_tbl") != 0 ||
-      result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 4)
+      __type_of (result->objects.objects_val) != ENTRY_OBJ ||
+      strcmp(result->objects.objects_val[0].EN_data.en_type,
+            "hosts_tbl") != 0 ||
+      result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 4)
     return 0;
 
   if (room_left < NISENTRYLEN (0, 2, result) + 1)
@@ -162,37 +163,58 @@ _nss_nisplus_parse_hostent (nis_result *result, int af, struct hostent *host,
       host->h_aliases[i] = line;
 
       while (*line != '\0' && *line != ' ')
-       line++;
+       ++line;
 
-      if (line != host->h_aliases[i])
-            {
-              *line = '\0';
-              line++;
-              i++;
-            }
+      if (*line == ' ')
+       {
+         *line = '\0';
+         ++line;
+         ++i;
+       }
+      else
+       host->h_aliases[i+1] = NULL;
     }
 
   return 1;
 
 }
 
+static enum nss_status
+_nss_create_tablename (void)
+{
+  if (tablename_val == NULL)
+    {
+      char buf [40 + strlen (nis_local_directory ())];
+      char *p;
+
+      p = stpcpy (buf, "hosts.org_dir.");
+      p = stpcpy (p, nis_local_directory ());
+      tablename_val = strdup (buf);
+      if (tablename_val == NULL)
+        return NSS_STATUS_TRYAGAIN;
+      tablename_len = strlen (tablename_val);
+    }
+  return NSS_STATUS_SUCCESS;
+}
+
 enum nss_status
 _nss_nisplus_sethostent (void)
 {
+  enum nss_status status = NSS_STATUS_SUCCESS;
+
   __libc_lock_lock (lock);
 
   if (result)
     nis_freeresult (result);
   result = NULL;
-  if (names)
-    {
-      nis_freenames (names);
-      names = NULL;
-    }
+
+  if (tablename_val == NULL)
+    if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
+      status = NSS_STATUS_UNAVAIL;
 
   __libc_lock_unlock (lock);
 
-  return NSS_STATUS_SUCCESS;
+  return status;
 }
 
 enum nss_status
@@ -203,11 +225,6 @@ _nss_nisplus_endhostent (void)
   if (result)
     nis_freeresult (result);
   result = NULL;
-  if (names)
-    {
-      nis_freenames (names);
-      names = NULL;
-    }
 
   __libc_lock_unlock (lock);
 
@@ -225,11 +242,11 @@ internal_nisplus_gethostent_r (struct hostent *host, char *buffer,
     {
       if (result == NULL)
        {
-         names = nis_getnames("hosts.org_dir");
-         if (names == NULL || names[0] == NULL)
-           return NSS_STATUS_UNAVAIL;
+         if (tablename_val == NULL)
+           if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
+             return NSS_STATUS_UNAVAIL;
 
-         result = nis_first_entry(names[0]);
+         result = nis_first_entry(tablename_val);
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
             {
               int retval;
@@ -248,7 +265,7 @@ internal_nisplus_gethostent_r (struct hostent *host, char *buffer,
        {
          nis_result *res2;
 
-         res2 = nis_next_entry(names[0], &result->cookie);
+         res2 = nis_next_entry(tablename_val, &result->cookie);
          nis_freeresult (result);
          result = res2;
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
@@ -302,6 +319,13 @@ _nss_nisplus_gethostbyname2_r (const char *name, int af, struct hostent *host,
 {
   int parse_res, retval;
 
+  if (tablename_val == NULL)
+    if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
+      {
+       *herrnop = NETDB_INTERNAL;
+       return NSS_STATUS_UNAVAIL;
+      }
+
   if (name == NULL)
     {
       __set_errno (EINVAL);
@@ -311,28 +335,27 @@ _nss_nisplus_gethostbyname2_r (const char *name, int af, struct hostent *host,
   else
     {
       nis_result *result;
-      char buf[strlen (name) + 255];
+      char buf[strlen (name) + 255 + tablename_len];
 
       /* Search at first in the alias list, and use the correct name
         for the next search */
-      sprintf(buf, "[name=%s],hosts.org_dir", name);
-      result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+      sprintf(buf, "[name=%s],%s", name, tablename_val);
+      result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
       /* If we do not find it, try it as original name. But if the
         database is correct, we should find it in the first case, too */
-      if ((result->status != NIS_SUCCESS &&
-          result->status != NIS_S_SUCCESS) ||
-         result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
-         strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+      if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
+         __type_of (result->objects.objects_val) != ENTRY_OBJ ||
+         strcmp(result->objects.objects_val->EN_data.en_type,
                 "hosts_tbl") != 0 ||
-         result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len
-         < 3)
-       sprintf(buf, "[cname=%s],hosts.org_dir", name);
+         result->objects.objects_val->EN_data.en_cols.en_cols_len < 3)
+       sprintf(buf, "[cname=%s],%s", name, tablename_val);
       else
-       sprintf(buf, "[cname=%s],hosts.org_dir", NISENTRYVAL(0, 0, result));
+       sprintf(buf, "[cname=%s],%s", NISENTRYVAL(0, 0, result),
+               tablename_val);
 
       nis_freeresult (result);
-      result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+      result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
       retval = niserr2nss (result->status);
       if (retval != NSS_STATUS_SUCCESS)
@@ -385,17 +408,21 @@ _nss_nisplus_gethostbyaddr_r (const char *addr, int addrlen, int type,
                              struct hostent *host, char *buffer,
                              size_t buflen, int *herrnop)
 {
+  if (tablename_val == NULL)
+    if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
+      return NSS_STATUS_UNAVAIL;
+
   if (addr == NULL)
     return NSS_STATUS_NOTFOUND;
   else
     {
       nis_result *result;
-      char buf[1025];
+      char buf[255 + tablename_len];
       int retval, parse_res;
 
-      snprintf(buf, sizeof (buf) -1, "[addr=%s],hosts.org_dir",
-              inet_ntoa (*(struct in_addr *)addr));
-      result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+      snprintf(buf, sizeof (buf) -1, "[addr=%s],%s",
+              inet_ntoa (*(struct in_addr *)addr), tablename_val);
+      result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
       retval = niserr2nss (result->status);
       if (retval != NSS_STATUS_SUCCESS)
index 5907882..670d0bb 100644 (file)
@@ -36,10 +36,10 @@ static unsigned long data_size = 0;
 static unsigned long position = 0;
 
 #define NISENTRYVAL(idx,col,res) \
-        ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
+        ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
 
 #define NISENTRYLEN(idx,col,res) \
-        ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
+        ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
 
 static enum nss_status
 _nss_nisplus_parse_netgroup (struct __netgrent *result, char *buffer,
@@ -49,8 +49,7 @@ _nss_nisplus_parse_netgroup (struct __netgrent *result, char *buffer,
 
   /* Some sanity checks.  */
   if (data == NULL || data_size == 0)
-    /* User bug.  setnetgrent() wasn't called before.  */
-    abort ();
+    return NSS_STATUS_NOTFOUND;
 
   if (position == data_size)
     return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
@@ -154,9 +153,9 @@ _nss_nisplus_setnetgrent (char *group)
       position = 0;
     }
 
-  sprintf(buf, "[name=%s],netgroup.org_dir", group);
+  sprintf (buf, "[name=%s],netgroup.org_dir", group);
 
-  data = nis_list(buf, EXPAND_NAME, NULL, NULL);
+  data = nis_list (buf, EXPAND_NAME, NULL, NULL);
 
   if (niserr2nss (data->status) != NSS_STATUS_SUCCESS)
     {
index 8d6e08b..9a46397 100644 (file)
 
 #include "nss-nisplus.h"
 
-/* Get the declaration of the parser function.  */
-#define ENTNAME netent
-#define DATABASE "networks"
-#define TRAILING_LIST_MEMBER            n_aliases
-#define TRAILING_LIST_SEPARATOR_P       isspace
-#include "../nss/nss_files/files-parse.c"
-LINE_PARSER
-("#",
- {
-   char *addr;
-
-   STRING_FIELD (result->n_name, isspace, 1);
-
-   STRING_FIELD (addr, isspace, 1);
-   result->n_net = inet_network (addr);
-
- })
-
 __libc_lock_define_initialized (static, lock)
 
 static nis_result *result = NULL;
-static nis_name *names = NULL;
+static nis_name tablename_val = NULL;
+static u_long tablename_len = 0;
 
 #define NISENTRYVAL(idx,col,res) \
-        ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
+        ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
 
 #define NISENTRYLEN(idx,col,res) \
-        ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
+        ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
 
 
 static int
 _nss_nisplus_parse_netent (nis_result *result, struct netent *network,
                            char *buffer, size_t buflen)
 {
-  char *p = buffer;
+  char *first_unused = buffer;
   size_t room_left = buflen;
   unsigned int i;
-  struct parser_data *data = (void *) buffer;
+  char *p, *line;
 
   if (result == NULL)
     return 0;
 
   if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
-      result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
-      strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+      __type_of (result->objects.objects_val) != ENTRY_OBJ ||
+      strcmp(result->objects.objects_val[0].EN_data.en_type,
              "networks_tbl") != 0 ||
-      result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3)
+      result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 3)
     return 0;
 
-  /* Generate the network entry format and use the normal parser */
-  if (NISENTRYLEN (0, 0, result) +1 > room_left)
+  if (NISENTRYLEN(0, 0, result) >= room_left)
     {
+      /* The line is too long for our buffer.  */
+    no_more_room:
       __set_errno (ERANGE);
       return 0;
     }
 
-  memset (p, '\0', room_left);
+  strncpy (first_unused, NISENTRYVAL(0, 0, result),
+           NISENTRYLEN (0, 0, result));
+  first_unused[NISENTRYLEN(0, 0, result)] = '\0';
+  network->n_name = first_unused;
+  room_left -= (strlen (first_unused) +1);
+  first_unused += strlen (first_unused) +1;
+  network->n_addrtype = 0;
+  network->n_net = inet_network (NISENTRYVAL (0, 2, result));
+  p = first_unused;
+
+  line = p;
+  for (i = 0; i < result->objects.objects_len; i++)
+    {
+      if (strcmp (NISENTRYVAL (i, 1, result), network->n_name) != 0)
+        {
+          if (NISENTRYLEN (i, 1, result) + 2 > room_left)
+            {
+              __set_errno (ERANGE);
+              return 0;
+            }
+          p = stpcpy(p, " ");
+          p = stpncpy (p, NISENTRYVAL (i, 1, result),
+                       NISENTRYLEN (i, 1, result));
+          *p = '\0';
+          room_left -= (NISENTRYLEN (i, 1, result) + 1);
+        }
+    }
+  ++p;
+  first_unused = p;
+
+  /* Adjust the pointer so it is aligned for
+     storing pointers.  */
+  first_unused += __alignof__ (char *) - 1;
+  first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *));
+  network->n_aliases = (char **) first_unused;
+  if (room_left < 2 * sizeof (char *))
+    goto no_more_room;
+  room_left -= (2 * sizeof (char *));
+  network->n_aliases[0] = NULL;
+
+    i = 0;
+  while (*line != '\0')
+    {
+      /* Skip leading blanks.  */
+      while (isspace (*line))
+        line++;
 
-  strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
-  room_left -= (NISENTRYLEN (0, 0, result) +1);
+      if (*line == '\0')
+        break;
 
-  if (NISENTRYLEN (0, 2, result) +1 > room_left)
-    {
-      __set_errno (ERANGE);
-      return 0;
+      if (room_left < sizeof (char *))
+        {
+          __set_errno (ERANGE);
+          return 0;
+        }
+
+      room_left -= sizeof (char *);
+      network->n_aliases[i] = line;
+
+      while (*line != '\0' && *line != ' ')
+        ++line;
+
+      if (line != network->n_aliases[i])
+        {
+          if (*line != '\0')
+            {
+              *line = '\0';
+              ++line;
+            }
+          ++i;
+        }
+      else
+        network->n_aliases[i] = NULL;
     }
-  strcat (p, "\t");
-  strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result));
-  room_left -= (NISENTRYLEN (0, 2, result) + 1);
-                                        /* + 1: We overwrite the last \0 */
 
-  for (i = 1; i < result->objects.objects_len; i++)
+  return 1;
+}
+
+static enum nss_status
+_nss_create_tablename (void)
+{
+  if (tablename_val == NULL)
     {
-      if (NISENTRYLEN (i, 1, result) +1 > room_left)
-       {
-         __set_errno (ERANGE);
-         return 0;
-       }
-      strcat (p, " ");
-      strncat (p, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));
-      room_left -= (NISENTRYLEN (i, 1, result) + 1);
+      char buf [40 + strlen (nis_local_directory ())];
+      char *p;
+
+      p = stpcpy (buf, "networks.org_dir.");
+      p = stpcpy (p, nis_local_directory ());
+      tablename_val = strdup (buf);
+      if (tablename_val == NULL)
+        return NSS_STATUS_TRYAGAIN;
+      tablename_len = strlen (tablename_val);
     }
-
-  return _nss_files_parse_netent (p, network, data, buflen);
+  return NSS_STATUS_SUCCESS;
 }
 
 enum nss_status
 _nss_nisplus_setnetent (void)
 {
+  enum nss_status status = NSS_STATUS_SUCCESS;
+
   __libc_lock_lock (lock);
 
   if (result)
     nis_freeresult (result);
   result = NULL;
-  if (names)
-    {
-      nis_freenames (names);
-      names = NULL;
-    }
+
+  if (tablename_val == NULL)
+    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+      status = NSS_STATUS_UNAVAIL;
 
   __libc_lock_unlock (lock);
 
-  return NSS_STATUS_SUCCESS;
+  return status;
 }
 
 enum nss_status
@@ -142,11 +193,6 @@ _nss_nisplus_endnetent (void)
   if (result)
     nis_freeresult (result);
   result = NULL;
-  if (names)
-    {
-      nis_freenames (names);
-      names = NULL;
-    }
 
   __libc_lock_unlock (lock);
 
@@ -164,11 +210,11 @@ internal_nisplus_getnetent_r (struct netent *network, char *buffer,
     {
       if (result == NULL)
        {
-         names = nis_getnames("networks.org_dir");
-         if (names == NULL || names[0] == NULL)
-           return NSS_STATUS_UNAVAIL;
+         if (tablename_val == NULL)
+           if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
+             return NSS_STATUS_UNAVAIL;
 
-         result = nis_first_entry(names[0]);
+         result = nis_first_entry(tablename_val);
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
            {
              int retval;
@@ -178,15 +224,17 @@ internal_nisplus_getnetent_r (struct netent *network, char *buffer,
                {
                  *herrnop = NETDB_INTERNAL;
                  __set_errno (EAGAIN);
+                 return retval;
                }
-             return retval;
+             else
+               return retval;
            }
        }
       else
        {
          nis_result *res;
 
-         res = nis_next_entry(names[0], &result->cookie);
+         res = nis_next_entry(tablename_val, &result->cookie);
          nis_freeresult (result);
          result = res;
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
@@ -236,6 +284,10 @@ _nss_nisplus_getnetbyname_r (const char *name, struct netent *network,
 {
   int parse_res, retval;
 
+  if (tablename_val == NULL)
+    if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
+      return NSS_STATUS_UNAVAIL;
+
   if (name == NULL)
     {
       __set_errno (EINVAL);
@@ -245,28 +297,28 @@ _nss_nisplus_getnetbyname_r (const char *name, struct netent *network,
   else
     {
       nis_result *result;
-      char buf[strlen (name) + 255];
-
+      char buf[strlen (name) + 255 + tablename_len];
 
       /* Search at first in the alias list, and use the correct name
         for the next search */
-      sprintf(buf, "[name=%s],networks.org_dir", name);
-      result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+      sprintf(buf, "[name=%s],%s", name, tablename_val);
+      result = nis_list(buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
 
       /* If we do not find it, try it as original name. But if the
         database is correct, we should find it in the first case, too */
       if ((result->status != NIS_SUCCESS &&
           result->status != NIS_S_SUCCESS) ||
-         result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
-         strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+         __type_of (result->objects.objects_val) != ENTRY_OBJ ||
+         strcmp(result->objects.objects_val[0].EN_data.en_type,
                 "networks_tbl") != 0 ||
-         result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3)
-       sprintf(buf, "[cname=%s],networks.org_dir", name);
+         result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 3)
+       sprintf(buf, "[cname=%s],%s", name, tablename_val);
       else
-       sprintf(buf, "[cname=%s],networks.org_dir", NISENTRYVAL(0, 0, result));
+       sprintf(buf, "[cname=%s],%s", NISENTRYVAL(0, 0, result),
+               tablename_val);
 
       nis_freeresult (result);
-      result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+      result = nis_list(buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
 
       retval = niserr2nss (result->status);
       if (retval != NSS_STATUS_SUCCESS)
@@ -301,39 +353,45 @@ _nss_nisplus_getnetbyaddr_r (const unsigned long addr, const int type,
                             struct netent *network,
                             char *buffer, size_t buflen, int *herrnop)
 {
-  int parse_res, retval;
-  nis_result *result;
-  char buf[1024];
-  struct in_addr in;
+  if (tablename_val == NULL)
+    if (_nss_create_tablename() != NSS_STATUS_SUCCESS)
+      return NSS_STATUS_UNAVAIL;
 
-  in = inet_makeaddr (addr, 0);
-  snprintf(buf, sizeof (buf) - 1, "[addr=%s],networks.org_dir",
-          inet_ntoa (in));
+  {
+    int parse_res, retval;
+    nis_result *result;
+    char buf[1024 + tablename_len];
+    struct in_addr in;
 
-  result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+    in = inet_makeaddr (addr, 0);
+    snprintf(buf, sizeof (buf) - 1, "[addr=%s],%s",
+            inet_ntoa (in), tablename_len);
 
-  retval = niserr2nss (result->status);
-  if (retval != NSS_STATUS_SUCCESS)
-    {
-      if (retval == NSS_STATUS_TRYAGAIN)
-       {
-         __set_errno (EAGAIN);
-         *herrnop = NETDB_INTERNAL;
-       }
-      nis_freeresult (result);
-      return retval;
-    }
+    result = nis_list(buf, EXPAND_NAME, NULL, NULL);
 
-  parse_res = _nss_nisplus_parse_netent (result, network, buffer, buflen);
+    retval = niserr2nss (result->status);
+    if (retval != NSS_STATUS_SUCCESS)
+      {
+       if (retval == NSS_STATUS_TRYAGAIN)
+         {
+           __set_errno (EAGAIN);
+           *herrnop = NETDB_INTERNAL;
+         }
+       nis_freeresult (result);
+       return retval;
+      }
 
-  nis_freeresult (result);
+    parse_res = _nss_nisplus_parse_netent (result, network, buffer, buflen);
 
-  if (parse_res)
-    return NSS_STATUS_SUCCESS;
+    nis_freeresult (result);
 
-  *herrnop = NETDB_INTERNAL;
-  if (!parse_res && errno == ERANGE)
-    return NSS_STATUS_TRYAGAIN;
-  else
-    return NSS_STATUS_NOTFOUND;
+    if (parse_res)
+      return NSS_STATUS_SUCCESS;
+
+    *herrnop = NETDB_INTERNAL;
+    if (!parse_res && errno == ERANGE)
+      return NSS_STATUS_TRYAGAIN;
+    else
+      return NSS_STATUS_NOTFOUND;
+  }
 }
diff --git a/nis/nss_nisplus/nisplus-parser.c b/nis/nss_nisplus/nisplus-parser.c
new file mode 100644 (file)
index 0000000..bb6bba1
--- /dev/null
@@ -0,0 +1,337 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <pwd.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <rpcsvc/nis.h>
+
+#include "nisplus-parser.h"
+
+#define NISENTRYVAL(idx,col,res) \
+        ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
+
+#define NISENTRYLEN(idx,col,res) \
+        ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
+
+
+int
+_nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
+                         char *buffer, size_t buflen)
+{
+  char *first_unused = buffer;
+  size_t room_left = buflen;
+
+  if (result == NULL)
+    return 0;
+
+  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
+      result->objects.objects_len != 1 ||
+      __type_of (result->objects.objects_val) != ENTRY_OBJ ||
+      strcmp(result->objects.objects_val->EN_data.en_type,
+            "passwd_tbl") != 0 ||
+      result->objects.objects_val->EN_data.en_cols.en_cols_len < 7)
+    return 0;
+
+  if (NISENTRYLEN (0, 0, result) >= room_left)
+    {
+      /* The line is too long for our buffer.  */
+    no_more_room:
+      __set_errno (ERANGE);
+      return 0;
+    }
+
+  strncpy (first_unused, NISENTRYVAL(0, 0, result),
+          NISENTRYLEN (0, 0, result));
+  first_unused[NISENTRYLEN(0, 0, result)] = '\0';
+  pw->pw_name = first_unused;
+  room_left -= (strlen (first_unused) +1);
+  first_unused += strlen (first_unused) +1;
+
+  if (NISENTRYLEN(0, 1, result) >= room_left)
+    goto no_more_room;
+
+  strncpy (first_unused, NISENTRYVAL(0, 1, result),
+          NISENTRYLEN (0, 1, result));
+  first_unused[NISENTRYLEN(0, 1, result)] = '\0';
+  pw->pw_passwd = first_unused;
+  room_left -= (strlen (first_unused) +1);
+  first_unused += strlen (first_unused) +1;
+
+  if (NISENTRYLEN(0, 2, result) >= room_left)
+    goto no_more_room;
+
+  strncpy (first_unused, NISENTRYVAL (0, 2, result),
+          NISENTRYLEN (0, 2, result));
+  first_unused[NISENTRYLEN(0, 2, result)] = '\0';
+  pw->pw_uid = atoi (first_unused);
+  room_left -= (strlen (first_unused) +1);
+  first_unused += strlen (first_unused) +1;
+
+  if (NISENTRYLEN(0, 3, result) >= room_left)
+    goto no_more_room;
+
+  strncpy (first_unused, NISENTRYVAL(0, 3, result),
+          NISENTRYLEN (0, 3, result));
+  first_unused[NISENTRYLEN(0, 3, result)] = '\0';
+  pw->pw_gid = atoi (first_unused);
+  room_left -= (strlen (first_unused) +1);
+  first_unused += strlen (first_unused) +1;
+
+  if (NISENTRYLEN(0, 4, result) >= room_left)
+    goto no_more_room;
+
+  strncpy (first_unused, NISENTRYVAL(0, 4, result),
+          NISENTRYLEN (0, 4, result));
+  first_unused[NISENTRYLEN(0, 4, result)] = '\0';
+  pw->pw_gecos = first_unused;
+  room_left -= (strlen (first_unused) +1);
+  first_unused += strlen (first_unused) +1;
+
+  if (NISENTRYLEN(0, 5, result) >= room_left)
+    goto no_more_room;
+
+  strncpy (first_unused, NISENTRYVAL (0, 5, result),
+          NISENTRYLEN (0, 5, result));
+  first_unused[NISENTRYLEN(0, 5, result)] = '\0';
+  pw->pw_dir = first_unused;
+  room_left -= (strlen (first_unused) +1);
+  first_unused += strlen (first_unused) +1;
+
+  if (NISENTRYLEN(0, 6, result) >= room_left)
+    goto no_more_room;
+
+  strncpy (first_unused, NISENTRYVAL (0, 6, result),
+          NISENTRYLEN (0, 6, result));
+  first_unused[NISENTRYLEN (0, 6, result)] = '\0';
+  pw->pw_shell = first_unused;
+  room_left -= (strlen (first_unused) +1);
+  first_unused += strlen (first_unused) +1;
+
+  return 1;
+}
+
+int
+_nss_nisplus_parse_grent (nis_result *result, u_long entry,
+                         struct group *gr, char *buffer, size_t buflen)
+{
+  char *first_unused = buffer;
+  size_t room_left = buflen;
+  char *line;
+  int count;
+
+  if (result == NULL)
+    return 0;
+
+  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
+      __type_of(result->objects.objects_val) != ENTRY_OBJ ||
+      strcmp (result->objects.objects_val[entry].EN_data.en_type,
+             "group_tbl") != 0 ||
+      result->objects.objects_val[entry].EN_data.en_cols.en_cols_len < 4)
+    return 0;
+
+  if (NISENTRYLEN (entry, 0, result) >= room_left)
+    {
+      /* The line is too long for our buffer.  */
+    no_more_room:
+      __set_errno (ERANGE);
+      return 0;
+    }
+
+  strncpy (first_unused, NISENTRYVAL (entry, 0, result),
+          NISENTRYLEN (entry, 0, result));
+  first_unused[NISENTRYLEN (entry, 0, result)] = '\0';
+  gr->gr_name = first_unused;
+  room_left -= (strlen (first_unused) + 1);
+  first_unused += strlen (first_unused) + 1;
+
+  if (NISENTRYLEN (entry, 1, result) >= room_left)
+    goto no_more_room;
+
+  strncpy (first_unused, NISENTRYVAL (entry, 1, result),
+          NISENTRYLEN (entry, 1, result));
+  first_unused[NISENTRYLEN (entry, 1, result)] = '\0';
+  gr->gr_passwd = first_unused;
+  room_left -= (strlen (first_unused) + 1);
+  first_unused += strlen (first_unused) + 1;
+
+  if (NISENTRYLEN (entry, 2, result) >= room_left)
+    goto no_more_room;
+
+  strncpy (first_unused, NISENTRYVAL (entry, 2, result),
+          NISENTRYLEN (entry, 2, result));
+  first_unused[NISENTRYLEN (entry, 2, result)] = '\0';
+  gr->gr_gid = atoi (first_unused);
+  room_left -= (strlen (first_unused) + 1);
+  first_unused += strlen (first_unused) + 1;
+
+  if (NISENTRYLEN (entry, 3, result) >= room_left)
+    goto no_more_room;
+
+  strncpy (first_unused, NISENTRYVAL (entry, 3, result),
+          NISENTRYLEN (entry, 3, result));
+  first_unused[NISENTRYLEN (entry, 3, result)] = '\0';
+  line = first_unused;
+  room_left -= (strlen (line) + 1);
+  first_unused += strlen (line) + 1;
+  /* Adjust the pointer so it is aligned for
+     storing pointers.  */
+  first_unused += __alignof__ (char *) - 1;
+  first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *));
+  gr->gr_mem = (char **) first_unused;
+
+  count = 0;
+  while (*line != '\0')
+    {
+      /* Skip leading blanks.  */
+      while (isspace (*line))
+       ++line;
+
+      if (*line == '\0')
+       break;
+
+      if (room_left < sizeof (char *))
+         goto no_more_room;
+      room_left -= sizeof (char *);
+      gr->gr_mem[count] = line;
+
+      while (*line != '\0' && *line != ',' && !isspace(*line))
+       ++line;
+
+      if (line != gr->gr_mem[count])
+       {
+         if (*line != '\0')
+           {
+             *line = '\0';
+             ++line;
+           }
+         ++count;
+       }
+      else
+       gr->gr_mem[count] = NULL;
+    }
+  if (room_left < sizeof (char *))
+      goto no_more_room;
+  room_left -= sizeof (char *);
+  gr->gr_mem[count] = NULL;
+
+  return 1;
+}
+
+int
+_nss_nisplus_parse_spent (nis_result *result, struct spwd *sp,
+                         char *buffer, size_t buflen)
+{
+  char *first_unused = buffer;
+  size_t room_left = buflen;
+  
+  if (result == NULL)
+    return 0;
+
+  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
+      result->objects.objects_len != 1 ||
+      __type_of(result->objects.objects_val) != ENTRY_OBJ ||
+      strcmp (result->objects.objects_val->EN_data.en_type,
+             "passwd_tbl") != 0 ||
+      result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 8)
+    return 0;
+
+  if (NISENTRYLEN(0, 0, result) >= room_left)
+    {
+      /* The line is too long for our buffer.  */
+    no_more_room:
+      __set_errno (ERANGE);
+      return 0;
+    }
+
+  strncpy (first_unused, NISENTRYVAL (0, 0, result),
+          NISENTRYLEN (0, 0, result));
+  first_unused[NISENTRYLEN(0, 0, result)] = '\0';
+  sp->sp_namp = first_unused;
+  room_left -= (strlen (first_unused) +1);
+  first_unused += strlen (first_unused) +1;
+
+  if (NISENTRYLEN(0, 1, result) >= room_left)
+    goto no_more_room;
+
+  strncpy (first_unused, NISENTRYVAL (0, 1, result),
+          NISENTRYLEN (0, 1, result));
+  first_unused[NISENTRYLEN(0, 1, result)] = '\0';
+  sp->sp_pwdp = first_unused;
+  room_left -= (strlen (first_unused) +1);
+  first_unused += strlen (first_unused) +1;
+
+  sp->sp_lstchg = sp->sp_min = sp->sp_max = sp->sp_warn = sp->sp_inact =
+    sp->sp_expire = sp->sp_flag = -1;
+
+  if (NISENTRYLEN (0, 7, result) > 0)
+    {
+      char *line, *cp;
+
+      line = NISENTRYVAL (0, 7, result);
+      cp = strchr (line, ':');
+      if (cp == NULL)
+       return 0;
+      *cp++ = '\0';
+      sp->sp_lstchg = atol (line);
+
+      line = cp;
+      cp = strchr (line, ':');
+      if (cp == NULL)
+       return 0;
+      *cp++ = '\0';
+      sp->sp_min = atol(line);
+
+      line = cp;
+      cp = strchr (line, ':');
+      if (cp == NULL)
+       return 0;
+      *cp++ = '\0';
+      sp->sp_max = atol(line);
+
+      line = cp;
+      cp = strchr (line, ':');
+      if (cp == NULL)
+       return 0;
+      *cp++ = '\0';
+      sp->sp_warn = atol(line);
+
+      line = cp;
+      cp = strchr (line, ':');
+      if (cp == NULL)
+       return 0;
+      *cp++ = '\0';
+      sp->sp_inact = atol(line);
+
+      line = cp;
+      cp = strchr (line, ':');
+      if (cp == NULL)
+       return 0;
+      *cp++ = '\0';
+      sp->sp_expire = atol(line);
+
+      line = cp;
+      if (line == NULL)
+       return 0;
+      sp->sp_flag = atol(line);
+    }
+
+  return 1;
+}
index ee0341d..1ee9a89 100644 (file)
 __libc_lock_define_initialized (static, lock)
 
 static nis_result *result = NULL;
-static nis_name *names = NULL;
-
-#define ENTNAME         protoent
-#define DATABASE        "protocols"
-#define TRAILING_LIST_MEMBER            p_aliases
-#define TRAILING_LIST_SEPARATOR_P       isspace
-#include "../../nss/nss_files/files-parse.c"
-LINE_PARSER
-("#",
- STRING_FIELD (result->p_name, isspace, 1);
- INT_FIELD (result->p_proto, isspace, 1, 10,);
-)
+static nis_name tablename_val = NULL;
+static u_long tablename_len = 0;
 
 #define NISENTRYVAL(idx,col,res) \
-        ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
+        ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
 
 #define NISENTRYLEN(idx,col,res) \
-        ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
+        ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
 
 static int
 _nss_nisplus_parse_protoent (nis_result * result, struct protoent *proto,
                             char *buffer, size_t buflen)
 {
-  char *p = buffer;
+  char *first_unused = buffer;
   size_t room_left = buflen;
   unsigned int i;
-  struct parser_data *data = (void *) buffer;
+  char *p, *line;
 
   if (result == NULL)
     return 0;
 
   if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
-      result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
-   strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
-          "protocols_tbl") != 0 ||
-      result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3)
+      __type_of (NIS_RES_OBJECT (result)) != ENTRY_OBJ ||
+      strcmp (NIS_RES_OBJECT (result)->EN_data.en_type, "protocols_tbl") != 0
+      || NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 3)
     return 0;
 
-  memset (p, '\0', room_left);
-
   /* Generate the protocols entry format and use the normal parser */
   if (NISENTRYLEN (0, 0, result) + 1 > room_left)
     {
+    no_more_room:
       __set_errno (ERANGE);
       return 0;
     }
-  strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
-  room_left -= (NISENTRYLEN (0, 0, result) + 1);
+  strncpy (first_unused, NISENTRYVAL (0, 0, result),
+           NISENTRYLEN (0, 0, result));
+  first_unused[NISENTRYLEN (0, 0, result)] = '\0';
+  proto->p_name = first_unused;
+  room_left -= (strlen (first_unused) +1);
+  first_unused += strlen (first_unused) +1;
+
 
   if (NISENTRYLEN (0, 2, result) + 1 > room_left)
+    goto no_more_room;
+  proto->p_proto = atoi (NISENTRYVAL (0, 2, result));
+  p = first_unused;
+
+  line = p;
+  for (i = 0; i < result->objects.objects_len; i++)
     {
-      __set_errno (ERANGE);
-      return 0;
+      if (strcmp (NISENTRYVAL (i, 1, result), proto->p_name) != 0)
+        {
+          if (NISENTRYLEN (i, 1, result) + 2 > room_left)
+            goto no_more_room;
+          p = stpcpy(p, " ");
+          p = stpncpy (p, NISENTRYVAL (i, 1, result),
+                       NISENTRYLEN (i, 1, result));
+          *p = '\0';
+          room_left -= (NISENTRYLEN (i, 1, result) + 1);
+        }
     }
-  strcat (p, "\t");
-  strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result));
-  room_left -= (NISENTRYLEN (0, 2, result) + 1);
-  /* + 1: We overwrite the last \0 */
-
-  for (i = 1; i < result->objects.objects_len; i++)
+  ++p;
+  first_unused = p;
+
+  /* Adjust the pointer so it is aligned for
+     storing pointers.  */
+  first_unused += __alignof__ (char *) - 1;
+  first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *));
+  proto->p_aliases = (char **) first_unused;
+  if (room_left < sizeof (char *))
+    goto no_more_room;
+  room_left -= (sizeof (char *));
+  proto->p_aliases[0] = NULL;
+
+  i = 0;
+  while (*line != '\0')
     {
-      if (NISENTRYLEN (i, 1, result) + 1 > room_left)
-       {
-         __set_errno (ERANGE);
-         return 0;
-       }
-      strcat (p, " ");
-      strncat (p, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));
-      room_left -= (NISENTRYLEN (i, 1, result) + 1);
+      /* Skip leading blanks.  */
+      while (isspace (*line))
+        line++;
+      if (*line == '\0')
+        break;
+
+      if (room_left < sizeof (char *))
+        goto no_more_room;
+
+      room_left -= sizeof (char *);
+      proto->p_aliases[i] = line;
+
+      while (*line != '\0' && *line != ' ')
+        ++line;
+
+      if (*line == ' ')
+        {
+          *line = '\0';
+          ++line;
+          ++i;
+        }
+      else
+        proto->p_aliases[i+1] = NULL;
     }
 
-  return _nss_files_parse_protoent (p, proto, data, buflen);
+  return 1;
+}
+
+static enum nss_status
+_nss_create_tablename (void)
+{
+  if (tablename_val == NULL)
+    {
+      char buf [40 + strlen (nis_local_directory ())];
+      char *p;
+
+      p = stpcpy (buf, "protocols.org_dir.");
+      p = stpcpy (p, nis_local_directory ());
+      tablename_val = strdup (buf);
+      if (tablename_val == NULL)
+        return NSS_STATUS_TRYAGAIN;
+      tablename_len = strlen (tablename_val);
+    }
+  return NSS_STATUS_SUCCESS;
 }
 
 enum nss_status
 _nss_nisplus_setprotoent (void)
 {
+  enum nss_status status = NSS_STATUS_SUCCESS;
+
   __libc_lock_lock (lock);
 
   if (result)
     nis_freeresult (result);
   result = NULL;
-  if (names)
-    {
-      nis_freenames (names);
-      names = NULL;
-    }
+
+  if (tablename_val == NULL)
+    status = _nss_create_tablename ();
 
   __libc_lock_unlock (lock);
 
-  return NSS_STATUS_SUCCESS;
+  return status;
 }
 
 enum nss_status
@@ -132,11 +181,6 @@ _nss_nisplus_endprotoent (void)
   if (result)
     nis_freeresult (result);
   result = NULL;
-  if (names)
-    {
-      nis_freenames (names);
-      names = NULL;
-    }
 
   __libc_lock_unlock (lock);
 
@@ -154,11 +198,11 @@ internal_nisplus_getprotoent_r (struct protoent *proto, char *buffer,
     {
       if (result == NULL)
        {
-         names = nis_getnames ("protocols.org_dir");
-         if (names == NULL || names[0] == NULL)
-           return NSS_STATUS_UNAVAIL;
+         if (tablename_val == NULL)
+           if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+             return NSS_STATUS_UNAVAIL;
 
-         result = nis_first_entry (names[0]);
+         result = nis_first_entry (tablename_val);
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
            return niserr2nss (result->status);
        }
@@ -166,7 +210,7 @@ internal_nisplus_getprotoent_r (struct protoent *proto, char *buffer,
        {
          nis_result *res;
 
-         res = nis_next_entry (names[0], &result->cookie);
+         res = nis_next_entry (tablename_val, &result->cookie);
          nis_freeresult (result);
          result = res;
 
@@ -202,32 +246,37 @@ _nss_nisplus_getprotobyname_r (const char *name, struct protoent *proto,
 {
   int parse_res;
 
+  if (tablename_val == NULL)
+    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+      return NSS_STATUS_UNAVAIL;
+
   if (name == NULL)
     return NSS_STATUS_NOTFOUND;
   else
     {
       nis_result *result;
-      char buf[strlen (name) + 255];
+      char buf[strlen (name) + 255 + tablename_len];
 
       /* Search at first in the alias list, and use the correct name
          for the next search */
-      sprintf (buf, "[name=%s],protocols.org_dir", name);
-      result = nis_list (buf, EXPAND_NAME, NULL, NULL);
+      sprintf (buf, "[name=%s],%s", name, tablename_val);
+      result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
       /* If we do not find it, try it as original name. But if the
          database is correct, we should find it in the first case, too */
       if ((result->status != NIS_SUCCESS &&
           result->status != NIS_S_SUCCESS) ||
-         result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
-         strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+         __type_of (result->objects.objects_val) != ENTRY_OBJ ||
+         strcmp (result->objects.objects_val->EN_data.en_type,
                  "protocols_tbl") != 0 ||
-         result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3)
-       sprintf (buf, "[cname=%s],protocols.org_dir", name);
+         result->objects.objects_val->EN_data.en_cols.en_cols_len < 3)
+       sprintf (buf, "[cname=%s],%s", name, tablename_val);
       else
-       sprintf (buf, "[cname=%s],protocols.org_dir", NISENTRYVAL (0, 0, result));
+       sprintf (buf, "[cname=%s],%s", NISENTRYVAL (0, 0, result),
+                tablename_val);
 
       nis_freeresult (result);
-      result = nis_list (buf, EXPAND_NAME, NULL, NULL);
+      result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
       if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
        {
@@ -255,30 +304,35 @@ enum nss_status
 _nss_nisplus_getprotobynumber_r (const int number, struct protoent *proto,
                                 char *buffer, size_t buflen)
 {
-  int parse_res;
-  nis_result *result;
-  char buf[46];
-
-  snprintf (buf, sizeof (buf), "[number=%d],protocols.org_dir", number);
+  if (tablename_val == NULL)
+    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+      return NSS_STATUS_UNAVAIL;
+  {
+    int parse_res;
+    nis_result *result;
+    char buf[46 + tablename_len];
 
-  result = nis_list (buf, EXPAND_NAME, NULL, NULL);
+    snprintf (buf, sizeof (buf), "[number=%d],%s", number, tablename_val);
 
-  if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
-    {
-      enum nss_status status = niserr2nss (result->status);
+    result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
 
-      nis_freeresult (result);
-      return status;
-    }
+    if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+      {
+       enum nss_status status = niserr2nss (result->status);
 
-  parse_res = _nss_nisplus_parse_protoent (result, proto, buffer, buflen);
+       nis_freeresult (result);
+       return status;
+      }
 
-  nis_freeresult (result);
-  if (parse_res)
-    return NSS_STATUS_SUCCESS;
+    parse_res = _nss_nisplus_parse_protoent (result, proto, buffer, buflen);
 
-  if (!parse_res && errno == ERANGE)
-    return NSS_STATUS_TRYAGAIN;
-  else
-    return NSS_STATUS_NOTFOUND;
+    nis_freeresult (result);
+    if (parse_res)
+      return NSS_STATUS_SUCCESS;
+
+    if (!parse_res && errno == ERANGE)
+      return NSS_STATUS_TRYAGAIN;
+    else
+      return NSS_STATUS_NOTFOUND;
+  }
 }
index 91cfba7..4c596b8 100644 (file)
@@ -61,10 +61,10 @@ _nss_nisplus_getpublickey (const char *netname, char *pkey)
            netname, domain);
 
   if (buf[strlen (buf)-1] != '.')
-    strcat(buf, ".");
+    strcat (buf, ".");
 
-  res = nis_list(buf, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH,
-                NULL, NULL);
+  res = nis_list (buf, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH,
+                 NULL, NULL);
 
   retval = niserr2nss (res->status);
 
@@ -192,7 +192,7 @@ parse_grp_str (const char *s, gid_t *gidp, int *gidlenp, gid_t *gidlist)
       return NSS_STATUS_NOTFOUND;
     }
 
-  *gidp = (atoi (s));
+  *gidp = atoi (s);
 
   gidlen = 0;
 
@@ -238,7 +238,7 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
   /* XXX but we cant, for now. XXX */
   res = nis_list (sname, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH,
                  NULL, NULL);
-  switch(res->status)
+  switch (res->status)
     {
     case NIS_SUCCESS:
     case NIS_S_SUCCESS:
@@ -274,10 +274,10 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
              netname, domain);
     }
 
-  len = ENTRY_LEN(res->objects.objects_val, 0);
-  strncpy(principal, ENTRY_VAL(res->objects.objects_val, 0), len);
+  len = ENTRY_LEN (res->objects.objects_val, 0);
+  strncpy (principal, ENTRY_VAL (res->objects.objects_val, 0), len);
   principal[len] = '\0';
-  nis_freeresult(res);
+  nis_freeresult (res);
 
   if (principal[0] == '\0')
     return NSS_STATUS_UNAVAIL;
@@ -287,45 +287,45 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
    *      LOCAL entry in **local** cred table.
    */
   domain = nis_local_directory ();
-  if ((strlen(principal)+strlen(domain)+45) >
+  if ((strlen (principal)+strlen (domain)+45) >
       (size_t) NIS_MAXNAMELEN)
     {
       syslog (LOG_ERR, _("netname2user: principal name '%s' too long"),
              principal);
       return NSS_STATUS_UNAVAIL;
     }
-  sprintf(sname, "[cname=%s,auth_type=LOCAL],cred.org_dir.%s",
+  sprintf (sname, "[cname=%s,auth_type=LOCAL],cred.org_dir.%s",
          principal, domain);
   if (sname[strlen(sname) - 1] != '.')
     strcat(sname, ".");
 
   /* must use authenticated call here */
   /* XXX but we cant, for now. XXX */
-  res = nis_list(sname, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH,
-                NULL, NULL);
-  switch(res->status) {
-  case NIS_NOTFOUND:
-  case NIS_PARTIAL:
-  case NIS_NOSUCHNAME:
-  case NIS_NOSUCHTABLE:
-    nis_freeresult (res);
-    return NSS_STATUS_NOTFOUND;
-  case NIS_S_NOTFOUND:
-  case NIS_TRYAGAIN:
-    syslog (LOG_ERR,
-           "netname2user: (nis+ lookup): %s\n",
-           nis_sperrno (res->status));
-    nis_freeresult (res);
-    return NSS_STATUS_TRYAGAIN;
-  case NIS_SUCCESS:
-  case NIS_S_SUCCESS:
-    break;   /* go and do something useful */
-  default:
-    syslog (LOG_ERR, "netname2user: (nis+ lookup): %s\n",
-           nis_sperrno (res->status));
-    nis_freeresult (res);
-    return NSS_STATUS_UNAVAIL;
-  }
+  res = nis_list (sname, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH,
+                 NULL, NULL);
+  switch(res->status)
+    {
+    case NIS_NOTFOUND:
+    case NIS_PARTIAL:
+    case NIS_NOSUCHNAME:
+    case NIS_NOSUCHTABLE:
+      nis_freeresult (res);
+      return NSS_STATUS_NOTFOUND;
+    case NIS_S_NOTFOUND:
+    case NIS_TRYAGAIN:
+      syslog (LOG_ERR, "netname2user: (nis+ lookup): %s\n",
+             nis_sperrno (res->status));
+      nis_freeresult (res);
+      return NSS_STATUS_TRYAGAIN;
+    case NIS_SUCCESS:
+    case NIS_S_SUCCESS:
+      break;   /* go and do something useful */
+    default:
+      syslog (LOG_ERR, "netname2user: (nis+ lookup): %s\n",
+             nis_sperrno (res->status));
+      nis_freeresult (res);
+      return NSS_STATUS_UNAVAIL;
+    }
 
   if (res->objects.objects_len > 1)
     {
@@ -339,7 +339,7 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
             netname, domain);
     }
   /* Fetch the uid */
-  *uidp = (atoi (ENTRY_VAL (res->objects.objects_val, 2)));
+  *uidp = atoi (ENTRY_VAL (res->objects.objects_val, 2));
 
   if (*uidp == 0)
     {
index 89b0eff..459a1a4 100644 (file)
 __libc_lock_define_initialized (static, lock)
 
 static nis_result *result = NULL;
-static nis_name *names = NULL;
+static nis_name tablename_val = NULL;
+static u_long tablename_len = 0;
 
-#define NISENTRYVAL(idx,col,res) \
-        ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
+extern int _nss_nisplus_parse_pwent (nis_result *res, struct passwd *pw,
+                                    char *buffer, size_t buflen);
 
-#define NISENTRYLEN(idx,col,res) \
-        ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
-
-int
-_nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
-                         char *buffer, size_t buflen)
+static enum nss_status
+_nss_create_tablename (void)
 {
-  char *first_unused = buffer;
-  size_t room_left = buflen;
-
-  if (result == NULL)
-    return 0;
-
-  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
-      result->objects.objects_len != 1 ||
-      result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
-      strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
-            "passwd_tbl") != 0 ||
-      result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 7)
-    return 0;
-
-  if (NISENTRYLEN(0, 0, result) >= room_left)
+  if (tablename_val == NULL)
     {
-      /* The line is too long for our buffer.  */
-    no_more_room:
-      __set_errno (ERANGE);
-      return 0;
+      char buf [40 + strlen (nis_local_directory ())];
+      char *p;
+
+      p = stpcpy (buf, "passwd.org_dir.");
+      p = stpcpy (p, nis_local_directory ());
+      tablename_val = strdup (buf);
+      if (tablename_val == NULL)
+        return NSS_STATUS_TRYAGAIN;
+      tablename_len = strlen (tablename_val);
     }
-
-  strncpy (first_unused, NISENTRYVAL(0, 0, result),
-          NISENTRYLEN (0, 0, result));
-  first_unused[NISENTRYLEN(0, 0, result)] = '\0';
-  pw->pw_name = first_unused;
-  room_left -= (strlen (first_unused) +1);
-  first_unused += strlen (first_unused) +1;
-
-  if (NISENTRYLEN(0, 1, result) >= room_left)
-    goto no_more_room;
-
-  strncpy (first_unused, NISENTRYVAL(0, 1, result),
-          NISENTRYLEN (0, 1, result));
-  first_unused[NISENTRYLEN(0, 1, result)] = '\0';
-  pw->pw_passwd = first_unused;
-  room_left -= (strlen (first_unused) +1);
-  first_unused += strlen (first_unused) +1;
-
-  if (NISENTRYLEN(0, 2, result) >= room_left)
-    goto no_more_room;
-
-  strncpy (first_unused, NISENTRYVAL (0, 2, result),
-          NISENTRYLEN (0, 2, result));
-  first_unused[NISENTRYLEN(0, 2, result)] = '\0';
-  pw->pw_uid = atoi (first_unused);
-  room_left -= (strlen (first_unused) +1);
-  first_unused += strlen (first_unused) +1;
-
-  if (NISENTRYLEN(0, 3, result) >= room_left)
-    goto no_more_room;
-
-  strncpy (first_unused, NISENTRYVAL(0, 3, result),
-          NISENTRYLEN (0, 3, result));
-  first_unused[NISENTRYLEN(0, 3, result)] = '\0';
-  pw->pw_gid = atoi (first_unused);
-  room_left -= (strlen (first_unused) +1);
-  first_unused += strlen (first_unused) +1;
-
-  if (NISENTRYLEN(0, 4, result) >= room_left)
-    goto no_more_room;
-
-  strncpy (first_unused, NISENTRYVAL(0, 4, result),
-          NISENTRYLEN (0, 4, result));
-  first_unused[NISENTRYLEN(0, 4, result)] = '\0';
-  pw->pw_gecos = first_unused;
-  room_left -= (strlen (first_unused) +1);
-  first_unused += strlen (first_unused) +1;
-
-  if (NISENTRYLEN(0, 5, result) >= room_left)
-    goto no_more_room;
-
-  strncpy (first_unused, NISENTRYVAL (0, 5, result),
-          NISENTRYLEN (0, 5, result));
-  first_unused[NISENTRYLEN(0, 5, result)] = '\0';
-  pw->pw_dir = first_unused;
-  room_left -= (strlen (first_unused) +1);
-  first_unused += strlen (first_unused) +1;
-
-  if (NISENTRYLEN(0, 6, result) >= room_left)
-    goto no_more_room;
-
-  strncpy (first_unused, NISENTRYVAL (0, 6, result),
-          NISENTRYLEN (0, 6, result));
-  first_unused[NISENTRYLEN (0, 6, result)] = '\0';
-  pw->pw_shell = first_unused;
-  room_left -= (strlen (first_unused) +1);
-  first_unused += strlen (first_unused) +1;
-
-  return 1;
+  return NSS_STATUS_SUCCESS;
 }
 
+
 enum nss_status
 _nss_nisplus_setpwent (void)
 {
+  enum nss_status status = NSS_STATUS_SUCCESS;
+
   __libc_lock_lock (lock);
 
   if (result)
     nis_freeresult (result);
   result = NULL;
-  if (names)
-    {
-      nis_freenames (names);
-      names = NULL;
-    }
+
+  if (tablename_val == NULL)
+    status = _nss_create_tablename ();
 
   __libc_lock_unlock (lock);
 
-  return NSS_STATUS_SUCCESS;
+  return status;
 }
 
 enum nss_status
@@ -161,11 +82,6 @@ _nss_nisplus_endpwent (void)
   if (result)
     nis_freeresult (result);
   result = NULL;
-  if (names)
-    {
-      nis_freenames (names);
-      names = NULL;
-    }
 
   __libc_lock_unlock (lock);
 
@@ -182,11 +98,11 @@ internal_nisplus_getpwent_r (struct passwd *pw, char *buffer, size_t buflen)
     {
       if (result == NULL)
        {
-         names = nis_getnames ("passwd.org_dir");
-         if (names == NULL || names[0] == NULL)
-           return NSS_STATUS_UNAVAIL;
+          if (tablename_val == NULL)
+            if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+              return NSS_STATUS_UNAVAIL;
 
-         result = nis_first_entry(names[0]);
+         result = nis_first_entry(tablename_val);
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
            return niserr2nss (result->status);
        }
@@ -194,7 +110,7 @@ internal_nisplus_getpwent_r (struct passwd *pw, char *buffer, size_t buflen)
        {
          nis_result *res;
 
-         res = nis_next_entry(names[0], &result->cookie);
+         res = nis_next_entry(tablename_val, &result->cookie);
          nis_freeresult (result);
          result = res;
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
@@ -227,16 +143,20 @@ _nss_nisplus_getpwnam_r (const char *name, struct passwd *pw,
 {
   int parse_res;
 
+  if (tablename_val == NULL)
+    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+      return NSS_STATUS_UNAVAIL;
+
   if (name == NULL || strlen (name) > 8)
     return NSS_STATUS_NOTFOUND;
   else
     {
       nis_result *result;
-      char buf[strlen (name) + 24];
+      char buf[strlen (name) + 24 + tablename_len];
 
-      sprintf(buf, "[name=%s],passwd.org_dir", name);
+      sprintf(buf, "[name=%s],%s", name, tablename_val);
 
-      result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+      result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
       if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
        {
@@ -264,30 +184,35 @@ enum nss_status
 _nss_nisplus_getpwuid_r (const uid_t uid, struct passwd *pw,
                     char *buffer, size_t buflen)
 {
-  int parse_res;
-  nis_result *result;
-  char buf[100];
-
-  sprintf(buf, "[uid=%d],passwd.org_dir", uid);
+  if (tablename_val == NULL)
+    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+      return NSS_STATUS_UNAVAIL;
+  {
+    int parse_res;
+    nis_result *result;
+    char buf[100 + tablename_len];
 
-  result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+    sprintf(buf, "[uid=%d],%s", uid, tablename_val);
 
-  if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
-   {
-     enum nss_status status = niserr2nss (result->status);
+    result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
-     nis_freeresult (result);
-     return status;
-   }
+    if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+      {
+       enum nss_status status = niserr2nss (result->status);
 
-  parse_res = _nss_nisplus_parse_pwent (result, pw, buffer, buflen);
+       nis_freeresult (result);
+       return status;
+      }
 
-  nis_freeresult (result);
-  if (parse_res)
-    return NSS_STATUS_SUCCESS;
+    parse_res = _nss_nisplus_parse_pwent (result, pw, buffer, buflen);
 
-  if (!parse_res && errno == ERANGE)
-    return NSS_STATUS_TRYAGAIN;
-  else
-    return NSS_STATUS_NOTFOUND;
+    nis_freeresult (result);
+    if (parse_res)
+      return NSS_STATUS_SUCCESS;
+
+    if (!parse_res && errno == ERANGE)
+      return NSS_STATUS_TRYAGAIN;
+    else
+      return NSS_STATUS_NOTFOUND;
+  }
 }
index 180e916..cebd5d7 100644 (file)
 __libc_lock_define_initialized (static, lock)
 
 static nis_result *result = NULL;
-static nis_name *names = NULL;
-
-#define ENTNAME         rpcent
-#define DATABASE        "rpc"
-#define TRAILING_LIST_MEMBER            r_aliases
-#define TRAILING_LIST_SEPARATOR_P       isspace
-#include "../../nss/nss_files/files-parse.c"
-LINE_PARSER
-("#",
- STRING_FIELD (result->r_name, isspace, 1);
- INT_FIELD (result->r_number, isspace, 1, 10,);
- )
+static nis_name tablename_val = NULL;
+static u_long tablename_len = 0;
 
 #define NISENTRYVAL(idx,col,res) \
-        ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
+        ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
 
 #define NISENTRYLEN(idx,col,res) \
-        ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
+        ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
 
 static int
 _nss_nisplus_parse_rpcent (nis_result *result, struct rpcent *rpc,
                           char *buffer, size_t buflen)
 {
-  char *p = buffer;
+  char *first_unused = buffer;
   size_t room_left = buflen;
   unsigned int i;
-  struct parser_data *data = (void *) buffer;
+  char *p, *line;
+
 
   if (result == NULL)
     return 0;
 
   if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
-      result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
-      strcmp(result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+      __type_of (result->objects.objects_val) != ENTRY_OBJ ||
+      strcmp(result->objects.objects_val[0].EN_data.en_type,
              "rpc_tbl") != 0 ||
-      result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3)
+      result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 3)
     return 0;
 
-  memset (p, '\0', room_left);
-
-  /* Generate the rpc entry format and use the normal parser */
-  if (NISENTRYLEN (0, 0, result) +1 > room_left)
+  if (NISENTRYLEN (0, 0, result) >= room_left)
     {
+    no_more_room:
       __set_errno (ERANGE);
       return 0;
     }
-  strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
-  room_left -= (NISENTRYLEN (0, 0, result) +1);
-
-  if (NISENTRYLEN (0, 2, result) +1 > room_left)
+  strncpy (first_unused, NISENTRYVAL (0, 0, result),
+           NISENTRYLEN (0, 0, result));
+  first_unused[NISENTRYLEN (0, 0, result)] = '\0';
+  rpc->r_name = first_unused;
+  room_left -= (strlen (first_unused) +1);
+  first_unused += strlen (first_unused) +1;
+  rpc->r_number = atoi (NISENTRYVAL (0, 2, result));
+  p = first_unused;
+
+  line = p;
+  for (i = 0; i < result->objects.objects_len; i++)
     {
-      __set_errno (ERANGE);
-      return 0;
+      if (strcmp (NISENTRYVAL (i, 1, result), rpc->r_name) != 0)
+        {
+          if (NISENTRYLEN (i, 1, result) + 2 > room_left)
+           goto no_more_room;
+          p = stpcpy(p, " ");
+          p = stpncpy (p, NISENTRYVAL (i, 1, result),
+                       NISENTRYLEN (i, 1, result));
+          *p = '\0';
+          room_left -= (NISENTRYLEN (i, 1, result) + 1);
+        }
     }
-  strcat (p, "\t");
-  strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result));
-  room_left -= (NISENTRYLEN (0, 2, result) + 1);
-                                       /* + 1: We overwrite the last \0 */
-
-  for (i = 0; i < result->objects.objects_len; i++)
-    /* XXX should we start with i = 0 or with i = 1 ? */
+  ++p;
+  first_unused = p;
+
+  /* Adjust the pointer so it is aligned for
+     storing pointers.  */
+  first_unused += __alignof__ (char *) - 1;
+  first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *));
+  rpc->r_aliases = (char **) first_unused;
+  if (room_left < sizeof (char *))
+    goto no_more_room;
+  room_left -= (sizeof (char *));
+  rpc->r_aliases[0] = NULL;
+
+  i = 0;
+  while (*line != '\0')
     {
-      if (NISENTRYLEN (i, 1, result) +1 > room_left)
+      /* Skip leading blanks.  */
+      while (isspace (*line))
+        line++;
+
+      if (*line == '\0')
+        break;
+
+      if (room_left < sizeof (char *))
+       goto no_more_room;
+
+      room_left -= sizeof (char *);
+      rpc->r_aliases[i] = line;
+
+      while (*line != '\0' && *line != ' ')
+        ++line;
+
+      if (line != rpc->r_aliases[i])
         {
-          __set_errno (ERANGE);
-          return 0;
+          if (*line != '\0')
+            {
+              *line = '\0';
+              ++line;
+            }
+          ++i;
         }
-      strcat (p, " ");
-      strncat (p, NISENTRYVAL (i, 1, result), NISENTRYLEN (i, 1, result));
-      room_left -= (NISENTRYLEN (i, 1, result) + 1);
+      else
+        rpc->r_aliases[i] = NULL;
     }
 
-  return _nss_files_parse_rpcent (p, rpc, data, buflen);
+  return 1;
 }
 
+static enum nss_status
+_nss_create_tablename (void)
+{
+  if (tablename_val == NULL)
+    {
+      char buf [40 + strlen (nis_local_directory ())];
+      char *p;
+
+      p = stpcpy (buf, "rpc.org_dir.");
+      p = stpcpy (p, nis_local_directory ());
+      tablename_val = strdup (buf);
+      if (tablename_val == NULL)
+        return NSS_STATUS_TRYAGAIN;
+      tablename_len = strlen (tablename_val);
+    }
+  return NSS_STATUS_SUCCESS;
+}
+
+
 enum nss_status
 _nss_nisplus_setrpcent (void)
 {
+  enum nss_status status = NSS_STATUS_SUCCESS;
+
   __libc_lock_lock (lock);
 
   if (result)
     nis_freeresult (result);
   result = NULL;
-  if (names)
-    {
-      nis_freenames (names);
-      names = NULL;
-    }
+
+  if (tablename_val == NULL)
+    status = _nss_create_tablename ();
 
   __libc_lock_unlock (lock);
 
-  return NSS_STATUS_SUCCESS;
+  return status;
 }
 
 enum nss_status
@@ -133,11 +183,6 @@ _nss_nisplus_endrpcent (void)
   if (result)
     nis_freeresult (result);
   result = NULL;
-  if (names)
-    {
-      nis_freenames (names);
-      names = NULL;
-    }
 
   __libc_lock_unlock (lock);
 
@@ -155,11 +200,11 @@ internal_nisplus_getrpcent_r (struct rpcent *rpc, char *buffer,
     {
       if (result == NULL)
        {
-         names = nis_getnames ("rpc.org_dir");
-         if (names == NULL || names[0] == NULL)
-           return NSS_STATUS_UNAVAIL;
+          if (tablename_val == NULL)
+            if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+              return NSS_STATUS_UNAVAIL;
 
-         result = nis_first_entry(names[0]);
+         result = nis_first_entry(tablename_val);
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
            return niserr2nss (result->status);
        }
@@ -167,7 +212,7 @@ internal_nisplus_getrpcent_r (struct rpcent *rpc, char *buffer,
        {
          nis_result *res;
 
-         res = nis_next_entry (names[0], &result->cookie);
+         res = nis_next_entry (tablename_val, &result->cookie);
          nis_freeresult (result);
          result = res;
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
@@ -201,32 +246,37 @@ _nss_nisplus_getrpcbyname_r (const char *name, struct rpcent *rpc,
 {
   int parse_res;
 
+  if (tablename_val == NULL)
+    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+      return NSS_STATUS_UNAVAIL;
+
   if (name == NULL)
     return NSS_STATUS_NOTFOUND;
   else
     {
       nis_result *result;
-      char buf[strlen (name) + 255];
+      char buf[strlen (name) + 255 + tablename_len];
 
       /* Search at first in the alias list, and use the correct name
          for the next search */
-      sprintf (buf, "[name=%s],rpc.org_dir", name);
-      result = nis_list (buf, EXPAND_NAME, NULL, NULL);
+      sprintf (buf, "[name=%s],%s", name, tablename_val);
+      result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
       /* If we do not find it, try it as original name. But if the
          database is correct, we should find it in the first case, too */
       if ((result->status != NIS_SUCCESS &&
            result->status != NIS_S_SUCCESS) ||
-          result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
-          strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+          __type_of (result->objects.objects_val) != ENTRY_OBJ ||
+          strcmp (result->objects.objects_val->EN_data.en_type,
                  "rpc_tbl") != 0 ||
-          result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 3)
-        sprintf (buf, "[cname=%s],rpc.org_dir", name);
+          result->objects.objects_val->EN_data.en_cols.en_cols_len < 3)
+        sprintf (buf, "[cname=%s],%s", name, tablename_val);
       else
-        sprintf (buf, "[cname=%s],rpc.org_dir", NISENTRYVAL(0, 0, result));
+        sprintf (buf, "[cname=%s],%s", NISENTRYVAL(0, 0, result),
+                tablename_val);
 
       nis_freeresult (result);
-      result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+      result = nis_list(buf, FOLLOW_PATH | FOLLOW_LINKS , NULL, NULL);
 
       if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
        {
@@ -254,31 +304,37 @@ enum nss_status
 _nss_nisplus_getrpcbynumber_r (const int number, struct rpcent *rpc,
                                char *buffer, size_t buflen)
 {
-  int parse_res;
-  nis_result *result;
-  char buf[100];
+  if (tablename_val == NULL)
+    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+      return NSS_STATUS_UNAVAIL;
 
-  snprintf (buf, sizeof (buf), "[number=%d],rpc.org_dir", number);
+  {
+    int parse_res;
+    nis_result *result;
+    char buf[100 + tablename_len];
 
-  result = nis_list(buf, EXPAND_NAME, NULL, NULL);
+    snprintf (buf, sizeof (buf), "[number=%d],%s", number, tablename_val);
 
-  if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
-    {
-      enum nss_status status = niserr2nss (result->status);
+    result = nis_list(buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
 
-      nis_freeresult (result);
-      return status;
-    }
+    if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+      {
+       enum nss_status status = niserr2nss (result->status);
 
-  parse_res = _nss_nisplus_parse_rpcent (result, rpc, buffer, buflen);
+       nis_freeresult (result);
+       return status;
+      }
 
-  nis_freeresult (result);
+    parse_res = _nss_nisplus_parse_rpcent (result, rpc, buffer, buflen);
 
-  if (parse_res)
-    return NSS_STATUS_SUCCESS;
+    nis_freeresult (result);
 
-  if (!parse_res && errno == ERANGE)
-    return NSS_STATUS_TRYAGAIN;
-  else
-    return NSS_STATUS_NOTFOUND;
+    if (parse_res)
+      return NSS_STATUS_SUCCESS;
+
+    if (!parse_res && errno == ERANGE)
+      return NSS_STATUS_TRYAGAIN;
+    else
+      return NSS_STATUS_NOTFOUND;
+  }
 }
index 6cad42d..50bc7e2 100644 (file)
 __libc_lock_define_initialized (static, lock);
 
 static nis_result *result = NULL;
-static nis_name *names = NULL;
-
-#define ENTNAME         servent
-#define DATABASE        "services"
-#define TRAILING_LIST_MEMBER            s_aliases
-#define TRAILING_LIST_SEPARATOR_P       isspace
-#include "../../nss/nss_files/files-parse.c"
-#define ISSLASH(c) ((c) == '/')
-LINE_PARSER
-("#",
- STRING_FIELD (result->s_name, isspace, 1);
- INT_FIELD (result->s_port, ISSLASH, 10, 0, htons);
- STRING_FIELD (result->s_proto, isspace, 1);
- )
-
+static nis_name tablename_val = NULL;
+static u_long tablename_len = 0;
 
 #define NISENTRYVAL(idx,col,res) \
-  ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
+  ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
 
 #define NISENTRYLEN(idx,col,res) \
-    ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
+    ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
 
 static int
 _nss_nisplus_parse_servent (nis_result *result, struct servent *serv,
                            char *buffer, size_t buflen)
 {
-  char *p = buffer;
+  char *first_unused = buffer;
   size_t room_left = buflen;
   unsigned int i;
-  struct parser_data *data = (void *) buffer;
+  char *p, *line;
 
   if (result == NULL)
     return 0;
 
   if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
-      result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
-   strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
-          "services_tbl") != 0 ||
-      result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 4)
+      __type_of (result->objects.objects_val) != ENTRY_OBJ ||
+      strcmp (result->objects.objects_val->EN_data.en_type,
+             "services_tbl") != 0 ||
+      result->objects.objects_val->EN_data.en_cols.en_cols_len < 4)
     return 0;
 
-  memset (p, '\0', room_left);
-
-  /* Generate the services entry format and use the normal parser */
-  if (NISENTRYLEN (0, 0, result) + 1 > room_left)
+  if (NISENTRYLEN (0, 0, result) >= room_left)
     {
+    no_more_room:
       __set_errno (ERANGE);
       return 0;
     }
-  strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
-  room_left -= (NISENTRYLEN (0, 0, result) + 1);
-
-  if (NISENTRYLEN (0, 3, result) + 1 > room_left)
+  strncpy (first_unused, NISENTRYVAL (0, 0, result),
+           NISENTRYLEN (0, 0, result));
+  first_unused[NISENTRYLEN (0, 0, result)] = '\0';
+  serv->s_name = first_unused;
+  room_left -= (strlen (first_unused) +1);
+  first_unused += strlen (first_unused) +1;
+
+  if (NISENTRYLEN (0, 2, result) >= room_left)
+    goto no_more_room;
+  strncpy (first_unused, NISENTRYVAL (0, 2, result),
+           NISENTRYLEN (0, 2, result));
+  first_unused[NISENTRYLEN (0, 2, result)] = '\0';
+  serv->s_proto = first_unused;
+  room_left -= (strlen (first_unused) +1);
+  first_unused += strlen (first_unused) +1;
+
+  serv->s_port = atoi (NISENTRYVAL (0, 3, result));
+  p = first_unused;
+
+  line = p;
+  for (i = 0; i < result->objects.objects_len; i++)
     {
-      __set_errno (ERANGE);
-      return 0;
+      if (strcmp (NISENTRYVAL (i, 1, result), serv->s_name) != 0)
+        {
+          if (NISENTRYLEN (i, 1, result) + 2 > room_left)
+            goto no_more_room;
+          p = stpcpy(p, " ");
+          p = stpncpy (p, NISENTRYVAL (i, 1, result),
+                       NISENTRYLEN (i, 1, result));
+          *p = '\0';
+          room_left -= (NISENTRYLEN (i, 1, result) + 1);
+        }
     }
-  strcat (p, "\t");
-  strncat (p, NISENTRYVAL (0, 3, result), NISENTRYLEN (0, 3, result));
-  room_left -= (NISENTRYLEN (0, 3, result) + 1);
-  if (NISENTRYLEN (0, 2, result) + 1 > room_left)
+  ++p;
+  first_unused = p;
+
+  /* Adjust the pointer so it is aligned for
+     storing pointers.  */
+  first_unused += __alignof__ (char *) - 1;
+  first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *));
+  serv->s_aliases = (char **) first_unused;
+  if (room_left < sizeof (char *))
+    goto no_more_room;
+  room_left -= (sizeof (char *));
+  serv->s_aliases[0] = NULL;
+
+  i = 0;
+  while (*line != '\0')
     {
-      __set_errno (ERANGE);
-      return 0;
-    }
-  strcat (p, "/");
-  strncat (p, NISENTRYVAL (0, 2, result), NISENTRYLEN (0, 2, result));
-  room_left -= (NISENTRYLEN (0, 2, result) + 1);
+      /* Skip leading blanks.  */
+      while (isspace (*line))
+        line++;
 
-  for (i = 1; i < result->objects.objects_len; i++)
-    {
-      if (NISENTRYLEN (i, 1, result) + 1 > room_left)
-       {
-         __set_errno (ERANGE);
-         return 0;
+      if (*line == '\0')
+        break;
+
+      if (room_left < sizeof (char *))
+        goto no_more_room;
+
+      room_left -= sizeof (char *);
+      serv->s_aliases[i] = line;
+
+      while (*line != '\0' && *line != ' ')
+        ++line;
+
+      if (*line == ' ')
+        {
+         *line = '\0';
+         ++line;
+          ++i;
        }
-      strcat (p, " ");
-      strcat (p, NISENTRYVAL (i, 1, result));
-      room_left -= (NISENTRYLEN (i, 1, result) + 1);
+      else
+        serv->s_aliases[i+1] = NULL;
     }
 
-  return _nss_files_parse_servent (p, serv, data, buflen);
+  return 1;
+}
+
+static enum nss_status
+_nss_create_tablename (void)
+{
+  if (tablename_val == NULL)
+    {
+      char buf [40 + strlen (nis_local_directory ())];
+      char *p;
+
+      p = stpcpy (buf, "services.org_dir.");
+      p = stpcpy (p, nis_local_directory ());
+      tablename_val = strdup (buf);
+      if (tablename_val == NULL)
+        return NSS_STATUS_TRYAGAIN;
+      tablename_len = strlen (tablename_val);
+    }
+  return NSS_STATUS_SUCCESS;
 }
 
+
 enum nss_status
 _nss_nisplus_setservent (void)
 {
+  enum nss_status status = NSS_STATUS_SUCCESS;
+
   __libc_lock_lock (lock);
 
   if (result)
     nis_freeresult (result);
   result = NULL;
-  if (names)
-    {
-      nis_freenames (names);
-      names = NULL;
-    }
+
+  if (tablename_val == NULL)
+    status = _nss_create_tablename ();
 
   __libc_lock_unlock (lock);
 
-  return NSS_STATUS_SUCCESS;
+  return status;
 }
 
 enum nss_status
@@ -142,11 +189,6 @@ _nss_nisplus_endservent (void)
   if (result)
     nis_freeresult (result);
   result = NULL;
-  if (names)
-    {
-      nis_freenames (names);
-      names = NULL;
-    }
 
   __libc_lock_unlock (lock);
 
@@ -164,11 +206,11 @@ internal_nisplus_getservent_r (struct servent *serv, char *buffer,
     {
       if (result == NULL)
        {
-         names = nis_getnames ("services.org_dir");
-         if (names == NULL || names[0] == NULL)
-           return NSS_STATUS_UNAVAIL;
+          if (tablename_val == NULL)
+            if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+              return NSS_STATUS_UNAVAIL;
 
-         result = nis_first_entry (names[0]);
+         result = nis_first_entry (tablename_val);
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
            return niserr2nss (result->status);
        }
@@ -176,7 +218,7 @@ internal_nisplus_getservent_r (struct servent *serv, char *buffer,
        {
          nis_result *res;
 
-         res = nis_next_entry (names[0], &result->cookie);
+         res = nis_next_entry (tablename_val, &result->cookie);
          nis_freeresult (result);
          result = res;
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
@@ -212,6 +254,10 @@ _nss_nisplus_getservbyname_r (const char *name, const char *protocol,
 {
   int parse_res;
 
+  if (tablename_val == NULL)
+    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+      return NSS_STATUS_UNAVAIL;
+
   if (name == NULL || protocol == NULL)
     {
       __set_errno (EINVAL);
@@ -220,29 +266,30 @@ _nss_nisplus_getservbyname_r (const char *name, const char *protocol,
   else
     {
       nis_result *result;
-      char buf[strlen (name) + 255];
+      char buf[strlen (name) + 255 + tablename_len];
 
       /* Search at first in the alias list, and use the correct name
          for the next search */
-      sprintf (buf, "[name=%s,proto=%s],services.org_dir", name,
-              protocol);
-      result = nis_list (buf, EXPAND_NAME, NULL, NULL);
+      sprintf (buf, "[name=%s,proto=%s],%s", name, protocol,
+              tablename_val);
+      result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
       /* If we do not find it, try it as original name. But if the
          database is correct, we should find it in the first case, too */
       if ((result->status != NIS_SUCCESS &&
           result->status != NIS_S_SUCCESS) ||
-         result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
-         strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
+         __type_of (result->objects.objects_val) != ENTRY_OBJ ||
+         strcmp (result->objects.objects_val->EN_data.en_type,
                  "services_tbl") != 0 ||
-         result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 4)
-       sprintf (buf, "[cname=%s,proto=%s],services.org_dir", name, protocol);
+         result->objects.objects_val->EN_data.en_cols.en_cols_len < 4)
+       sprintf (buf, "[cname=%s,proto=%s],%s", name, protocol,
+                tablename_val);
       else
-       sprintf (buf, "[cname=%s,proto=%s],services.org_dir",
-                NISENTRYVAL (0, 0, result), protocol);
+       sprintf (buf, "[cname=%s,proto=%s],%s",
+                NISENTRYVAL (0, 0, result), protocol, tablename_val);
 
       nis_freeresult (result);
-      result = nis_list (buf, EXPAND_NAME, NULL, NULL);
+      result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
       if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
        {
@@ -271,38 +318,44 @@ _nss_nisplus_getservbynumber_r (const int number, const char *protocol,
                                struct servent *serv,
                                char *buffer, size_t buflen)
 {
-  int parse_res;
-  nis_result *result;
-  char buf[60 + strlen (protocol)];
+  if (tablename_val == NULL)
+    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+      return NSS_STATUS_UNAVAIL;
 
   if (protocol == NULL)
     {
       __set_errno (EINVAL);
       return NSS_STATUS_NOTFOUND;
     }
+  else
+    {
+      int parse_res;
+      nis_result *result;
+      char buf[60 + strlen (protocol) + tablename_len];
 
-  snprintf (buf, sizeof (buf), "[number=%d,proto=%s],services.org_dir",
-           number, protocol);
+      snprintf (buf, sizeof (buf), "[number=%d,proto=%s],%s",
+               number, protocol, tablename_val);
 
-  result = nis_list (buf, EXPAND_NAME, NULL, NULL);
+      result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
-  if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
-    {
-      enum nss_status status = niserr2nss (result->status);
+      if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
+       {
+         enum nss_status status = niserr2nss (result->status);
 
-      nis_freeresult (result);
-      return status;
-    }
+         nis_freeresult (result);
+         return status;
+       }
 
-  parse_res = _nss_nisplus_parse_servent (result, serv, buffer, buflen);
+      parse_res = _nss_nisplus_parse_servent (result, serv, buffer, buflen);
 
-  nis_freeresult (result);
+      nis_freeresult (result);
 
-  if (parse_res)
-    return NSS_STATUS_SUCCESS;
+      if (parse_res)
+       return NSS_STATUS_SUCCESS;
 
-  if (!parse_res && errno == ERANGE)
-    return NSS_STATUS_TRYAGAIN;
-  else
-    return NSS_STATUS_NOTFOUND;
+      if (!parse_res && errno == ERANGE)
+       return NSS_STATUS_TRYAGAIN;
+      else
+       return NSS_STATUS_NOTFOUND;
+    }
 }
index e6ff674..81bde4e 100644 (file)
 #include <rpcsvc/nislib.h>
 
 #include "nss-nisplus.h"
+#include "nisplus-parser.h"
 
 __libc_lock_define_initialized (static, lock)
 
 static nis_result *result = NULL;
-static nis_name *names = NULL;
+static nis_name tablename_val = NULL;
+static u_long tablename_len = 0;
 
-#define NISENTRYVAL(idx,col,res) \
-        ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
-
-#define NISENTRYLEN(idx,col,res) \
-        ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
-
-int
-_nss_nisplus_parse_spent (nis_result *result, struct spwd *sp,
-                         char *buffer, size_t buflen)
+static enum nss_status
+_nss_create_tablename (void)
 {
-  char *first_unused = buffer;
-  size_t room_left = buflen;
-
-  if (result == NULL)
-    return 0;
-
-  if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) ||
-      result->objects.objects_len != 1 ||
-      result->objects.objects_val[0].zo_data.zo_type != ENTRY_OBJ ||
-      strcmp (result->objects.objects_val[0].zo_data.objdata_u.en_data.en_type,
-             "passwd_tbl") != 0 ||
-      result->objects.objects_val[0].zo_data.objdata_u.en_data.en_cols.en_cols_len < 8)
-    return 0;
-
-  if (NISENTRYLEN(0, 0, result) >= room_left)
-    {
-      /* The line is too long for our buffer.  */
-    no_more_room:
-      __set_errno (ERANGE);
-      return 0;
-    }
-
-  strncpy (first_unused, NISENTRYVAL (0, 0, result),
-          NISENTRYLEN (0, 0, result));
-  first_unused[NISENTRYLEN(0, 0, result)] = '\0';
-  sp->sp_namp = first_unused;
-  room_left -= (strlen (first_unused) +1);
-  first_unused += strlen (first_unused) +1;
-
-  if (NISENTRYLEN(0, 1, result) >= room_left)
-    goto no_more_room;
-
-  strncpy (first_unused, NISENTRYVAL (0, 1, result),
-          NISENTRYLEN (0, 1, result));
-  first_unused[NISENTRYLEN(0, 1, result)] = '\0';
-  sp->sp_pwdp = first_unused;
-  room_left -= (strlen (first_unused) +1);
-  first_unused += strlen (first_unused) +1;
-
-  sp->sp_lstchg = sp->sp_min = sp->sp_max = sp->sp_warn = sp->sp_inact =
-    sp->sp_expire = sp->sp_flag = -1;
-
-  if (NISENTRYVAL (0, 7, result) != NULL)
+  if (tablename_val == NULL)
     {
-      char *line, *cp;
-
-      line = NISENTRYVAL (0, 7, result);
-      cp = strchr (line, ':');
-      if (cp == NULL)
-       return 0;
-      *cp++ = '\0';
-      sp->sp_lstchg = atol (line);
-
-      line = cp;
-      cp = strchr (line, ':');
-      if (cp == NULL)
-       return 0;
-      *cp++ = '\0';
-      sp->sp_min = atol(line);
-
-      line = cp;
-      cp = strchr (line, ':');
-      if (cp == NULL)
-       return 0;
-      *cp++ = '\0';
-      sp->sp_max = atol(line);
-
-      line = cp;
-      cp = strchr (line, ':');
-      if (cp == NULL)
-       return 0;
-      *cp++ = '\0';
-      sp->sp_warn = atol(line);
-
-      line = cp;
-      cp = strchr (line, ':');
-      if (cp == NULL)
-       return 0;
-      *cp++ = '\0';
-      sp->sp_inact = atol(line);
-
-      line = cp;
-      cp = strchr (line, ':');
-      if (cp == NULL)
-       return 0;
-      *cp++ = '\0';
-      sp->sp_expire = atol(line);
-
-      line = cp;
-      if (line == NULL)
-       return 0;
-      sp->sp_flag = atol(line);
+      char buf [40 + strlen (nis_local_directory ())];
+      char *p;
+
+      p = stpcpy (buf, "passwd.org_dir.");
+      p = stpcpy (p, nis_local_directory ());
+      tablename_val = strdup (buf);
+      if (tablename_val == NULL)
+        return NSS_STATUS_TRYAGAIN;
+      tablename_len = strlen (tablename_val);
     }
-
-  return 1;
+  return NSS_STATUS_SUCCESS;
 }
 
 enum nss_status
 _nss_nisplus_setspent (void)
 {
+  enum nss_status status = NSS_STATUS_SUCCESS;
+
   __libc_lock_lock (lock);
 
   if (result)
     nis_freeresult (result);
   result = NULL;
-  if (names)
-    {
-      nis_freenames (names);
-      names = NULL;
-    }
+
+  if (tablename_val == NULL)
+    status = _nss_create_tablename ();
 
   __libc_lock_unlock (lock);
 
@@ -166,11 +79,6 @@ _nss_nisplus_endspent (void)
   if (result)
     nis_freeresult (result);
   result = NULL;
-  if (names)
-    {
-      nis_freenames (names);
-      names = NULL;
-    }
 
   __libc_lock_unlock (lock);
 
@@ -187,11 +95,11 @@ internal_nisplus_getspent_r (struct spwd *sp, char *buffer, size_t buflen)
     {
       if (result == NULL)
        {
-         names = nis_getnames ("passwd.org_dir");
-         if (names == NULL || names[0] == NULL)
-           return NSS_STATUS_UNAVAIL;
+          if (tablename_val == NULL)
+            if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+              return NSS_STATUS_UNAVAIL;
 
-         result = nis_first_entry (names[0]);
+         result = nis_first_entry (tablename_val);
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
            return niserr2nss (result->status);
        }
@@ -199,7 +107,7 @@ internal_nisplus_getspent_r (struct spwd *sp, char *buffer, size_t buflen)
        {
          nis_result *res;
 
-         res = nis_next_entry (names[0], &result->cookie);
+         res = nis_next_entry (tablename_val, &result->cookie);
          nis_freeresult (result);
          result = res;
          if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
@@ -232,16 +140,20 @@ _nss_nisplus_getspnam_r (const char *name, struct spwd *sp,
 {
   int parse_res;
 
+  if (tablename_val == NULL)
+    if (_nss_create_tablename () != NSS_STATUS_SUCCESS)
+      return NSS_STATUS_UNAVAIL;
+
   if (name == NULL || strlen (name) > 8)
     return NSS_STATUS_NOTFOUND;
   else
     {
       nis_result *result;
-      char buf[strlen (name) + 24];
+      char buf[strlen (name) + 24 + tablename_len];
 
-      sprintf (buf, "[name=%s],passwd.org_dir", name);
+      sprintf (buf, "[name=%s],%s", name, tablename_val);
 
-      result = nis_list (buf, EXPAND_NAME, NULL, NULL);
+      result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
       if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
        {
diff --git a/nis/rpcsvc/nis_cache.h b/nis/rpcsvc/nis_cache.h
new file mode 100644 (file)
index 0000000..ca91a22
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef __RPCSVC_NIS_CACHE_H_
+#define __RPCSVC_NIS_CACHE_H_
+
+#include <features.h>
+#include <rpc/rpc.h>
+#include <rpc/types.h>
+#include <rpcsvc/nis.h>
+
+__BEGIN_DECLS
+
+/* default cache file */
+#define CACHEFILE "/var/nis/NIS_SHARED_DIRCACHE" 
+
+/* clients have to read-lock the cache file, and SVR4 locking requires that */
+/*   the file be writable, but we don't want a world-writable cache file.   */
+/*   So... everyone agrees to use a different, world-writable file for the  */
+/*   locking operations, but the data is in CACHEFILE.                      */
+#define CACHELOCK "/usr/tmp/.NIS_DIR_CACHELOCK"
+
+/* the file containing one trusted XDR'ed directory object.
+ * This has to be present for the system to work.
+ */
+#define COLD_START_FILE "/var/nis/NIS_COLD_START"
+
+enum pc_status {HIT, MISS, NEAR_MISS};
+
+#define CACHEPROG ((u_long)100301)
+#define CACHE_VER_1 ((u_long)1)
+
+#define NIS_CACHE_ADD_ENTRY ((u_long)1)
+#define NIS_CACHE_REMOVE_ENTRY ((u_long)2)
+#define NIS_CACHE_READ_COLDSTART ((u_long)3)
+#define NIS_CACHE_REFRESH_ENTRY ((u_long)4)
+
+extern void *nis_cache_add_entry_1 __P ((fd_result *, CLIENT *));
+extern void *nis_cache_add_entry_1_svc __P ((fd_result *, struct svc_req *));
+extern void *nis_cache_remove_entry_1 __P ((directory_obj *, CLIENT *));
+extern void *nis_cache_remove_entry_1_svc __P ((directory_obj *,
+                                               struct svc_req *));
+extern void *nis_cache_read_coldstart_1 __P ((void *, CLIENT *));
+extern void *nis_cache_read_coldstart_1_svc __P ((void *, struct svc_req *));
+extern void *nis_cache_refresh_entry_1 __P ((char **, CLIENT *));
+extern void *nis_cache_refresh_entry_1_svc __P ((char **, struct svc_req *));
+
+__END_DECLS
+
+#endif /* !_RPCSVC_NIS_CACHE_H_ */
diff --git a/nis/rpcsvc/nis_cache.x b/nis/rpcsvc/nis_cache.x
new file mode 100644 (file)
index 0000000..91870d8
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *     nis_cache.x
+ *
+ *     Copyright (c) 1988-1992 Sun Microsystems Inc
+ *     All Rights Reserved.
+ */
+
+%#pragma ident "@(#)nis_cache.x        1.8     92/07/14 SMI"
+
+
+#ifdef RPC_HDR
+%#include <rpc/types.h>
+%#include <rpcsvc/nis.h>
+%
+%/* default cache file */
+%#define CACHEFILE "/var/nis/NIS_SHARED_DIRCACHE" 
+%
+%/* clients have to read-lock the cache file, and SVR4 locking requires that */
+%/*   the file be writable, but we don't want a world-writable cache file.   */
+%/*   So... everyone agrees to use a different, world-writable file for the  */
+%/*   locking operations, but the data is in CACHEFILE.                      */
+%#define CACHELOCK "/usr/tmp/.NIS_DIR_CACHELOCK"
+%
+%/* the file containing one trusted XDR'ed directory object.
+% * This has to be present for the system to work.
+% */
+%#define COLD_START_FILE "/var/nis/NIS_COLD_START"
+%
+%enum pc_status {HIT, MISS, NEAR_MISS};
+%
+%extern int __nis_debuglevel;
+%
+%
+#endif
+
+#ifdef RPC_CLNT
+%#include "../gen/nis_clnt.h"
+#endif
+
+program CACHEPROG {
+       version CACHE_VER_1 {
+               void NIS_CACHE_ADD_ENTRY(fd_result) = 1;
+               void NIS_CACHE_REMOVE_ENTRY(directory_obj) = 2;
+               void NIS_CACHE_READ_COLDSTART(void) = 3;
+               void NIS_CACHE_REFRESH_ENTRY(string<>) = 4;
+       } = 1;
+} = 100301;
index cbd8fbd..73b3804 100644 (file)
@@ -254,10 +254,14 @@ extern nis_name __nis_default_owner __P ((char *));
 extern nis_name __nis_default_group __P ((char *));
 extern u_long __nis_default_ttl __P ((char *));
 extern u_long __nis_default_access __P ((char *, u_long));
-extern fd_result *__nis_finddirectory __P ((directory_obj *, nis_name));
+extern fd_result *__nis_finddirectory __P ((directory_obj *, const_nis_name));
+extern u_long __nis_hash __P ((const void *keyarg, register size_t len));
 extern log_result *__nis_dumplog __P ((nis_server *,nis_name, u_long));
 extern log_result *__nis_dump __P ((nis_server *, nis_name,
                                    int (*)(nis_name, nis_object *, void *)));
+/* NIS+ cache locking */
+extern int __nis_lock_cache __P ((void));
+extern int __nis_unlock_cache __P ((void));
 
 __END_DECLS
 
index c231ec6..fc37638 100644 (file)
@@ -116,6 +116,7 @@ execvp (file, argv)
                 that we did find one but were denied access.  */
              got_eacces = 1;
            case ENOENT:
+           case ESTALE:
              /* Those errors indicate the file is missing or not executable
                 by us, in which case we want to just try the next path
                 directory.  */
index b649b9d..4f125be 100644 (file)
@@ -128,15 +128,15 @@ char *realloc ();
 #define SWITCH_ENUM_CAST(x) (x)
 #endif
 
+/* How many characters in the character set.  */
+#define CHAR_SET_SIZE 256
+
 #ifdef SYNTAX_TABLE
 
 extern char *re_syntax_table;
 
 #else /* not SYNTAX_TABLE */
 
-/* How many characters in the character set.  */
-#define CHAR_SET_SIZE 256
-
 static char re_syntax_table[CHAR_SET_SIZE];
 
 static void
index bb3747c..962cf01 100644 (file)
@@ -18,6 +18,8 @@
 
 #include <errno.h>
 #include <signal.h>
+#define __need_NULL
+#include <stddef.h>
 
 /* Combine sets LEFT and RIGHT by logical AND and place result in DEST.  */
 int
index 50dc343..24e166d 100644 (file)
@@ -18,6 +18,8 @@
 
 #include <errno.h>
 #include <signal.h>
+#define __need_NULL
+#include <stddef.h>
 
 /* Test whether SET is empty.  */
 int
index e8ae22f..474cff3 100644 (file)
@@ -18,6 +18,8 @@
 
 #include <errno.h>
 #include <signal.h>
+#define __need_NULL
+#include <stddef.h>
 
 /* Combine sets LEFT and RIGHT by logical OR and place result in DEST.  */
 int
index ba74466..3e6950d 100644 (file)
    string FORMAT, writing no more than MAXLEN characters.  */
 /* VARARGS3 */
 int
-__snprintf (s, maxlen, format)
-      char *s;
-      size_t maxlen;
-      const char *format;
+__snprintf (char *s, size_t maxlen, const char *format, ...)
 {
   va_list arg;
   int done;
diff --git a/sysdeps/alpha/DEFS.h b/sysdeps/alpha/DEFS.h
deleted file mode 100644 (file)
index c2a4fc8..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifdef __STDC__
-#define FUNC__(name)           \
-       .align 3;               \
-        .globl __##name;       \
-        .ent __##name;         \
-        __##name:              \
-       lda sp, -16(sp);        \
-       .frame sp, 16, t9, 0;   \
-       .prologue 0
-#else
-#define FUNC__(name)           \
-       .align 3;               \
-        .globl __/**/name;     \
-        .ent __/**/name,0;     \
-        __/**/name:            \
-       lda sp, -16(sp);        \
-       .frame sp, 16, t9, 0;   \
-       .prologue 0
-#endif
-
-#ifdef __STDC__
-#define NAME__(name)   \
-       __##name
-#else
-#define NAME__(name)   \
-       __/**/name
-#endif
index 022fa03..581022f 100644 (file)
@@ -1,5 +1,4 @@
 setjmp_aux.c
-DEFS.h
 divrem.h
 divl.S divq.S reml.S remq.S
 _mcount.S
diff --git a/sysdeps/i370/Implies b/sysdeps/i370/Implies
new file mode 100644 (file)
index 0000000..39a34c5
--- /dev/null
@@ -0,0 +1 @@
+wordsize-32
index 4677f13..f0fb2fe 100644 (file)
@@ -1,5 +1,5 @@
 /* FPU control word bits.  i387 version.
-   Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Olaf Flebbe.
 
@@ -82,7 +82,7 @@
 
 #define _FPU_DEFAULT  0x137f
 
-/* IEEE:  same as above, but exceptions */
+/* IEEE:  same as above */
 #define _FPU_IEEE     0x137f
 
 /* Type of the control word.  */
index 351fa8a..d8e2d8a 100644 (file)
@@ -32,7 +32,7 @@ feholdexcept (fenv_t *envp)
   fpsr = envp->status_register & ~FE_ALL_EXCEPT;
   __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr));
   /* And set all exceptions to non-stop.  */
-  fpcr = envp->control_register & ~(FE_ALL_EXCEPT << 5);
+  fpcr = envp->control_register & ~(FE_ALL_EXCEPT << 6);
   __asm__ __volatile__ ("fmove%.l %0,%!" : : "dm" (fpcr));
 
   return 1;
index f6611a2..8b4d6b0 100644 (file)
@@ -32,15 +32,15 @@ fesetenv (const fenv_t *envp)
   __asm__ ("fmovem%.l %/fpcr/%/fpsr,%0" : "=m" (*&temp));
 
   temp.status_register &= ~FE_ALL_EXCEPT;
-  temp.control_register &= ~((FE_ALL_EXCEPT << 5) | FE_UPWARD);
+  temp.control_register &= ~((FE_ALL_EXCEPT << 6) | FE_UPWARD);
   if (envp == FE_DFL_ENV)
     ;
   else if (envp == FE_NOMASK_ENV)
-    temp.control_register |= FE_ALL_EXCEPT << 5;
+    temp.control_register |= FE_ALL_EXCEPT << 6;
   else
     {
       temp.control_register |= (envp->control_register
-                               & ((FE_ALL_EXCEPT << 5) | FE_UPWARD));
+                               & ((FE_ALL_EXCEPT << 6) | FE_UPWARD));
       temp.status_register |= envp->status_register & FE_ALL_EXCEPT;
     }
 
index be27b66..904e141 100644 (file)
@@ -223,7 +223,7 @@ __select (nfds, readfds, writefds, exceptfds, timeout)
          /* We got a message.  Decode it.  */
 #define IO_SELECT_REPLY_MSGID (21012 + 100) /* XXX */
          const mach_msg_type_t inttype =
-           { MACH_MSG_TYPE_INTEGER_T, sizeof (MACH_MSG_TYPE_INTEGER_T),
+           { MACH_MSG_TYPE_INTEGER_T, sizeof (MACH_MSG_TYPE_INTEGER_T) * 8,
              1, 1, 0, 0 };
          if (msg.head.msgh_id == IO_SELECT_REPLY_MSGID &&
              msg.head.msgh_size >= sizeof msg.error &&
diff --git a/sysdeps/mvs/Implies b/sysdeps/mvs/Implies
new file mode 100644 (file)
index 0000000..b3188f7
--- /dev/null
@@ -0,0 +1 @@
+posix
diff --git a/sysdeps/sparc/DEFS.h b/sysdeps/sparc/DEFS.h
deleted file mode 100644 (file)
index ab70f55..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifdef HAVE_ELF
-# define FUNC(name)            \
-       .global name;           \
-       .type name,@function;   \
-       .align 4;               \
-       name:
-#else
-# define FUNC(name)    \
-       .global name;   \
-       .align 4;       \
-       name:
-#endif
index 55f2614..8bd3729 100644 (file)
@@ -1,5 +1,3 @@
-DEFS.h
-elf/DEFS.h
 dotmul.S umul.S
 divrem.m4 sdiv.S udiv.S rem.S urem.S
 alloca.S
index 207f75c..dcbd171 100644 (file)
@@ -16,7 +16,7 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#include "DEFS.h"
+#include "sysdep.h"
 
 /* Code produced by Sun's C compiler calls this function with two extra
    arguments which it makes relocatable symbols but seem always to be
@@ -26,7 +26,7 @@
 #define __builtin_alloca ___builtin_alloca
 #endif
 
-FUNC (__builtin_alloca)
+ENTRY (__builtin_alloca)
        sub %sp, %o0, %sp       /* Push some stack space.  */
        retl                    /* Return; the returned buffer leaves 96 */
        add %sp, 96, %o0        /* bytes of register save area at the top. */
index cada804..665abf1 100644 (file)
@@ -82,7 +82,7 @@ L.$1.eval(2**N+$2):
        ', `    DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2-1)')')
        ifelse($1, 1, `9:')')dnl
 
-#include "DEFS.h"
+#include "sysdep.h"
 #ifdef __linux__
 #include <asm/traps.h>
 #else
index 1c59a27..7ce695c 100644 (file)
@@ -10,8 +10,8 @@
  * This code optimizes short (less than 13-bit) multiplies.
  */
 
-#include "DEFS.h"
-FUNC(.mul)
+#include "sysdep.h"
+ENTRY(.mul)
        mov     %o0, %y         ! multiplier -> Y
        andncc  %o0, 0xfff, %g0 ! test bits 12..31
        be      Lmul_shortway   ! if zero, can do it the short way
diff --git a/sysdeps/sparc/elf/DEFS.h b/sysdeps/sparc/elf/DEFS.h
deleted file mode 100644 (file)
index 84f078a..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-#define        FUNC(name)              \
-       .global name;           \
-       .type name,@function;   \
-       .align 4;               \
-       name:
index 05916f0..d50f1af 100644 (file)
 
 
 
-#include "DEFS.h"
+#include "sysdep.h"
+#ifdef __linux__
+#include <asm/traps.h>
+#else
+#ifdef __svr4__
 #include <sys/trap.h>
+#else
+#include <machine/trap.h>
+#endif
+#endif
 
-FUNC(.rem)
+ENTRY(.rem)
        ! compute sign of result; if neither is negative, no problem
        orcc    %o1, %o0, %g0   ! either negative?
        bge     2f                      ! no, go do the divide
index 910cea5..02ed2e9 100644 (file)
 
 
 
-#include "DEFS.h"
+#include "sysdep.h"
+#ifdef __linux__
+#include <asm/traps.h>
+#else
+#ifdef __svr4__
 #include <sys/trap.h>
+#else
+#include <machine/trap.h>
+#endif
+#endif
 
-FUNC(.div)
+ENTRY(.div)
        ! compute sign of result; if neither is negative, no problem
        orcc    %o1, %o0, %g0   ! either negative?
        bge     2f                      ! no, go do the divide
index 49df8ab..4a7d152 100644 (file)
 
 
 
-#include "DEFS.h"
+#include "sysdep.h"
+#ifdef __linux__
+#include <asm/traps.h>
+#else
+#ifdef __svr4__
 #include <sys/trap.h>
+#else
+#include <machine/trap.h>
+#endif
+#endif
 
-FUNC(.udiv)
+ENTRY(.udiv)
 
        ! Ready to divide.  Compute size of quotient; scale comparand.
        orcc    %o1, %g0, %o5
index 9126b64..74b932d 100644 (file)
@@ -26,7 +26,7 @@
 ! n1           i1
 ! n0           i2
 ! d            i3
-#include "DEFS.h"
+
 #include "sysdep.h"
 #undef ret     /* Kludge for glibc */
 
@@ -38,7 +38,7 @@ LC1:  .double 0r2147483648
        .align  4
        .global __udiv_qrnnd
        .type   __udiv_qrnnd,@function
-FUNC(__udiv_qrnnd)
+ENTRY(__udiv_qrnnd)
        !#PROLOGUE# 0
        save    %sp,-104,%sp
        !#PROLOGUE# 1
index 7f6a081..e72c33d 100644 (file)
 
 
 
-#include "DEFS.h"
+#include "sysdep.h"
+#ifdef __linux__
+#include <asm/traps.h>
+#else
+#ifdef __svr4__
 #include <sys/trap.h>
+#else
+#include <machine/trap.h>
+#endif
+#endif
 
-FUNC(.urem)
+ENTRY(.urem)
 
        ! Ready to divide.  Compute size of quotient; scale comparand.
        orcc    %o1, %g0, %o5
index 8462383..fa4dcdd 100644 (file)
 typedef int __libc_key_t;
 
 /* Create key for thread specific data.  */
-#define __libc_key_create(KEY,DEST)
+#define __libc_key_create(KEY,DEST) -1
 
 /* Set thread-specific data associated with KEY to VAL.  */
-#define __libc_setspecific(KEY,VAL)
+#define __libc_setspecific(KEY,VAL) -1
 
 /* Get thread-specific data associated with KEY.  */
 #define __libc_getspecific(KEY) 0
index 1cfec5f..c8f9ea8 100644 (file)
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-unsigned int if_nametoindex(const char *ifname)
+#define __need_NULL
+#include <stddef.h>
+
+unsigned int
+if_nametoindex (const char *ifname)
 {
   return 0;
 }
 
-char *if_indextoname(unsigned int ifindex, char *ifname)
+char *
+if_indextoname (unsigned int ifindex, char *ifname)
 {
   return NULL;
 }
 
-void if_freenameindex(struct if_nameindex *ifn)
+void
+if_freenameindex (struct if_nameindex *ifn)
 {
 }
 
-struct if_nameindex *if_nameindex(void)
+struct if_nameindex *
+if_nameindex (void)
 {
   return NULL;
 }
index fe74a91..576813a 100644 (file)
 #define        syscall_error   C_SYMBOL_NAME(__syscall_error)
 #endif
 
-#define        ENTRY(name)                                                           \
-  .global C_SYMBOL_NAME(name);                                               \
-  .align 2;                                                                  \
+#ifdef HAVE_ELF
+#define        ENTRY(name)             \
+  .global C_SYMBOL_NAME(name); \
+  .type name,@function;                \
+  .align 4;                    \
   C_LABEL(name)
 
-#define        PSEUDO(name, syscall_name, args)                                      \
-  .global syscall_error;                                                     \
-  ENTRY (name)                                                               \
-  mov SYS_ify(syscall_name), %g1;                                            \
-  ta 0;                                                                              \
-  bcc 1f;                                                                    \
-  sethi %hi(syscall_error), %g1;                                             \
-  jmp %g1 + %lo(syscall_error);        nop;                                          \
+#else
+#define        ENTRY(name)             \
+  .global C_SYMBOL_NAME(name); \
+  .align 4;                    \
+  C_LABEL(name)
+
+#endif /* HAVE_ELF */
+
+#define        PSEUDO(name, syscall_name, args)        \
+  .global syscall_error;                       \
+  ENTRY (name)                                 \
+  mov SYS_ify(syscall_name), %g1;              \
+  ta 0;                                                \
+  bcc 1f;                                      \
+  sethi %hi(syscall_error), %g1;               \
+  jmp %g1 + %lo(syscall_error);        nop;            \
 1:
 
 #define        ret             retl; nop
index c380417..c53f208 100644 (file)
@@ -172,11 +172,15 @@ localtime_r (t, tp)
 #endif /* ! defined (_LIBC) */
 
 
-#if !defined (memset) && !defined (HAVE_MEMSET) && !defined (_LIBC)
+#if !defined memset && !defined HAVE_MEMSET && !defined _LIBC
 /* Some systems lack the `memset' function and we don't want to
    introduce additional dependencies.  */
-static const char spaces[16] = "                ";
-static const char zeroes[16] = "0000000000000000";
+/* The SGI compiler reportedly barfs on the trailing null
+   if we use a string constant as the initializer.  28 June 1997, rms.  */
+static const char spaces[16] = /* "                " */
+  { ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' };
+static const char zeroes[16] = /* "0000000000000000" */
+  { '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0' };
 
 # define memset_space(P, Len) \
   do {                                                                       \
index b5a715b..1cd5694 100644 (file)
@@ -20,6 +20,7 @@
 
 #define __need_wchar_t
 #include <stddef.h>
+#include <locale.h>
 
 #define USE_IN_EXTENDED_LOCALE_MODEL   1
 
index 13d4c10..193fc86 100644 (file)
@@ -20,6 +20,7 @@
 
 #define __need_wchar_t
 #include <stddef.h>
+#include <locale.h>
 
 #define USE_IN_EXTENDED_LOCALE_MODEL   1
 
index 5d8fdb0..abe7a98 100644 (file)
@@ -20,6 +20,7 @@
 
 #define __need_wchar_t
 #include <stddef.h>
+#include <locale.h>
 
 #define USE_IN_EXTENDED_LOCALE_MODEL   1
 
index 20a2228..596c7ce 100644 (file)
@@ -20,6 +20,7 @@
 
 #define __need_wchar_t
 #include <stddef.h>
+#include <locale.h>
 
 #define USE_IN_EXTENDED_LOCALE_MODEL   1
 
index 12a8c2d..136d0c7 100644 (file)
@@ -20,6 +20,7 @@
 
 #define __need_wchar_t
 #include <stddef.h>
+#include <locale.h>
 
 #define USE_IN_EXTENDED_LOCALE_MODEL   1
 
index 852d930..0a346cc 100644 (file)
@@ -20,6 +20,7 @@
 
 #define __need_wchar_t
 #include <stddef.h>
+#include <locale.h>
 
 #define USE_IN_EXTENDED_LOCALE_MODEL   1
 
index c849a31..5f6238c 100644 (file)
@@ -20,6 +20,7 @@
 
 #define __need_wchar_t
 #include <stddef.h>
+#include <locale.h>
 
 #define USE_IN_EXTENDED_LOCALE_MODEL   1