]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
last: allow --file to be defined multiple times
authorSami Kerola <kerolasa@iki.fi>
Sat, 17 Aug 2013 18:15:20 +0000 (19:15 +0100)
committerKarel Zak <kzak@redhat.com>
Fri, 23 Aug 2013 09:31:34 +0000 (11:31 +0200)
This is useful when an admin is trying to find something, and has to
process all available data.

Signed-off-by: Sami Kerola <kerolasa@iki.fi>
login-utils/last.1
login-utils/last.c

index eff6fe449a9ea079e78936e7e2518d8e2ee5d897..e2ac438156c6b234ba9266ce6ecac7eb91297e75 100644 (file)
@@ -76,6 +76,10 @@ Tell
 .B last
 to use a specific file instead of
 .BR /var/log/wtmp .
+The
+.BI \-\-file " file"
+can be specified multiple times, and all of the defined files will be
+processed.
 .TP
 \fB\-\fInumber\fR
 .TQ
index e3add591a328e80c36a98de3f8fef44b2289ab7f..90bd932cd76a5cfec43ee93bde2619027ff957fe 100644 (file)
@@ -473,7 +473,7 @@ static time_t parsetm(char *ts)
        return tm;
 }
 
-int main(int argc, char **argv)
+static void process_wtmp_file(char *ufile, int lastb, int extended, time_t until)
 {
        FILE *fp;               /* Filepointer of wtmp file */
 
@@ -491,95 +491,6 @@ int main(int argc, char **argv)
        struct stat st;         /* To stat the [uw]tmp file */
        int quit = 0;           /* Flag */
        int down = 0;           /* Down flag */
-       int lastb = 0;          /* Is this 'lastb' ? */
-       int extended = 0;       /* Lots of info. */
-       char *altufile = NULL;  /* Alternate wtmp */
-
-       time_t until = 0;       /* at what time to stop parsing the file */
-
-       static const struct option long_opts[] = {
-             { "limit",        required_argument, NULL, 'n' },
-             { "help", no_argument,       NULL, 'h' },
-             { "file",       required_argument, NULL, 'f' },
-             { "nohostname", no_argument,       NULL, 'R' },
-             { "version",    no_argument,       NULL, 'V' },
-             { "hostlast",   no_argument,       NULL, 'a' },
-             { "until",      required_argument, NULL, 't' },
-             { "system",     no_argument,       NULL, 'x' },
-             { "dns",        no_argument,       NULL, 'd' },
-             { "ip",         no_argument,       NULL, 'i' },
-             { "fulltimes",  no_argument,       NULL, 'F' },
-             { "fullnames",  no_argument,       NULL, 'w' },
-             { NULL, 0, NULL, 0 }
-       };
-
-       setlocale(LC_ALL, "");
-       bindtextdomain(PACKAGE, LOCALEDIR);
-       textdomain(PACKAGE);
-       atexit(close_stdout);
-
-       while ((c = getopt_long(argc, argv,
-                       "hVf:n:RxadFit:0123456789w", long_opts, NULL)) != -1) {
-               switch(c) {
-               case 'h':
-                       usage(stdout);
-                       break;
-               case 'V':
-                       printf(UTIL_LINUX_VERSION);
-                       return EXIT_SUCCESS;
-               case 'R':
-                       showhost = 0;
-                       break;
-               case 'x':
-                       extended = 1;
-                       break;
-               case 'n':
-                       maxrecs = strtos32_or_err(optarg, _("failed to parse number"));
-                       break;
-               case 'f':
-                       altufile = xstrdup(optarg);
-                       break;
-               case 'd':
-                       usedns++;
-                       break;
-               case 'i':
-                       useip++;
-                       break;
-               case 'a':
-                       altlist++;
-                       break;
-               case 'F':
-                       fulltime++;
-                       break;
-               case 't':
-                       until = parsetm(optarg);
-                       if (until == (time_t) -1)
-                               errx(EXIT_FAILURE, _("invalid time value \"%s\""), optarg);
-                       break;
-               case 'w':
-                       if (UT_NAMESIZE > name_len)
-                               name_len = UT_NAMESIZE;
-                       if (UT_HOSTSIZE > domain_len)
-                               domain_len = UT_HOSTSIZE;
-                       break;
-               case '0': case '1': case '2': case '3': case '4':
-               case '5': case '6': case '7': case '8': case '9':
-                       maxrecs = 10 * maxrecs + c - '0';
-                       break;
-               default:
-                       usage(stderr);
-                       break;
-               }
-       }
-
-       if (optind < argc)
-               show = argv + optind;
-
-       /*
-        * Which file do we want to read?
-        */
-       lastb = !strcmp(program_invocation_short_name, "lastb");
-       ufile = altufile ? altufile : lastb ? _PATH_BTMP : _PATH_WTMP;
 
        time(&lastdown);
        lastrch = lastdown;
@@ -805,7 +716,116 @@ int main(int argc, char **argv)
        }
 
        printf(_("\n%s begins %s"), basename(ufile), ctime(&begintime));
-
        fclose(fp);
+}
+
+int main(int argc, char **argv)
+{
+       int c, i;               /* Scratch */
+       char **altv = NULL;     /* Alternate wtmp files */
+       int altc = 0;           /* Number of alternative files */
+       int lastb = 0;          /* Is this 'lastb' ? */
+       int extended = 0;       /* Lots of info. */
+
+       time_t until = 0;       /* at what time to stop parsing the file */
+
+       static const struct option long_opts[] = {
+             { "limit",        required_argument, NULL, 'n' },
+             { "help", no_argument,       NULL, 'h' },
+             { "file",       required_argument, NULL, 'f' },
+             { "nohostname", no_argument,       NULL, 'R' },
+             { "version",    no_argument,       NULL, 'V' },
+             { "hostlast",   no_argument,       NULL, 'a' },
+             { "until",      required_argument, NULL, 't' },
+             { "system",     no_argument,       NULL, 'x' },
+             { "dns",        no_argument,       NULL, 'd' },
+             { "ip",         no_argument,       NULL, 'i' },
+             { "fulltimes",  no_argument,       NULL, 'F' },
+             { "fullnames",  no_argument,       NULL, 'w' },
+             { NULL, 0, NULL, 0 }
+       };
+
+       setlocale(LC_ALL, "");
+       bindtextdomain(PACKAGE, LOCALEDIR);
+       textdomain(PACKAGE);
+       atexit(close_stdout);
+
+       while ((c = getopt_long(argc, argv,
+                       "hVf:n:RxadFit:0123456789w", long_opts, NULL)) != -1) {
+               switch(c) {
+               case 'h':
+                       usage(stdout);
+                       break;
+               case 'V':
+                       printf(UTIL_LINUX_VERSION);
+                       return EXIT_SUCCESS;
+               case 'R':
+                       showhost = 0;
+                       break;
+               case 'x':
+                       extended = 1;
+                       break;
+               case 'n':
+                       maxrecs = strtos32_or_err(optarg, _("failed to parse number"));
+                       break;
+               case 'f':
+                       if (!altv)
+                               altv = xmalloc(sizeof(char *) * argc);
+                       altv[altc++] = xstrdup(optarg);
+                       break;
+               case 'd':
+                       usedns++;
+                       break;
+               case 'i':
+                       useip++;
+                       break;
+               case 'a':
+                       altlist++;
+                       break;
+               case 'F':
+                       fulltime++;
+                       break;
+               case 't':
+                       until = parsetm(optarg);
+                       if (until == (time_t) -1)
+                               errx(EXIT_FAILURE, _("invalid time value \"%s\""), optarg);
+                       break;
+               case 'w':
+                       if (UT_NAMESIZE > name_len)
+                               name_len = UT_NAMESIZE;
+                       if (UT_HOSTSIZE > domain_len)
+                               domain_len = UT_HOSTSIZE;
+                       break;
+               case '0': case '1': case '2': case '3': case '4':
+               case '5': case '6': case '7': case '8': case '9':
+                       maxrecs = 10 * maxrecs + c - '0';
+                       break;
+               default:
+                       usage(stderr);
+                       break;
+               }
+       }
+
+       if (optind < argc)
+               show = argv + optind;
+
+       /*
+        * Which file do we want to read?
+        */
+       lastb = !strcmp(program_invocation_short_name, "lastb");
+       if (!altc) {
+               altv = xmalloc(sizeof(char *));
+               if (lastb)
+                       altv[0] = xstrdup(_PATH_BTMP);
+               else
+                       altv[0] = xstrdup(_PATH_WTMP);
+               altc++;
+       }
+
+       for (i = 0; i < altc; i++) {
+               process_wtmp_file(altv[i], lastb, extended, until);
+               free(altv[i]);
+       }
+       free(altv);
        return EXIT_SUCCESS;
 }