Do network lookups ignoring case.
[kopensolaris-gnu/glibc.git] / nss / nss_files / files-alias.c
index 2b0f292..84d771d 100644 (file)
@@ -1,5 +1,5 @@
 /* Mail alias file parser in nss_files module.
-   Copyright (C) 1996 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
@@ -21,7 +21,8 @@
 #include <aliases.h>
 #include <ctype.h>
 #include <errno.h>
-#include <libc-lock.h>
+#include <fcntl.h>
+#include <bits/libc-lock.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -48,7 +49,27 @@ internal_setent (void)
       stream = fopen ("/etc/aliases", "r");
 
       if (stream == NULL)
-       status = NSS_STATUS_UNAVAIL;
+       status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
+      else
+       {
+         /* We have to make sure the file is  `closed on exec'.  */
+         int result, flags;
+
+         result = flags = fcntl (fileno (stream), F_GETFD, 0);
+         if (result >= 0)
+           {
+             flags |= FD_CLOEXEC;
+             result = fcntl (fileno (stream), F_SETFD, flags);
+           }
+         if (result < 0)
+           {
+             /* Something went wrong.  Close the stream and return a
+                failure.  */
+             fclose (stream);
+             stream = NULL;
+             status = NSS_STATUS_UNAVAIL;
+           }
+       }
     }
   else
     rewind (stream);
@@ -110,7 +131,7 @@ _nss_files_endaliasent (void)
 /* Parsing the database file into `struct aliasent' data structures.  */
 static enum nss_status
 get_next_alias (const char *match, struct aliasent *result,
-               char *buffer, size_t buflen)
+               char *buffer, size_t buflen, int *errnop)
 {
   enum nss_status status = NSS_STATUS_NOTFOUND;
   int ignore = 0;
@@ -138,7 +159,7 @@ get_next_alias (const char *match, struct aliasent *result,
        {
          /* The line is too long for our buffer.  */
        no_more_room:
-         __set_errno (ERANGE);
+         *errnop = ERANGE;
          status = NSS_STATUS_TRYAGAIN;
          break;
        }
@@ -149,7 +170,7 @@ get_next_alias (const char *match, struct aliasent *result,
          /* If we are in IGNORE mode and the first character in the
             line is a white space we ignore the line and start
             reading the next.  */
-         if (ignore && isspace (first_unused))
+         if (ignore && isspace (*first_unused))
            continue;
 
          /* Terminate the line for any case.  */
@@ -179,7 +200,8 @@ get_next_alias (const char *match, struct aliasent *result,
             looking for.  If it does not match we simply ignore all
             lines until the next line containing the start of a new
             alias is found.  */
-         ignore = match != NULL && strcmp (result->alias_name, match) == 0;
+         ignore = (match != NULL
+                   && strcasecmp (result->alias_name, match) != 0);
 
          while (! ignore)
            {
@@ -192,16 +214,11 @@ get_next_alias (const char *match, struct aliasent *result,
 
              if (first_unused != cp)
                {
+                 /* OK, we can have a regular entry or an include
+                    request.  */
                  if (*line != '\0')
-                   {
-                     /* OK, we can have a regular entry or an include
-                        request.  */
-                     *first_unused++ = '\0';
-                     ++line;
-                   }
-                 else
-                   ++first_unused;
-
+                   ++line;
+                 *first_unused++ = '\0';
 
                  if (strncmp (cp, ":include:", 9) != 0)
                    {
@@ -295,10 +312,8 @@ get_next_alias (const char *match, struct aliasent *result,
                     just read character.  */
                  int ch;
 
-                 first_unused[room_left - 1] = '\0';
-                 line = first_unused;
                  ch = fgetc (stream);
-                 if (ch == EOF || !isspace (ch))
+                 if (ch == EOF || ch == '\n' || !isspace (ch))
                    {
                      size_t cnt;
 
@@ -329,6 +344,10 @@ get_next_alias (const char *match, struct aliasent *result,
 
                  /* The just read character is a white space and so
                     can be ignored.  */
+                 first_unused[room_left - 1] = '\0';
+                 line = fgets (first_unused, room_left, stream);
+                 if (first_unused[room_left - 1] != '\0')
+                   goto no_more_room;
                  cp = strpbrk (line, "#\n");
                  if (cp != NULL)
                    *cp = '\0';
@@ -346,7 +365,8 @@ get_next_alias (const char *match, struct aliasent *result,
 
 
 enum nss_status
-_nss_files_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen)
+_nss_files_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen,
+                         int *errnop)
 {
   /* Return next entry in host file.  */
   enum nss_status status = NSS_STATUS_SUCCESS;
@@ -373,7 +393,7 @@ _nss_files_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen)
 
          /* Read lines until we get a definite result.  */
          do
-           status = get_next_alias (NULL, result, buffer, buflen);
+           status = get_next_alias (NULL, result, buffer, buflen, errnop);
          while (status == NSS_STATUS_RETURN);
 
          /* If we successfully read an entry remember this position.  */
@@ -392,7 +412,7 @@ _nss_files_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen)
 
 enum nss_status
 _nss_files_getaliasbyname_r (const char *name, struct aliasent *result,
-                            char *buffer, size_t buflen)
+                            char *buffer, size_t buflen, int *errnop)
 {
   /* Return next entry in host file.  */
   enum nss_status status = NSS_STATUS_SUCCESS;
@@ -415,10 +435,12 @@ _nss_files_getaliasbyname_r (const char *name, struct aliasent *result,
 
       /* Read lines until we get a definite result.  */
       do
-       status = get_next_alias (name, result, buffer, buflen);
+       status = get_next_alias (name, result, buffer, buflen, errnop);
       while (status == NSS_STATUS_RETURN);
     }
 
+  internal_endent ();
+
   __libc_lock_unlock (lock);
 
   return status;