Example #1
0
/*
 * wtmp --
 *	read through the wtmp file
 */
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);
}
Example #2
0
/*
 * read through the wtmp file
 */
void
wtmp(void)
{
	time_t	delta, total = 0;
	int	timesize, wfd, snapfound = 0;
	char	*ct, *crmsg, tim[40];
	struct utmp	*bp;
	struct stat	stb;
	ssize_t	bytes;
	off_t	bl;
	struct ttytab	*T;

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

	if (fulltime)
		timesize = 8;	/* HH:MM:SS */
	else
		timesize = 5;	/* HH:MM */

	(void)time(&buf[0].ut_time);
	(void)signal(SIGINT, onintr);
	(void)signal(SIGQUIT, onintr);

	while (--bl >= 0) {
		if (lseek(wfd, bl * sizeof(buf), SEEK_SET) == -1 ||
		    (bytes = read(wfd, buf, sizeof(buf))) == -1)
			err(1, "%s", file);
		for (bp = &buf[bytes / sizeof(buf[0]) - 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_time;
				currentout = -bp->ut_time;
				crmsg = strncmp(bp->ut_name, "shutdown",
				    UT_NAMESIZE) ? "crash" : "shutdown";

				/*
				 * if we're in snapshot mode, we want to
				 * exit if this shutdown/reboot appears
				 * while we we are tracking the active
				 * range
				 */
				if (snaptime && snapfound) {
					close(wfd);
					return;
				}

				/*
				 * don't print shutdown/reboot entries
				 * unless flagged for
				 */
				if (want(bp, NO)) {
					if (seconds) {
						snprintf(tim, sizeof tim, "%ld",
						    (long)bp->ut_time);
					} else {
						ct = ctime(&bp->ut_time);
						snprintf(tim, sizeof tim,
						    "%10.10s %*.*s", ct,
						    timesize, timesize, ct + 11);
					}
					printf("%-*.*s %-*.*s %-*.*s %s \n",
					    NAME_WIDTH, UT_NAMESIZE, bp->ut_name,
					    UT_LINESIZE, UT_LINESIZE, bp->ut_line,
					    HOST_WIDTH, UT_HOSTSIZE, bp->ut_host,
					    tim);

					if (maxrec != -1 && !--maxrec) {
						close(wfd);
						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)) {
					if (seconds) {
						snprintf(tim, sizeof tim, "%ld",
						    (long)bp->ut_time);
					} else {
						ct = ctime(&bp->ut_time);
						snprintf(tim, sizeof tim,
						    "%10.10s %*.*s", ct,
						    timesize, timesize, ct + 11);
					}
					printf("%-*.*s %-*.*s %-*.*s %s \n",
					    NAME_WIDTH, UT_NAMESIZE, bp->ut_name,
					    UT_LINESIZE, UT_LINESIZE, bp->ut_line,
					    HOST_WIDTH, UT_HOSTSIZE, bp->ut_host,
					    tim);

					if (maxrec && !--maxrec) {
						close(wfd);
						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, UT_LINESIZE))
					break;
			}

			/*
			 * print record if not in snapshot mode and wanted
			 * or in snapshot mode and in snapshot range
			 */
			if (bp->ut_name[0] &&
			    ((want(bp, YES)) || (bp->ut_time < snaptime &&
			    (T->logout > snaptime || !T->logout ||
			    T->logout < 0)))) {
				snapfound = 1;
				if (seconds) {
					snprintf(tim, sizeof tim, "%ld",
					    (long)bp->ut_time);
				} else {
					ct = ctime(&bp->ut_time);
					snprintf(tim, sizeof tim,
					    "%10.10s %*.*s", ct,
					    timesize, timesize, ct + 11);
				}
				printf("%-*.*s %-*.*s %-*.*s %s ",
				    NAME_WIDTH, UT_NAMESIZE, bp->ut_name,
				    UT_LINESIZE, UT_LINESIZE, bp->ut_line,
				    HOST_WIDTH, UT_HOSTSIZE, bp->ut_host,
				    tim);

				if (!T->logout)
					puts("  still logged in");
				else {
					if (T->logout < 0) {
						T->logout = -T->logout;
						printf("- %s", crmsg);
					} else {
						if (seconds)
							printf("- %ld",
							    (long)T->logout);
						else
							printf("- %*.*s",
							    timesize, timesize,
							    ctime(&T->logout)+11);
					}
					delta = T->logout - bp->ut_time;
					if (seconds)
						printf("  (%ld)\n", (long)delta);
					else {
						if (delta < SECSPERDAY)
							printf("  (%*.*s)\n",
							    timesize, timesize,
							    asctime(gmtime(&delta))+11);
						else
							printf(" (%ld+%*.*s)\n",
							    delta / SECSPERDAY,
							    timesize, timesize,
							    asctime(gmtime(&delta))+11);
					}
					if (calculate)
						total += delta;
				}
				if (maxrec != -1 && !--maxrec) {
					close(wfd);
					return;
				}
			}
			T->logout = bp->ut_time;
		}
	}
	close(wfd);
	if (calculate) {
		if ((total / SECSPERDAY) > 0) {
			int days = (total / SECSPERDAY);
			total -= (days * SECSPERDAY);

			printf("\nTotal time: %d days, %*.*s\n",
			    days, timesize, timesize,
			    asctime(gmtime(&total))+11);
		} else
			printf("\nTotal time: %*.*s\n",
			    timesize, timesize,
			    asctime(gmtime(&total))+11);
	}
	ct = ctime(&buf[0].ut_time);
	printf("\nwtmp begins %10.10s %*.*s %4.4s\n", ct, timesize, timesize,
	    ct + 11, ct + 20);
}
Example #3
0
/*
 * wtmp --
 *	read through the wtmp file
 */
static void
wtmp(void) {
	register struct utmp	*bp;		/* current structure */
	register TTY	*T;			/* tty list entry */
	long	delta;				/* time difference */
	char *crmsg = NULL;
	char *ct = NULL;
	int fd;
	struct utmp *utl;
	struct stat st;
	int utl_len;
	int listnr = 0;
	int i;

	utmpname(file);

	{
#if defined(_HAVE_UT_TV)
		struct timeval tv;
		gettimeofday(&tv, NULL);
		utmpbuf.ut_tv.tv_sec = tv.tv_sec;
		utmpbuf.ut_tv.tv_usec = tv.tv_usec;
#else
		time_t t;
		time(&t);
		utmpbuf.ut_time = t;
#endif
	}

	(void)signal(SIGINT, onintr);
	(void)signal(SIGQUIT, onintr);

	if ((fd = open(file,O_RDONLY)) < 0)
		exit(1);
	fstat(fd, &st);
	utl_len = st.st_size;
	utl = mmap(NULL, utl_len, PROT_READ|PROT_WRITE,
		   MAP_PRIVATE|MAP_FILE, fd, 0);
	if (utl == NULL)
		exit(1);
	listnr = utl_len/sizeof(struct utmp);

	if(listnr) 
		ct = utmp_ctime(&utl[0]);

	for(i = listnr - 1; i >= 0; i--) {
		bp = utl+i;
		/*
		 * if the terminal line is '~', the machine stopped.
		 * see utmp(5) for more info.
		 */
		if (!strncmp(bp->ut_line, "~", LMAX)) {
		    /* 
		     * utmp(5) also mentions that the user 
		     * name should be 'shutdown' or 'reboot'.
		     * Not checking the name causes e.g. runlevel
		     * changes to be displayed as 'crash'. -thaele
		     */
		    if (!strncmp(bp->ut_user, "reboot", NMAX) ||
			!strncmp(bp->ut_user, "shutdown", NMAX)) {	
			/* everybody just logged out */
			for (T = ttylist; T; T = T->next)
			    T->logout = -bp->ut_time;
		    }

		    currentout = -bp->ut_time;
		    crmsg = (strncmp(bp->ut_name, "shutdown", NMAX)
			    ? "crash" : "down ");
		    if (!bp->ut_name[0])
			(void)strcpy(bp->ut_name, "reboot");
		    if (want(bp, NO)) {
			ct = utmp_ctime(bp);
			if(bp->ut_type != LOGIN_PROCESS) {
			    print_partial_line(bp);
			    putchar('\n');
			}
			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, LMAX))
			break;
		}
		if (bp->ut_name[0] && bp->ut_type != LOGIN_PROCESS
		    && bp->ut_type != DEAD_PROCESS
		    && want(bp, YES)) {

		    print_partial_line(bp);

		    if (!T->logout)
			puts(_("  still logged in"));
		    else {
			if (T->logout < 0) {
			    T->logout = -T->logout;
			    printf("- %s", crmsg);
			}
			else
			    printf("- %5.5s", ctime(&T->logout)+11);
			delta = T->logout - bp->ut_time;
			if (delta < SECDAY)
			    printf("  (%5.5s)\n", asctime(gmtime(&delta))+11);
			else
			    printf(" (%ld+%5.5s)\n", delta / SECDAY, asctime(gmtime(&delta))+11);
		    }
		    if (maxrec != -1 && !--maxrec)
			return;
		}
		T->logout = bp->ut_time;
		utmpbuf.ut_time = bp->ut_time;
	}
	munmap(utl,utl_len);
	close(fd);
	if(ct) printf(_("\nwtmp begins %s"), ct); 	/* ct already ends in \n */
}