diff options
author | Ulrich Drepper <drepper@redhat.com> | 1996-11-10 02:21:51 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 1996-11-10 02:21:51 +0000 |
commit | 2303f5fdd96d7bec2dea11b41cc0c07eddd50979 (patch) | |
tree | 9e840de64f211d9d2244f490be68f1229dfdad81 /inet/getnetgrent_r.c | |
parent | fe92af183235942f1aea400ce57a173d8f3235d6 (diff) | |
download | glibc-2303f5fdd96d7bec2dea11b41cc0c07eddd50979.tar.gz glibc-2303f5fdd96d7bec2dea11b41cc0c07eddd50979.tar.xz glibc-2303f5fdd96d7bec2dea11b41cc0c07eddd50979.zip |
update from main archive 961109 cvs/libc-961110
Sun Nov 10 02:37:15 1996 Ulrich Drepper <drepper@cygnus.com> * inet/gethstent_r.c: Update copyright. * nss/getXXbyYY_r.c: Likewise. * nss/nsswitch.c: Likewise. * nss/getXXent_r.c: Likewise. * nss/nss_files/files-XXX.c: Likewise. * nss/nss_files/files-netgroup.c: Likewise. * nss/nss_files/files-parse.c: Likewise. * nss/getXXent_r.c: Change implementation. It's not necessary to call all setXXent functions. Just find first available and when necessary let getXXent_r call the others. * nss/nss_files/files-XXX.c: Make really reentrant. Now calls of getXXent and getXXbyYY can be mixed. The cursor for traversing the database with getXXent will be remembered. * stdlib/test-canon.c (cwd): Change size to PATH_MAX. Sat Nov 9 15:34:48 1996 Ulrich Drepper <drepper@cygnus.com> * sysdeps/unix/sysv/linux/Dist: Add sys/mtio.h. * sysdeps/unix/sysv/linux/sys/mtio.h: New file. * signal/signal.h [__USE_BSD]: Add prototype for siggetmask. Fri Nov 8 13:29:30 1996 Ulrich Drepper <drepper@cygnus.com> * ctype/ctype.h (__isascii): Don't test for seventh bit not to be set. Instead for none beside the first seven bits to be set. X/Open allows the argument to be an `int' value. Reported by Alain Williams <addw@phcomp.co.uk>. (toascii, isascii): Define macro also when __USE_XOPEN. * sysdeps/posix/fpathconf.c: Use fstatfs to compute NAME_MAX, not PATH_MAX. Thu Nov 7 03:04:29 1996 Ulrich Drepper <drepper@cygnus.com> * nss/getXXXent_r.c (SETFUNC_NAME): Reset `nip' after loop to NULL so that GETFUNC will see first entry. (ENDFUNC_NAME): Likewise. Rewrite Netgroups implementation to avoid global data. * inet/netgroup.h: Add definition of name_list and struct __netgrent. Add prototypes for internal netgroup functions. * nss/nss_files/files-netgroup.c (_nss_files_setnetgrent): Take extra argument and use the included data instead of global vars. (_nss_files_endnetgrent): Likewise. (_nss_netgroup_parseline): Change to be static and use data included in the RESULT structure. * inet/getnetgrent_r.c (startp): Move into setup function. (known_groups, needed_groups): new part of the __netgrent sruct. (freememory): Take extra argument and use included data. (__internal_endnetgrent): Likewise. (internal_setnetgrent): Renamed to __internal_setnetgrent_reuse and take extra argument. (__internal_setnetgrent): New function. Call __internal_setnetgrent_reuse after calling free_memory. (setnetgrent): Only call __internal_setnetgrent. (__getnetgrent_r): Split into two functions. __getnetgrent_r calls __internal_getnetgrent after locking. (innetgr): Use dynamic data only. I.e., innetgr now is fully reentrant. Thu Nov 7 00:15:14 1996 Ulrich Drepper <drepper@cygnus.com> * sysdeps/stub/setenv.c: Correct typo: unseenv -> unsetenv. Reported by Joshua Cowan <jcowan@jcowan.reslife.okstate.edu>. Wed Nov 6 13:13:37 1996 Ulrich Drepper <drepper@cygnus.com> * manual/creature.texi: Document that _GNU_SOURCE is no longer the default when no *_SOURCE macro is given. Reported by Karsten Weiss <karsten@addx.au.s.shuttle.de>. * NOTES: remade from manual/creature.texi. * manual/libc.texinfo: Add back line about GPL translation which somehow got lost. * Make-dist (dist.tar): Depend on README being updated. * rellns-sh: Correct thinko in removing leading /. Reported by Andreas Jaeger <aj@arthur.pfalz.de>. * pwd/fgetpwent_r.c: Recognize lines containing only names starting with `+' or `-' in parser. * grp/fgetgrent_r.c: Likewise. * shadow/sgetspent_r.c: Likewise. * nss/nss_files/files-spwd.c: Don't accept entries starting with `+' or `-'. * sysdeps/stub/lchown.c: New file.
Diffstat (limited to 'inet/getnetgrent_r.c')
-rw-r--r-- | inet/getnetgrent_r.c | 155 |
1 files changed, 89 insertions, 66 deletions
diff --git a/inet/getnetgrent_r.c b/inet/getnetgrent_r.c index 7288dbeb4c..1848ad7f35 100644 --- a/inet/getnetgrent_r.c +++ b/inet/getnetgrent_r.c @@ -18,6 +18,7 @@ Boston, MA 02111-1307, USA. */ #include <libc-lock.h> #include <netdb.h> +#include <string.h> #include "netgroup.h" #include "nsswitch.h" @@ -28,18 +29,10 @@ __libc_lock_define_initialized (static, lock) /* This handle for the NSS data base is shared between all set/get/endXXXent functions. */ static service_user *nip; -/* Remember the first service_entry, it's always the same. */ -static service_user *startp; -/* A netgroup can consist of names of other netgroups. We have to - track which netgroups were read and which still have to be read. */ -struct name_list -{ - const char *name; - struct name_list *next; -}; -struct name_list *known_groups; -struct name_list *needed_groups; +/* The whole information for the set/get/endnetgrent functions are + kept in this structure. */ +static struct __netgrent dataset; /* The lookup function for the first entry of this service. */ @@ -52,7 +45,10 @@ extern int __nss_netgroup_lookup (service_user **nip, const char *name, static enum nss_status setup (void **fctp, const char *func_name, int all) { + /* Remember the first service_entry, it's always the same. */ + static service_user *startp = NULL; int no_more; + if (startp == NULL) { no_more = __nss_netgroup_lookup (&nip, func_name, fctp); @@ -74,29 +70,29 @@ setup (void **fctp, const char *func_name, int all) /* Free used memory. */ static void -free_memory (void) +free_memory (struct __netgrent *data) { - while (known_groups != NULL) + while (data->known_groups != NULL) { - struct name_list *tmp = known_groups; - known_groups = known_groups->next; + struct name_list *tmp = data->known_groups; + data->known_groups = data->known_groups->next; free (tmp->name); free (tmp); } - while (needed_groups != NULL) + while (data->needed_groups != NULL) { - struct name_list *tmp = needed_groups; - needed_groups = needed_groups->next; + struct name_list *tmp = data->needed_groups; + data->needed_groups = data->needed_groups->next; free (tmp->name); free (tmp); } } static int -internal_setnetgrent (const char *group) +__internal_setnetgrent_reuse (const char *group, struct __netgrent *datap) { - enum nss_status (*fct) (const char *); + enum nss_status (*fct) (const char *, struct __netgrent *); enum nss_status status = NSS_STATUS_UNAVAIL; struct name_list *new_elem; int no_more; @@ -106,7 +102,7 @@ internal_setnetgrent (const char *group) while (! no_more) { /* Ignore status, we force check in `__nss_next'. */ - status = (*fct) (group); + status = (*fct) (group, datap); no_more = __nss_next (&nip, "setnetgrent", (void **) &fct, status, 0); } @@ -121,24 +117,30 @@ internal_setnetgrent (const char *group) } else { - new_elem->next = known_groups; - known_groups = new_elem; + new_elem->next = datap->known_groups; + datap->known_groups = new_elem; } return status == NSS_STATUS_SUCCESS; } int +__internal_setnetgrent (const char *group, struct __netgrent *datap) +{ + /* Free list of all netgroup names from last run. */ + free_memory (datap); + + return __internal_setnetgrent_reuse (group, datap); +} + +int setnetgrent (const char *group) { int result; __libc_lock_lock (lock); - /* Free list of all netgroup names from last run. */ - free_memory (); - - result = internal_setnetgrent (group); + result = __internal_setnetgrent (group, &dataset); __libc_lock_unlock (lock); @@ -147,14 +149,12 @@ setnetgrent (const char *group) void -endnetgrent (void) +__internal_endnetgrent (struct __netgrent *datap) { service_user *old_nip; - enum nss_status (*fct) (void); + enum nss_status (*fct) (struct __netgrent *); int no_more; - __libc_lock_lock (lock); - /* Remember which was the last used service. */ old_nip = nip; @@ -163,66 +163,75 @@ endnetgrent (void) while (! no_more) { /* Ignore status, we force check in `__nss_next'. */ - (void) (*fct) (); + (void) (*fct) (datap); no_more = (nip == old_nip || __nss_next (&nip, "endnetgrent", (void **) &fct, 0, 1)); } /* Now free list of all netgroup names from last run. */ - free_memory (); + free_memory (datap); +} + + +void +endnetgrent (void) +{ + __libc_lock_lock (lock); + + __internal_endnetgrent (&dataset); __libc_lock_unlock (lock); } int -__getnetgrent_r (char **hostp, char **userp, char **domainp, - char *buffer, size_t buflen) +__internal_getnetgrent (char **hostp, char **userp, char **domainp, + struct __netgrent *datap, + char *buffer, size_t buflen) { enum nss_status (*fct) (struct __netgrent *, char *, int); - struct __netgrent result; int no_more; /* Initialize status to return if no more functions are found. */ enum nss_status status = NSS_STATUS_NOTFOUND; - __libc_lock_lock (lock); - /* Run through available functions, starting with the same function last run. We will repeat each function as long as it succeeds, and then go on to the next service action. */ no_more = setup ((void **) &fct, "getnetgrent_r", 0); while (! no_more) { - status = (*fct) (&result, buffer, buflen); + status = (*fct) (datap, buffer, buflen); if (status == NSS_STATUS_RETURN) { /* This was the last one for this group. Look at next group if available. */ int found = 0; - while (needed_groups != NULL && ! found) + while (datap->needed_groups != NULL && ! found) { - struct name_list *tmp = needed_groups; - needed_groups = needed_groups->next; - tmp->next = known_groups; - known_groups = tmp; + struct name_list *tmp = datap->needed_groups; + datap->needed_groups = datap->needed_groups->next; + tmp->next = datap->known_groups; + datap->known_groups = tmp; - found = internal_setnetgrent (known_groups->name); + found = __internal_setnetgrent_reuse (datap->known_groups->name, + datap); } if (found) continue; } - else if (status == NSS_STATUS_SUCCESS && result.type == group_val) + else if (status == NSS_STATUS_SUCCESS && datap->type == group_val) { /* The last entry was a name of another netgroup. */ struct name_list *namep; /* Ignore if we've seen the name before. */ - for (namep = known_groups; namep != NULL; namep = namep->next) - if (strcmp (result.val.group, namep->name) == 0) + for (namep = datap->known_groups; namep != NULL; + namep = namep->next) + if (strcmp (datap->val.group, namep->name) == 0) break; if (namep != NULL) /* Really ignore. */ @@ -230,7 +239,7 @@ __getnetgrent_r (char **hostp, char **userp, char **domainp, namep = (struct name_list *) malloc (sizeof (struct name_list)); if (namep == NULL - || (namep->name = __strdup (result.val.group)) == NULL) + || (namep->name = __strdup (datap->val.group)) == NULL) { /* We are out of memory. */ if (namep != NULL) @@ -239,8 +248,8 @@ __getnetgrent_r (char **hostp, char **userp, char **domainp, } else { - namep->next = needed_groups; - needed_groups = namep; + namep->next = datap->needed_groups; + datap->needed_groups = namep; /* And get the next entry. */ continue; } @@ -251,14 +260,29 @@ __getnetgrent_r (char **hostp, char **userp, char **domainp, if (status == NSS_STATUS_SUCCESS) { - *hostp = result.val.triple.host; - *userp = result.val.triple.user; - *domainp = result.val.triple.domain; + *hostp = datap->val.triple.host; + *userp = datap->val.triple.user; + *domainp = datap->val.triple.domain; } + return status == NSS_STATUS_SUCCESS ? 1 : 0; +} + +/* The real entry point. */ +int +__getnetgrent_r (char **hostp, char **userp, char **domainp, + char *buffer, size_t buflen) +{ + enum nss_status status; + + __libc_lock_lock (lock); + + status = __internal_getnetgrent (hostp, userp, domainp, &dataset, + buffer, buflen); + __libc_lock_unlock (lock); - return status == NSS_STATUS_SUCCESS ? 1 : 0; + return status; } weak_alias (__getnetgrent_r, getnetgrent_r) @@ -267,18 +291,16 @@ int innetgr (const char *netgroup, const char *host, const char *user, const char *domain) { - int (*setfct) (const char *); - void (*endfct) (void); + int (*setfct) (const char *, struct __netgrent *); + void (*endfct) (struct __netgrent *); int (*getfct) (struct __netgrent *, char *, int); + struct name_list *known; + struct name_list *needed; int result = 0; int no_more; - struct name_list *known = NULL; - struct name_list *needed = NULL; const char *current_group = netgroup; int real_entry = 0; - __libc_lock_lock (lock); - /* Walk through the services until we found an answer or we shall not work further. We can do some optimization here. Since all services must provide the `setnetgrent' function we can do all @@ -289,14 +311,17 @@ innetgr (const char *netgroup, const char *host, const char *user, while (! no_more) { enum nss_status status; + struct __netgrent entry; + + /* Clear the space for the netgroup data. */ + bzero (&entry, sizeof (entry)); /* Open netgroup. */ - status = (*setfct) (current_group); + status = (*setfct) (current_group, &entry); if (status == NSS_STATUS_SUCCESS && __nss_lookup (&nip, "getnetgrent_r", (void **) &getfct) == 0) { char buffer[1024]; - struct __netgrent entry; while ((*getfct) (&entry, buffer, sizeof buffer) == NSS_STATUS_SUCCESS) @@ -356,7 +381,7 @@ innetgr (const char *netgroup, const char *host, const char *user, /* Free all resources of the service. */ if (__nss_lookup (&nip, "endnetgrent", (void **) &endfct) == 0) - (*endfct) (); + (*endfct) (&entry); /* Look for the next service. */ no_more = __nss_next (&nip, "setnetgrent", @@ -377,8 +402,6 @@ innetgr (const char *netgroup, const char *host, const char *user, break; } - __libc_lock_unlock (lock); - /* Free the memory. */ while (known != NULL) { |