* nss/nss_files/files-parse.c (parse_list): Reset ELT for elements
authorRoland McGrath <roland@gnu.org>
Tue, 25 Jun 1996 10:20:09 +0000 (10:20 +0000)
committerRoland McGrath <roland@gnu.org>
Tue, 25 Jun 1996 10:20:09 +0000 (10:20 +0000)
after the first!

* nss/nsswitch.c (__nss_database_lookup): If nsswitch.conf is missing
or doesn't mention DATABASE, use an internal default equivalent to
"DATABASE: compat [NOTFOUND=return] dns [NOTFOUND=return] files".
(nss_lookup_function): Call nss_new_service as needed.
(nss_parse_file): Don't bother calling nss_new_service here.

* grp/fgetgrent.c (LINE_PARSER): Pass zero SWALLOW arg for fields.
* pwd/fgetpwent.c: Likewise.

ChangeLog
grp/fgetgrent.c
nss/nss_files/files-parse.c
nss/nsswitch.c
pwd/fgetpwent.c

index 2721aa9..7630460 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 Tue Jun 25 02:59:11 1996  Roland McGrath  <roland@delasyd.gnu.ai.mit.edu>
 
+       * nss/nss_files/files-parse.c (parse_list): Reset ELT for elements
+       after the first!
+
+       * nss/nsswitch.c (__nss_database_lookup): If nsswitch.conf is missing
+       or doesn't mention DATABASE, use an internal default equivalent to
+       "DATABASE: compat [NOTFOUND=return] dns [NOTFOUND=return] files".
+       (nss_lookup_function): Call nss_new_service as needed.
+       (nss_parse_file): Don't bother calling nss_new_service here.
+
+       * grp/fgetgrent.c (LINE_PARSER): Pass zero SWALLOW arg for fields.
+       * pwd/fgetpwent.c: Likewise.
+
        * malloc/malloc.h: Declare malloc_object_allocated_size, malloc_walk.
        * malloc/Makefile (dist-routines): Add malloc-size, malloc-walk.
        * malloc/malloc-size.c: New file.
index 031ccb9..aced929 100644 (file)
@@ -31,9 +31,9 @@ struct grent_data {};
 #include "../nss/nss_files/files-parse.c"
 LINE_PARSER
 (
- STRING_FIELD (result->gr_name, ISCOLON);
- STRING_FIELD (result->gr_passwd, ISCOLON);
- INT_FIELD (result->gr_gid, ISCOLON, 10,);
+ STRING_FIELD (result->gr_name, ISCOLON, 0);
+ STRING_FIELD (result->gr_passwd, ISCOLON, 0);
+ INT_FIELD (result->gr_gid, ISCOLON, 0, 10,);
 )
 
 
index a93bee1..ff67e97 100644 (file)
@@ -137,6 +137,7 @@ parse_list (char *line, struct parser_data *data, int datalen)
              do
                ++line;
              while (TRAILING_LIST_SEPARATOR_P (*line));
+             elt = line;
            }
          else if (*line == '\0' || *line == '\n')
            {
index 4c2ccf6..2b3ae0b 100644 (file)
@@ -86,29 +86,50 @@ nss_init (void)
 int
 __nss_database_lookup (const char *database, service_user **ni)
 {
-  /* Return first `service_user' entry for DATABASE.
-     XXX Will use perfect hashing function for known databases.  */
-  name_database_entry *entry;
+  if (nss_initialized == 0)
+    nss_init ();
 
   /* Test whether configuration data is available.  */
-  if (service_table == NULL)
+  if (service_table)
     {
-      if (nss_initialized == 0)
-       nss_init ();
-
-      if (service_table == NULL)
-       return -1;
+      /* Return first `service_user' entry for DATABASE.
+        XXX Will use perfect hashing function for known databases.  */
+      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;
+           return 0;
+         }
     }
 
-  /* 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)
-      break;
-
-  if (entry == NULL || (*ni = entry->service) == NULL)
-    return -1;
-
+  /* No configuration data is available, either because nsswitch.conf
+     doesn't exist or because it doesn't have a line for this database.
+     Use a default equivalent to:
+       database: compat [NOTFOUND=return] dns [NOTFOUND=return] files
+     */
+  {
+#define DEFAULT_SERVICE(name, next)                                          \
+    static service_user default_##name =                                     \
+      {                                                                              \
+       #name,                                                                \
+       {                                                                     \
+         NSS_ACTION_CONTINUE,                                                \
+         NSS_ACTION_CONTINUE,                                                \
+         NSS_ACTION_RETURN,                                                  \
+         NSS_ACTION_RETURN,                                                  \
+       },                                                                    \
+       NULL, NULL,                                                           \
+       next                                                                  \
+      }
+    DEFAULT_SERVICE (files, NULL);
+    DEFAULT_SERVICE (dns, &default_files);
+    DEFAULT_SERVICE (compat, &default_dns);
+    *ni = &default_compat;
+  }
   return 0;
 }
 
@@ -196,15 +217,26 @@ nss_lookup_function (service_user *ni, const char *fct_name)
   if (nss_find_entry (&ni->known, fct_name, &result) >= 0)
     return result;
 
-  /* If we failed to allocate the needed data structures for the
-     service return an error.  This should only happen when we are out
-     of memory.  */
-  if (ni->library == NULL)
-    return NULL;
-
   /* We now modify global data.  Protect it.  */
   __libc_lock_lock (lock);
 
+  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)
+       {
+         /* This only happens when out of memory.  */
+         __libc_lock_unlock (lock);
+         return NULL;
+       }
+    }
+
   if (ni->library->lib_handle == NULL)
     {
       /* Load the shared library.  */
@@ -374,15 +406,6 @@ nss_parse_file (const char *fname)
   /* Close configuration file.  */
   fclose (fp);
 
-  /* Now create for each service we could use an entry in LIBRARY list.  */
-  for (last = result->entry; last != NULL; last = last->next)
-    {
-      service_user *runp;
-
-      for (runp = last->service; runp != NULL; runp = runp->next)
-       runp->library = nss_new_service (result, runp->name);
-    }
-
   return result;
 }
 
index ba9f834..c29e96e 100644 (file)
@@ -29,12 +29,12 @@ struct pwent_data {};
 #include "../nss/nss_files/files-parse.c"
 LINE_PARSER
 (
- STRING_FIELD (result->pw_name, ISCOLON);
- STRING_FIELD (result->pw_passwd, ISCOLON);
- INT_FIELD (result->pw_uid, ISCOLON, 10,);
- INT_FIELD (result->pw_gid, ISCOLON, 10,);
- STRING_FIELD (result->pw_gecos, ISCOLON);
- STRING_FIELD (result->pw_dir, ISCOLON);
+ STRING_FIELD (result->pw_name, ISCOLON, 0);
+ STRING_FIELD (result->pw_passwd, ISCOLON, 0);
+ INT_FIELD (result->pw_uid, ISCOLON, 0, 10,);
+ INT_FIELD (result->pw_gid, ISCOLON, 0, 10,);
+ STRING_FIELD (result->pw_gecos, ISCOLON, 0);
+ STRING_FIELD (result->pw_dir, ISCOLON, 0);
  result->pw_shell = line;
 )