From e852e889444a8bf27f3e5075d064e9922b38e7e2 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 28 Jul 1998 16:26:04 +0000 Subject: Update. 1998-07-28 Ulrich Drepper * math/libm-test.c (tgamma_test): Remove redundant tests. 1998-07-28 16:20 Ulrich Drepper * sysdeps/generic/glob.c: Correct problems with */foo and GLOB_NOCHECK where foo does not exist in any of the subdirectories. Reported by Paul D. Smith . * posix/globtest.sh: Add test for this bug. 1998-07-28 Mark Kettenis * io/sys/statfs.h: Fix typos. * io/sys/statvfs.h: Fix typos. 1998-07-28 Ulrich Drepper * version.h (VERSION): Bump to 2.0.95. * math/Makefile (libm-calls): Remove w_gamma, add w_tgamma. * math/Versions [GLIBC_2.1]: Add tgamma, tgammaf, and tgammal. * math/libm-test.c: Split old gamma_test and move half of it in new function tgamma_test. * math/bits/mathcalls.h: Add declaration of tgamma. * sysdeps/libm-ieee754/k_standard.c: Change gamma errors into tgamma errors. * sysdeps/libm-ieee754/w_gamma.c: Remove lgamma compatibility code and rename to ... * sysdeps/libm-ieee754/w_tgamma.c: ... this. New file. * sysdeps/libm-ieee754/w_gammaf.c: Remove lgammaf compatibility code and rename to ... * sysdeps/libm-ieee754/w_tgammaf.c: ... this. New file. * sysdeps/libm-ieee754/w_gammal.c: Remove lgammal compatibility code and rename to ... * sysdeps/libm-ieee754/w_tgammal.c: ... this. New file. * sysdeps/libm-ieee754/w_lgamma.c: Add gamma as weak alias. * sysdeps/libm-ieee754/w_lgammaf.c: Likewise. * sysdeps/libm-ieee754/w_lgammal.c: Likewise. * stgdio-common/printf-parse.h: Implement handling of j, t, and z modifiers. * stdio-common/vfprintf.c: Likewise. * stdio-common/vfscanf.c: Likewise. * manual/stdio.texi: Document new printf/scanf modifiers. * sysdeps/unix/sysv/linux/recvmsg.c: Remove alias __recvmsg. * sysdeps/unix/sysv/linux/sendmsg.c: Remove alias __sendmsg. 1998-07-28 Thorsten Kukuk * sunrpc/Makefile (routines): Add clnt_unix and svc_unix. * sunrpc/Versions: Add new *unix_create functions. * sunrpc/clnt_gen.c: Add support for RPC over AF_UNIX. * sunrpc/clnt_unix.c: New, client side of RPC over AF_UNIX. * sunrpc/key_call.c: Use RPC over AF_UNIX for communication with keyserv daemon. * sunrpc/rpc/clnt.h: Add AF_UNIX based RPC function prototypes. * sunrpc/rpc/svc.h: Likewise. * sunrpc/svc_authux.c: Copy internal auth flavor if none is given. * sunrpc/svc_tcp.c: Fix typos. * sunrpc/svc_unix.c: New, server side of AF_UNIX based RPC. * nis/Makefile: Remove currently not working cache functions. * nis/Versions: Add __nisbind_* functions for rpc.nisd. * nis/nis_call.c: Rewrite binding to a NIS+ server to reuse CLIENT handles. * nis/nis_file.c: Fix memory leaks. * nis/nis_intern.h: Move internal structs from here ... * nis/rpcsvc/nislib.h: ... to here for NIS+ server and tools. * nis/nis_lookup.c: Try at first if last client handle works. * nis/nis_table.c: Likewise. * nis/nis_checkpoint.c: Adjust __do_niscall2 parameters. * nis/nis_mkdir.c: Likewise. * nis/nis_ping.c: Likewise. * nis/nis_rmdir.c: Likewise. * nis/nis_server.c: Likewise. * nis/nis_util.c: Likewise. * nis/nis_findserv.c (__nis_findfastest): Little optimization. 1998-07-28 Andreas Jaeger * stdlib/strtol.c (STRTOL_LONG_MAX): Correct typo in last patch - define as LONG_MAX. 1998-07-28 09:31 Ulrich Drepper * nscd/connections.c (gr_send_answer): Deal with missing UIO_MAXIOV. Correct test whether writev send all data. * nscd/nscd_getgr_r.c (__nscd_getgr_r): Correct test whether readv received all data. 1998-07-28 Mark Kettenis * nscd/nscd_getgr_r.c (__nscd_getgr_r): Deal with missing UIO_MAXIOV. 1998-07-28 Mark Kettenis * sysdeps/mach/hurd/dl-sysdep.c (open_file): Change assert call to allow mode to be 0. (__xstat): New function. (__fxstat): New function. (_dl_sysdep_read_whole_file): Removed. The implementation in `elf/dl-misc.c' now also works for the Hurd. --- nis/nis_table.c | 399 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 239 insertions(+), 160 deletions(-) (limited to 'nis/nis_table.c') diff --git a/nis/nis_table.c b/nis/nis_table.c index ed4b3740dd..e0885ca024 100644 --- a/nis/nis_table.c +++ b/nis/nis_table.c @@ -110,6 +110,40 @@ __create_ib_request (const_nis_name name, u_long flags) return ibreq; } +static struct timeval RPCTIMEOUT = {10, 0}; + +static char * +__get_tablepath (char *name, dir_binding *bptr) +{ + enum clnt_stat result; + nis_result *res = calloc (1, sizeof (nis_result)); + struct ns_request req; + + if (res == NULL) + return NULL; + + req.ns_name = name; + req.ns_object.ns_object_len = 0; + req.ns_object.ns_object_val = NULL; + + result = clnt_call (bptr->clnt, NIS_LOOKUP, (xdrproc_t) _xdr_ns_request, + (caddr_t) &req, (xdrproc_t) _xdr_nis_result, + (caddr_t) res, RPCTIMEOUT); + + if (result == RPC_SUCCESS && NIS_RES_STATUS (res) == NIS_SUCCESS && + __type_of (NIS_RES_OBJECT (res)) == NIS_TABLE_OBJ) + { + char *cptr = strdup (NIS_RES_OBJECT (res)->TA_data.ta_path); + nis_freeresult (res); + return cptr; + } + else + { + nis_freeresult (res); + return strdup (""); + } +} + nis_result * nis_list (const_nis_name name, u_long flags, int (*callback) (const_nis_name name, @@ -120,12 +154,16 @@ nis_list (const_nis_name name, u_long flags, nis_result *res = NULL; ib_request *ibreq; int status; + enum clnt_stat clnt_status; int count_links = 0; /* We will only follow NIS_MAXLINKS links! */ int done = 0; nis_name *names; nis_name namebuf[2] = {NULL, NULL}; int name_nr = 0; nis_cb *cb = NULL; + char *tableptr, *tablepath = NULL; + int have_tablepath = 0; + int first_try = 0; /* Do we try the old binding at first ? */ res = calloc (1, sizeof (nis_result)); if (res == NULL) @@ -164,189 +202,230 @@ nis_list (const_nis_name name, u_long flags, cb = NULL; - if (flags & FOLLOW_PATH || flags & ALL_RESULTS) + while (!done) { - nis_result *lres; - u_long newflags = flags & ~FOLLOW_PATH & ~ALL_RESULTS; - char table_path[NIS_MAXPATH + 3]; - char *ntable, *p; - u_long done = 0, failures = 0; - - while (names[name_nr] != NULL && !done) - { - lres = nis_lookup (names[name_nr], newflags | NO_AUTHINFO); - if (lres == NULL || NIS_RES_STATUS (lres) != NIS_SUCCESS) - { - NIS_RES_STATUS (res) = NIS_RES_STATUS (lres); - nis_freeresult (lres); - ++name_nr; - continue; - } - - /* nis_lookup handles FOLLOW_LINKS, - so we must have a table object.*/ - if (__type_of (NIS_RES_OBJECT (lres)) != NIS_TABLE_OBJ) - { - nis_freeresult (lres); - NIS_RES_STATUS (res) = NIS_INVALIDOBJ; - break; - } + dir_binding bptr; + directory_obj *dir = NULL; - /* Save the path, discard everything else. */ - p = __stpncpy (table_path, names[name_nr], NIS_MAXPATH); - *p++ = ':'; - p = __stpncpy (p, NIS_RES_OBJECT (lres)->TA_data.ta_path, - NIS_MAXPATH - (p - table_path)); - *p = '\0'; - nis_freeresult (lres); - free (res); - res = NULL; + memset (res, '\0', sizeof (nis_result)); - p = table_path; + status = __nisfind_server (ibreq->ibr_name, &dir); + if (status != NIS_SUCCESS) + { + NIS_RES_STATUS (res) = status; + return res; + } - while (((ntable = strsep (&p, ":")) != NULL) && !done) - { - char *c; + status = __nisbind_create (&bptr, dir->do_servers.do_servers_val, + dir->do_servers.do_servers_len, flags); + if (status != NIS_SUCCESS) + { + NIS_RES_STATUS (res) = status; + nis_free_directory (dir); + return res; + } - if (res != NULL) - nis_freeresult (res); + while (__nisbind_connect (&bptr) != NIS_SUCCESS) + if (__nisbind_next (&bptr) != NIS_SUCCESS) + { + __nisbind_destroy (&bptr); + nis_free_directory (dir); + NIS_RES_STATUS (res) = NIS_NAMEUNREACHABLE; + return res; + } - /* Do the job recursive here! */ - if ((c = strchr(name, ']')) != NULL) - { - /* Have indexed name ! */ - int index_len = c - name + 2; - char buf[index_len + strlen (ntable) + 1]; - - c = __stpncpy (buf, name, index_len); - strcpy (c, ntable); - res = nis_list (buf, newflags, callback,userdata); - } - else - res = nis_list (ntable, newflags, callback, userdata); - if (res == NULL) - return NULL; - switch (NIS_RES_STATUS (res)) - { - case NIS_SUCCESS: - case NIS_CBRESULTS: - if (!(flags & ALL_RESULTS)) - done = 1; - break; - case NIS_PARTIAL: /* The table is correct, we doesn't found - the entry */ - break; - default: - if (flags & ALL_RESULTS) - ++failures; - else - done = 1; - break; - } - } - if (NIS_RES_STATUS (res) == NIS_SUCCESS && failures) - NIS_RES_STATUS (res) = NIS_S_SUCCESS; - if (NIS_RES_STATUS (res) == NIS_NOTFOUND && failures) - NIS_RES_STATUS (res) = NIS_S_NOTFOUND; - break; - } - } - else - { if (callback != NULL) { cb = __nis_create_callback (callback, userdata, flags); ibreq->ibr_cbhost.ibr_cbhost_len = 1; ibreq->ibr_cbhost.ibr_cbhost_val = cb->serv; - } - - while (!done) - { - memset (res, '\0', sizeof (nis_result)); - - status = __do_niscall (ibreq->ibr_name, NIS_IBLIST, - (xdrproc_t) _xdr_ib_request, - (caddr_t) ibreq, (xdrproc_t) _xdr_nis_result, - (caddr_t) res, flags, cb); - if (status != NIS_SUCCESS) - NIS_RES_STATUS (res) = status; + } - switch (NIS_RES_STATUS (res)) - { - case NIS_PARTIAL: - case NIS_SUCCESS: - case NIS_S_SUCCESS: - if (__type_of (NIS_RES_OBJECT (res)) == NIS_LINK_OBJ && - flags & FOLLOW_LINKS) /* We are following links. */ - { - /* If we hit the link limit, bail. */ - if (count_links > NIS_MAXLINKS) + again: + clnt_status = clnt_call (bptr.clnt, NIS_IBLIST, + (xdrproc_t) _xdr_ib_request, (caddr_t) ibreq, + (xdrproc_t) _xdr_nis_result, + (caddr_t) res, RPCTIMEOUT); + + if (clnt_status != RPC_SUCCESS) + NIS_RES_STATUS (res) = NIS_RPCERROR; + else + switch (NIS_RES_STATUS (res)) + { /* start switch */ + case NIS_PARTIAL: + case NIS_SUCCESS: + case NIS_S_SUCCESS: + if (__type_of (NIS_RES_OBJECT (res)) == NIS_LINK_OBJ && + flags & FOLLOW_LINKS) /* We are following links. */ + { + free (ibreq->ibr_name); + /* If we hit the link limit, bail. */ + if (count_links > NIS_MAXLINKS) + { + NIS_RES_STATUS (res) = NIS_LINKNAMEERROR; + ++done; + break; + } + ++count_links; + ibreq->ibr_name = + strdup (NIS_RES_OBJECT (res)->LI_data.li_name); + if (NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_len) + if (ibreq->ibr_srch.ibr_srch_len == 0) { - NIS_RES_STATUS (res) = NIS_LINKNAMEERROR; - ++done; - break; + ibreq->ibr_srch.ibr_srch_len = + NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_len; + ibreq->ibr_srch.ibr_srch_val = + NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_val; } - if (count_links) - free (ibreq->ibr_name); - ++count_links; - free (ibreq->ibr_name); - ibreq->ibr_name = - strdup (NIS_RES_OBJECT (res)->LI_data.li_name); - if (NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_len) - if (ibreq->ibr_srch.ibr_srch_len == 0) + nis_freeresult (res); + res = calloc (1, sizeof (nis_result)); + if (res == NULL) + { + if (have_tablepath) + free (tablepath); + __nisbind_destroy (&bptr); + nis_free_directory (dir); + return NULL; + } + first_try = 1; /* Try at first the old binding */ + goto again; + } + else if ((flags & FOLLOW_PATH) && + NIS_RES_STATUS (res) == NIS_PARTIAL) + { + if (!have_tablepath) + { + tablepath = __get_tablepath (ibreq->ibr_name, &bptr); + tableptr = tablepath; + have_tablepath = 1; + } + if (tableptr == NULL) + { + ++done; + break; + } + free (ibreq->ibr_name); + ibreq->ibr_name = strsep (&tableptr, ":"); + if (ibreq->ibr_name == NULL || ibreq->ibr_name[0] == '\0') + { + ibreq->ibr_name = strdup (""); + ++done; + } + else + { + ibreq->ibr_name = strdup (ibreq->ibr_name); + nis_freeresult (res); + res = calloc (1, sizeof (nis_result)); + if (res == NULL) { - ibreq->ibr_srch.ibr_srch_len = - NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_len; - ibreq->ibr_srch.ibr_srch_val = - NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_val; + if (have_tablepath) + free (tablepath); + __nisbind_destroy (&bptr); + nis_free_directory (dir); + return NULL; } - nis_freeresult (res); - res = calloc (1, sizeof (nis_result)); - } - else - ++done; - break; - case NIS_CBRESULTS: - /* Calback is handled in nis_call.c (__do_niscall2), - but we have to change the error code */ - NIS_RES_STATUS (res) = cb->result; + first_try = 1; + goto again; + } + } + else ++done; - break; - case NIS_UNAVAIL: - /* NIS+ is not installed, or all servers are down. */ - ++done; - break; - default: - /* Try the next domainname if we don't follow a link. */ - if (count_links) - { - free (ibreq->ibr_name); - NIS_RES_STATUS (res) = NIS_LINKNAMEERROR; - ++done; - break; - } - ++name_nr; - if (names[name_nr] == NULL) - { + break; + case NIS_CBRESULTS: + if (cb != NULL) + { + __nis_do_callback (&bptr, &res->cookie, cb); + NIS_RES_STATUS (res) = cb->result; + + if (!(flags & ALL_RESULTS)) ++done; - break; - } - ibreq->ibr_name = names[name_nr]; - break; - } + else + { + if (!have_tablepath) + { + tablepath = __get_tablepath (ibreq->ibr_name, &bptr); + tableptr = tablepath; + have_tablepath = 1; + } + if (tableptr == NULL) + { + ++done; + break; + } + free (ibreq->ibr_name); + ibreq->ibr_name = strsep (&tableptr, ":"); + if (ibreq->ibr_name == NULL || ibreq->ibr_name[0] == '\0') + { + ibreq->ibr_name = strdup (""); + ++done; + } + else + ibreq->ibr_name = strdup (ibreq->ibr_name); + } + } + break; + case NIS_SYSTEMERROR: + case NIS_NOSUCHNAME: + case NIS_NOT_ME: + /* If we had first tried the old binding, do nothing, but + get a new binding */ + if (!first_try) + { + if (__nisbind_next (&bptr) != NIS_SUCCESS) + { + ++done; + break; /* No more servers to search */ + } + while (__nisbind_connect (&bptr) != NIS_SUCCESS) + { + if (__nisbind_next (&bptr) != NIS_SUCCESS) + { + ++done; + break; /* No more servers to search */ + } + } + goto again; + } + break; + default: + if (!first_try) + { + /* Try the next domainname if we don't follow a link. */ + if (count_links) + { + free (ibreq->ibr_name); + NIS_RES_STATUS (res) = NIS_LINKNAMEERROR; + ++done; + break; + } + ++name_nr; + if (names[name_nr] == NULL) + { + ++done; + break; + } + ibreq->ibr_name = names[name_nr]; + first_try = 1; /* Try old binding at first */ + goto again; + } + break; + } + first_try = 0; + + if (cb) + { + __nis_destroy_callback (cb); + ibreq->ibr_cbhost.ibr_cbhost_len = 0; + ibreq->ibr_cbhost.ibr_cbhost_val = NULL; } - } /* End of not FOLLOW_PATH. */ + + __nisbind_destroy (&bptr); + nis_free_directory (dir); + } if (names != namebuf) nis_freenames (names); - if (cb) - { - __nis_destroy_callback (cb); - ibreq->ibr_cbhost.ibr_cbhost_len = 0; - ibreq->ibr_cbhost.ibr_cbhost_val = NULL; - } - nis_free_request (ibreq); return res; -- cgit 1.4.1