summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2001-06-09 09:00:24 +0000
committerJim Meyering <jim@meyering.net>2001-06-09 09:00:24 +0000
commit2beac10424a4f9a8cee26ed26508fadadf112f22 (patch)
tree5f9c5249c5e8a3b3b9956387c3b16374064e597c /src
parent7c976d94854bb783859a1fcbcc0091e008b30fc5 (diff)
downloadcoreutils-2beac10424a4f9a8cee26ed26508fadadf112f22.tar.xz
Add options to make `who' more POSIX compliant.
Accept new options: --all (-a), --boot (-b), --dead (-d), --login, --process (-p), --runlevel (-r), --short (-s), --time (-t), --users (-u). The -u option now produces POSIX-specified results and is the same as the long option `--users'. --idle is no longer the same as -u. (time_string, print_line, print_boottime, print_deadprocs, print_login, print_initspawn, print_clockchange, print_runlevel): New functions. (print_user): Renamed from print_entry and reworked. (search_entries): Remove function. (who_am_i): Likewise. (usage): Describe new options. (main): Handle new options. Mostly from Michael Stone.
Diffstat (limited to 'src')
-rw-r--r--src/who.c564
1 files changed, 415 insertions, 149 deletions
diff --git a/src/who.c b/src/who.c
index 06b01a7df..39cd08523 100644
--- a/src/who.c
+++ b/src/who.c
@@ -1,5 +1,5 @@
/* GNU's who.
- Copyright (C) 1992-2000 Free Software Foundation, Inc.
+ Copyright (C) 1992-2001 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
@@ -15,10 +15,10 @@
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* Written by jla; revised by djm */
+/* Written by jla; revised by djm; revised again by mstone */
/* Output format:
- name [state] line time [idle] host
+ name [state] line time [activity] [pid] [comment] [exit]
state: -T
name, line, time: not -q
idle: -u
@@ -38,7 +38,7 @@
/* The official name of this program (e.g., no `g' prefix). */
#define PROGRAM_NAME "who"
-#define AUTHORS "Joseph Arceneaux and David MacKenzie"
+#define AUTHORS "Joseph Arceneaux, David MacKenzie, and Michael Stone"
#ifndef MAXHOSTNAMELEN
# define MAXHOSTNAMELEN 64
@@ -48,6 +48,32 @@
# define S_IWGRP 020
#endif
+#ifndef USER_PROCESS
+# define USER_PROCESS INT_MAX
+#endif
+
+#ifndef RUN_LVL
+# define RUN_LVL INT_MAX
+#endif
+
+#ifndef INIT_PROCESS
+# define INIT_PROCESS INT_MAX
+#endif
+
+#ifndef LOGIN_PROCESS
+# define LOGIN_PROCESS INT_MAX
+#endif
+
+#ifndef DEAD_PROCESS
+# define DEAD_PROCESS INT_MAX
+#endif
+
+#ifndef NEW_TIME
+# define NEW_TIME INT_MAX
+#endif
+
+#define IDLESTR_LEN 6
+
int gethostname ();
char *ttyname ();
char *canon_host ();
@@ -63,6 +89,9 @@ static int do_lookup;
Ignored for `who am i'. */
static int short_list;
+/* If nonzero, display only name, line, and time fields */
+static int short_output;
+
/* If nonzero, display the hours:minutes since each user has touched
the keyboard, or "." if within the last minute, or "old" if
not within the last day. */
@@ -75,14 +104,56 @@ static int include_heading;
or a `?' if their tty cannot be statted. */
static int include_mesg;
-static struct option const longopts[] =
+/* If nonzero, display process termination & exit status */
+static int include_exit;
+
+/* If nonzero, display the last boot time */
+static int need_boottime;
+
+/* If nonzero, display dead processes */
+static int need_deadprocs;
+
+/* If nonzero, display processes waiting for user login */
+static int need_login;
+
+/* If nonzero, display processes started by init */
+static int need_initspawn;
+
+/* If nonzero, display the last clock change */
+static int need_clockchange;
+
+/* If nonzero, display the current runlevel */
+static int need_runlevel;
+
+/* If nonzero, display user processes */
+static int need_users;
+
+/* If nonzero, display info only for the controlling tty */
+static int my_line_only;
+
+/* for long options with no corresponding short option, use enum */
+enum
{
+ LOOKUP_OPTION = CHAR_MAX + 1,
+ LOGIN_OPTION
+};
+
+static struct option const longopts[] = {
+ {"all", no_argument, NULL, 'a'},
+ {"boot", no_argument, NULL, 'b'},
{"count", no_argument, NULL, 'q'},
- {"idle", no_argument, NULL, 'u'},
+ {"dead", no_argument, NULL, 'd'},
{"heading", no_argument, NULL, 'H'},
- {"lookup", no_argument, NULL, 'l'},
+ {"idle", no_argument, NULL, 'i'},
+ {"login", no_argument, NULL, LOGIN_OPTION},
+ {"lookup", no_argument, NULL, LOOKUP_OPTION},
{"message", no_argument, NULL, 'T'},
{"mesg", no_argument, NULL, 'T'},
+ {"process", no_argument, NULL, 'p'},
+ {"runlevel", no_argument, NULL, 'r'},
+ {"short", no_argument, NULL, 's'},
+ {"time", no_argument, NULL, 't'},
+ {"users", no_argument, NULL, 'u'},
{"writable", no_argument, NULL, 'T'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
@@ -90,13 +161,13 @@ static struct option const longopts[] =
};
/* Return a string representing the time between WHEN and the time
- that this function is first run. */
-
+ that this function is first run.
+ FIXME: locale? */
static const char *
idle_string (time_t when)
{
static time_t now = 0;
- static char idle_hhmm[10];
+ static char idle_hhmm[IDLESTR_LEN];
time_t seconds_idle;
if (now == 0)
@@ -105,7 +176,7 @@ idle_string (time_t when)
seconds_idle = now - when;
if (seconds_idle < 60) /* One minute. */
return " . ";
- if (seconds_idle < (24 * 60 * 60)) /* One day. */
+ if (seconds_idle < (24 * 60 * 60)) /* One day. */
{
sprintf (idle_hhmm, "%02d:%02d",
(int) (seconds_idle / (60 * 60)),
@@ -115,20 +186,75 @@ idle_string (time_t when)
return _(" old ");
}
-/* Display a line of information about UTMP_ENT. */
+/* Return a standard time string, "mon dd hh:mm"
+ FIXME: handle localization */
+static const char *
+time_string (const STRUCT_UTMP *utmp_ent)
+{
+ /* Don't take the address of UT_TIME_MEMBER directly.
+ Ulrich Drepper wrote:
+ ``... GNU libc (and perhaps other libcs as well) have extended
+ utmp file formats which do not use a simple time_t ut_time field.
+ In glibc, ut_time is a macro which selects for backward compatibility
+ the tv_sec member of a struct timeval value.'' */
+ time_t tm = UT_TIME_MEMBER (utmp_ent);
+
+ char *ptr = ctime (&tm) + 4;
+ ptr[12] = '\0';
+ return ptr;
+}
+/* Print formatted output line. Uses mostly arbitrary field sizes, probably
+ will need tweaking if any of the localization stuff is done, or for 64 bit
+ pids, etc. */
static void
-print_entry (const STRUCT_UTMP *utmp_ent)
+print_line (const char *user, const char state, const char *line,
+ const char *time_str, const char *idle, const char *pid,
+ const char *comment, const char *exitstr)
+{
+ printf ("%-8s", user ? user : " .");
+ if (include_mesg)
+ printf (" %c", state);
+ printf (" %-12s", line);
+ printf (" %-12s", time_str);
+ if (include_idle && !short_output)
+ printf (" %-6s", idle);
+ if (!short_output)
+ printf (" %10s", pid);
+ /* FIXME: it's not really clear whether the following should be in short_output.
+ a strict reading of SUSv2 would suggest not, but I haven't seen any
+ implementations that actually work that way... */
+ printf (" %-8s", comment);
+ if (include_exit && exitstr && *exitstr)
+ printf (" %-12s", exitstr);
+ putchar ('\n');
+}
+
+#if HAVE_STRUCT_XTMP_UT_PID
+# define PIDSTR_DECL_AND_INIT(Var) \
+ char Var[INT_STRLEN_BOUND (utmp_ent->ut_pid) + 1]; \
+ sprintf (Var, "%d", utmp_ent->ut_pid)
+#else
+# define PIDSTR_DECL_AND_INIT(Var) \
+ const char *Var = ""
+#endif
+
+/* Send properly parsed USER_PROCESS info to print_line */
+static void
+print_user (const STRUCT_UTMP *utmp_ent)
{
struct stat stats;
time_t last_change;
char mesg;
+ char idlestr[IDLESTR_LEN];
+ static char *hoststr;
+ static int hostlen;
#define DEV_DIR_WITH_TRAILING_SLASH "/dev/"
#define DEV_DIR_LEN (sizeof (DEV_DIR_WITH_TRAILING_SLASH) - 1)
char line[sizeof (utmp_ent->ut_line) + DEV_DIR_LEN + 1];
- time_t tm;
+ PIDSTR_DECL_AND_INIT (pidstr);
/* Copy ut_line into LINE, prepending `/dev/' if ut_line is not
already an absolute pathname. Some system may put the full,
@@ -141,7 +267,8 @@ print_entry (const STRUCT_UTMP *utmp_ent)
else
{
strcpy (line, DEV_DIR_WITH_TRAILING_SLASH);
- strncpy (line + DEV_DIR_LEN, utmp_ent->ut_line, sizeof (utmp_ent->ut_line));
+ strncpy (line + DEV_DIR_LEN, utmp_ent->ut_line,
+ sizeof (utmp_ent->ut_line));
line[DEV_DIR_LEN + sizeof (utmp_ent->ut_line)] = '\0';
}
@@ -156,27 +283,11 @@ print_entry (const STRUCT_UTMP *utmp_ent)
last_change = 0;
}
- printf ("%-8.*s", (int) sizeof (UT_USER (utmp_ent)), UT_USER (utmp_ent));
- if (include_mesg)
- printf (" %c ", mesg);
- printf (" %-8.*s", (int) sizeof (utmp_ent->ut_line), utmp_ent->ut_line);
-
- /* Don't take the address of UT_TIME_MEMBER directly.
- Ulrich Drepper wrote:
- ``... GNU libc (and perhaps other libcs as well) have extended
- utmp file formats which do not use a simple time_t ut_time field.
- In glibc, ut_time is a macro which selects for backward compatibility
- the tv_sec member of a struct timeval value.'' */
- tm = UT_TIME_MEMBER (utmp_ent);
- printf (" %-12.12s", ctime (&tm) + 4);
+ if (last_change)
+ sprintf (idlestr, "%.6s", idle_string (last_change));
+ else
+ sprintf (idlestr, " ?");
- if (include_idle)
- {
- if (last_change)
- printf (" %s", idle_string (last_change));
- else
- printf (" . ");
- }
#if HAVE_UT_HOST
if (utmp_ent->ut_host[0])
{
@@ -202,31 +313,149 @@ print_entry (const STRUCT_UTMP *utmp_ent)
host = ut_host;
if (display)
- printf (" (%s:%s)", host, display);
+ {
+ if (hostlen < strlen (host) + strlen (display) + 4)
+ {
+ hostlen = strlen (host) + strlen (display) + 4;
+ hoststr = (char *) realloc (hoststr, hostlen);
+ }
+ sprintf (hoststr, "(%s:%s)", host, display);
+ }
else
- printf (" (%s)", host);
+ {
+ if (hostlen < strlen (host) + 3)
+ {
+ hostlen = strlen (host) + 3;
+ hoststr = (char *) realloc (hoststr, hostlen);
+ }
+ sprintf (hoststr, "(%s)", host);
+ }
+ }
+ else
+ {
+ if (hostlen < 1)
+ {
+ hostlen = 1;
+ hoststr = (char *) realloc (hoststr, hostlen);
+ }
+ stpcpy (hoststr, "");
}
#endif
- putchar ('\n');
+ print_line (UT_USER (utmp_ent), mesg, utmp_ent->ut_line,
+ time_string (utmp_ent), idlestr, pidstr,
+ hoststr ? hoststr : "", "");
+}
+
+static void
+print_boottime (const STRUCT_UTMP *utmp_ent)
+{
+ print_line ("", ' ', "system boot", time_string (utmp_ent), "", "", "", "");
+}
+
+static void
+print_deadprocs (const STRUCT_UTMP *utmp_ent)
+{
+ static char *comment, *exitstr;
+ PIDSTR_DECL_AND_INIT (pidstr);
+
+ if (!comment)
+ comment =
+ (char *) malloc (sizeof (_("id=")) + sizeof (utmp_ent->ut_id) + 1);
+ sprintf (comment, "%s%.*s", _("id="), sizeof utmp_ent->ut_id,
+ utmp_ent->ut_id);
+
+ if (!exitstr)
+ exitstr = (char *) malloc (sizeof (_("term="))
+ + INT_STRLEN_BOUND (utmp_ent->ut_exit.e_termination) + 1
+ + sizeof (_("exit="))
+ + INT_STRLEN_BOUND (utmp_ent->ut_exit.e_exit)
+ + 1);
+ sprintf (exitstr, "%s%d %s%d", _("term="), utmp_ent->ut_exit.e_termination,
+ _("exit="), utmp_ent->ut_exit.e_exit);
+
+ /* FIXME: add idle time? */
+
+ print_line ("", ' ', utmp_ent->ut_line,
+ time_string (utmp_ent), "", pidstr, comment, exitstr);
+}
+
+static void
+print_login (const STRUCT_UTMP *utmp_ent)
+{
+ static char *comment;
+ PIDSTR_DECL_AND_INIT (pidstr);
+
+ if (!comment)
+ comment =
+ (char *) malloc (sizeof (_("id=")) + sizeof (utmp_ent->ut_id) + 1);
+ sprintf (comment, "%s%s", _("id="), utmp_ent->ut_id);
+
+ /* FIXME: add idle time? */
+
+ print_line ("LOGIN", ' ', utmp_ent->ut_line,
+ time_string (utmp_ent), "", pidstr, comment, "");
+}
+
+static void
+print_initspawn (const STRUCT_UTMP *utmp_ent)
+{
+ static char *comment;
+ PIDSTR_DECL_AND_INIT (pidstr);
+
+ if (!comment)
+ comment =
+ (char *) malloc (sizeof (_("id=")) + sizeof (utmp_ent->ut_id) + 1);
+ sprintf (comment, "%s%s", _("id="), utmp_ent->ut_id);
+
+ print_line ("", ' ', utmp_ent->ut_line,
+ time_string (utmp_ent), "", pidstr, comment, "");
+}
+
+static void
+print_clockchange (const STRUCT_UTMP *utmp_ent)
+{
+ /* FIXME: handle NEW_TIME & OLD_TIME both */
+ print_line ("", ' ', _("clock change"),
+ time_string (utmp_ent), "", "", "", "");
+}
+
+static void
+print_runlevel (const STRUCT_UTMP *utmp_ent)
+{
+ static char *runlevline, *comment;
+
+ /* FIXME: The following is correct for linux, may need help
+ on other platforms */
+#if 1 || HAVE_STRUCT_XTMP_UT_PID
+ int last = utmp_ent->ut_pid / 256;
+ int curr = utmp_ent->ut_pid % 256;
+#endif
+
+ if (!runlevline)
+ runlevline = (char *) malloc (sizeof (_("run-level")) + 3);
+ sprintf (runlevline, "%s %c", _("run-level"), curr);
+
+ if (!comment)
+ comment = (char *) malloc (sizeof (_("last=")) + 2);
+ sprintf (comment, "%s%c", _("last="), (last == 'N') ? 'S' : last);
+
+ print_line ("", ' ', runlevline, time_string (utmp_ent),
+ "", "", comment, "");
+
+ return;
}
/* Print the username of each valid entry and the number of valid entries
in UTMP_BUF, which should have N elements. */
-
static void
list_entries_who (int n, const STRUCT_UTMP *utmp_buf)
{
- int entries;
+ int entries = 0;
- entries = 0;
while (n--)
{
- if (UT_USER (utmp_buf)[0]
-#ifdef USER_PROCESS
- && utmp_buf->ut_type == USER_PROCESS
-#endif
- )
+ if (UT_USER (utmp_buf)[0] && UT_TYPE (utmp_buf) == USER_PROCESS)
{
char *trimmed_name;
@@ -244,38 +473,59 @@ list_entries_who (int n, const STRUCT_UTMP *utmp_buf)
static void
print_heading (void)
{
- printf ("%-8s ", _("USER"));
- if (include_mesg)
- printf (_("MESG "));
- printf ("%-8s ", _("LINE"));
- printf (_("LOGIN-TIME "));
- if (include_idle)
- printf (_("IDLE "));
- printf (_("FROM\n"));
+ print_line (_("NAME"), ' ', _("LINE"), _("TIME"), _("IDLE"), _("PID"),
+ _("COMMENT"), _("EXIT"));
}
/* Display UTMP_BUF, which should have N entries. */
-
static void
scan_entries (int n, const STRUCT_UTMP *utmp_buf)
{
+ char *ttyname_b IF_LINT ( = NULL);
+
if (include_heading)
print_heading ();
+ if (my_line_only)
+ {
+ ttyname_b = ttyname (0);
+ if (!ttyname_b)
+ return;
+ if (strncmp (ttyname_b, DEV_DIR_WITH_TRAILING_SLASH, DEV_DIR_LEN) == 0)
+ ttyname_b += DEV_DIR_LEN; /* Discard /dev/ prefix. */
+ }
+
while (n--)
{
- if (UT_USER (utmp_buf)[0]
-#ifdef USER_PROCESS
- && utmp_buf->ut_type == USER_PROCESS
-#endif
- )
- print_entry (utmp_buf);
+ if (!my_line_only ||
+ strncmp (ttyname_b, utmp_buf->ut_line,
+ sizeof (utmp_buf->ut_line)) == 0)
+ {
+ if (need_users && UT_USER (utmp_buf)[0]
+ && UT_TYPE (utmp_buf) == USER_PROCESS)
+ print_user (utmp_buf);
+ else if (need_runlevel && UT_TYPE (utmp_buf) == RUN_LVL)
+ print_runlevel (utmp_buf);
+ else if (need_boottime && UT_TYPE (utmp_buf) == BOOT_TIME)
+ print_boottime (utmp_buf);
+ /* I've never seen one of these, so I don't know what it should
+ look like :^)
+ FIXME: handle OLD_TIME also, perhaps show the delta? */
+ else if (need_clockchange && UT_TYPE (utmp_buf) == NEW_TIME)
+ print_clockchange (utmp_buf);
+ else if (need_initspawn && UT_TYPE (utmp_buf) == INIT_PROCESS)
+ print_initspawn (utmp_buf);
+ else if (need_login && UT_TYPE (utmp_buf) == LOGIN_PROCESS)
+ print_login (utmp_buf);
+ else if (need_deadprocs && UT_TYPE (utmp_buf) == DEAD_PROCESS)
+ print_deadprocs (utmp_buf);
+ }
+
utmp_buf++;
}
}
-/* Display a list of who is on the system, according to utmp file FILENAME. */
-
+/* Display a list of who is on the system, according to utmp file filename. */
static void
who (const char *filename)
{
@@ -292,67 +542,6 @@ who (const char *filename)
scan_entries (n_users, utmp_buf);
}
-/* 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
- is no matching entry. */
-
-static const STRUCT_UTMP *
-search_entries (int n, const STRUCT_UTMP *utmp_buf, const char *line)
-{
- while (n--)
- {
- if (UT_USER (utmp_buf)[0]
-#ifdef USER_PROCESS
- && utmp_buf->ut_type == USER_PROCESS
-#endif
- && !strncmp (line, utmp_buf->ut_line, sizeof (utmp_buf->ut_line)))
- return utmp_buf;
- utmp_buf++;
- }
- return NULL;
-}
-
-/* Display the entry in utmp file FILENAME for this tty on standard input,
- or nothing if there is no entry for it. */
-
-static void
-who_am_i (const char *filename)
-{
- const STRUCT_UTMP *utmp_entry;
- STRUCT_UTMP *utmp_buf;
- char hostname[MAXHOSTNAMELEN + 1];
- char *tty;
- int fail;
- int n_users;
-
- if (gethostname (hostname, MAXHOSTNAMELEN + 1))
- *hostname = 0;
-
- if (include_heading)
- {
- printf ("%*s ", (int) strlen (hostname), " ");
- print_heading ();
- }
-
- tty = ttyname (0);
- if (tty == NULL)
- return;
- tty += 5; /* Remove "/dev/". */
-
- fail = read_utmp (filename, &n_users, &utmp_buf);
-
- if (fail)
- error (1, errno, "%s", filename);
-
- utmp_entry = search_entries (n_users, utmp_buf, tty);
- if (utmp_entry == NULL)
- return;
-
- printf ("%s!", hostname);
- print_entry (utmp_entry);
-}
-
void
usage (int status)
{
@@ -364,13 +553,24 @@ usage (int status)
printf (_("Usage: %s [OPTION]... [ FILE | ARG1 ARG2 ]\n"), program_name);
printf (_("\
\n\
+ -a, --all same as -b -d --login -p -r -t -T -u\n\
+ -b, --boot time of last system boot\n\
+ -d, --dead print dead processes\n\
-H, --heading print line of column headings\n\
- -i, -u, --idle add user idle time as HOURS:MINUTES, . or old\n\
+ -i, --idle add idle time as HOURS:MINUTES, . or old\n\
+ (deprecated, use -u)\n\
+ --login print system login processes\n\
+ (equivalent to SUS -l)\n\
-l, --lookup attempt to canonicalize hostnames via DNS\n\
+ (-l is deprecated, use --lookup)\n\
-m only hostname and user associated with stdin\n\
+ -p, --process print active processes spawned by init\n\
-q, --count all login names and number of users logged on\n\
- -s (ignored)\n\
+ -r, --runlevel print current runlevel\n\
+ -s, --short print only name, line, and time (default)\n\
+ -t, --time print last system clock change\n\
-T, -w, --mesg add user's message status as +, - or ?\n\
+ -u, --users lists users logged in\n\
--message same as -T\n\
--writable same as -T\n\
--help display this help and exit\n\
@@ -388,7 +588,7 @@ int
main (int argc, char **argv)
{
int optc, longind;
- int my_line_only = 0;
+ int assumptions = 1;
program_name = argv[0];
setlocale (LC_ALL, "");
@@ -397,70 +597,136 @@ main (int argc, char **argv)
atexit (close_stdout);
- while ((optc = getopt_long (argc, argv, "ilmqsuwHT", longopts, &longind))
- != -1)
+ while ((optc = getopt_long (argc, argv, "abdilmpqrstuwHT", longopts,
+ &longind)) != -1)
{
switch (optc)
{
case 0:
break;
+ case 'a':
+ need_boottime = 1;
+ need_deadprocs = 1;
+ need_login = 1;
+ need_initspawn = 1;
+ need_runlevel = 1;
+ need_clockchange = 1;
+ need_users = 1;
+ include_mesg = 1;
+ include_idle = 1;
+ include_exit = 1;
+ assumptions = 0;
+ break;
+
+ case 'b':
+ need_boottime = 1;
+ assumptions = 0;
+ break;
+
+ case 'd':
+ need_deadprocs = 1;
+ include_idle = 1;
+ include_exit = 1;
+ assumptions = 0;
+ break;
+
+ case 'H':
+ include_heading = 1;
+ break;
+
+ /* FIXME: This should be -l in a future version */
+ case LOGIN_OPTION:
+ need_login = 1;
+ include_idle = 1;
+ assumptions = 0;
+ break;
+
case 'm':
my_line_only = 1;
break;
- case 'l':
- do_lookup = 1;
+ case 'p':
+ need_initspawn = 1;
+ assumptions = 0;
break;
case 'q':
short_list = 1;
break;
- case 's':
+ case 'r':
+ need_runlevel = 1;
+ include_idle = 1;
+ assumptions = 0;
break;
- case 'i':
- case 'u':
- include_idle = 1;
+ case 's':
+ short_output = 1;
break;
- case 'H':
- include_heading = 1;
+ case 't':
+ need_clockchange = 1;
+ assumptions = 0;
break;
- case 'w':
case 'T':
+ case 'w':
include_mesg = 1;
break;
- case_GETOPT_HELP_CHAR;
+ case 'i':
+ error (0, 0,
+ _("Warning: -i will be removed in a future release; \
+ use -u instead"));
+ /* Fall through. */
+ case 'u':
+ need_users = 1;
+ include_idle = 1;
+ assumptions = 0;
+ break;
- case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
+ case 'l':
+ error (0, 0,
+ _("Warning: the meaning of '-l' will change in a future\
+ release to conform to POSIX"));
+ case LOOKUP_OPTION:
+ do_lookup = 1;
+ break;
+
+ case_GETOPT_HELP_CHAR;
+
+ case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
usage (1);
}
}
+ if (assumptions)
+ {
+ need_users = 1;
+ short_output = 1;
+ }
+
+ if (include_exit)
+ {
+ short_output = 0;
+ }
+
switch (argc - optind)
{
case 0: /* who */
- if (my_line_only)
- who_am_i (UTMP_FILE);
- else
- who (UTMP_FILE);
+ who (UTMP_FILE);
break;
case 1: /* who <utmp file> */
- if (my_line_only)
- who_am_i (argv[optind]);
- else
- who (argv[optind]);
+ who (argv[optind]);
break;
case 2: /* who <blurf> <glop> */
- who_am_i (UTMP_FILE);
+ my_line_only = 1;
+ who (UTMP_FILE);
break;
default: /* lose */