diff --git a/man/wtmpdb.8.xml b/man/wtmpdb.8.xml
index 1cd07ca..a814b86 100644
--- a/man/wtmpdb.8.xml
+++ b/man/wtmpdb.8.xml
@@ -81,16 +81,6 @@
-
-
- FILE
-
-
-
- Use FILE as wtmpdb database.
-
-
-
@@ -242,16 +232,6 @@
to the /var/lib/wtmpdb/wtmp.db database.
boot options
-
-
- FILE
-
-
-
- Use FILE as wtmpdb database.
-
-
-
@@ -264,6 +244,16 @@
+
+
+ boottime
+ option…
+
+
+ wtmpdb boottime shows the time of the
+ last boot.
+
+
shutdown
option…
@@ -273,17 +263,6 @@
requests to the /var/lib/wtmpdb/wtmp.db
database.
- shutdown options
-
-
- FILE
-
-
-
- Use FILE as wtmpdb database.
-
-
-
@@ -296,17 +275,6 @@
database and removes these entries from the original one.
rotate options
-
-
- FILE
-
-
-
- Use FILE as wtmpdb database.
- The exported DB file will be on the same location.
-
-
-
DAYS
@@ -331,22 +299,20 @@
files to the /var/lib/wtmpdb/wtmp.db
database.
- import options
-
-
- FILE
-
-
-
- Use FILE as wtmpdb database.
-
-
-
- global options
+ common options
global options
+
+
+ FILE
+
+
+ Use FILE as wtmpdb
+ database.
+
+
diff --git a/src/wtmpdb.c b/src/wtmpdb.c
index 4bd4671..64e1589 100644
--- a/src/wtmpdb.c
+++ b/src/wtmpdb.c
@@ -93,6 +93,22 @@ static time_t since = 0; /* Who was logged in after this time? */
static time_t until = 0; /* Who was logged in until this time? */
static char **match = NULL; /* user/tty to display only */
+typedef enum cmd_idx {
+ CMD_NONE = 0,
+ CMD_LAST,
+ CMD_BOOT,
+ CMD_SHUTDOWN,
+ CMD_BOOTTIME,
+ CMD_ROTATE,
+ CMD_IMPORT,
+ CMD_MAX /* per contract the always the last one */
+} cmd_idx_t;
+
+static const char *cmd_name[] = {
+ "unknown", "last", "boot", "shutdown", "boottime",
+ "rotate", "import", NULL
+};
+
/* isipaddr - find out if string provided is an IP address or not
0 - no IP address
@@ -644,16 +660,37 @@ print_entry (void *unused __attribute__((__unused__)),
}
static void
-usage (int retval)
+show_version(void)
{
- FILE *output = (retval != EXIT_SUCCESS) ? stderr : stdout;
+ printf ("wtmpdb %s\n", VERSION);
+ exit(EXIT_SUCCESS);
+}
- fprintf (output, "Usage: wtmpdb [command] [options]\n");
- fputs ("Commands: last, boot, boottime, rotate, shutdown, import\n\n", output);
- fputs ("Options for last:\n", output);
+static void
+usage (int retval, cmd_idx_t cmd)
+{
+ FILE *output = (retval != EXIT_SUCCESS) ? stderr : stdout;
+ int i;
+
+ if (cmd == CMD_NONE) {
+ fprintf (output, "Usage: wtmpdb [command] [options] [operand]\n");
+ fprintf (output, "\nCommands: %s", cmd_name[1]);
+ for (i=2; i < CMD_MAX; i++)
+ fprintf(output, ", %s", cmd_name[i]);
+ fputs("\n\nCommon options:\n", output);
+ } else {
+ fprintf (output, "Usage: wtmpdb %s [options]%s\n", cmd_name[cmd],
+ (cmd == CMD_LAST || cmd == CMD_IMPORT) ? " [operand]" : "");
+ fputs ("\nOptions:\n", output);
+ }
+ fputs (" -f, --file FILE Use FILE as wtmpdb database\n", output);
+ fputs (" -h, --help Display this help message and exit\n", output);
+ fputs (" -v, --version Print version number and exit\n", output);
+ if (cmd == CMD_NONE)
+ fprintf (output, "\nOptions for %s:\n", cmd_name[CMD_LAST]);
+ if (cmd == CMD_LAST || cmd == CMD_NONE) {
fputs (" -a, --hostlast Display hostnames as last entry\n", output);
fputs (" -d, --dns Translate IP addresses into a hostname\n", output);
- fputs (" -f, --file FILE Use FILE as wtmpdb database\n", output);
fputs (" -F, --fulltimes Display full times and dates\n", output);
fputs (" -i, --ip Translate hostnames to IP addresses\n", output);
fputs (" -j, --json Generate JSON output\n", output);
@@ -665,40 +702,30 @@ usage (int retval)
fputs (" -t, --until TIME Display who was logged in until TIME\n", output);
fputs (" -w, --fullnames Display full IP addresses and user and domain names\n", output);
fputs (" -x, --system Display system shutdown entries\n", output);
- fputs (" --time-format FORMAT Display timestamps in the specified FORMAT:\n", output);
- fputs (" notime|short|full|iso\n", output);
-
- fputs (" [username...] Display only entries matching these arguments\n", output);
- fputs (" [tty...] Display only entries matching these arguments\n", output);
- fputs ("TIME must be in the format \"YYYY-MM-DD HH:MM:SS\"\n", output);
- fputs ("\n", output);
-
- fputs ("Options for boot (writes boot entry to wtmpdb):\n", output);
- fputs (" -f, --file FILE Use FILE as wtmpdb database\n", output);
- fputs ("\n", output);
-
- fputs ("Options for boottime (print time of last system boot):\n", output);
- fputs (" -f, --file FILE Use FILE as wtmpdb database\n", output);
- fputs ("\n", output);
-
- fputs ("Options for rotate (exports old entries to wtmpdb_)):\n", output);
- fputs (" -f, --file FILE Use FILE as wtmpdb database\n", output);
+ fputs (" --time-format FMT Display timestamps in the specified format.\n", output);
+ fputs ("\n FMT format: notime|short|full|iso\n", output);
+ fputs (" TIME format: YYYY-MM-DD HH:MM:SS\n", output);
+ }
+ if (cmd == CMD_NONE)
+ fprintf (output, "\nOperands for %s:\n", cmd_name[CMD_LAST]);
+ if (cmd == CMD_LAST) {
+ fputs ("\nOperands:\n", output);
+ }
+ if (cmd == CMD_LAST || cmd == CMD_NONE) {
+ fputs (" username... Display only entries matching these arguments\n", output);
+ fputs (" tty... Display only entries matching these arguments\n", output);
+ }
+ if (cmd == CMD_NONE)
+ fputs ("\nOptions for rotate (exports old entries to wtmpdb_)):\n", output);
+ if (cmd == CMD_NONE || cmd == CMD_ROTATE) {
fputs (" -d, --days INTEGER Export all entries which are older than the given days\n", output);
- fputs ("\n", output);
-
- fputs ("Options for shutdown (writes shutdown time to wtmpdb):\n", output);
- fputs (" -f, --file FILE Use FILE as wtmpdb database\n", output);
- fputs ("\n", output);
-
- fputs ("Options for import (imports legacy wtmp logs):\n", output);
- fputs (" -f, --file FILE Use FILE as wtmpdb database\n", output);
+ }
+ if (cmd == CMD_NONE)
+ fprintf (output, "\nOperands for %s:\n", cmd_name[CMD_IMPORT]);
+ if (cmd == CMD_IMPORT)
+ fputs ("\nOperands:\n", output);
+ if (cmd == CMD_IMPORT || cmd == CMD_NONE)
fputs (" logs... Legacy log files to import\n", output);
- fputs ("\n", output);
-
- fputs ("Generic options:\n", output);
- fputs (" -h, --help Display this help message and exit\n", output);
- fputs (" -v, --version Print version number and exit\n", output);
- fputs ("\n", output);
exit (retval);
}
@@ -706,6 +733,8 @@ static int
main_rotate (int argc, char **argv)
{
struct option const longopts[] = {
+ {"help", no_argument, NULL, 'h'},
+ {"version", no_argument, NULL, 'v'},
{"file", required_argument, NULL, 'f'},
{"days", no_argument, NULL, 'd'},
{NULL, 0, NULL, '\0'}
@@ -717,7 +746,7 @@ main_rotate (int argc, char **argv)
int c;
- while ((c = getopt_long (argc, argv, "f:d:", longopts, NULL)) != -1)
+ while ((c = getopt_long (argc, argv, "f:d:hv", longopts, NULL)) != -1)
{
switch (c)
{
@@ -727,8 +756,14 @@ main_rotate (int argc, char **argv)
case 'd':
days = atoi (optarg);
break;
+ case 'v':
+ show_version();
+ break;
+ case 'h':
+ usage (EXIT_SUCCESS, CMD_ROTATE);
+ break;
default:
- usage (EXIT_FAILURE);
+ usage (EXIT_FAILURE, CMD_ROTATE);
break;
}
}
@@ -736,7 +771,7 @@ main_rotate (int argc, char **argv)
if (argc > optind)
{
fprintf (stderr, "Unexpected argument: %s\n", argv[optind]);
- usage (EXIT_FAILURE);
+ usage (EXIT_FAILURE, CMD_ROTATE);
}
if (wtmpdb_rotate (wtmpdb_path, days, &error,
@@ -768,6 +803,8 @@ static int
main_last (int argc, char **argv)
{
struct option const longopts[] = {
+ {"help", no_argument, NULL, 'h'},
+ {"version", no_argument, NULL, 'v'},
{"hostlast", no_argument, NULL, 'a'},
{"dns", no_argument, NULL, 'd'},
{"file", required_argument, NULL, 'f'},
@@ -789,7 +826,7 @@ main_last (int argc, char **argv)
char *error = NULL;
int c;
- while ((c = getopt_long (argc, argv, "0123456789adf:Fijn:p:RSs:t:wx",
+ while ((c = getopt_long (argc, argv, "0123456789adf:Fhijn:p:RSs:t:vwx",
longopts, NULL)) != -1)
{
switch (c)
@@ -871,8 +908,14 @@ main_last (int argc, char **argv)
exit (EXIT_FAILURE);
}
break;
+ case 'v':
+ show_version();
+ break;
+ case 'h':
+ usage (EXIT_SUCCESS, CMD_LAST);
+ break;
default:
- usage (EXIT_FAILURE);
+ usage (EXIT_FAILURE, CMD_LAST);
break;
}
}
@@ -883,25 +926,25 @@ main_last (int argc, char **argv)
if (nohostname && hostlast)
{
fprintf (stderr, "The options -a and -R cannot be used together.\n");
- usage (EXIT_FAILURE);
+ usage (EXIT_FAILURE, CMD_LAST);
}
if (nohostname && dflag)
{
fprintf (stderr, "The options -d and -R cannot be used together.\n");
- usage (EXIT_FAILURE);
+ usage (EXIT_FAILURE, CMD_LAST);
}
if (nohostname && iflag)
{
fprintf (stderr, "The options -i and -R cannot be used together.\n");
- usage (EXIT_FAILURE);
+ usage (EXIT_FAILURE, CMD_LAST);
}
if (dflag && iflag)
{
fprintf (stderr, "The options -d and -i cannot be used together.\n");
- usage (EXIT_FAILURE);
+ usage (EXIT_FAILURE, CMD_LAST);
}
if (jflag)
@@ -1024,6 +1067,8 @@ static int
main_boot (int argc, char **argv)
{
struct option const longopts[] = {
+ {"help", no_argument, NULL, 'h'},
+ {"version", no_argument, NULL, 'v'},
{"file", required_argument, NULL, 'f'},
{"quiet", no_argument, NULL, 'q'},
{NULL, 0, NULL, '\0'}
@@ -1035,7 +1080,7 @@ main_boot (int argc, char **argv)
int quiet = 0;
#endif
- while ((c = getopt_long (argc, argv, "f:q", longopts, NULL)) != -1)
+ while ((c = getopt_long (argc, argv, "f:hqv", longopts, NULL)) != -1)
{
switch (c)
{
@@ -1047,8 +1092,14 @@ main_boot (int argc, char **argv)
quiet = 1;
#endif
break;
+ case 'v':
+ show_version();
+ break;
+ case 'h':
+ usage (EXIT_SUCCESS, CMD_BOOT);
+ break;
default:
- usage (EXIT_FAILURE);
+ usage (EXIT_FAILURE, CMD_BOOT);
break;
}
}
@@ -1056,7 +1107,7 @@ main_boot (int argc, char **argv)
if (argc > optind)
{
fprintf (stderr, "Unexpected argument: %s\n", argv[optind]);
- usage (EXIT_FAILURE);
+ usage (EXIT_FAILURE, CMD_BOOT);
}
struct utsname uts;
@@ -1125,6 +1176,8 @@ static int
main_boottime (int argc, char **argv)
{
struct option const longopts[] = {
+ {"help", no_argument, NULL, 'h'},
+ {"version", no_argument, NULL, 'v'},
{"file", required_argument, NULL, 'f'},
{NULL, 0, NULL, '\0'}
};
@@ -1132,15 +1185,21 @@ main_boottime (int argc, char **argv)
int c;
uint64_t boottime;
- while ((c = getopt_long (argc, argv, "f:", longopts, NULL)) != -1)
+ while ((c = getopt_long (argc, argv, "f:hv", longopts, NULL)) != -1)
{
switch (c)
{
case 'f':
wtmpdb_path = optarg;
break;
+ case 'v':
+ show_version();
+ break;
+ case 'h':
+ usage (EXIT_SUCCESS, CMD_BOOTTIME);
+ break;
default:
- usage (EXIT_FAILURE);
+ usage (EXIT_FAILURE, CMD_BOOTTIME);
break;
}
}
@@ -1148,7 +1207,7 @@ main_boottime (int argc, char **argv)
if (argc > optind)
{
fprintf (stderr, "Unexpected argument: %s\n", argv[optind]);
- usage (EXIT_FAILURE);
+ usage (EXIT_FAILURE, CMD_BOOTTIME);
}
boottime = wtmpdb_get_boottime (wtmpdb_path, &error);
@@ -1172,21 +1231,29 @@ static int
main_shutdown (int argc, char **argv)
{
struct option const longopts[] = {
+ {"help", no_argument, NULL, 'h'},
+ {"version", no_argument, NULL, 'v'},
{"file", required_argument, NULL, 'f'},
{NULL, 0, NULL, '\0'}
};
char *error = NULL;
int c;
- while ((c = getopt_long (argc, argv, "f:", longopts, NULL)) != -1)
+ while ((c = getopt_long (argc, argv, "f:hv", longopts, NULL)) != -1)
{
switch (c)
{
case 'f':
wtmpdb_path = optarg;
break;
+ case 'v':
+ show_version();
+ break;
+ case 'h':
+ usage (EXIT_SUCCESS, CMD_SHUTDOWN);
+ break;
default:
- usage (EXIT_FAILURE);
+ usage (EXIT_FAILURE, CMD_SHUTDOWN);
break;
}
}
@@ -1194,7 +1261,7 @@ main_shutdown (int argc, char **argv)
if (argc > optind)
{
fprintf (stderr, "Unexpected argument: %s\n", argv[optind]);
- usage (EXIT_FAILURE);
+ usage (EXIT_FAILURE, CMD_SHUTDOWN);
}
#if HAVE_AUDIT
@@ -1239,20 +1306,28 @@ static int
main_import (int argc, char **argv)
{
struct option const longopts[] = {
+ {"help", no_argument, NULL, 'h'},
+ {"version", no_argument, NULL, 'v'},
{"file", required_argument, NULL, 'f'},
{NULL, 0, NULL, '\0'}
};
int c;
- while ((c = getopt_long (argc, argv, "f:", longopts, NULL)) != -1)
+ while ((c = getopt_long (argc, argv, "f:hv", longopts, NULL)) != -1)
{
switch (c)
{
case 'f':
wtmpdb_path = optarg;
break;
+ case 'v':
+ show_version();
+ break;
+ case 'h':
+ usage (EXIT_SUCCESS, CMD_IMPORT);
+ break;
default:
- usage (EXIT_FAILURE);
+ usage (EXIT_FAILURE, CMD_IMPORT);
break;
}
}
@@ -1260,7 +1335,7 @@ main_import (int argc, char **argv)
if (argc == optind)
{
fprintf (stderr, "No files specified to import.\n");
- usage (EXIT_FAILURE);
+ usage (EXIT_FAILURE, CMD_IMPORT);
}
for (; optind < argc; optind++)
@@ -1276,39 +1351,43 @@ main (int argc, char **argv)
struct option const longopts[] = {
{"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'v'},
+ {"file", required_argument, NULL, 'f'},
{NULL, 0, NULL, '\0'}
};
int c;
if (strcmp (basename(argv[0]), "last") == 0)
return main_last (argc, argv);
- else if (argc == 1)
- usage (EXIT_SUCCESS);
- else if (strcmp (argv[1], "last") == 0)
+ if (argc == 1)
+ usage (EXIT_SUCCESS, CMD_NONE);
+ if (strcmp (argv[1], cmd_name[CMD_LAST]) == 0)
return main_last (--argc, ++argv);
- else if (strcmp (argv[1], "boot") == 0)
+ if (strcmp (argv[1], cmd_name[CMD_BOOT]) == 0)
return main_boot (--argc, ++argv);
- else if (strcmp (argv[1], "shutdown") == 0)
+ if (strcmp (argv[1], cmd_name[CMD_SHUTDOWN]) == 0)
return main_shutdown (--argc, ++argv);
- else if (strcmp (argv[1], "boottime") == 0)
+ if (strcmp (argv[1], cmd_name[CMD_BOOTTIME]) == 0)
return main_boottime (--argc, ++argv);
- else if (strcmp (argv[1], "rotate") == 0)
+ if (strcmp (argv[1], cmd_name[CMD_ROTATE]) == 0)
return main_rotate (--argc, ++argv);
- else if (strcmp (argv[1], "import") == 0)
+ if (strcmp (argv[1], cmd_name[CMD_IMPORT]) == 0)
return main_import (--argc, ++argv);
- while ((c = getopt_long (argc, argv, "hv", longopts, NULL)) != -1)
+ while ((c = getopt_long (argc, argv, "f:hv", longopts, NULL)) != -1)
{
switch (c)
{
case 'h':
- usage (EXIT_SUCCESS);
+ usage (EXIT_SUCCESS, CMD_NONE);
break;
case 'v':
- printf ("wtmpdb %s\n", VERSION);
+ show_version();
+ break;
+ case 'f':
+ /* ignore common option */
break;
default:
- usage (EXIT_FAILURE);
+ usage (EXIT_FAILURE, CMD_NONE);
break;
}
}
@@ -1316,7 +1395,7 @@ main (int argc, char **argv)
if (argc > optind)
{
fprintf (stderr, "Unexpected argument: %s\n", argv[optind]);
- usage (EXIT_FAILURE);
+ usage (EXIT_FAILURE, CMD_NONE);
}
exit (EXIT_SUCCESS);