]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
(list_entries): Delete. Split in two actually...
authorJim Meyering <jim@meyering.net>
Fri, 18 Nov 1994 05:15:04 +0000 (05:15 +0000)
committerJim Meyering <jim@meyering.net>
Fri, 18 Nov 1994 05:15:04 +0000 (05:15 +0000)
(list_entries_users, list_entries_who, userid_compare): New functions.
(list_entries_users): Sort the user names.  Reported by
Michael I Bushnell.
Topologically sort the functions and remove fwd declarations.

src/who.c

index acfd1d09748e764430f559d9d03277b721883cbb..e9e9628980b4ea3b37a4ed24bd7547905f734e4c 100644 (file)
--- a/src/who.c
+++ b/src/who.c
 #endif /* USERS */
 #endif /* WHO */
 
-char *xmalloc ();
 void error ();
-char *ttyname ();
 int gethostname ();
-
-static int read_utmp ();
-#ifdef WHO
-static const char *idle_string ();
-static STRUCT_UTMP *search_entries ();
-static void print_entry ();
-static void print_heading ();
-static void scan_entries ();
-static void who_am_i ();
-#endif /* WHO */
-static void list_entries ();
-static void usage ();
-static void who ();
+char *ttyname ();
+char *xmalloc ();
 
 /* The name this program was run with. */
 char *program_name;
@@ -146,164 +133,60 @@ static struct option const longopts[] =
   {NULL, 0, NULL, 0}
 };
 
-void
-main (argc, argv)
-     int argc;
-     char **argv;
-{
-  int optc, longind;
-#ifdef WHO
-  int my_line_only = 0;
-#endif /* WHO */
-
-  program_name = argv[0];
-
-#ifdef WHO
-  while ((optc = getopt_long (argc, argv, "imqsuwHT", longopts, &longind))
-#else
-  while ((optc = getopt_long (argc, argv, "", longopts, &longind))
-#endif /* WHO */
-        != EOF)
-    {
-      switch (optc)
-       {
-       case 0:
-         break;
-
-#ifdef WHO
-       case 'm':
-         my_line_only = 1;
-         break;
-
-       case 'q':
-         short_list = 1;
-         break;
-
-       case 's':
-         break;
-
-       case 'i':
-       case 'u':
-         include_idle = 1;
-         break;
-
-       case 'H':
-         include_heading = 1;
-         break;
-
-       case 'w':
-       case 'T':
-         include_mesg = 1;
-         break;
-#endif /* WHO */
-
-       default:
-         error (0, 0, "too many arguments");
-         usage (1);
-       }
-    }
-
-  if (show_version)
-    {
-      printf ("%s - %s\n", COMMAND_NAME, version_string);
-      exit (0);
-    }
-
-  if (show_help)
-    usage (0);
-
-  switch (argc - optind)
-    {
-    case 0:                    /* who */
-#ifdef WHO
-      if (my_line_only)
-       who_am_i (UTMP_FILE);
-      else
-#endif /* WHO */
-       who (UTMP_FILE);
-      break;
+static STRUCT_UTMP *utmp_contents;
 
-    case 1:                    /* who <utmp file> */
-#ifdef WHO
-      if (my_line_only)
-       who_am_i (argv[optind]);
-      else
-#endif /* WHO */
-       who (argv[optind]);
-      break;
+#if defined (WHO) || defined (USERS)
 
-#ifdef WHO
-    case 2:                    /* who <blurf> <glop> */
-      who_am_i (UTMP_FILE);
-      break;
-#endif /* WHO */
+/* Copy UT->ut_name into storage obtained from malloc.  Then remove any
+   trailing spaces from the copy, NUL terminate it, and return the copy.  */
 
-    default:                   /* lose */
-      usage (1);
-    }
-
-  exit (0);
+static char *
+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));
+  /* 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)] = ' ';
+  p = index (trimmed_name, ' ');
+  if (p != NULL)
+    *p = '\0';
+  return trimmed_name;
 }
 
-static STRUCT_UTMP *utmp_contents;
+#endif /* WHO || USERS */
 
-/* Display a list of who is on the system, according to utmp file FILENAME. */
-
-static void
-who (filename)
-     char *filename;
-{
-  int users;
+#if WHO
 
-  users = read_utmp (filename);
-#ifdef WHO
-  if (short_list)
-    list_entries (users);
-  else
-    scan_entries (users);
-#else
-#ifdef USERS
-  list_entries (users);
-#endif /* USERS */
-#endif /* WHO */
-}
-
-/* Read the utmp file FILENAME into UTMP_CONTENTS and return the
-   number of entries it contains. */
+/* Return a string representing the time between WHEN and the time
+   that this function is first run. */
 
-static int
-read_utmp (filename)
-     char *filename;
+static const char *
+idle_string (when)
+     time_t when;
 {
-  FILE *utmp;
-  struct stat file_stats;
-  int n_read;
-  size_t size;
+  static time_t now = 0;
+  static char idle[10];
+  time_t seconds_idle;
 
-  utmp = fopen (filename, "r");
-  if (utmp == NULL)
-    error (1, errno, "%s", filename);
+  if (now == 0)
+    time (&now);
 
-  fstat (fileno (utmp), &file_stats);
-  size = file_stats.st_size;
-  if (size > 0)
-    utmp_contents = (STRUCT_UTMP *) xmalloc (size);
-  else
+  seconds_idle = now - when;
+  if (seconds_idle < 60)       /* One minute. */
+    return "  .  ";
+  if (seconds_idle < (24 * 60 * 60)) /* One day. */
     {
-      fclose (utmp);
-      return 0;
+      sprintf (idle, "%02d:%02d",
+              (int) (seconds_idle / (60 * 60)),
+              (int) ((seconds_idle % (60 * 60)) / 60));
+      return (const char *) idle;
     }
-
-  /* Use < instead of != in case the utmp just grew.  */
-  n_read = fread (utmp_contents, 1, size, utmp);
-  if (ferror (utmp) || fclose (utmp) == EOF
-      || n_read < size)
-    error (1, errno, "%s", filename);
-
-  return size / sizeof (STRUCT_UTMP);
+  return " old ";
 }
 
-#ifdef WHO
 /* Display a line of information about entry THIS. */
 
 static void
@@ -329,7 +212,7 @@ print_entry (this)
     }
   else
     {
-      strcpy(line, DEV_DIR_WITH_TRAILING_SLASH);
+      strcpy (line, DEV_DIR_WITH_TRAILING_SLASH);
       strncpy (line + DEV_DIR_LEN, this->ut_line, sizeof (this->ut_line));
       line[DEV_DIR_LEN + sizeof (this->ut_line)] = '\0';
     }
@@ -370,19 +253,18 @@ print_entry (this)
 
   putchar ('\n');
 }
-#endif /* WHO */
 
-#if defined (WHO) || defined (USERS)
 /* Print the username of each valid entry and the number of valid entries
    in `utmp_contents', which should have N elements. */
 
 static void
-list_entries (n)
+list_entries_who (n)
      int n;
 {
   register STRUCT_UTMP *this = utmp_contents;
-  register int entries = 0;
+  int entries;
 
+  entries = 0;
   while (n--)
     {
       if (this->ut_name[0]
@@ -391,30 +273,76 @@ list_entries (n)
 #endif
         )
        {
-         char trimmed_name[sizeof (this->ut_name) + 1];
-         int i;
-
-         strncpy (trimmed_name, this->ut_name, sizeof (this->ut_name));
-         trimmed_name[sizeof (this->ut_name)] = ' ';
-         for (i = 0; i <= sizeof (this->ut_name); i++)
-           {
-             if (trimmed_name[i] == ' ')
-               break;
-           }
-         trimmed_name[i] = '\0';
+         char *trimmed_name;
+
+         trimmed_name = extract_trimmed_name (this);
 
          printf ("%s ", trimmed_name);
+         free (trimmed_name);
          entries++;
        }
       this++;
     }
-#ifdef WHO
   printf ("\n# users=%u\n", entries);
-#else
-  putchar('\n');
+}
+
 #endif /* WHO */
+
+#ifdef USERS
+
+static int
+userid_compare (const void *v_a, const void *v_b)
+{
+  char **a = (char **) v_a;
+  char **b = (char **) v_b;
+  return strcmp (*a, *b);
 }
-#endif /* defined (WHO) || defined (USERS) */
+
+static void
+list_entries_users (n)
+     int n;
+{
+  register STRUCT_UTMP *this = utmp_contents;
+  char **u;
+  int i;
+  int n_entries;
+
+  n_entries = 0;
+  u = (char **) xmalloc (n * sizeof (u[0]));
+  for (i=0; i<n; i++)
+    {
+      if (this->ut_name[0]
+#ifdef USER_PROCESS
+         && this->ut_type == USER_PROCESS
+#endif
+        )
+       {
+         char *trimmed_name;
+
+         trimmed_name = extract_trimmed_name (this);
+
+         u[n_entries] = trimmed_name;
+         ++n_entries;
+       }
+      this++;
+    }
+
+  qsort (u, n_entries, sizeof (u[0]), userid_compare);
+
+  for (i=0; i<n_entries; i++)
+    {
+      int c;
+      fputs (u[i], stdout);
+      c = (i < n_entries-1 ? ' ' : '\n');
+      putchar (c);
+    }
+
+  for (i=0; i<n_entries; i++)
+    free (u[i]);
+  free (u);
+}
+
+#endif /* USERS */
 
 #ifdef WHO
 
@@ -454,6 +382,66 @@ scan_entries (n)
     }
 }
 
+#endif /* WHO */
+
+/* Read the utmp file FILENAME into UTMP_CONTENTS and return the
+   number of entries it contains. */
+
+static int
+read_utmp (filename)
+     char *filename;
+{
+  FILE *utmp;
+  struct stat file_stats;
+  int n_read;
+  size_t size;
+
+  utmp = fopen (filename, "r");
+  if (utmp == NULL)
+    error (1, errno, "%s", filename);
+
+  fstat (fileno (utmp), &file_stats);
+  size = file_stats.st_size;
+  if (size > 0)
+    utmp_contents = (STRUCT_UTMP *) xmalloc (size);
+  else
+    {
+      fclose (utmp);
+      return 0;
+    }
+
+  /* Use < instead of != in case the utmp just grew.  */
+  n_read = fread (utmp_contents, 1, size, utmp);
+  if (ferror (utmp) || fclose (utmp) == EOF
+      || n_read < size)
+    error (1, errno, "%s", filename);
+
+  return size / sizeof (STRUCT_UTMP);
+}
+
+/* Display a list of who is on the system, according to utmp file FILENAME. */
+
+static void
+who (filename)
+     char *filename;
+{
+  int users;
+
+  users = read_utmp (filename);
+#ifdef WHO
+  if (short_list)
+    list_entries_who (users);
+  else
+    scan_entries (users);
+#else
+#ifdef USERS
+  list_entries_users (users);
+#endif /* USERS */
+#endif /* WHO */
+}
+
+#ifdef WHO
+
 /* Search `utmp_contents', which should have N entries, for
    an entry with a `ut_line' field identical to LINE.
    Return the first matching entry found, or NULL if there
@@ -512,33 +500,6 @@ who_am_i (filename)
   print_entry (utmp_entry);
 }
 
-/* Return a string representing the time between WHEN and the time
-   that this function is first run. */
-
-static const char *
-idle_string (when)
-     time_t when;
-{
-  static time_t now = 0;
-  static char idle[10];
-  time_t seconds_idle;
-
-  if (now == 0)
-    time (&now);
-
-  seconds_idle = now - when;
-  if (seconds_idle < 60)       /* One minute. */
-    return "  .  ";
-  if (seconds_idle < (24 * 60 * 60)) /* One day. */
-    {
-      sprintf (idle, "%02d:%02d",
-              (int) (seconds_idle / (60 * 60)),
-              (int) ((seconds_idle % (60 * 60)) / 60));
-      return (const char *) idle;
-    }
-  return " old ";
-}
-
 static void
 usage (status)
      int status;
@@ -570,7 +531,7 @@ If ARG1 ARG2 given, -m presumed: `am i' or `mom likes' are usual.\n\
 }
 #endif /* WHO */
 
-#if defined (USERS)
+#ifdef USERS
 static void
 usage (status)
      int status;
@@ -592,3 +553,102 @@ If FILE not given, uses /etc/utmp.  /etc/wtmp as FILE is common.\n\
   exit (status);
 }
 #endif /* USERS */
+
+void
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int optc, longind;
+#ifdef WHO
+  int my_line_only = 0;
+#endif /* WHO */
+
+  program_name = argv[0];
+
+#ifdef WHO
+  while ((optc = getopt_long (argc, argv, "imqsuwHT", longopts, &longind))
+#else
+  while ((optc = getopt_long (argc, argv, "", longopts, &longind))
+#endif /* WHO */
+        != EOF)
+    {
+      switch (optc)
+       {
+       case 0:
+         break;
+
+#ifdef WHO
+       case 'm':
+         my_line_only = 1;
+         break;
+
+       case 'q':
+         short_list = 1;
+         break;
+
+       case 's':
+         break;
+
+       case 'i':
+       case 'u':
+         include_idle = 1;
+         break;
+
+       case 'H':
+         include_heading = 1;
+         break;
+
+       case 'w':
+       case 'T':
+         include_mesg = 1;
+         break;
+#endif /* WHO */
+
+       default:
+         error (0, 0, "too many arguments");
+         usage (1);
+       }
+    }
+
+  if (show_version)
+    {
+      printf ("%s - %s\n", COMMAND_NAME, version_string);
+      exit (0);
+    }
+
+  if (show_help)
+    usage (0);
+
+  switch (argc - optind)
+    {
+    case 0:                    /* who */
+#ifdef WHO
+      if (my_line_only)
+       who_am_i (UTMP_FILE);
+      else
+#endif /* WHO */
+       who (UTMP_FILE);
+      break;
+
+    case 1:                    /* who <utmp file> */
+#ifdef WHO
+      if (my_line_only)
+       who_am_i (argv[optind]);
+      else
+#endif /* WHO */
+       who (argv[optind]);
+      break;
+
+#ifdef WHO
+    case 2:                    /* who <blurf> <glop> */
+      who_am_i (UTMP_FILE);
+      break;
+#endif /* WHO */
+
+    default:                   /* lose */
+      usage (1);
+    }
+
+  exit (0);
+}