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 }