usr.bin/last/want.c
void
wtmp(const char *file, int namesz, int linesz, int hostsz)
{
	struct utmp	*bp;		/* current structure */
	TTY	*T;			/* tty list entry */
	struct stat	stb;		/* stat of file for sz */
	time_t	delta;			/* time difference */
	off_t	bl;
	int	bytes, wfd;
	char	*ct;
	const char *crmsg;
	size_t  len = sizeof(*buf) * MAXUTMP;

	if ((buf = malloc(len)) == NULL)
		err(1, "Cannot allocate utmp buffer");

	crmsg = NULL;

	if ((wfd = open(file, O_RDONLY, 0)) < 0 || fstat(wfd, &stb) == -1)
		err(1, "%s", file);
	bl = (stb.st_size + len - 1) / len;

	buf[FIRSTVALID].ut_timefld = time(NULL);
	(void)signal(SIGINT, onintr);
	(void)signal(SIGQUIT, onintr);

	while (--bl >= 0) {
		if (lseek(wfd, bl * len, SEEK_SET) == -1 ||
		    (bytes = read(wfd, buf, len)) == -1)
			err(1, "%s", file);
		for (bp = &buf[bytes / sizeof(*buf) - 1]; bp >= buf; --bp) {
			/*
			 * if the terminal line is '~', the machine stopped.
			 * see utmp(5) for more info.
			 */
			if (bp->ut_line[0] == '~' && !bp->ut_line[1]) {
				/* everybody just logged out */
				for (T = ttylist; T; T = T->next)
					T->logout = -bp->ut_timefld;
				currentout = -bp->ut_timefld;
				crmsg = strncmp(bp->ut_name, "shutdown",
				    namesz) ? "crash" : "shutdown";
				if (want(bp, NO)) {
					ct = fmttime(bp->ut_timefld, fulltime);
					printf("%-*.*s  %-*.*s %-*.*s %s\n",
					    namesz, namesz, bp->ut_name,
					    linesz, linesz, bp->ut_line,
					    hostsz, hostsz, bp->ut_host, ct);
					if (maxrec != -1 && !--maxrec)
						return;
				}
				continue;
			}
			/*
			 * if the line is '{' or '|', date got set; see
			 * utmp(5) for more info.
			 */
			if ((bp->ut_line[0] == '{' || bp->ut_line[0] == '|')
			    && !bp->ut_line[1]) {
				if (want(bp, NO)) {
					ct = fmttime(bp->ut_timefld, fulltime);
				printf("%-*.*s  %-*.*s %-*.*s %s\n",
				    namesz, namesz,
				    bp->ut_name,
				    linesz, linesz,
				    bp->ut_line,
				    hostsz, hostsz,
				    bp->ut_host,
				    ct);
					if (maxrec && !--maxrec)
						return;
				}
				continue;
			}
			/* find associated tty */
			for (T = ttylist;; T = T->next) {
				if (!T) {
					/* add new one */
					T = addtty(bp->ut_line);
					break;
				}
				if (!strncmp(T->tty, bp->ut_line, LINESIZE))
					break;
			}
			if (TYPE(bp) == SIGNATURE)
				continue;
			if (bp->ut_name[0] && want(bp, YES)) {
				ct = fmttime(bp->ut_timefld, fulltime);
				printf("%-*.*s  %-*.*s %-*.*s %s ",
				    namesz, namesz, bp->ut_name,
				    linesz, linesz, bp->ut_line,
				    hostsz, hostsz, bp->ut_host,
				    ct);
				if (!T->logout)
					puts("  still logged in");
				else {
					if (T->logout < 0) {
						T->logout = -T->logout;
						printf("- %s", crmsg);
					}
					else
						printf("- %s",
						    fmttime(T->logout,
						    fulltime | TIMEONLY));
					delta = T->logout - bp->ut_timefld;
					if (delta < SECSPERDAY)
						printf("  (%s)\n",
						    fmttime(delta,
						    fulltime | TIMEONLY | GMT));
					else
						printf(" (%ld+%s)\n",
						    delta / SECSPERDAY,
						    fmttime(delta,
						    fulltime | TIMEONLY | GMT));
				}
				if (maxrec != -1 && !--maxrec)
					return;
			}
			T->logout = bp->ut_timefld;
		}
	}
	fulltime = 1;	/* show full time */
	crmsg = fmttime(buf[FIRSTVALID].ut_timefld, FULLTIME);
	if ((ct = strrchr(file, '/')) != NULL)
		ct++;
	printf("\n%s begins %s\n", ct ? ct : file, crmsg);
}
/*
 * wtmp --
 *	read through the wtmp file
 */
wtmp
read through the wtmp file
wtmp read through the wtmp file
void
wtmp(const char *file, int namesz, int linesz, int hostsz)
{
	struct utmp	*bp;		
	TTY	*T;			
	struct stat	stb;		
	time_t	delta;			
	off_t	bl;
	int	bytes, wfd;
	char	*ct;
	const char *crmsg;
	size_t  len = sizeof(*buf) * MAXUTMP;
	if ((buf = malloc(len)) == NULL)
		err(1, "Cannot allocate utmp buffer");
	crmsg = NULL;
	if ((wfd = open(file, O_RDONLY, 0)) < 0 || fstat(wfd, &stb) == -1)
		err(1, "%s", file);
	bl = (stb.st_size + len - 1) / len;
	buf[FIRSTVALID].ut_timefld = time(NULL);
	(void)signal(SIGINT, onintr);
	(void)signal(SIGQUIT, onintr);
	while (--bl >= 0) {
		if (lseek(wfd, bl * len, SEEK_SET) == -1 ||
		    (bytes = read(wfd, buf, len)) == -1)
			err(1, "%s", file);
		for (bp = &buf[bytes / sizeof(*buf) - 1]; bp >= buf; --bp) {
			if (bp->ut_line[0] == '~' && !bp->ut_line[1]) {
				for (T = ttylist; T; T = T->next)
					T->logout = -bp->ut_timefld;
				currentout = -bp->ut_timefld;
				crmsg = strncmp(bp->ut_name, "shutdown",
				    namesz) ? "crash" : "shutdown";
				if (want(bp, NO)) {
					ct = fmttime(bp->ut_timefld, fulltime);
					printf("%-*.*s  %-*.*s %-*.*s %s\n",
					    namesz, namesz, bp->ut_name,
					    linesz, linesz, bp->ut_line,
					    hostsz, hostsz, bp->ut_host, ct);
					if (maxrec != -1 && !--maxrec)
						return;
				}
				continue;
			}
			if ((bp->ut_line[0] == '{' || bp->ut_line[0] == '|')
			    && !bp->ut_line[1]) {
				if (want(bp, NO)) {
					ct = fmttime(bp->ut_timefld, fulltime);
				printf("%-*.*s  %-*.*s %-*.*s %s\n",
				    namesz, namesz,
				    bp->ut_name,
				    linesz, linesz,
				    bp->ut_line,
				    hostsz, hostsz,
				    bp->ut_host,
				    ct);
					if (maxrec && !--maxrec)
						return;
				}
				continue;
			}
			for (T = ttylist;; T = T->next) {
				if (!T) {
					T = addtty(bp->ut_line);
					break;
				}
				if (!strncmp(T->tty, bp->ut_line, LINESIZE))
					break;
			}
			if (TYPE(bp) == SIGNATURE)
				continue;
			if (bp->ut_name[0] && want(bp, YES)) {
				ct = fmttime(bp->ut_timefld, fulltime);
				printf("%-*.*s  %-*.*s %-*.*s %s ",
				    namesz, namesz, bp->ut_name,
				    linesz, linesz, bp->ut_line,
				    hostsz, hostsz, bp->ut_host,
				    ct);
				if (!T->logout)
					puts("  still logged in");
				else {
					if (T->logout < 0) {
						T->logout = -T->logout;
						printf("- %s", crmsg);
					}
					else
						printf("- %s",
						    fmttime(T->logout,
						    fulltime | TIMEONLY));
					delta = T->logout - bp->ut_timefld;
					if (delta < SECSPERDAY)
						printf("  (%s)\n",
						    fmttime(delta,
						    fulltime | TIMEONLY | GMT));
					else
						printf(" (%ld+%s)\n",
						    delta / SECSPERDAY,
						    fmttime(delta,
						    fulltime | TIMEONLY | GMT));
				}
				if (maxrec != -1 && !--maxrec)
					return;
			}
			T->logout = bp->ut_timefld;
		}
	}
	fulltime = 1;	
	crmsg = fmttime(buf[FIRSTVALID].ut_timefld, FULLTIME);
	if ((ct = strrchr(file, '/')) != NULL)
		ct++;
	printf("\n%s begins %s\n", ct ? ct : file, crmsg);
}
void wtmp ( const char * file , int namesz , int linesz , int hostsz ) { struct utmp * bp ; TTY * T ; struct stat stb ; time_t delta ; off_t bl ; int bytes , wfd ; char * ct ; const char * crmsg ; size_t len = sizeof ( * buf ) * MAXUTMP ; if ( ( buf = malloc ( len ) ) == NULL ) err ( 1 , " " ) ; crmsg = NULL ; if ( ( wfd = open ( file , O_RDONLY , 0 ) ) < 0 || fstat ( wfd , & stb ) == -1 ) err ( 1 , " " , file ) ; bl = ( stb . st_size + len - 1 ) / len ; buf [ FIRSTVALID ] . ut_timefld = time ( NULL ) ; ( void ) signal ( SIGINT , onintr ) ; ( void ) signal ( SIGQUIT , onintr ) ; while ( -- bl >= 0 ) { if ( lseek ( wfd , bl * len , SEEK_SET ) == -1 || ( bytes = read ( wfd , buf , len ) ) == -1 ) err ( 1 , " " , file ) ; for ( bp = & buf [ bytes / sizeof ( * buf ) - 1 ] ; bp >= buf ; -- bp ) { if ( bp -> ut_line [ 0 ] == ' ' && ! bp -> ut_line [ 1 ] ) { for ( T = ttylist ; T ; T = T -> next ) T -> logout = - bp -> ut_timefld ; currentout = - bp -> ut_timefld ; crmsg = strncmp ( bp -> ut_name , " " , namesz ) ? " " : " " ; if ( want ( bp , NO ) ) { ct = fmttime ( bp -> ut_timefld , fulltime ) ; printf ( " \n " , namesz , namesz , bp -> ut_name , linesz , linesz , bp -> ut_line , hostsz , hostsz , bp -> ut_host , ct ) ; if ( maxrec != -1 && ! -- maxrec ) return ; } continue ; } if ( ( bp -> ut_line [ 0 ] == ' ' || bp -> ut_line [ 0 ] == ' ' ) && ! bp -> ut_line [ 1 ] ) { if ( want ( bp , NO ) ) { ct = fmttime ( bp -> ut_timefld , fulltime ) ; printf ( " \n " , namesz , namesz , bp -> ut_name , linesz , linesz , bp -> ut_line , hostsz , hostsz , bp -> ut_host , ct ) ; if ( maxrec && ! -- maxrec ) return ; } continue ; } for ( T = ttylist ; ; T = T -> next ) { if ( ! T ) { T = addtty ( bp -> ut_line ) ; break ; } if ( ! strncmp ( T -> tty , bp -> ut_line , LINESIZE ) ) break ; } if ( TYPE ( bp ) == SIGNATURE ) continue ; if ( bp -> ut_name [ 0 ] && want ( bp , YES ) ) { ct = fmttime ( bp -> ut_timefld , fulltime ) ; printf ( " " , namesz , namesz , bp -> ut_name , linesz , linesz , bp -> ut_line , hostsz , hostsz , bp -> ut_host , ct ) ; if ( ! T -> logout ) puts ( " " ) ; else { if ( T -> logout < 0 ) { T -> logout = - T -> logout ; printf ( " " , crmsg ) ; } else printf ( " " , fmttime ( T -> logout , fulltime | TIMEONLY ) ) ; delta = T -> logout - bp -> ut_timefld ; if ( delta < SECSPERDAY ) printf ( " \n " , fmttime ( delta , fulltime | TIMEONLY | GMT ) ) ; else printf ( " \n " , delta / SECSPERDAY , fmttime ( delta , fulltime | TIMEONLY | GMT ) ) ; } if ( maxrec != -1 && ! -- maxrec ) return ; } T -> logout = bp -> ut_timefld ; } } fulltime = 1 ; crmsg = fmttime ( buf [ FIRSTVALID ] . ut_timefld , FULLTIME ) ; if ( ( ct = strrchr ( file , ' ' ) ) != NULL ) ct ++ ; printf ( " \n \n " , ct ? ct : file , crmsg ) ; }
wtmp
      read through the wtmp file
wtmp read through the wtmp file
/* current structure */ /* tty list entry */ /* stat of file for sz */ /* time difference */ /*
			 * if the terminal line is '~', the machine stopped.
			 * see utmp(5) for more info.
			 */ /* everybody just logged out */ /*
			 * if the line is '{' or '|', date got set; see
			 * utmp(5) for more info.
			 */ /* find associated tty */ /* add new one */ /* show full time */