Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-3]: src/lib/libc/gen Pull up revision 1.67 (requested by lukem in...



details:   https://anonhg.NetBSD.org/src/rev/912a96f20658
branches:  netbsd-3
changeset: 576571:912a96f20658
user:      tron <tron%NetBSD.org@localhost>
date:      Mon Jul 11 21:22:27 2005 +0000

description:
Pull up revision 1.67 (requested by lukem in ticket #540):
PR/29849, PR/29850: Add getpwent_r and getgrent_r

diffstat:

 lib/libc/gen/getpwent.c |  250 +++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 238 insertions(+), 12 deletions(-)

diffs (truncated from 321 to 300 lines):

diff -r 122850c3ac51 -r 912a96f20658 lib/libc/gen/getpwent.c
--- a/lib/libc/gen/getpwent.c   Mon Jul 11 21:22:21 2005 +0000
+++ b/lib/libc/gen/getpwent.c   Mon Jul 11 21:22:27 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: getpwent.c,v 1.66 2005/02/28 00:40:05 lukem Exp $      */
+/*     $NetBSD: getpwent.c,v 1.66.2.1 2005/07/11 21:22:27 tron Exp $   */
 
 /*-
  * Copyright (c) 1997-2000, 2004-2005 The NetBSD Foundation, Inc.
@@ -95,7 +95,7 @@
 #if 0
 static char sccsid[] = "@(#)getpwent.c 8.2 (Berkeley) 4/27/95";
 #else
-__RCSID("$NetBSD: getpwent.c,v 1.66 2005/02/28 00:40:05 lukem Exp $");
+__RCSID("$NetBSD: getpwent.c,v 1.66.2.1 2005/07/11 21:22:27 tron Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -137,6 +137,7 @@
 #ifdef __weak_alias
 __weak_alias(endpwent,_endpwent)
 __weak_alias(getpwent,_getpwent)
+__weak_alias(getpwent_r,_getpwent_r)
 __weak_alias(getpwnam,_getpwnam)
 __weak_alias(getpwnam_r,_getpwnam_r)
 __weak_alias(getpwuid,_getpwuid)
@@ -566,6 +567,32 @@
 
 /*ARGSUSED*/
 static int
+_files_getpwent_r(void *nsrv, void *nscb, va_list ap)
+{
+       int             *retval = va_arg(ap, int *);
+       struct passwd   *pw     = va_arg(ap, struct passwd *);
+       char            *buffer = va_arg(ap, char *);
+       size_t           buflen = va_arg(ap, size_t);
+       struct passwd  **result = va_arg(ap, struct passwd **);
+
+       int     rv;
+
+       _DIAGASSERT(retval != NULL);
+       _DIAGASSERT(pw != NULL);
+       _DIAGASSERT(buffer != NULL);
+       _DIAGASSERT(result != NULL);
+
+       rv = _files_pwscan(retval, pw, buffer, buflen, &_files_state,
+           _PW_KEYBYNUM, NULL, 0);
+       if (rv == NS_SUCCESS)
+               *result = pw;
+       else
+               *result = NULL;
+       return rv;
+}
+
+/*ARGSUSED*/
+static int
 _files_getpwnam(void *nsrv, void *nscb, va_list ap)
 {
        struct passwd   **retval = va_arg(ap, struct passwd **);
@@ -868,6 +895,71 @@
        return rv;
 }
 
+/*ARGSUSED*/
+static int
+_dns_getpwent_r(void *nsrv, void *nscb, va_list ap)
+{
+       int             *retval = va_arg(ap, int *);
+       struct passwd   *pw     = va_arg(ap, struct passwd *);
+       char            *buffer = va_arg(ap, char *);
+       size_t           buflen = va_arg(ap, size_t);
+       struct passwd  **result = va_arg(ap, struct passwd **);
+
+       char    **hp, *ep;
+       int       rv;
+
+       _DIAGASSERT(retval != NULL);
+       _DIAGASSERT(pw != NULL);
+       _DIAGASSERT(buffer != NULL);
+       _DIAGASSERT(result != NULL);
+
+       *retval = 0;
+
+       if (_dns_state.num == -1)                       /* exhausted search */
+               return NS_NOTFOUND;
+
+       if (_dns_state.context == NULL) {
+                       /* only start if Hesiod not setup */
+               rv = _dns_start(&_dns_state);
+               if (rv != NS_SUCCESS)
+                       return rv;
+       }
+
+ next_dns_entry:
+       hp = NULL;
+       rv = NS_NOTFOUND;
+
+                                                       /* find passwd-NNN */
+       snprintf(buffer, buflen, "passwd-%u", _dns_state.num);
+       _dns_state.num++;
+
+       hp = hesiod_resolve(_dns_state.context, buffer, "passwd");
+       if (hp == NULL) {
+               if (errno == ENOENT)
+                       _dns_state.num = -1;
+               else
+                       rv = NS_UNAVAIL;
+       } else {
+               if ((ep = strchr(hp[0], '\n')) != NULL)
+                       *ep = '\0';                     /* clear trailing \n */
+                                                       /* validate line */
+               if (_pw_parse(hp[0], pw, buffer, buflen, 1))
+                       rv = NS_SUCCESS;
+               else {                          /* dodgy entry, try again */
+                       hesiod_free_list(_dns_state.context, hp);
+                       goto next_dns_entry;
+               }
+       }
+
+       if (hp)
+               hesiod_free_list(_dns_state.context, hp);
+       if (rv == NS_SUCCESS)
+               *result = pw;
+       else
+               *result = NULL;
+       return rv;
+}
+
 static const char *_dns_uid_zones[] = {
        "uid",
        "passwd",
@@ -1309,6 +1401,91 @@
 
 /*ARGSUSED*/
 static int
+_nis_getpwent_r(void *nsrv, void *nscb, va_list ap)
+{
+       int             *retval = va_arg(ap, int *);
+       struct passwd   *pw     = va_arg(ap, struct passwd *);
+       char            *buffer = va_arg(ap, char *);
+       size_t           buflen = va_arg(ap, size_t);
+       struct passwd  **result = va_arg(ap, struct passwd **);
+
+       char    *key, *data;
+       int     keylen, datalen, rv, nisr;
+
+       _DIAGASSERT(retval != NULL);
+       _DIAGASSERT(pw != NULL);
+       _DIAGASSERT(buffer != NULL);
+       _DIAGASSERT(result != NULL);
+
+       *retval = 0;
+
+       if (_nis_state.done)                            /* exhausted search */
+               return NS_NOTFOUND;
+       if (_nis_state.domain == NULL) {
+                                       /* only start if NIS not setup */
+               rv = _nis_start(&_nis_state);
+               if (rv != NS_SUCCESS)
+                       return rv;
+       }
+
+ next_nis_entry:
+       key = NULL;
+       data = NULL;
+       rv = NS_NOTFOUND;
+
+       if (_nis_state.current) {                       /* already searching */
+               nisr = yp_next(_nis_state.domain, PASSWD_BYNAME(&_nis_state),
+                   _nis_state.current, _nis_state.currentlen,
+                   &key, &keylen, &data, &datalen);
+               free(_nis_state.current);
+               _nis_state.current = NULL;
+               switch (nisr) {
+               case 0:
+                       _nis_state.current = key;
+                       _nis_state.currentlen = keylen;
+                       key = NULL;
+                       break;
+               case YPERR_NOMORE:
+                       _nis_state.done = 1;
+                       goto nisent_out;
+               default:
+                       rv = NS_UNAVAIL;
+                       goto nisent_out;
+               }
+       } else {                                        /* new search */
+               if (yp_first(_nis_state.domain, PASSWD_BYNAME(&_nis_state),
+                   &_nis_state.current, &_nis_state.currentlen,
+                   &data, &datalen)) {
+                       rv = NS_UNAVAIL;
+                       goto nisent_out;
+               }
+       }
+
+       data[datalen] = '\0';                           /* clear trailing \n */
+                                                       /* validate line */
+       if (_nis_parse(data, pw, buffer, buflen, &_nis_state))
+               rv = NS_SUCCESS;
+       else {                                  /* dodgy entry, try again */
+               if (key)
+                       free(key);
+               free(data);
+               goto next_nis_entry;
+       }
+
+ nisent_out:
+       if (key)
+               free(key);
+       if (data)
+               free(data);
+       if (rv == NS_SUCCESS)
+               *result = pw;
+       else
+               *result = NULL;
+       return rv;
+}
+
+/*ARGSUSED*/
+static int
 _nis_getpwuid(void *nsrv, void *nscb, va_list ap)
 {
        struct passwd   **retval = va_arg(ap, struct passwd **);
@@ -1662,8 +1839,8 @@
 {
        static const ns_dtab compatentdtab[] = {
                NS_FILES_CB(_passwdcompat_bad, "files")
-               NS_DNS_CB(_dns_getpwent, NULL)
-               NS_NIS_CB(_nis_getpwent, NULL)
+               NS_DNS_CB(_dns_getpwent_r, NULL)
+               NS_NIS_CB(_nis_getpwent_r, NULL)
                NS_COMPAT_CB(_passwdcompat_bad, "compat")
                { 0 }
        };
@@ -1687,15 +1864,9 @@
 
        switch (search) {
        case _PW_KEYBYNUM:
-/* XXXREENTRANT: implement & use getpwent_r */
                rv = nsdispatch(NULL, compatentdtab,
-                   NSDB_PASSWD_COMPAT, "getpwent", __nsdefaultnis,
-                   &cpw);
-               if (rv == NS_SUCCESS &&
-                   ! _pw_copy(cpw, pw, buffer, buflen, NULL, 0)) {
-                       errno = ERANGE;
-                       rv = NS_UNAVAIL;
-               }
+                   NSDB_PASSWD_COMPAT, "getpwent_r", __nsdefaultnis,
+                   &crv, pw, buffer, buflen, &cpw);
                break;
        case _PW_KEYBYNAME:
                _DIAGASSERT(name != NULL);
@@ -2024,6 +2195,33 @@
 
 /*ARGSUSED*/
 static int
+_compat_getpwent_r(void *nsrv, void *nscb, va_list ap)
+{
+       int             *retval = va_arg(ap, int *);
+       struct passwd   *pw     = va_arg(ap, struct passwd *);
+       char            *buffer = va_arg(ap, char *);
+       size_t           buflen = va_arg(ap, size_t);
+       struct passwd  **result = va_arg(ap, struct passwd **);
+
+       int             rv;
+
+       _DIAGASSERT(retval != NULL);
+       _DIAGASSERT(pw != NULL);
+       _DIAGASSERT(buffer != NULL);
+       _DIAGASSERT(result != NULL);
+
+       rv = _compat_pwscan(retval, pw, buffer, buflen, &_compat_state,
+           _PW_KEYBYNUM, NULL, 0);
+       if (rv == NS_SUCCESS)
+               *result = pw;
+       else
+               *result = NULL;
+       return rv;
+}
+
+
+/*ARGSUSED*/
+static int
 _compat_getpwnam(void *nsrv, void *nscb, va_list ap)
 {
        struct passwd   **retval = va_arg(ap, struct passwd **);
@@ -2158,6 +2356,34 @@
        return (r == NS_SUCCESS) ? retval : NULL;
 }
 
+int
+getpwent_r(struct passwd *pwd, char *buffer, size_t buflen,
+    struct passwd **result)
+{
+       int     r, retval;
+
+       static const ns_dtab dtab[] = {
+               NS_FILES_CB(_files_getpwent_r, NULL)
+               NS_DNS_CB(_dns_getpwent_r, NULL)
+               NS_NIS_CB(_nis_getpwent_r, NULL)



Home | Main Index | Thread Index | Old Index