lastlog.c - ubase - suckless linux base utils
 (HTM) git clone git://git.suckless.org/ubase
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) 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 }