lastlog for SVR4
Tin Le
tin at smsc.sony.com
Thu May 23 07:09:55 AEST 1991
I ported this from Tom C.'s posting in just a few minutes. There is also
a lastlogin for System V (I have it running on ISC v2.0.2). With this,
you could have the same functionalities as with BSD systems.
Submitted-by: tin at rn31
Archive-name: lastlog/part01
---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is lastlog, a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 05/22/1991 21:05 UTC by tin at rn31
# Source directory /usr1/tin/News/last
#
# existing files will NOT be overwritten unless -c is specified
# This format requires very little intelligence at unshar time.
# "if test", "echo", "true", and "sed" may be needed.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 282 -rw-r--r-- Makefile
# 3458 -rw-r--r-- lastlog.c
#
# ============= Makefile ==============
if test -f 'Makefile' -a X"$1" != X"-c"; then
echo 'x - skipping Makefile (File already exists)'
else
echo 'x - extracting Makefile (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
X#
X# Makefile for last
X#
X# 5/22/91 Tin
X#
XTARGET = last
XOBJECTS = lastlog.o
XCFLAGS = -O -DSVR4
XLDFLAGS = -s
XLIBS =
XINCLDIR = /usr/include
X
X$(TARGET): $(OBJECTS)
X $(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(OBJECTS) $(LIBS)
X
Xclean:
X -rm -f $(OBJECTS) core
X
Xclobber: clean
X -rm -f $(TARGET)
X
SHAR_EOF
true || echo 'restore of Makefile failed'
fi
# ============= lastlog.c ==============
if test -f 'lastlog.c' -a X"$1" != X"-c"; then
echo 'x - skipping lastlog.c (File already exists)'
else
echo 'x - extracting lastlog.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'lastlog.c' &&
X/*
X * lastlog - print last login time for all users, based on times
X * stored in /usr/adm/lastlog.
X *
X * Lines are printed oldest first, with name, date/time, and gecos
X * field on each line.
X *
X * No command line options. Runs on VAX/4.2 BSD Unix, Sony RISC SVR4.
X *
X * compile with: cc -O -o lastlog lastlog.c
X *
X * Tin Le, Sony Microsystems, San Jose 5/22/91
X * - Adapted for SVR4.
X *
X * Rex Sanders, US Geological Survey, Pacific Marine Geology, 12/19/85
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#ifdef SVR4
X#include <fcntl.h>
X#include <string.h>
X#else
X#include <sys/file.h>
X#include <strings.h>
X#endif
X#include <lastlog.h>
X#include <pwd.h>
X#ifndef SVR4
X#include <sysexits.h>
X#else
X#define EX_OSFILE 1
X#define EX_SOFTWARE 2
X#endif
X
X/* In case your UNIX put lastlog somewhere other than */adm/lastlog */
X#define LASTLOG "/usr/adm/lastlog"
X
X/* maximum number of users/entries in /etc/passwd */
X#define MAXU 5000
X/* maximum length of the gecos field in /etc/passwd */
X#define MAXG 100
X
Xchar *ctime ();
Xlong lseek ();
X
Xstruct info_s {
X int time;
X#ifdef SVR4 /* Actually there is no hard limit in SVR4 struct passwd
X ** Change this to char *name, and malloc your string if you
X ** really want to get complicated.
X ** 5/22/91 Tin
X */
X char name[15];
X#else
X char name[9];
X#endif
X char gecos[MAXG];
X};
Xstruct info_s info[MAXU];
X
Xmain (argc, argv) char **argv; {
X int infocmp ();
X struct lastlog ll;
X struct passwd *pw;
X char lastdate[25];
X int llfd;
X register int nusers = 0;
X register int i;
X
X if ((llfd = open (LASTLOG, O_RDONLY)) < 0) {
X perror("open()");
X fprintf(stderr, "lastlog: %s\n", LASTLOG);
X exit (EX_OSFILE);
X }
X
X/*
X * For each user in password file, grab password info
X */
X while (pw = getpwent ()) {
X /*
X * Grab info from lastlog file
X */
X if (!strcmp(pw->pw_passwd,"*"))
X continue;
X if (lseek (llfd, (long) pw -> pw_uid * sizeof ll, 0) == -1) {
X fprintf(stderr,"%s: lseek for uid %d failed\n", *argv, pw->pw_uid);
X continue;
X }
X if (read (llfd, (char *) & ll, sizeof ll) != sizeof ll) {
X fprintf(stderr, "%s: read for uid %d (%s) failed\n",
X *argv, pw->pw_uid, pw->pw_name);
X continue;
X }
X
X
X info[nusers].time = ll.ll_time;
X#ifdef SVR4
X strcpy (info[nusers].name, pw -> pw_name);
X#else
X strncpy (info[nusers].name, pw -> pw_name, 9);
X#endif
X strncpy (info[nusers].gecos, pw -> pw_gecos, MAXG);
X if (nusers++ == MAXU) {
X fprintf(stderr, "%s: recompile with MAXU > %d\n",
X *argv, MAXU);
X exit(EX_SOFTWARE);
X }
X }
X
X/*
X * Sort users by last login time
X */
X qsort ((char *) info, nusers, sizeof (struct info_s), infocmp);
X
X/*
X * Print info for each user
X */
X for (i = 0; i < nusers; i++) {
X if (info[i].time) {
X strncpy (lastdate, ctime (&info[i].time), 24);
X lastdate[24] = '\0';
X }
X else
X strcpy (lastdate, "never logged in");
X
X printf ("%-12s %-24s %s\n", info[i].name, lastdate,
X info[i].gecos);
X }
X
X close (llfd);
X endpwent ();
X}
X
X/*
X * infocmp - compare 2 info entries for qsort
X */
X
Xinfocmp (info1, info2)
Xstruct info_s *info1,
X *info2;
X{
X register int r;
X
X if (info1 -> time == info2 -> time)
X r = 0;
X else
X r = (info1 -> time > info2 -> time) ? 1 : -1;
X
X return (r);
X}
X
SHAR_EOF
true || echo 'restore of lastlog.c failed'
fi
exit 0
--
.----------------------------------------------------------------------
. Tin Le Work Internet: tin at smsc.Sony.COM
. Sony Microsystems UUCP: {uunet,mips}!sonyusa!tin
. Work: (408) 944-4157 Home Internet: tin at szebra.uu.net
More information about the Alt.sources
mailing list