(nscd_gethst_r): Make sure resultbuf->h_addr_list addresses are
[kopensolaris-gnu/glibc.git] / nscd / cache.c
index 4ab83db..61fb770 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 1998 Free Software Foundation, Inc.
+/* Copyright (c) 1998, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -23,6 +23,8 @@
 #include <limits.h>
 #include <stdlib.h>
 #include <string.h>
+#include <libintl.h>
+#include <arpa/inet.h>
 #include <rpcsvc/nis.h>
 #include <sys/param.h>
 #include <sys/stat.h>
@@ -37,7 +39,8 @@
 
    This function must be called with the read-lock held.  */
 struct hashentry *
-cache_search (int type, void *key, size_t len, struct database *table)
+cache_search (int type, void *key, size_t len, struct database *table,
+             uid_t owner)
 {
   unsigned long int hash = __nis_hash (key, len) % table->module;
   struct hashentry *work;
@@ -46,8 +49,8 @@ cache_search (int type, void *key, size_t len, struct database *table)
 
   while (work != NULL)
     {
-      if (type == work->type
-         && len == work->len && memcmp (key, work->key, len) == 0)
+      if (type == work->type && len == work->len
+         && memcmp (key, work->key, len) == 0 && work->owner == owner)
        {
          /* We found the entry.  Increment the appropriate counter.  */
          if (work->data == (void *) -1)
@@ -75,7 +78,7 @@ cache_search (int type, void *key, size_t len, struct database *table)
    the readlock reduces the chance of conflicts.  */
 void
 cache_add (int type, void *key, size_t len, const void *packet, size_t total,
-          void *data, int last, time_t t, struct database *table)
+          void *data, int last, time_t t, struct database *table, uid_t owner)
 {
   unsigned long int hash = __nis_hash (key, len) % table->module;
   struct hashentry *newp;
@@ -87,6 +90,7 @@ cache_add (int type, void *key, size_t len, const void *packet, size_t total,
   newp->type = type;
   newp->len = len;
   newp->key = key;
+  newp->owner = owner;
   newp->data = data;
   newp->timeout = t;
   newp->packet = packet;
@@ -128,6 +132,10 @@ prune_cache (struct database *table, time_t now)
   size_t first = cnt + 1;
   size_t last = 0;
 
+  /* If this table is not actually used don't do anything.  */
+  if (cnt == 0)
+    return;
+
   /* If we check for the modification of the underlying file we invalidate
      the entries also in this case.  */
   if (table->check_file)
@@ -137,16 +145,21 @@ prune_cache (struct database *table, time_t now)
       if (stat (table->filename, &st) < 0)
        {
          char buf[128];
-         /* We cannot stat() the file, disable file checking.  */
+         /* We cannot stat() the file, disable file checking if the
+             file does not exist.  */
          dbg_log (_("cannot stat() file `%s': %s"),
                   table->filename, strerror_r (errno, buf, sizeof (buf)));
-         table->check_file = 0;
+         if (errno == ENOENT)
+           table->check_file = 0;
        }
       else
        {
          if (st.st_mtime != table->file_mtime)
-           /* The file changed.  Invalidate all entries.  */
-           now = LONG_MAX;
+           {
+             /* The file changed.  Invalidate all entries.  */
+             now = LONG_MAX;
+             table->file_mtime = st.st_mtime;
+           }
        }
     }
 
@@ -225,10 +238,23 @@ prune_cache (struct database *table, time_t now)
          struct hashentry *old = head;
 
          if (debug_level > 0)
-           dbg_log ("remove %s entry \"%s\"",
-                    serv2str[old->type],
-                    old->last
-                    ? old->key : old->data == (void *) -1 ? old->key : "???");
+           {
+             char buf[INET6_ADDRSTRLEN];
+             const char *str;
+
+             if ((old->type == GETHOSTBYADDR || old->type == GETHOSTBYADDRv6)
+                 && (old->last || old->data == (void *) -1))
+               {
+                 inet_ntop (old->type == GETHOSTBYADDR ? AF_INET : AF_INET6,
+                            old->key, buf, sizeof (buf));
+                 str = buf;
+               }
+             else
+               str = old->last ? old->key : (old->data == (void *) -1
+                                             ? old->key : "???");
+
+             dbg_log ("remove %s entry \"%s\"", serv2str[old->type], str);
+           }
 
          /* Free the data structures.  */
          if (old->data == (void *) -1)