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 }