1 /* $NetBSD: lastlogin.c,v 1.6 2001/02/19 23:22:44 cgd Exp $ */ 2 /* 3 * Copyright (c) 1996 John M. Vinopal 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed for the NetBSD Project 17 * by John M. Vinopal. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include <sys/cdefs.h> 35 #ifndef lint 36 __RCSID("$NetBSD: lastlogin.c,v 1.6 2001/02/19 23:22:44 cgd Exp $"); 37 #endif 38 39 #include <sys/types.h> 40 #include <err.h> 41 #include <errno.h> 42 #include <pwd.h> 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <time.h> 46 #include <utmp.h> 47 #include <unistd.h> 48 49 static char *logfile = _PATH_LASTLOG; 50 51 int main __P((int, char **)); 52 static void output __P((struct passwd *, struct lastlog *)); 53 static void usage __P((void)); 54 55 int 56 main(argc, argv) 57 int argc; 58 char *argv[]; 59 { 60 int ch, i; 61 FILE *fp; 62 struct passwd *passwd; 63 struct lastlog last; 64 65 while ((ch = getopt(argc, argv, "")) != -1) { 66 usage(); 67 } 68 69 fp = fopen(logfile, "r"); 70 if (fp == NULL) 71 err(1, "%s", logfile); 72 73 setpassent(1); /* Keep passwd file pointers open */ 74 75 /* Process usernames given on the command line. */ 76 if (argc > 1) { 77 long offset; 78 for (i = 1; i < argc; ++i) { 79 if ((passwd = getpwnam(argv[i])) == NULL) { 80 warnx("user '%s' not found", argv[i]); 81 continue; 82 } 83 /* Calculate the offset into the lastlog file. */ 84 offset = (long)(passwd->pw_uid * sizeof(last)); 85 if (fseek(fp, offset, SEEK_SET)) { 86 warn("fseek error"); 87 continue; 88 } 89 if (fread(&last, sizeof(last), 1, fp) != 1) { 90 warnx("fread error on '%s'", passwd->pw_name); 91 clearerr(fp); 92 continue; 93 } 94 output(passwd, &last); 95 } 96 } 97 /* Read all lastlog entries, looking for active ones */ 98 else { 99 for (i = 0; fread(&last, sizeof(last), 1, fp) == 1; i++) { 100 if (last.ll_time == 0) 101 continue; 102 if ((passwd = getpwuid(i)) != NULL) 103 output(passwd, &last); 104 } 105 if (ferror(fp)) 106 warnx("fread error"); 107 } 108 109 setpassent(0); /* Close passwd file pointers */ 110 111 fclose(fp); 112 exit(0); 113 } 114 115 /* Duplicate the output of last(1) */ 116 static void 117 output(p, l) 118 struct passwd *p; 119 struct lastlog *l; 120 { 121 printf("%-*.*s %-*.*s %-*.*s %s", 122 UT_NAMESIZE, UT_NAMESIZE, p->pw_name, 123 UT_LINESIZE, UT_LINESIZE, l->ll_line, 124 UT_HOSTSIZE, UT_HOSTSIZE, l->ll_host, 125 (l->ll_time) ? ctime(&(l->ll_time)) : "Never logged in\n"); 126 } 127 128 static void 129 usage() 130 { 131 fprintf(stderr, "usage: %s [user ...]\n", getprogname()); 132 exit(1); 133 } 134