update comment re power of 2
[gnulib.git] / lib / readutmp.c
index 39ea070..29b24a5 100644 (file)
@@ -1,5 +1,5 @@
 /* GNU's read utmp module.
-   Copyright (C) 1992-1999 Free Software Foundation, Inc.
+   Copyright (C) 1992-2000 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -19,6 +19,9 @@
 
 #include <config.h>
 
+#include <stdio.h>
+
+#include <sys/types.h>
 #include <sys/stat.h>
 #if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
 # include <string.h>
@@ -29,6 +32,7 @@
 #include "readutmp.h"
 
 char *xmalloc ();
+char *realloc ();
 
 /* Copy UT->ut_name into storage obtained from malloc.  Then remove any
    trailing spaces from the copy, NUL terminate it, and return the copy.  */
@@ -38,82 +42,53 @@ extract_trimmed_name (const STRUCT_UTMP *ut)
 {
   char *p, *trimmed_name;
 
-  trimmed_name = xmalloc (sizeof (ut->ut_name) + 1);
-  strncpy (trimmed_name, ut->ut_name, sizeof (ut->ut_name));
+  trimmed_name = xmalloc (sizeof (UT_USER (ut)) + 1);
+  strncpy (trimmed_name, UT_USER (ut), sizeof (UT_USER (ut)));
   /* Append a trailing space character.  Some systems pad names shorter than
      the maximum with spaces, others pad with NULs.  Remove any spaces.  */
-  trimmed_name[sizeof (ut->ut_name)] = ' ';
+  trimmed_name[sizeof (UT_USER (ut))] = ' ';
   p = strchr (trimmed_name, ' ');
   if (p != NULL)
     *p = '\0';
   return trimmed_name;
 }
 
-/* Read the utmp file FILENAME into *UTMP_BUF, set *N_ENTRIES to the
-   number of entries read, and return zero.  If there is any error,
+/* Read the utmp entries corresponding to file FILENAME into freshly-
+   malloc'd storage, set *UTMP_BUF to that pointer, set *N_ENTRIES to
+   the number of entries, and return zero.  If there is any error,
    return non-zero and don't modify the parameters.  */
 
-/* FIXME: use `#if HAVE_UTMPNAME' instead...  */
-#if 0
+#ifdef UTMP_NAME_FUNCTION
 
 int
 read_utmp (const char *filename, int *n_entries, STRUCT_UTMP **utmp_buf)
 {
-  int count_utmp = 0;
   int n_read;
   STRUCT_UTMP *u;
-  STRUCT_UTMP *uptr;
-  STRUCT_UTMP *utmp_contents;
-
-  if (utmpname (filename))
-    {
-      return 1;
-    }
+  STRUCT_UTMP *utmp = NULL;
 
-  /* FIXME: going through the list twice is wasteful. */
+  /* Ignore the return value for now.
+     Solaris' utmpname returns 1 upon success -- which is contrary
+     to what the GNU libc version does.  In addition, older GNU libc
+     versions are actually void.   */
+  UTMP_NAME_FUNCTION (filename);
 
-  /* count the entries in utmp */
-  setutent ();
-  while ((u = getutent ()) != NULL)
-    ++count_utmp;
-
-  if (count_utmp == 0)
-    return 0;
-
-  utmp_contents = (STRUCT_UTMP *) xmalloc (count_utmp * sizeof (STRUCT_UTMP));
-
-  /* read the entries in utmp */
-
-  /* FIXME: can this fail? */
-  setutent ();
+  SET_UTMP_ENT ();
 
   n_read = 0;
-  uptr = utmp_contents;
-  while ((u = getutent ()) != NULL)
+  while ((u = GET_UTMP_ENT ()) != NULL)
     {
       ++n_read;
-      if (n_read > count_utmp)
-       {
-         STRUCT_UTMP *old_utmp_contents = utmp_contents;
-         ++count_utmp;
-         utmp_contents = (STRUCT_UTMP *) xrealloc (utmp_contents,
-                                                   (count_utmp
-                                                    * sizeof (STRUCT_UTMP)));
-         uptr = utmp_contents + (uptr - old_utmp_contents);
-       }
-      *uptr = *u;
-      ++uptr;
+      utmp = (STRUCT_UTMP *) realloc (utmp, n_read * sizeof (STRUCT_UTMP));
+      if (utmp == NULL)
+       return 1;
+      utmp[n_read - 1] = *u;
     }
 
-  if (n_read != count_utmp)
-    utmp_contents = (STRUCT_UTMP *) xrealloc (utmp_contents,
-                                             n_read * sizeof (STRUCT_UTMP));
-
-  /* FIXME: can this fail? */
-  endutent ();
+  END_UTMP_ENT ();
 
   *n_entries = n_read;
-  *utmp_buf = utmp_contents;
+  *utmp_buf = utmp;
 
   return 0;
 }
@@ -155,4 +130,4 @@ read_utmp (const char *filename, int *n_entries, STRUCT_UTMP **utmp_buf)
   return 0;
 }
 
-#endif /* HAVE_UTMPNAME */
+#endif