summaryrefslogtreecommitdiffstats
path: root/login-utils/last.c
diff options
context:
space:
mode:
authorSami Kerola2013-08-17 20:15:20 +0200
committerKarel Zak2013-08-23 11:31:34 +0200
commit7ec782296506497aa133631d5af2f48a61367f29 (patch)
treee1ff7e59de612e33f9da47baade531e65c0f593f /login-utils/last.c
parentlast: global variables are initialize automatically to zero (diff)
downloadkernel-qcow2-util-linux-7ec782296506497aa133631d5af2f48a61367f29.tar.gz
kernel-qcow2-util-linux-7ec782296506497aa133631d5af2f48a61367f29.tar.xz
kernel-qcow2-util-linux-7ec782296506497aa133631d5af2f48a61367f29.zip
last: allow --file to be defined multiple times
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>
Diffstat (limited to 'login-utils/last.c')
-rw-r--r--login-utils/last.c202
1 files changed, 111 insertions, 91 deletions
diff --git a/login-utils/last.c b/login-utils/last.c
index e3add591a..90bd932cd 100644
--- a/login-utils/last.c
+++ b/login-utils/last.c
@@ -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;
}