lastlog.c - ubase - suckless linux base utils | |
git clone git://git.suckless.org/ubase | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
lastlog.c (1555B) | |
--- | |
1 /* See LICENSE file for copyright and license details. */ | |
2 #include <errno.h> | |
3 #include <paths.h> | |
4 #include <pwd.h> | |
5 #include <stdio.h> | |
6 #include <stdlib.h> | |
7 #include <string.h> | |
8 #include <time.h> | |
9 #include <utmp.h> | |
10 | |
11 #include "text.h" | |
12 #include "util.h" | |
13 | |
14 #define PASSWD "/etc/passwd" | |
15 | |
16 static FILE *last; | |
17 | |
18 static void | |
19 lastlog(char *user) | |
20 { | |
21 struct passwd *pwd; | |
22 struct lastlog ll; | |
23 time_t lltime; | |
24 | |
25 errno = 0; | |
26 if ((pwd = getpwnam(user)) == NULL) { | |
27 if (errno) | |
28 weprintf("getpwnam %s:", user); | |
29 else | |
30 weprintf("unknown user: %s\n", user); | |
31 return; | |
32 } | |
33 | |
34 fseek(last, pwd->pw_uid * sizeof(struct lastlog), 0); | |
35 fread(&ll, sizeof(struct lastlog), 1, last); | |
36 | |
37 if (ferror(last)) | |
38 eprintf("%s: read error:", _PATH_LASTLOG); | |
39 | |
40 /* on glibc `ll_time' can be an int32_t with compat32 | |
41 * avoid compiler warning when calling ctime() */ | |
42 lltime = ll.ll_time; | |
43 printf("%-8.8s %-8.8s %-16.16s %s", | |
44 user, ll.ll_line, ll.ll_host, ctime(&lltime)); | |
45 } | |
46 | |
47 int | |
48 main(int argc, char **argv) | |
49 { | |
50 FILE *fp; | |
51 char *line = NULL, *p; | |
52 size_t sz = 0; | |
53 | |
54 if ((last = fopen(_PATH_LASTLOG, "r")) == NULL) | |
55 eprintf("fopen %s:", _PATH_LASTLOG); | |
56 | |
57 if (argc > 1) { | |
58 while (*++argv) | |
59 lastlog(*argv); | |
60 } else { | |
61 if ((fp = fopen(PASSWD, "r")) == NULL) | |
62 eprintf("fopen %s:", PASSWD); | |
63 while (agetline(&line, &sz, fp) != -1) { | |
64 if ((p = strchr(line, ':')) == NULL) | |
65 eprintf("invalid passwd entry\n"); | |
66 *p = '\0'; | |
67 lastlog(line); | |
68 } | |
69 if (fclose(fp)) | |
70 eprintf("fclose %s:", PASSWD); | |
71 free(line); | |
72 } | |
73 | |
74 if (fclose(last)) | |
75 eprintf("fclose %s:", _PATH_LASTLOG); | |
76 | |
77 return 0; | |
78 } |