lastlogin.c revision 99800
168723Sru/* 268723Sru * Copyright (c) 1996 John M. Vinopal 368723Sru * All rights reserved. 468723Sru * 568723Sru * Redistribution and use in source and binary forms, with or without 668723Sru * modification, are permitted provided that the following conditions 768723Sru * are met: 868723Sru * 1. Redistributions of source code must retain the above copyright 968723Sru * notice, this list of conditions and the following disclaimer. 1068723Sru * 2. Redistributions in binary form must reproduce the above copyright 1168723Sru * notice, this list of conditions and the following disclaimer in the 1268723Sru * documentation and/or other materials provided with the distribution. 1368723Sru * 3. All advertising materials mentioning features or use of this software 1468723Sru * must display the following acknowledgement: 1568723Sru * This product includes software developed for the NetBSD Project 1668723Sru * by John M. Vinopal. 1768723Sru * 4. The name of the author may not be used to endorse or promote products 1868723Sru * derived from this software without specific prior written permission. 1968723Sru * 2068723Sru * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2168723Sru * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2268723Sru * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2368723Sru * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2468723Sru * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 2568723Sru * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 2668723Sru * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 2768723Sru * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 2868723Sru * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2968723Sru * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3068723Sru * SUCH DAMAGE. 3168723Sru */ 3268723Sru 3368723Sru#include <sys/cdefs.h> 3468723Sru#ifndef lint 3568723Sru__RCSID("$FreeBSD: head/usr.sbin/lastlogin/lastlogin.c 99800 2002-07-11 18:31:16Z alfred $"); 3668723Sru__RCSID("$NetBSD: lastlogin.c,v 1.4 1998/02/03 04:45:35 perry Exp $"); 3768723Sru#endif 3868723Sru 3998069Smike#include <sys/types.h> 4068723Sru#include <err.h> 4168723Sru#include <pwd.h> 4268723Sru#include <stdio.h> 4378719Sdd#include <stdlib.h> 4468723Sru#include <time.h> 4599604Sbde#include <timeconv.h> 4668723Sru#include <utmp.h> 4768723Sru#include <unistd.h> 4868723Sru 4968723Srustatic const char *logfile = _PATH_LASTLOG; 5068723Sru 5199800Salfred int main(int, char **); 5299800Salfredstatic void output(struct passwd *, struct lastlog *); 5399800Salfredstatic void usage(void); 5468723Sru 5568723Sruint 5668723Srumain(argc, argv) 5768723Sru int argc; 5868723Sru char *argv[]; 5968723Sru{ 6068723Sru int ch, i; 6168723Sru FILE *fp; 6268723Sru struct passwd *passwd; 6368723Sru struct lastlog last; 6468723Sru 6568723Sru while ((ch = getopt(argc, argv, "")) != -1) { 6668723Sru usage(); 6768723Sru } 6868723Sru 6968723Sru fp = fopen(logfile, "r"); 7068723Sru if (fp == NULL) 7168723Sru err(1, "%s", logfile); 7268723Sru 7368723Sru setpassent(1); /* Keep passwd file pointers open */ 7468723Sru 7568723Sru /* Process usernames given on the command line. */ 7668723Sru if (argc > 1) { 7768723Sru long offset; 7868723Sru for (i = 1; i < argc; ++i) { 7968723Sru if ((passwd = getpwnam(argv[i])) == NULL) { 8068723Sru warnx("user '%s' not found", argv[i]); 8168723Sru continue; 8268723Sru } 8368723Sru /* Calculate the offset into the lastlog file. */ 8468723Sru offset = (long)(passwd->pw_uid * sizeof(last)); 8568723Sru if (fseek(fp, offset, SEEK_SET)) { 8668723Sru warn("fseek error"); 8768723Sru continue; 8868723Sru } 8968723Sru if (fread(&last, sizeof(last), 1, fp) != 1) { 9068723Sru warnx("fread error on '%s'", passwd->pw_name); 9168723Sru clearerr(fp); 9268723Sru continue; 9368723Sru } 9468723Sru output(passwd, &last); 9568723Sru } 9668723Sru } 9768723Sru /* Read all lastlog entries, looking for active ones */ 9868723Sru else { 9968723Sru for (i = 0; fread(&last, sizeof(last), 1, fp) == 1; i++) { 10068723Sru if (last.ll_time == 0) 10168723Sru continue; 10268723Sru if ((passwd = getpwuid((uid_t)i)) != NULL) 10368723Sru output(passwd, &last); 10468723Sru } 10568723Sru if (ferror(fp)) 10668723Sru warnx("fread error"); 10768723Sru } 10868723Sru 10968723Sru setpassent(0); /* Close passwd file pointers */ 11068723Sru 11168723Sru fclose(fp); 11268723Sru exit(0); 11368723Sru} 11468723Sru 11568723Sru/* Duplicate the output of last(1) */ 11668723Srustatic void 11768723Sruoutput(p, l) 11868723Sru struct passwd *p; 11968723Sru struct lastlog *l; 12068723Sru{ 12189572Sdillon time_t t = _int_to_time(l->ll_time); 12268723Sru printf("%-*.*s %-*.*s %-*.*s %s", 12368723Sru UT_NAMESIZE, UT_NAMESIZE, p->pw_name, 12468723Sru UT_LINESIZE, UT_LINESIZE, l->ll_line, 12568723Sru UT_HOSTSIZE, UT_HOSTSIZE, l->ll_host, 12685651Sdillon (l->ll_time) ? ctime(&t) : "Never logged in\n"); 12768723Sru} 12868723Sru 12968723Srustatic void 13068723Sruusage() 13168723Sru{ 13269828Scharnier fprintf(stderr, "usage: lastlogin [user ...]\n"); 13368723Sru exit(1); 13468723Sru} 135