From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-1.mimecast.com (us-smtp-1.mimecast.com [205.139.110.61]) by sourceware.org (Postfix) with ESMTP id 189523857007 for ; Wed, 1 Jul 2020 19:51:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 189523857007 Received: from mail-qt1-f199.google.com (mail-qt1-f199.google.com [209.85.160.199]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-352-JDMhR6P2Mh26_wzgbAC5XQ-1; Wed, 01 Jul 2020 15:51:28 -0400 X-MC-Unique: JDMhR6P2Mh26_wzgbAC5XQ-1 Received: by mail-qt1-f199.google.com with SMTP id c5so17580245qtv.20 for ; Wed, 01 Jul 2020 12:51:28 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:organization :message-id:date:user-agent:mime-version:in-reply-to :content-language:content-transfer-encoding; bh=hxMBJFyb5nUs+SIDuNwHIS+axe0OPf4c+oexQt/iLNA=; b=ZQIXG6u8fXEzphZ6RpU0/OSu3EzOfjfl8BDksJFpP5h4sb7kZ/MCJ6kxGeNetJ6c5L S4rvMZJ3uMyI4ei1JSUlWt+vNJRK328bTfJsd/2BRojxoejvmlbdrYmHkd+Pr9Bbnu2a Rv/ByPPABtgizMxmnv4QjrmhaK+cZVkq0NbbDPVcH5DRNIahYPW2f/xwfpGGpb/jFz24 4IzsMIR1PXt43ZGWQ5vQ//pzJkmndAEw48oK0EHUXqCKxcM2OFZ1+6Sv8AltW6acM2R8 9wKq2PutN8zlPJQFlYT5dQOORM+oGuEo+sBA1OQ2E8SMFubHZk0BsSjtpXtIqWwqzSD9 +T/Q== X-Gm-Message-State: AOAM532yZ3gs76qTAvSSFF9QUgnGsi2nwTU8pitcMbZDXcgG6H4MhWLM jTa9MRLoESX41zW3IEAqJCXqSFJO9+c46UbLgj1f/+KuwRJN1SXaKPebDMmBqHl0kSMXC2lWtVd rvcjSoV4UOR+wwLO35QVg X-Received: by 2002:a37:40e:: with SMTP id 14mr26645509qke.493.1593633086081; Wed, 01 Jul 2020 12:51:26 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzwnZwkjfnENN0TtpQxxAvZKPXEXVqHKkFvrD1Vdt5wdnO33o257//KtK92MxgR8lBXQ7C5LA== X-Received: by 2002:a37:40e:: with SMTP id 14mr26645433qke.493.1593633084568; Wed, 01 Jul 2020 12:51:24 -0700 (PDT) Received: from [192.168.1.4] (198-84-170-103.cpe.teksavvy.com. [198.84.170.103]) by smtp.gmail.com with ESMTPSA id x26sm6070242qtr.4.2020.07.01.12.51.23 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 01 Jul 2020 12:51:23 -0700 (PDT) Subject: Re: [PATCH 4/4] nsswitch: use new internal API To: DJ Delorie , libc-alpha@sourceware.org References: From: Carlos O'Donell Organization: Red Hat Message-ID: <37945cd6-30d0-50c0-478a-d7167d492b5b@redhat.com> Date: Wed, 1 Jul 2020 15:51:22 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 In-Reply-To: Content-Language: en-US X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-13.9 required=5.0 tests=BAYES_00, DKIM_INVALID, DKIM_SIGNED, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 01 Jul 2020 19:51:39 -0000 On 6/25/20 12:05 AM, DJ Delorie via Libc-alpha wrote: > > Stitch new ABI and types throughout all NSS callers and providers. Thanks for all the wiring up. Please post v2. - Some comment suggestions. - Removal of dead #ifdef DJ code. Looks really good overall the wiring up was straight forward. > --- > grp/compat-initgroups.c | 2 +- > grp/initgroups.c | 41 +- > inet/ether_hton.c | 21 +- > inet/ether_ntoh.c | 21 +- > inet/getnetgrent_r.c | 40 +- > inet/netgroup.h | 2 +- > malloc/set-freeres.c | 4 +- > nscd/aicache.c | 17 +- > nscd/gai.c | 2 +- > nscd/initgrcache.c | 8 +- > nscd/netgroupcache.c | 4 +- > nscd/nscd_netgroup.c | 2 +- > nss/XXX-lookup.c | 2 +- > nss/compat-lookup.c | 8 +- > nss/getXXbyYY_r.c | 10 +- > nss/getXXent_r.c | 10 +- > nss/getnssent_r.c | 22 +- > nss/nss_action.c | 2 +- > nss/nss_action_parse.c | 22 +- > nss/nss_compat/compat-grp.c | 2 +- > nss/nss_compat/compat-initgroups.c | 2 +- > nss/nss_compat/compat-pwd.c | 2 +- > nss/nss_compat/compat-spwd.c | 2 +- > nss/nss_database.c | 40 +- > nss/nss_module.c | 107 +++- > nss/nsswitch.c | 817 ++--------------------------- > nss/nsswitch.h | 40 +- > posix/tst-rfc3484-2.c | 2 +- > posix/tst-rfc3484-3.c | 2 +- > posix/tst-rfc3484.c | 2 +- > sunrpc/netname.c | 21 +- > sunrpc/publickey.c | 42 +- > sysdeps/posix/getaddrinfo.c | 9 +- > 33 files changed, 299 insertions(+), 1031 deletions(-) > > diff --git a/grp/compat-initgroups.c b/grp/compat-initgroups.c > index 3dd50d2306..9df940767b 100644 > --- a/grp/compat-initgroups.c > +++ b/grp/compat-initgroups.c > @@ -10,7 +10,7 @@ typedef enum nss_status (*get_function) (struct group *, char *, > > > static enum nss_status > -compat_call (service_user *nip, const char *user, gid_t group, long int *start, > +compat_call (nss_action_list nip, const char *user, gid_t group, long int *start, > long int *size, gid_t **groupsp, long int limit, int *errnop) > { > struct group grpbuf; > diff --git a/grp/initgroups.c b/grp/initgroups.c > index f4c4e986e9..88eb853496 100644 > --- a/grp/initgroups.c > +++ b/grp/initgroups.c > @@ -69,7 +69,6 @@ internal_getgrouplist (const char *user, gid_t group, long int *size, > #endif > > enum nss_status status = NSS_STATUS_UNAVAIL; > - int no_more = 0; OK. > > /* Never store more than the starting *SIZE number of elements. */ > assert (*size > 0); > @@ -77,33 +76,28 @@ internal_getgrouplist (const char *user, gid_t group, long int *size, > /* Start is one, because we have the first group as parameter. */ > long int start = 1; > > - if (__nss_initgroups_database == NULL) > - { > - if (__nss_database_lookup2 ("initgroups", NULL, "", > - &__nss_initgroups_database) < 0) > - { > - if (__nss_group_database == NULL) > - no_more = __nss_database_lookup2 ("group", NULL, DEFAULT_CONFIG, > - &__nss_group_database); > + nss_action_list nip; OK. > > - __nss_initgroups_database = __nss_group_database; > - } > - else > - use_initgroups_entry = true; > + if (__nss_database_get (nss_database_initgroups, &nip)) > + { > + use_initgroups_entry = true; > + } > + else if (__nss_database_get (nss_database_group, &nip)) > + { > + use_initgroups_entry = false; OK. Replace with __nss_database_get and the enum value. > } > else > - /* __nss_initgroups_database might have been set through > - __nss_configure_lookup in which case use_initgroups_entry was > - not set here. */ > - use_initgroups_entry = __nss_initgroups_database != __nss_group_database; > + { > + nip = __nss_action_parse (DEFAULT_CONFIG); > + use_initgroups_entry = false; > + } OK. > > - service_user *nip = __nss_initgroups_database; > - while (! no_more) > + while (nip && nip->module) > { > long int prev_start = start; > > - initgroups_dyn_function fct = __nss_lookup_function (nip, > - "initgroups_dyn"); > + initgroups_dyn_function fct = __nss_lookup_function (nip, "initgroups_dyn"); > + OK. > if (fct == NULL) > status = compat_call (nip, user, group, &start, size, groupsp, > limit, &errno); > @@ -140,10 +134,7 @@ internal_getgrouplist (const char *user, gid_t group, long int *size, > && nss_next_action (nip, status) == NSS_ACTION_RETURN) > break; > > - if (nip->next == NULL) > - no_more = -1; > - else > - nip = nip->next; > + nip ++; OK. > } > > return start; > diff --git a/inet/ether_hton.c b/inet/ether_hton.c > index ff6943fc35..cccae17f10 100644 > --- a/inet/ether_hton.c > +++ b/inet/ether_hton.c > @@ -30,9 +30,7 @@ typedef int (*lookup_function) (const char *, struct etherent *, char *, int, > int > ether_hostton (const char *hostname, struct ether_addr *addr) > { > - static service_user *startp; > - static lookup_function start_fct; > - service_user *nip; > + nss_action_list nip; OK. > union > { > lookup_function f; > @@ -42,22 +40,7 @@ ether_hostton (const char *hostname, struct ether_addr *addr) > enum nss_status status = NSS_STATUS_UNAVAIL; > struct etherent etherent; > > - if (startp == NULL) > - { > - no_more = __nss_ethers_lookup2 (&nip, "gethostton_r", NULL, &fct.ptr); > - if (no_more) > - startp = (service_user *) -1; > - else > - { > - startp = nip; > - start_fct = fct.f; > - } > - } > - else > - { > - fct.f = start_fct; > - no_more = (nip = startp) == (service_user *) -1; > - } > + no_more = __nss_ethers_lookup2 (&nip, "gethostton_r", NULL, &fct.ptr); OK. > > while (no_more == 0) > { > diff --git a/inet/ether_ntoh.c b/inet/ether_ntoh.c > index e409773601..5ef654292c 100644 > --- a/inet/ether_ntoh.c > +++ b/inet/ether_ntoh.c > @@ -31,9 +31,7 @@ typedef int (*lookup_function) (const struct ether_addr *, struct etherent *, > int > ether_ntohost (char *hostname, const struct ether_addr *addr) > { > - static service_user *startp; > - static lookup_function start_fct; > - service_user *nip; > + nss_action_list nip; OK. > union > { > lookup_function f; > @@ -43,22 +41,7 @@ ether_ntohost (char *hostname, const struct ether_addr *addr) > enum nss_status status = NSS_STATUS_UNAVAIL; > struct etherent etherent; > > - if (startp == NULL) > - { > - no_more = __nss_ethers_lookup2 (&nip, "getntohost_r", NULL, &fct.ptr); > - if (no_more) > - startp = (service_user *) -1; > - else > - { > - startp = nip; > - start_fct = fct.f; > - } > - } > - else > - { > - fct.f = start_fct; > - no_more = (nip = startp) == (service_user *) -1; > - } > + no_more = __nss_ethers_lookup2 (&nip, "getntohost_r", NULL, &fct.ptr); OK. > > while (no_more == 0) > { > diff --git a/inet/getnetgrent_r.c b/inet/getnetgrent_r.c > index 78a66eee00..9c75af6f77 100644 > --- a/inet/getnetgrent_r.c > +++ b/inet/getnetgrent_r.c > @@ -39,40 +39,12 @@ static struct __netgrent dataset; > /* Set up NIP to run through the services. Return nonzero if there are no > services (left). */ > static int > -setup (void **fctp, service_user **nipp) > +setup (void **fctp, nss_action_list *nipp) OK. > { > - /* Remember the first service_entry, it's always the same. */ > - static bool startp_initialized; > - static service_user *startp; > int no_more; > > - if (!startp_initialized) > - { > - /* Executing this more than once at the same time must yield the > - same result every time. So we need no locking. */ > - no_more = __nss_netgroup_lookup2 (nipp, "setnetgrent", NULL, fctp); > - startp = no_more ? (service_user *) -1 : *nipp; > -#ifdef PTR_MANGLE > - PTR_MANGLE (startp); > -#endif > - atomic_write_barrier (); > - startp_initialized = true; > - } > - else > - { > - service_user *nip = startp; > -#ifdef PTR_DEMANGLE > - PTR_DEMANGLE (nip); > -#endif > - if (nip == (service_user *) -1) > - /* No services at all. */ > - return 1; > - > - /* Reset to the beginning of the service list. */ > - *nipp = nip; > - /* Look up the first function. */ > - no_more = __nss_lookup (nipp, "setnetgrent", NULL, fctp); > - } > + no_more = __nss_netgroup_lookup2 (nipp, "setnetgrent", NULL, fctp); > + OK. > return no_more; > } > > @@ -100,7 +72,7 @@ endnetgrent_hook (struct __netgrent *datap) > { > enum nss_status (*endfct) (struct __netgrent *); > > - if (datap->nip == NULL || datap->nip == (service_user *) -1l) > + if (datap->nip == NULL || datap->nip == (nss_action_list) -1l) > return; > > endfct = __nss_lookup_function (datap->nip, "endnetgrent"); > @@ -133,7 +105,7 @@ __internal_setnetgrent_reuse (const char *group, struct __netgrent *datap, > /* Ignore status, we force check in `__nss_next2'. */ > status = DL_CALL_FCT (*fct.f, (group, datap)); > > - service_user *old_nip = datap->nip; > + nss_action_list old_nip = datap->nip; > no_more = __nss_next2 (&datap->nip, "setnetgrent", NULL, &fct.ptr, > status, 0); > > @@ -275,7 +247,7 @@ __internal_getnetgrent_r (char **hostp, char **userp, char **domainp, > /* This bogus function pointer is a special marker left by > __nscd_setnetgrent to tell us to use the data it left > before considering any modules. */ > - if (datap->nip == (service_user *) -1l) > + if (datap->nip == (nss_action_list) -1l) OK. > fct = nscd_getnetgrent; > else > #endif > diff --git a/inet/netgroup.h b/inet/netgroup.h > index 53081db78f..910094b9ca 100644 > --- a/inet/netgroup.h > +++ b/inet/netgroup.h > @@ -64,7 +64,7 @@ struct __netgrent > > /* This handle for the NSS data base is shared between all > set/get/endXXXent functions. */ > - service_user *nip; > + struct nss_action *nip; OK. > }; > > > diff --git a/malloc/set-freeres.c b/malloc/set-freeres.c > index b328cca7c6..0769ad7a6f 100644 > --- a/malloc/set-freeres.c > +++ b/malloc/set-freeres.c > @@ -20,7 +20,7 @@ > #include > #include > > -#include "../nss/nss_module.h" > +#include "../nss/nsswitch.h" OK. > #include "../libio/libioP.h" > > DEFINE_HOOK (__libc_subfreeres, (void)); > @@ -43,6 +43,8 @@ __libc_freeres (void) > void *const *p; > > call_function_static_weak (__nss_module_freeres); > + call_function_static_weak (__nss_action_freeres); > + call_function_static_weak (__nss_database_freeres); OK. > > _IO_cleanup (); > > diff --git a/nscd/aicache.c b/nscd/aicache.c > index ee9c9b8843..ce3bb382ce 100644 > --- a/nscd/aicache.c > +++ b/nscd/aicache.c > @@ -71,20 +71,15 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req, > dbg_log (_("Reloading \"%s\" in hosts cache!"), (char *) key); > } > > - static service_user *hosts_database; > - service_user *nip; > + nss_action_list nip; > int no_more; > int rc6 = 0; > int rc4 = 0; > int herrno = 0; > > - if (hosts_database == NULL) > - no_more = __nss_database_lookup2 ("hosts", NULL, > - "dns [!UNAVAIL=return] files", > - &hosts_database); > - else > - no_more = 0; > - nip = hosts_database; > + no_more = __nss_database_lookup2 ("hosts", NULL, > + "dns [!UNAVAIL=return] files", > + &nip); OK. > > /* Initialize configurations. */ > struct resolv_context *ctx = __resolv_context_get (); > @@ -442,10 +437,10 @@ next_nip: > if (nss_next_action (nip, status[1]) == NSS_ACTION_RETURN) > break; > > - if (nip->next == NULL) > + if (nip[1].module == NULL) > no_more = -1; > else > - nip = nip->next; > + ++ nip; > } > > /* No result found. Create a negative result record. */ > diff --git a/nscd/gai.c b/nscd/gai.c > index 2e19530102..aaaddd8fe5 100644 > --- a/nscd/gai.c > +++ b/nscd/gai.c > @@ -43,4 +43,4 @@ > #include > > /* Some variables normally defined in libc. */ > -service_user *__nss_hosts_database attribute_hidden; > +nss_action_list __nss_hosts_database attribute_hidden; > diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c > index a9f230bfb0..03cc52368e 100644 > --- a/nscd/initgrcache.c > +++ b/nscd/initgrcache.c > @@ -83,8 +83,8 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req, > dbg_log (_("Reloading \"%s\" in group cache!"), (char *) key); > } > > - static service_user *group_database; > - service_user *nip; > + static nss_action_list group_database; > + nss_action_list nip; OK. > int no_more; > > if (group_database == NULL) > @@ -167,10 +167,10 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req, > && nss_next_action (nip, status) == NSS_ACTION_RETURN) > break; > > - if (nip->next == NULL) > + if (nip[1].module == NULL) > no_more = -1; > else > - nip = nip->next; > + ++ nip; OK. > } > > bool all_written; > diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c > index 88c69d1e9c..67be24e837 100644 > --- a/nscd/netgroupcache.c > +++ b/nscd/netgroupcache.c > @@ -124,7 +124,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, > dbg_log (_("Reloading \"%s\" in netgroup cache!"), key); > } > > - static service_user *netgroup_database; > + static nss_action_list netgroup_database; > time_t timeout; > struct dataset *dataset; > bool cacheable = false; > @@ -175,7 +175,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, > void *ptr; > } setfct; > > - service_user *nip = netgroup_database; > + nss_action_list nip = netgroup_database; OK. > int no_more = __nss_lookup (&nip, "setnetgrent", NULL, &setfct.ptr); > while (!no_more) > { > diff --git a/nscd/nscd_netgroup.c b/nscd/nscd_netgroup.c > index 7b8dc4081a..0ed9c0cda6 100644 > --- a/nscd/nscd_netgroup.c > +++ b/nscd/nscd_netgroup.c > @@ -116,7 +116,7 @@ __nscd_setnetgrent (const char *group, struct __netgrent *datap) > datap->data_size = datalen; > datap->cursor = respdata; > datap->first = 1; > - datap->nip = (service_user *) -1l; > + datap->nip = (nss_action_list) -1l; OK. > datap->known_groups = NULL; > datap->needed_groups = NULL; > > diff --git a/nss/XXX-lookup.c b/nss/XXX-lookup.c > index e26c6d7f8b..d291968db3 100644 > --- a/nss/XXX-lookup.c > +++ b/nss/XXX-lookup.c > @@ -53,7 +53,7 @@ > #endif > > int > -DB_LOOKUP_FCT (service_user **ni, const char *fct_name, const char *fct2_name, > +DB_LOOKUP_FCT (nss_action_list *ni, const char *fct_name, const char *fct2_name, > void **fctp) > { > if (DATABASE_NAME_SYMBOL == NULL > diff --git a/nss/compat-lookup.c b/nss/compat-lookup.c > index 9af34150bd..07fcc94f58 100644 > --- a/nss/compat-lookup.c > +++ b/nss/compat-lookup.c > @@ -29,7 +29,7 @@ > glibc 2.7 and earlier and glibc 2.8 and later, even on i386. */ > int > attribute_compat_text_section > -__nss_passwd_lookup (service_user **ni, const char *fct_name, void **fctp) > +__nss_passwd_lookup (nss_action_list *ni, const char *fct_name, void **fctp) > { > __set_errno (ENOSYS); > return -1; > @@ -46,11 +46,11 @@ compat_symbol (libc, __nss_hosts_lookup, __nss_hosts_lookup, GLIBC_2_0); > > /* These functions were exported under a non-GLIBC_PRIVATE version, > even though it is not usable externally due to the service_user > - type dependency. */ > + (now nss_action_list) type dependency. */ > > int > attribute_compat_text_section > -__nss_next (service_user **ni, const char *fct_name, void **fctp, int status, > +__nss_next (nss_action_list *ni, const char *fct_name, void **fctp, int status, > int all_values) > { > return -1; > @@ -60,7 +60,7 @@ compat_symbol (libc, __nss_next, __nss_next, GLIBC_2_0); > int > attribute_compat_text_section > __nss_database_lookup (const char *database, const char *alternate_name, > - const char *defconfig, service_user **ni) > + const char *defconfig, nss_action_list *ni) OK. > { > *ni = NULL; > return -1; > diff --git a/nss/getXXbyYY_r.c b/nss/getXXbyYY_r.c > index e8c9ab1bb3..cbe78e6d66 100644 > --- a/nss/getXXbyYY_r.c > +++ b/nss/getXXbyYY_r.c > @@ -179,7 +179,7 @@ typedef enum nss_status (*lookup_function) (ADD_PARAMS, LOOKUP_TYPE *, char *, > EXTRA_PARAMS); > > /* The lookup function for the first entry of this service. */ > -extern int DB_LOOKUP_FCT (service_user **nip, const char *name, > +extern int DB_LOOKUP_FCT (nss_action_list *nip, const char *name, > const char *name2, void **fctp); > libc_hidden_proto (DB_LOOKUP_FCT) > > @@ -190,9 +190,9 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer, > EXTRA_PARAMS) > { > static bool startp_initialized; > - static service_user *startp; > + static nss_action_list startp; > static lookup_function start_fct; > - service_user *nip; > + nss_action_list nip; > int do_merge = 0; > LOOKUP_TYPE mergegrp; > char *mergebuf = NULL; > @@ -270,7 +270,7 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer, > REENTRANT2_NAME_STRING, &fct.ptr); > if (no_more) > { > - void *tmp_ptr = (service_user *) -1l; > + void *tmp_ptr = (nss_action_list) -1l; > #ifdef PTR_MANGLE > PTR_MANGLE (tmp_ptr); > #endif > @@ -303,7 +303,7 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer, > PTR_DEMANGLE (fct.l); > PTR_DEMANGLE (nip); > #endif > - no_more = nip == (service_user *) -1l; > + no_more = nip == (nss_action_list) -1l; > } > > while (no_more == 0) > diff --git a/nss/getXXent_r.c b/nss/getXXent_r.c > index 8b64fcd795..dfcbd01f66 100644 > --- a/nss/getXXent_r.c > +++ b/nss/getXXent_r.c > @@ -95,11 +95,11 @@ > > /* This handle for the NSS data base is shared between all > set/get/endXXXent functions. */ > -static service_user *nip; > +static nss_action_list nip; > /* Remember the last service used since the last call to `endXXent'. */ > -static service_user *last_nip; > -/* Remember the first service_entry, it's always the same. */ > -static service_user *startp; > +static nss_action_list last_nip; > +/* Remember the first service_entry across set/get/endent. */ > +static nss_action_list startp; OK. > > #ifdef STAYOPEN_TMP > /* We need to remember the last `stayopen' flag given by the user > @@ -112,7 +112,7 @@ static STAYOPEN_TMP; > __libc_lock_define_initialized (static, lock) > > /* The lookup function for the first entry of this service. */ > -extern int DB_LOOKUP_FCT (service_user **nip, const char *name, > +extern int DB_LOOKUP_FCT (nss_action_list *nip, const char *name, > const char *name2, void **fctp); > libc_hidden_proto (DB_LOOKUP_FCT) > > diff --git a/nss/getnssent_r.c b/nss/getnssent_r.c > index 8a366bc7ea..84e977c33b 100644 > --- a/nss/getnssent_r.c > +++ b/nss/getnssent_r.c > @@ -25,20 +25,20 @@ > services (left). */ > static int > setup (const char *func_name, db_lookup_function lookup_fct, > - void **fctp, service_user **nip, service_user **startp, int all) > + void **fctp, nss_action_list *nip, nss_action_list *startp, int all) > { > int no_more; > - if (*startp == NULL) > + if (*startp == NULL || all) > { > no_more = lookup_fct (nip, func_name, NULL, fctp); > - *startp = no_more ? (service_user *) -1l : *nip; > + *startp = no_more ? (nss_action_list) -1l : *nip; > } > - else if (*startp == (service_user *) -1l) > + else if (*startp == (nss_action_list) -1l) > /* No services at all. */ > return 1; > else > { > - if (all || !*nip) > + if (!*nip) > /* Reset to the beginning of the service list. */ > *nip = *startp; > /* Look up the first function. */ > @@ -49,8 +49,8 @@ setup (const char *func_name, db_lookup_function lookup_fct, > > void > __nss_setent (const char *func_name, db_lookup_function lookup_fct, > - service_user **nip, service_user **startp, > - service_user **last_nip, int stayopen, int *stayopen_tmp, > + nss_action_list *nip, nss_action_list *startp, > + nss_action_list *last_nip, int stayopen, int *stayopen_tmp, > int res) > { > union > @@ -110,8 +110,8 @@ __nss_setent (const char *func_name, db_lookup_function lookup_fct, > > void > __nss_endent (const char *func_name, db_lookup_function lookup_fct, > - service_user **nip, service_user **startp, > - service_user **last_nip, int res) > + nss_action_list *nip, nss_action_list *startp, > + nss_action_list *last_nip, int res) > { > union > { > @@ -154,8 +154,8 @@ int > __nss_getent_r (const char *getent_func_name, > const char *setent_func_name, > db_lookup_function lookup_fct, > - service_user **nip, service_user **startp, > - service_user **last_nip, int *stayopen_tmp, int res, > + nss_action_list *nip, nss_action_list *startp, > + nss_action_list *last_nip, int *stayopen_tmp, int res, > void *resbuf, char *buffer, size_t buflen, > void **result, int *h_errnop) > { OK. > diff --git a/nss/nss_action.c b/nss/nss_action.c > index 24f1c5e4f9..91aebb37e8 100644 > --- a/nss/nss_action.c > +++ b/nss/nss_action.c > @@ -16,7 +16,7 @@ > License along with the GNU C Library; if not, see > . */ > > -#include > +#include > > #include > #include > diff --git a/nss/nss_action_parse.c b/nss/nss_action_parse.c > index ada3acbb08..7a80582842 100644 > --- a/nss/nss_action_parse.c > +++ b/nss/nss_action_parse.c > @@ -16,8 +16,7 @@ > License along with the GNU C Library; if not, see > . */ > > -#include "nss_action.h" > -#include "nss_module.h" > +#include > > #include > #include > @@ -169,18 +168,13 @@ nss_action_list > action_list_init (&list); > if (nss_action_parse (line, &list)) > { > - size_t size = action_list_size (&list); > - nss_action_list result > - = malloc (sizeof (*result) * (size + 1)); > - if (result == NULL) > - { > - action_list_free (&list); > - return NULL; > - } > - memcpy (result, action_list_begin (&list), sizeof (*result) * size); > - /* Sentinel. */ > - result[size].module = NULL; > - return result; > + size_t size; > + struct nss_action null_service > + = { .module = NULL, }; > + > + action_list_add (&list, null_service); > + size = action_list_size (&list); > + return __nss_action_allocate (action_list_begin (&list), size); OK. > } > else if (action_list_has_failed (&list)) > { > diff --git a/nss/nss_compat/compat-grp.c b/nss/nss_compat/compat-grp.c > index d4f750b95c..5593e075b4 100644 > --- a/nss/nss_compat/compat-grp.c > +++ b/nss/nss_compat/compat-grp.c > @@ -29,7 +29,7 @@ > > NSS_DECLARE_MODULE_FUNCTIONS (compat) > > -static service_user *ni; > +static nss_action_list ni; > static enum nss_status (*setgrent_impl) (int stayopen); > static enum nss_status (*getgrnam_r_impl) (const char *name, > struct group * grp, char *buffer, > diff --git a/nss/nss_compat/compat-initgroups.c b/nss/nss_compat/compat-initgroups.c > index 3671bef48b..0ce6141434 100644 > --- a/nss/nss_compat/compat-initgroups.c > +++ b/nss/nss_compat/compat-initgroups.c > @@ -32,7 +32,7 @@ > > NSS_DECLARE_MODULE_FUNCTIONS (compat) > > -static service_user *ni; > +static nss_action_list ni; > static enum nss_status (*initgroups_dyn_impl) (const char *, gid_t, > long int *, long int *, > gid_t **, long int, int *); > diff --git a/nss/nss_compat/compat-pwd.c b/nss/nss_compat/compat-pwd.c > index 394e39b811..8145fc2707 100644 > --- a/nss/nss_compat/compat-pwd.c > +++ b/nss/nss_compat/compat-pwd.c > @@ -33,7 +33,7 @@ > > NSS_DECLARE_MODULE_FUNCTIONS (compat) > > -static service_user *ni; > +static nss_action_list ni; > static enum nss_status (*setpwent_impl) (int stayopen); > static enum nss_status (*getpwnam_r_impl) (const char *name, > struct passwd * pwd, char *buffer, > diff --git a/nss/nss_compat/compat-spwd.c b/nss/nss_compat/compat-spwd.c > index ec5bf283cd..08dff30a59 100644 > --- a/nss/nss_compat/compat-spwd.c > +++ b/nss/nss_compat/compat-spwd.c > @@ -33,7 +33,7 @@ > > NSS_DECLARE_MODULE_FUNCTIONS (compat) > > -static service_user *ni; > +static nss_action_list ni; > static enum nss_status (*setspent_impl) (int stayopen); > static enum nss_status (*getspnam_r_impl) (const char *name, struct spwd * sp, > char *buffer, size_t buflen, > diff --git a/nss/nss_database.c b/nss/nss_database.c > index 0f6342d0c8..d82e9f9c7e 100644 > --- a/nss/nss_database.c > +++ b/nss/nss_database.c > @@ -217,6 +217,39 @@ process_line (struct nss_database_data *data, char *line) > return true; > } > > +int > +__nss_configure_lookup (const char *dbname, const char *service_line) OK. New implementation of __nss_configure_lookup. > +{ > + int db; > + nss_action_list result; > + struct nss_database_state *local; > + > + /* Convert named database to index. */ > + db = name_to_database_index (dbname); > + if (db < 0) > + /* Not our database (e.g., sudoers). */ > + return -1; > + > + /* Force any load/cache/read whatever to happen, so we can override > + it. */ > + __nss_database_get (db, &result); > + > + local = nss_database_state_get (); > + > + result = __nss_action_parse (service_line); > + if (result == NULL) > + return -1; > + > + atomic_store_release (&local->data.reload_disabled, 1); > + local->data.services[db] = result; > + > +#ifdef USE_NSCD > + __nss_database_custom[db] = true; > +#endif > + > + return 0; > +} > + > /* Iterate over the lines in FP, parse them, and store them in DATA. > Return false on memory allocation failure, true on success. */ > static bool > @@ -317,8 +350,11 @@ nss_database_check_reload_and_get (struct nss_database_state *local, > may have loaded the configuration first, so synchronize with the > Release MO store there. */ > if (atomic_load_acquire (&local->data.reload_disabled)) > - /* No reload, so there is no error. */ > - return true; > + { > + *result = local->data.services[database_index]; OK. Return result. > + /* No reload, so there is no error. */ > + return true; > + } > > struct file_change_detection initial; > if (!__file_change_detection_for_path (&initial, _PATH_NSSWITCH_CONF)) > diff --git a/nss/nss_module.c b/nss/nss_module.c > index 29dc1139c6..702c70e7ab 100644 > --- a/nss/nss_module.c > +++ b/nss/nss_module.c > @@ -16,7 +16,9 @@ > License along with the GNU C Library; if not, see > . */ > > -#include > +#include > +#include > +#include > > #include > #include > @@ -29,6 +31,14 @@ > #include > #include > > +#ifdef LINK_OBSOLETE_NSL > +# define DEFAULT_CONFIG "compat [NOTFOUND=return] files" > +# define DEFAULT_DEFCONFIG "nis [NOTFOUND=return] files" > +#else > +# define DEFAULT_CONFIG "files" > +# define DEFAULT_DEFCONFIG "files" > +#endif > + > /* Suffix after .so of NSS service modules. */ > static const char *const __nss_shlib_revision = LIBNSS_FILES_SO + 15; > > @@ -42,6 +52,13 @@ static struct nss_module *nss_module_list; > modules. */ > __libc_lock_define (static, nss_module_list_lock); > > +#if defined USE_NSCD && (!defined DO_STATIC_NSS || defined SHARED) > +/* Nonzero if this is the nscd process. */ > +static bool is_nscd; > +/* The callback passed to the init functions when nscd is used. */ > +static void (*nscd_init_cb) (size_t, struct traced_file *); > +#endif > + > struct nss_module * > __nss_module_allocate (const char *name, size_t name_length) > { > @@ -218,6 +235,34 @@ module_load (struct nss_module *module) > #endif > } > > +# ifdef USE_NSCD > + if (is_nscd) > + { > + /* Call the init function when nscd is used. */ > + size_t initlen = (5 + strlen (module->name) > + + strlen ("_init") + 1); > + char init_name[initlen]; > + > + /* Construct the init function name. */ > + __stpcpy (__stpcpy (__stpcpy (init_name, > + "_nss_"), > + module->name), > + "_init"); > + > + /* Find the optional init function. */ > + void (*ifct) (void (*) (size_t, struct traced_file *)) > + = __libc_dlsym (handle, init_name); > + if (ifct != NULL) > + { > + void (*cb) (size_t, struct traced_file *) = nscd_init_cb; > +# ifdef PTR_DEMANGLE > + PTR_DEMANGLE (cb); > +# endif > + ifct (cb); > + } > + } > +# endif OK. > + > /* Intall the function pointers, following the double-checked > locking idiom. Delay this after all processing, in case loading > the module triggers unwinding. */ > @@ -283,6 +328,66 @@ __nss_module_get_function (struct nss_module *module, const char *name) > return fptr; > } > > +#if defined SHARED && defined USE_NSCD > +/* Load all libraries for the service. */ > +static void > +nss_load_all_libraries (const char *service, const char *def) > +{ > + nss_action_list ni = NULL; > + > + if (__nss_database_lookup2 (service, NULL, def, &ni) == 0) > + while (ni->module != NULL) > + { > + __nss_module_load (ni->module); > + ++ ni; > + } > +} > + > +define_traced_file (pwd, _PATH_NSSWITCH_CONF); > +define_traced_file (grp, _PATH_NSSWITCH_CONF); > +define_traced_file (hst, _PATH_NSSWITCH_CONF); > +define_traced_file (serv, _PATH_NSSWITCH_CONF); > +define_traced_file (netgr, _PATH_NSSWITCH_CONF); OK. Reload on change for all databases if nsswitch.conf changes. > + > +/* Called by nscd and nscd alone. */ > +void > +__nss_disable_nscd (void (*cb) (size_t, struct traced_file *)) > +{ > + void (*cb1) (size_t, struct traced_file *); > + cb1 = cb; > +# ifdef PTR_MANGLE > + PTR_MANGLE (cb); > +# endif > + nscd_init_cb = cb; > + is_nscd = true; > + > + /* Find all the relevant modules so that the init functions are called. */ > + nss_load_all_libraries ("passwd", DEFAULT_CONFIG); > + nss_load_all_libraries ("group", DEFAULT_CONFIG); > + nss_load_all_libraries ("hosts", "dns [!UNAVAIL=return] files"); > + nss_load_all_libraries ("services", NULL); > + > + /* Make sure NSCD purges its cache if nsswitch.conf changes. */ > + init_traced_file (&pwd_traced_file.file, _PATH_NSSWITCH_CONF, 0); > + cb1 (pwddb, &pwd_traced_file.file); > + init_traced_file (&grp_traced_file.file, _PATH_NSSWITCH_CONF, 0); > + cb1 (grpdb, &grp_traced_file.file); > + init_traced_file (&hst_traced_file.file, _PATH_NSSWITCH_CONF, 0); > + cb1 (hstdb, &hst_traced_file.file); > + init_traced_file (&serv_traced_file.file, _PATH_NSSWITCH_CONF, 0); > + cb1 (servdb, &serv_traced_file.file); > + init_traced_file (&netgr_traced_file.file, _PATH_NSSWITCH_CONF, 0); > + cb1 (netgrdb, &netgr_traced_file.file); > + > + /* Disable all uses of NSCD. */ > + __nss_not_use_nscd_passwd = -1; > + __nss_not_use_nscd_group = -1; > + __nss_not_use_nscd_hosts = -1; > + __nss_not_use_nscd_services = -1; > + __nss_not_use_nscd_netgroup = -1; OK. > +} > +#endif > + > void __libc_freeres_fn_section > __nss_module_freeres (void) > { > diff --git a/nss/nsswitch.c b/nss/nsswitch.c > index 319e22c3fc..9b73296c5f 100644 > --- a/nss/nsswitch.c > +++ b/nss/nsswitch.c > @@ -32,6 +32,7 @@ > #include > #include > #include > +#include > > #if !defined DO_STATIC_NSS || defined SHARED > # include > @@ -42,44 +43,20 @@ > #include > #include > > -#ifdef LINK_OBSOLETE_NSL > -# define DEFAULT_CONFIG "compat [NOTFOUND=return] files" > -# define DEFAULT_DEFCONFIG "nis [NOTFOUND=return] files" > -#else > -# define DEFAULT_CONFIG "files" > -# define DEFAULT_DEFCONFIG "files" > -#endif > - > -/* Prototypes for the local functions. */ > -static name_database *nss_parse_file (const char *fname); > -static name_database_entry *nss_getline (char *line); > -static service_user *nss_parse_service_list (const char *line); > -#if !defined DO_STATIC_NSS || defined SHARED > -static service_library *nss_new_service (name_database *database, > - const char *name); > -#endif > - > - > /* Declare external database variables. */ > #define DEFINE_DATABASE(name) \ > - service_user *__nss_##name##_database attribute_hidden; \ > + nss_action_list __nss_##name##_database attribute_hidden; \ > weak_extern (__nss_##name##_database) > #include "databases.def" > #undef DEFINE_DATABASE > > -/* Structure to map database name to variable. */ > -static const struct > -{ > - const char name[10]; > - service_user **dbp; > -} databases[] = > -{ > -#define DEFINE_DATABASE(name) \ > - { #name, &__nss_##name##_database }, > -#include "databases.def" > + > #undef DEFINE_DATABASE > +#define DEFINE_DATABASE(name) #name, > +static const char * database_names[] = { > +#include "databases.def" > + NULL > }; > -#define ndatabases (sizeof (databases) / sizeof (databases[0])) > > #ifdef USE_NSCD > /* Flags whether custom rules for database is set. */ > @@ -87,103 +64,33 @@ bool __nss_database_custom[NSS_DBSIDX_max]; > #endif > > > -__libc_lock_define_initialized (static, lock) > - > -#if !defined DO_STATIC_NSS || defined SHARED > -/* String with revision number of the shared object files. */ > -static const char *const __nss_shlib_revision = LIBNSS_FILES_SO + 15; > -#endif > - > -/* The root of the whole data base. */ > -static name_database *service_table; > - > -/* List of default service lists that were generated by glibc because > - /etc/nsswitch.conf did not provide a value. > - The list is only maintained so we can free such service lists in > - __libc_freeres. */ > -static name_database_entry *defconfig_entries; > - > - > -#if defined USE_NSCD && (!defined DO_STATIC_NSS || defined SHARED) > -/* Nonzero if this is the nscd process. */ > -static bool is_nscd; > -/* The callback passed to the init functions when nscd is used. */ > -static void (*nscd_init_cb) (size_t, struct traced_file *); > -#endif > - > +/*__libc_lock_define_initialized (static, lock)*/ > > /* -1 == database not found > 0 == database entry pointer stored */ > int > __nss_database_lookup2 (const char *database, const char *alternate_name, > - const char *defconfig, service_user **ni) > + const char *defconfig, nss_action_list *ni) > { > - /* Prevent multiple threads to change the service table. */ > - __libc_lock_lock (lock); > + int database_id; > > - /* Reconsider database variable in case some other thread called > - `__nss_configure_lookup' while we waited for the lock. */ > - if (*ni != NULL) > - { > - __libc_lock_unlock (lock); > - return 0; > - } > + for (database_id = 0; database_names[database_id]; database_id ++) > + if (strcmp (database_names[database_id], database) == 0) > + break; > > - /* Are we initialized yet? */ > - if (service_table == NULL) > - /* Read config file. */ > - service_table = nss_parse_file (_PATH_NSSWITCH_CONF); > + if (database_names[database_id] == NULL) > + return -1; > > - /* Test whether configuration data is available. */ > - if (service_table != NULL) > + if (__nss_database_get (database_id, ni)) > { > - /* Return first `service_user' entry for DATABASE. */ > - name_database_entry *entry; > - > - /* XXX Could use some faster mechanism here. But each database is > - only requested once and so this might not be critical. */ > - for (entry = service_table->entry; entry != NULL; entry = entry->next) > - if (strcmp (database, entry->name) == 0) > - *ni = entry->service; > - > - if (*ni == NULL && alternate_name != NULL) > - /* We haven't found an entry so far. Try to find it with the > - alternative name. */ > - for (entry = service_table->entry; entry != NULL; entry = entry->next) > - if (strcmp (alternate_name, entry->name) == 0) > - *ni = entry->service; > + /* Success. */ > + return 0; > } > - > - /* No configuration data is available, either because nsswitch.conf > - doesn't exist or because it doesn't have a line for this database. > - > - DEFCONFIG specifies the default service list for this database, > - or null to use the most common default. */ > - if (*ni == NULL) > + else > { > - *ni = nss_parse_service_list (defconfig ?: DEFAULT_DEFCONFIG); > - if (*ni != NULL) > - { > - /* Record the memory we've just allocated in defconfig_entries list, > - so we can free it later. */ > - name_database_entry *entry; > - > - /* Allocate ENTRY plus size of name (1 here). */ > - entry = (name_database_entry *) malloc (sizeof (*entry) + 1); > - > - if (entry != NULL) > - { > - entry->next = defconfig_entries; > - entry->service = *ni; > - entry->name[0] = '\0'; > - defconfig_entries = entry; > - } > - } > + /* Failure. */ > + return -1; > } > - > - __libc_lock_unlock (lock); > - > - return *ni != NULL ? 0 : -1; > } > libc_hidden_def (__nss_database_lookup2) > > @@ -192,7 +99,7 @@ libc_hidden_def (__nss_database_lookup2) > 0 == function found > 1 == finished */ > int > -__nss_lookup (service_user **ni, const char *fct_name, const char *fct2_name, > +__nss_lookup (nss_action_list *ni, const char *fct_name, const char *fct2_name, > void **fctp) > { > *fctp = __nss_lookup_function (*ni, fct_name); > @@ -201,16 +108,16 @@ __nss_lookup (service_user **ni, const char *fct_name, const char *fct2_name, > > while (*fctp == NULL > && nss_next_action (*ni, NSS_STATUS_UNAVAIL) == NSS_ACTION_CONTINUE > - && (*ni)->next != NULL) > + && (*ni)[1].module != NULL) > { > - *ni = (*ni)->next; > + ++ (*ni); > > *fctp = __nss_lookup_function (*ni, fct_name); > if (*fctp == NULL && fct2_name != NULL) > *fctp = __nss_lookup_function (*ni, fct2_name); > } > > - return *fctp != NULL ? 0 : (*ni)->next == NULL ? 1 : -1; > + return *fctp != NULL ? 0 : (*ni)[1].module == NULL ? 1 : -1; > } > libc_hidden_def (__nss_lookup) > > @@ -219,7 +126,7 @@ libc_hidden_def (__nss_lookup) > 0 == adjusted for next function > 1 == finished */ > int > -__nss_next2 (service_user **ni, const char *fct_name, const char *fct2_name, > +__nss_next2 (nss_action_list *ni, const char *fct_name, const char *fct2_name, > void **fctp, int status, int all_values) > { > if (all_values) > @@ -241,12 +148,12 @@ __nss_next2 (service_user **ni, const char *fct_name, const char *fct2_name, > return 1; > } > > - if ((*ni)->next == NULL) > + if ((*ni)[1].module == NULL) > return -1; > > do > { > - *ni = (*ni)->next; > + ++ (*ni); > > *fctp = __nss_lookup_function (*ni, fct_name); > if (*fctp == NULL && fct2_name != NULL) > @@ -254,675 +161,17 @@ __nss_next2 (service_user **ni, const char *fct_name, const char *fct2_name, > } > while (*fctp == NULL > && nss_next_action (*ni, NSS_STATUS_UNAVAIL) == NSS_ACTION_CONTINUE > - && (*ni)->next != NULL); > + && (*ni)[1].module != NULL); > > return *fctp != NULL ? 0 : -1; > } > libc_hidden_def (__nss_next2) > > -int > -__nss_configure_lookup (const char *dbname, const char *service_line) > -{ > - service_user *new_db; > - size_t cnt; > - > - for (cnt = 0; cnt < ndatabases; ++cnt) > - { > - int cmp = strcmp (dbname, databases[cnt].name); > - if (cmp == 0) > - break; > - if (cmp < 0) > - { > - __set_errno (EINVAL); > - return -1; > - } > - } > - > - if (cnt == ndatabases) > - { > - __set_errno (EINVAL); > - return -1; > - } > - > - /* Test whether it is really used. */ > - if (databases[cnt].dbp == NULL) > - /* Nothing to do, but we could do. */ > - return 0; > - > - /* Try to generate new data. */ > - new_db = nss_parse_service_list (service_line); > - if (new_db == NULL) > - { > - /* Illegal service specification. */ > - __set_errno (EINVAL); > - return -1; > - } > - > - /* Prevent multiple threads to change the service table. */ > - __libc_lock_lock (lock); > - > - /* Install new rules. */ > - *databases[cnt].dbp = new_db; > -#ifdef USE_NSCD > - __nss_database_custom[cnt] = true; > -#endif > - > - __libc_lock_unlock (lock); > - > - return 0; > -} OK. Rewritten earlier. > - > - > -/* Comparison function for searching NI->known tree. */ > -static int > -known_compare (const void *p1, const void *p2) > -{ > - return p1 == p2 ? 0 : strcmp (*(const char *const *) p1, > - *(const char *const *) p2); > -} > - > - > -#if !defined DO_STATIC_NSS || defined SHARED > -/* Load library. */ > -static int > -nss_load_library (service_user *ni) > -{ > - if (ni->library == NULL) > - { > - /* This service has not yet been used. Fetch the service > - library for it, creating a new one if need be. If there > - is no service table from the file, this static variable > - holds the head of the service_library list made from the > - default configuration. */ > - static name_database default_table; > - ni->library = nss_new_service (service_table ?: &default_table, > - ni->name); > - if (ni->library == NULL) > - return -1; > - } > - > - if (ni->library->lib_handle == NULL) > - { > - /* Load the shared library. */ > - size_t shlen = (7 + strlen (ni->name) + 3 > - + strlen (__nss_shlib_revision) + 1); > - int saved_errno = errno; > - char shlib_name[shlen]; > - > - /* Construct shared object name. */ > - __stpcpy (__stpcpy (__stpcpy (__stpcpy (shlib_name, > - "libnss_"), > - ni->name), > - ".so"), > - __nss_shlib_revision); > - > - ni->library->lib_handle = __libc_dlopen (shlib_name); > - if (ni->library->lib_handle == NULL) > - { > - /* Failed to load the library. */ > - ni->library->lib_handle = (void *) -1l; > - __set_errno (saved_errno); > - } > -# ifdef USE_NSCD > - else if (is_nscd) > - { > - /* Call the init function when nscd is used. */ > - size_t initlen = (5 + strlen (ni->name) > - + strlen ("_init") + 1); > - char init_name[initlen]; > - > - /* Construct the init function name. */ > - __stpcpy (__stpcpy (__stpcpy (init_name, > - "_nss_"), > - ni->name), > - "_init"); > - > - /* Find the optional init function. */ > - void (*ifct) (void (*) (size_t, struct traced_file *)) > - = __libc_dlsym (ni->library->lib_handle, init_name); > - if (ifct != NULL) > - { > - void (*cb) (size_t, struct traced_file *) = nscd_init_cb; > -# ifdef PTR_DEMANGLE > - PTR_DEMANGLE (cb); > -# endif > - ifct (cb); > - } > - } > -# endif > - } > - > - return 0; > -} > -#endif > - > - > void * > -__nss_lookup_function (service_user *ni, const char *fct_name) > -{ > - void **found, *result; > - > - /* We now modify global data. Protect it. */ > - __libc_lock_lock (lock); > - > - /* Search the tree of functions previously requested. Data in the > - tree are `known_function' structures, whose first member is a > - `const char *', the lookup key. The search returns a pointer to > - the tree node structure; the first member of the is a pointer to > - our structure (i.e. what will be a `known_function'); since the > - first member of that is the lookup key string, &FCT_NAME is close > - enough to a pointer to our structure to use as a lookup key that > - will be passed to `known_compare' (above). */ > - > - found = __tsearch (&fct_name, &ni->known, &known_compare); > - if (found == NULL) > - /* This means out-of-memory. */ > - result = NULL; > - else if (*found != &fct_name) > - { > - /* The search found an existing structure in the tree. */ > - result = ((known_function *) *found)->fct_ptr; > -#ifdef PTR_DEMANGLE > - PTR_DEMANGLE (result); > -#endif > - } > - else > - { > - /* This name was not known before. Now we have a node in the tree > - (in the proper sorted position for FCT_NAME) that points to > - &FCT_NAME instead of any real `known_function' structure. > - Allocate a new structure and fill it in. */ > - > - known_function *known = malloc (sizeof *known); > - if (! known) > - { > -#if !defined DO_STATIC_NSS || defined SHARED > - remove_from_tree: > -#endif > - /* Oops. We can't instantiate this node properly. > - Remove it from the tree. */ > - __tdelete (&fct_name, &ni->known, &known_compare); > - free (known); > - result = NULL; > - } > - else > - { > - /* Point the tree node at this new structure. */ > - *found = known; > - known->fct_name = fct_name; > - > -#if !defined DO_STATIC_NSS || defined SHARED > - /* Load the appropriate library. */ > - if (nss_load_library (ni) != 0) > - /* This only happens when out of memory. */ > - goto remove_from_tree; > - > - if (ni->library->lib_handle == (void *) -1l) > - /* Library not found => function not found. */ > - result = NULL; > - else > - { > - /* Get the desired function. */ > - size_t namlen = (5 + strlen (ni->name) + 1 > - + strlen (fct_name) + 1); > - char name[namlen]; > - > - /* Construct the function name. */ > - __stpcpy (__stpcpy (__stpcpy (__stpcpy (name, "_nss_"), > - ni->name), > - "_"), > - fct_name); > - > - /* Look up the symbol. */ > - result = __libc_dlsym (ni->library->lib_handle, name); > - } > -#else > - /* We can't get function address dynamically in static linking. */ > - { > -# define DEFINE_ENT(h,nm) \ > - { #h"_get"#nm"ent_r", _nss_##h##_get##nm##ent_r }, \ > - { #h"_end"#nm"ent", _nss_##h##_end##nm##ent }, \ > - { #h"_set"#nm"ent", _nss_##h##_set##nm##ent }, > -# define DEFINE_GET(h,nm) \ > - { #h"_get"#nm"_r", _nss_##h##_get##nm##_r }, > -# define DEFINE_GETBY(h,nm,ky) \ > - { #h"_get"#nm"by"#ky"_r", _nss_##h##_get##nm##by##ky##_r }, > - static struct fct_tbl { const char *fname; void *fp; } *tp, tbl[] = > - { > -# include "function.def" > - { NULL, NULL } > - }; > - size_t namlen = (5 + strlen (ni->name) + 1 > - + strlen (fct_name) + 1); > - char name[namlen]; > - > - /* Construct the function name. */ > - __stpcpy (__stpcpy (__stpcpy (name, ni->name), > - "_"), > - fct_name); > - > - result = NULL; > - for (tp = &tbl[0]; tp->fname; tp++) > - if (strcmp (tp->fname, name) == 0) > - { > - result = tp->fp; > - break; > - } > - } > -#endif > - > - /* Remember function pointer for later calls. Even if null, we > - record it so a second try needn't search the library again. */ > - known->fct_ptr = result; > -#ifdef PTR_MANGLE > - PTR_MANGLE (known->fct_ptr); > -#endif > - } > - } > - > - /* Remove the lock. */ > - __libc_lock_unlock (lock); > - > - return result; > -} > -libc_hidden_def (__nss_lookup_function) > - > - > -static name_database * > -nss_parse_file (const char *fname) > +__nss_lookup_function (nss_action_list ni, const char *fct_name) > { > - FILE *fp; > - name_database *result; > - name_database_entry *last; > - char *line; > - size_t len; > - > - /* Open the configuration file. */ > - fp = fopen (fname, "rce"); > - if (fp == NULL) > + if (ni->module == NULL) > return NULL; > - > - /* No threads use this stream. */ > - __fsetlocking (fp, FSETLOCKING_BYCALLER); > - > - result = (name_database *) malloc (sizeof (name_database)); > - if (result == NULL) > - { > - fclose (fp); > - return NULL; > - } > - > - result->entry = NULL; > - result->library = NULL; > - last = NULL; > - line = NULL; > - len = 0; > - do > - { > - name_database_entry *this; > - ssize_t n; > - > - n = __getline (&line, &len, fp); > - if (n < 0) > - break; > - if (line[n - 1] == '\n') > - line[n - 1] = '\0'; > - > - /* Because the file format does not know any form of quoting we > - can search forward for the next '#' character and if found > - make it terminating the line. */ > - *__strchrnul (line, '#') = '\0'; > - > - /* If the line is blank it is ignored. */ > - if (line[0] == '\0') > - continue; > - > - /* Each line completely specifies the actions for a database. */ > - this = nss_getline (line); > - if (this != NULL) > - { > - if (last != NULL) > - last->next = this; > - else > - result->entry = this; > - > - last = this; > - } > - } > - while (!__feof_unlocked (fp)); > - > - /* Free the buffer. */ > - free (line); > - /* Close configuration file. */ > - fclose (fp); > - > - return result; > -} > - > - > -/* Read the source names: > - `( ( "[" "!"? ( "=" )+ "]" )? )*' > - */ > -static service_user * > -nss_parse_service_list (const char *line) > -{ > - service_user *result = NULL, **nextp = &result; > - > - while (1) > - { > - service_user *new_service; > - const char *name; > - > - while (isspace (line[0])) > - ++line; > - if (line[0] == '\0') > - /* No source specified. */ > - return result; > - > - /* Read identifier. */ > - name = line; > - while (line[0] != '\0' && !isspace (line[0]) && line[0] != '[') > - ++line; > - if (name == line) > - return result; > - > - > - new_service = (service_user *) malloc (sizeof (service_user) > - + (line - name + 1)); > - if (new_service == NULL) > - return result; > - > - *((char *) __mempcpy (new_service->name, name, line - name)) = '\0'; > - > - /* Set default actions. */ > - new_service->actions[2 + NSS_STATUS_TRYAGAIN] = NSS_ACTION_CONTINUE; > - new_service->actions[2 + NSS_STATUS_UNAVAIL] = NSS_ACTION_CONTINUE; > - new_service->actions[2 + NSS_STATUS_NOTFOUND] = NSS_ACTION_CONTINUE; > - new_service->actions[2 + NSS_STATUS_SUCCESS] = NSS_ACTION_RETURN; > - new_service->actions[2 + NSS_STATUS_RETURN] = NSS_ACTION_RETURN; > - new_service->library = NULL; > - new_service->known = NULL; > - new_service->next = NULL; > - > - while (isspace (line[0])) > - ++line; > - > - if (line[0] == '[') > - { > - /* Read criterions. */ > - do > - ++line; > - while (line[0] != '\0' && isspace (line[0])); > - > - do > - { > - int not; > - enum nss_status status; > - lookup_actions action; > - > - /* Grok ! before name to mean all statii but that one. */ > - not = line[0] == '!'; > - if (not) > - ++line; > - > - /* Read status name. */ > - name = line; > - while (line[0] != '\0' && !isspace (line[0]) && line[0] != '=' > - && line[0] != ']') > - ++line; > - > - /* Compare with known statii. */ > - if (line - name == 7) > - { > - if (__strncasecmp (name, "SUCCESS", 7) == 0) > - status = NSS_STATUS_SUCCESS; > - else if (__strncasecmp (name, "UNAVAIL", 7) == 0) > - status = NSS_STATUS_UNAVAIL; > - else > - goto finish; > - } > - else if (line - name == 8) > - { > - if (__strncasecmp (name, "NOTFOUND", 8) == 0) > - status = NSS_STATUS_NOTFOUND; > - else if (__strncasecmp (name, "TRYAGAIN", 8) == 0) > - status = NSS_STATUS_TRYAGAIN; > - else > - goto finish; > - } > - else > - goto finish; > - > - while (isspace (line[0])) > - ++line; > - if (line[0] != '=') > - goto finish; > - do > - ++line; > - while (isspace (line[0])); > - > - name = line; > - while (line[0] != '\0' && !isspace (line[0]) && line[0] != '=' > - && line[0] != ']') > - ++line; > - > - if (line - name == 6 && __strncasecmp (name, "RETURN", 6) == 0) > - action = NSS_ACTION_RETURN; > - else if (line - name == 8 > - && __strncasecmp (name, "CONTINUE", 8) == 0) > - action = NSS_ACTION_CONTINUE; > - else if (line - name == 5 > - && __strncasecmp (name, "MERGE", 5) == 0) > - action = NSS_ACTION_MERGE; > - else > - goto finish; > - > - if (not) > - { > - /* Save the current action setting for this status, > - set them all to the given action, and reset this one. */ > - const lookup_actions save = new_service->actions[2 + status]; > - new_service->actions[2 + NSS_STATUS_TRYAGAIN] = action; > - new_service->actions[2 + NSS_STATUS_UNAVAIL] = action; > - new_service->actions[2 + NSS_STATUS_NOTFOUND] = action; > - new_service->actions[2 + NSS_STATUS_SUCCESS] = action; > - new_service->actions[2 + status] = save; > - } > - else > - new_service->actions[2 + status] = action; > - > - /* Skip white spaces. */ > - while (isspace (line[0])) > - ++line; > - } > - while (line[0] != ']'); > - > - /* Skip the ']'. */ > - ++line; > - } > - > - *nextp = new_service; > - nextp = &new_service->next; > - continue; > - > - finish: > - free (new_service); > - return result; > - } > -} > - > -static name_database_entry * > -nss_getline (char *line) > -{ > - const char *name; > - name_database_entry *result; > - size_t len; > - > - /* Ignore leading white spaces. ATTENTION: this is different from > - what is implemented in Solaris. The Solaris man page says a line > - beginning with a white space character is ignored. We regard > - this as just another misfeature in Solaris. */ > - while (isspace (line[0])) > - ++line; > - > - /* Recognize ` ":"'. */ > - name = line; > - while (line[0] != '\0' && !isspace (line[0]) && line[0] != ':') > - ++line; > - if (line[0] == '\0' || name == line) > - /* Syntax error. */ > - return NULL; > - *line++ = '\0'; > - > - len = strlen (name) + 1; > - > - result = (name_database_entry *) malloc (sizeof (name_database_entry) + len); > - if (result == NULL) > - return NULL; > - > - /* Save the database name. */ > - memcpy (result->name, name, len); > - > - /* Parse the list of services. */ > - result->service = nss_parse_service_list (line); > - > - result->next = NULL; > - return result; > -} > - > - > -#if !defined DO_STATIC_NSS || defined SHARED > -static service_library * > -nss_new_service (name_database *database, const char *name) > -{ > - service_library **currentp = &database->library; > - > - while (*currentp != NULL) > - { > - if (strcmp ((*currentp)->name, name) == 0) > - return *currentp; > - currentp = &(*currentp)->next; > - } > - > - /* We have to add the new service. */ > - *currentp = (service_library *) malloc (sizeof (service_library)); > - if (*currentp == NULL) > - return NULL; > - > - (*currentp)->name = name; > - (*currentp)->lib_handle = NULL; > - (*currentp)->next = NULL; > - > - return *currentp; > -} > -#endif > - > - > -#if defined SHARED && defined USE_NSCD > -/* Load all libraries for the service. */ > -static void > -nss_load_all_libraries (const char *service, const char *def) > -{ > - service_user *ni = NULL; > - > - if (__nss_database_lookup2 (service, NULL, def, &ni) == 0) > - while (ni != NULL) > - { > - nss_load_library (ni); > - ni = ni->next; > - } > -} > - > - > -/* Called by nscd and nscd alone. */ > -void > -__nss_disable_nscd (void (*cb) (size_t, struct traced_file *)) > -{ > -# ifdef PTR_MANGLE > - PTR_MANGLE (cb); > -# endif > - nscd_init_cb = cb; > - is_nscd = true; > - > - /* Find all the relevant modules so that the init functions are called. */ > - nss_load_all_libraries ("passwd", DEFAULT_CONFIG); > - nss_load_all_libraries ("group", DEFAULT_CONFIG); > - nss_load_all_libraries ("hosts", "dns [!UNAVAIL=return] files"); > - nss_load_all_libraries ("services", NULL); > - > - /* Disable all uses of NSCD. */ > - __nss_not_use_nscd_passwd = -1; > - __nss_not_use_nscd_group = -1; > - __nss_not_use_nscd_hosts = -1; > - __nss_not_use_nscd_services = -1; > - __nss_not_use_nscd_netgroup = -1; > -} > -#endif > - > -static void > -free_database_entries (name_database_entry *entry) > -{ > - while (entry != NULL) > - { > - name_database_entry *olde = entry; > - service_user *service = entry->service; > - > - while (service != NULL) > - { > - service_user *olds = service; > - > - if (service->known != NULL) > - __tdestroy (service->known, free); > - > - service = service->next; > - free (olds); > - } > - > - entry = entry->next; > - free (olde); > - } > -} > - > -/* Free all resources if necessary. */ > -libc_freeres_fn (free_defconfig) > -{ > - name_database_entry *entry = defconfig_entries; > - > - if (entry == NULL) > - /* defconfig was not used. */ > - return; > - > - /* Don't disturb ongoing other threads (if there are any). */ > - defconfig_entries = NULL; > - > - free_database_entries (entry); > -} > - > -libc_freeres_fn (free_mem) > -{ > - name_database *top = service_table; > - service_library *library; > - > - if (top == NULL) > - /* Maybe we have not read the nsswitch.conf file. */ > - return; > - > - /* Don't disturb ongoing other threads (if there are any). */ > - service_table = NULL; > - > - free_database_entries (top->entry); > - > - library = top->library; > - while (library != NULL) > - { > - service_library *oldl = library; > - > - if (library->lib_handle && library->lib_handle != (void *) -1l) > - __libc_dlclose (library->lib_handle); > - > - library = library->next; > - free (oldl); > - } > - > - free (top); > + return __nss_module_get_function (ni->module, fct_name); > } > +libc_hidden_def (__nss_lookup_function) OK. > diff --git a/nss/nsswitch.h b/nss/nsswitch.h > index eaf81587d6..7e957d061b 100644 > --- a/nss/nsswitch.h > +++ b/nss/nsswitch.h > @@ -36,6 +36,7 @@ typedef enum > NSS_ACTION_MERGE > } lookup_actions; > > +struct nss_action; > > typedef struct service_library > { > @@ -58,6 +59,7 @@ typedef struct > } known_function; > > > +#ifdef DJ > typedef struct service_user > { > /* And the link to the next entry. */ > @@ -71,11 +73,14 @@ typedef struct service_user > /* Name of the service (`files', `dns', `nis', ...). */ > char name[0]; > } service_user; > +#endif Delete. > > /* To access the action based on the status value use this macro. */ > -#define nss_next_action(ni, status) ((ni)->actions[2 + status]) > +#define old_nss_next_action(ni, status) ((ni)->actions[2 + status]) > +#define nss_next_action(ni, status) nss_action_get (ni, status) > > > +#ifdef DJ > typedef struct name_database_entry > { > /* And the link to the next entry. */ > @@ -94,6 +99,7 @@ typedef struct name_database > /* List of libraries with service implementation. */ > service_library *library; > } name_database; > +#endif Delete. > > > #ifdef USE_NSCD > @@ -127,13 +133,13 @@ extern bool __nss_database_custom[NSS_DBSIDX_max] attribute_hidden; > than one function can use the database. */ > extern int __nss_database_lookup2 (const char *database, > const char *alternative_name, > - const char *defconfig, service_user **ni); > + const char *defconfig, struct nss_action **ni); > libc_hidden_proto (__nss_database_lookup2) > > /* Put first function with name FCT_NAME for SERVICE in FCTP. The > position is remembered in NI. The function returns a value < 0 if > an error occurred or no such function exists. */ > -extern int __nss_lookup (service_user **ni, const char *fct_name, > +extern int __nss_lookup (struct nss_action **ni, const char *fct_name, > const char *fct2_name, void **fctp); > libc_hidden_proto (__nss_lookup) > > @@ -150,16 +156,16 @@ libc_hidden_proto (__nss_lookup) > services. In other words, only if all four lookup results have > the action RETURN associated the lookup process stops before the > natural end. */ > -extern int __nss_next2 (service_user **ni, const char *fct_name, > +extern int __nss_next2 (struct nss_action **ni, const char *fct_name, > const char *fct2_name, void **fctp, int status, > int all_values) attribute_hidden; > libc_hidden_proto (__nss_next2) > -extern int __nss_next (service_user **ni, const char *fct_name, void **fctp, > +extern int __nss_next (struct nss_action **ni, const char *fct_name, void **fctp, > int status, int all_values); > > /* Search for the service described in NI for a function named FCT_NAME > and return a pointer to this function if successful. */ > -extern void *__nss_lookup_function (service_user *ni, const char *fct_name); > +extern void *__nss_lookup_function (struct nss_action *ni, const char *fct_name); > libc_hidden_proto (__nss_lookup_function) > > > @@ -169,7 +175,7 @@ struct traced_file; > extern void __nss_disable_nscd (void (*) (size_t, struct traced_file *)); > > > -typedef int (*db_lookup_function) (service_user **, const char *, const char *, > +typedef int (*db_lookup_function) (struct nss_action **, const char *, const char *, > void **); > typedef enum nss_status (*setent_function) (int); > typedef enum nss_status (*endent_function) (void); > @@ -180,20 +186,20 @@ typedef int (*getent_r_function) (void *, char *, size_t, > > extern void __nss_setent (const char *func_name, > db_lookup_function lookup_fct, > - service_user **nip, service_user **startp, > - service_user **last_nip, int stayon, > + struct nss_action **nip, struct nss_action **startp, > + struct nss_action **last_nip, int stayon, > int *stayon_tmp, int res) > attribute_hidden; > extern void __nss_endent (const char *func_name, > db_lookup_function lookup_fct, > - service_user **nip, service_user **startp, > - service_user **last_nip, int res) > + struct nss_action **nip, struct nss_action **startp, > + struct nss_action **last_nip, int res) > attribute_hidden; > extern int __nss_getent_r (const char *getent_func_name, > const char *setent_func_name, > db_lookup_function lookup_fct, > - service_user **nip, service_user **startp, > - service_user **last_nip, int *stayon_tmp, > + struct nss_action **nip, struct nss_action **startp, > + struct nss_action **last_nip, int *stayon_tmp, > int res, > void *resbuf, char *buffer, size_t buflen, > void **result, int *h_errnop) > @@ -227,11 +233,15 @@ libc_hidden_proto (__nss_hostname_digits_dots) > > /* Prototypes for __nss_*_lookup2 functions. */ > #define DEFINE_DATABASE(arg) \ > - extern service_user *__nss_##arg##_database attribute_hidden; \ > - int __nss_##arg##_lookup2 (service_user **, const char *, \ > + extern struct nss_action *__nss_##arg##_database attribute_hidden; \ > + int __nss_##arg##_lookup2 (struct nss_action **, const char *, \ > const char *, void **); \ > libc_hidden_proto (__nss_##arg##_lookup2) > #include "databases.def" > #undef DEFINE_DATABASE > > +#include > +#include > +#include OK. Added to internal nsswitch.h. > + > #endif /* nsswitch.h */ > diff --git a/posix/tst-rfc3484-2.c b/posix/tst-rfc3484-2.c > index 8c64ac59ff..5f5ada9420 100644 > --- a/posix/tst-rfc3484-2.c > +++ b/posix/tst-rfc3484-2.c > @@ -58,7 +58,7 @@ _res_hconf_init (void) > #undef USE_NSCD > #include "../sysdeps/posix/getaddrinfo.c" > > -service_user *__nss_hosts_database attribute_hidden; > +nss_action_list __nss_hosts_database attribute_hidden; > > /* This is the beginning of the real test code. The above defines > (among other things) the function rfc3484_sort. */ > diff --git a/posix/tst-rfc3484-3.c b/posix/tst-rfc3484-3.c > index 1c61aaf844..d9ec5cc851 100644 > --- a/posix/tst-rfc3484-3.c > +++ b/posix/tst-rfc3484-3.c > @@ -58,7 +58,7 @@ _res_hconf_init (void) > #undef USE_NSCD > #include "../sysdeps/posix/getaddrinfo.c" > > -service_user *__nss_hosts_database attribute_hidden; > +nss_action_list __nss_hosts_database attribute_hidden; > > /* This is the beginning of the real test code. The above defines > (among other things) the function rfc3484_sort. */ > diff --git a/posix/tst-rfc3484.c b/posix/tst-rfc3484.c > index 8f45848e44..97d065b6bf 100644 > --- a/posix/tst-rfc3484.c > +++ b/posix/tst-rfc3484.c > @@ -58,7 +58,7 @@ _res_hconf_init (void) > #undef USE_NSCD > #include "../sysdeps/posix/getaddrinfo.c" > > -service_user *__nss_hosts_database attribute_hidden; > +nss_action_list __nss_hosts_database attribute_hidden; > > /* This is the beginning of the real test code. The above defines > (among other things) the function rfc3484_sort. */ > diff --git a/sunrpc/netname.c b/sunrpc/netname.c > index 61d82ca31a..aa64362b4b 100644 > --- a/sunrpc/netname.c > +++ b/sunrpc/netname.c > @@ -145,9 +145,7 @@ int > netname2user (const char netname[MAXNETNAMELEN + 1], uid_t * uidp, gid_t * gidp, > int *gidlenp, gid_t * gidlist) > { > - static service_user *startp; > - static netname2user_function start_fct; > - service_user *nip; > + nss_action_list nip; > union > { > netname2user_function f; > @@ -156,22 +154,7 @@ netname2user (const char netname[MAXNETNAMELEN + 1], uid_t * uidp, gid_t * gidp, > enum nss_status status = NSS_STATUS_UNAVAIL; > int no_more; > > - if (startp == NULL) > - { > - no_more = __nss_publickey_lookup2 (&nip, "netname2user", NULL, &fct.ptr); > - if (no_more) > - startp = (service_user *) - 1; > - else > - { > - startp = nip; > - start_fct = fct.f; > - } > - } > - else > - { > - fct.f = start_fct; > - no_more = (nip = startp) == (service_user *) - 1; > - } > + no_more = __nss_publickey_lookup2 (&nip, "netname2user", NULL, &fct.ptr); OK. > > while (!no_more) > { > diff --git a/sunrpc/publickey.c b/sunrpc/publickey.c > index 2fa0252d5b..63866ef900 100644 > --- a/sunrpc/publickey.c > +++ b/sunrpc/publickey.c > @@ -34,9 +34,7 @@ typedef int (*secret_function) (const char *, char *, const char *, int *); > int > getpublickey (const char *name, char *key) > { > - static service_user *startp; > - static public_function start_fct; > - service_user *nip; > + nss_action_list nip; > union > { > public_function f; > @@ -45,22 +43,7 @@ getpublickey (const char *name, char *key) > enum nss_status status = NSS_STATUS_UNAVAIL; > int no_more; > > - if (startp == NULL) > - { > - no_more = __nss_publickey_lookup2 (&nip, "getpublickey", NULL, &fct.ptr); > - if (no_more) > - startp = (service_user *) -1; > - else > - { > - startp = nip; > - start_fct = fct.f; > - } > - } > - else > - { > - fct.f = start_fct; > - no_more = (nip = startp) == (service_user *) -1; > - } > + no_more = __nss_publickey_lookup2 (&nip, "getpublickey", NULL, &fct.ptr); > > while (! no_more) > { > @@ -77,9 +60,7 @@ libc_hidden_nolink_sunrpc (getpublickey, GLIBC_2_0) > int > getsecretkey (const char *name, char *key, const char *passwd) > { > - static service_user *startp; > - static secret_function start_fct; > - service_user *nip; > + nss_action_list nip; > union > { > secret_function f; > @@ -88,22 +69,7 @@ getsecretkey (const char *name, char *key, const char *passwd) > enum nss_status status = NSS_STATUS_UNAVAIL; > int no_more; > > - if (startp == NULL) > - { > - no_more = __nss_publickey_lookup2 (&nip, "getsecretkey", NULL, &fct.ptr); > - if (no_more) > - startp = (service_user *) -1; > - else > - { > - startp = nip; > - start_fct = fct.f; > - } > - } > - else > - { > - fct.f = start_fct; > - no_more = (nip = startp) == (service_user *) -1; > - } > + no_more = __nss_publickey_lookup2 (&nip, "getsecretkey", NULL, &fct.ptr); > > while (! no_more) > { > diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c > index ed04e564f9..84d3ce1957 100644 > --- a/sysdeps/posix/getaddrinfo.c > +++ b/sysdeps/posix/getaddrinfo.c > @@ -307,7 +307,7 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, > memory allocation failure. The returned string is allocated on the > heap; the caller has to free it. */ > static char * > -getcanonname (service_user *nip, struct gaih_addrtuple *at, const char *name) > +getcanonname (nss_action_list nip, struct gaih_addrtuple *at, const char *name) > { > nss_getcanonname_r *cfct = __nss_lookup_function (nip, "getcanonname_r"); > char *s = (char *) name; > @@ -538,7 +538,7 @@ gaih_inet (const char *name, const struct gaih_service *service, > struct gaih_addrtuple **pat = &at; > int no_data = 0; > int no_inet6_data = 0; > - service_user *nip; > + nss_action_list nip; > enum nss_status inet6_status = NSS_STATUS_UNAVAIL; > enum nss_status status = NSS_STATUS_UNAVAIL; > int no_more; > @@ -905,10 +905,9 @@ gaih_inet (const char *name, const struct gaih_service *service, > if (nss_next_action (nip, status) == NSS_ACTION_RETURN) > break; > > - if (nip->next == NULL) > + nip ++; > + if (nip->module == NULL) > no_more = -1; > - else > - nip = nip->next; > } > > __resolv_context_put (res_ctx); > -- Cheers, Carlos.