Bugtraq mailing list archives

lastx.c v2.0


From: warf () GOODNET COM (Ryan)
Date: Sun, 19 Apr 1998 04:17:42 -0700


Here's version 2.0 of Lastx.c.  There are 4 files here.

1.  README.TXT
2.  Makefile
3.  lastx.c
4.  lastx.h

just take all files and stick them into one directory.  type 'make' to
compile it, type 'make ; make install ; make clean' to make it, install
it, and clean it.  =)  It installs to /usr/local/bin/lastx

===== 1st file  -  README.TXT =============================

lastx v2.0    By Ryan Wyler <ryanw () goodnet com>


Package Includes:

        README.TXT      This file
        Makefile        Standard Makefile
        lastx.c         Main C file for lastx
        lastx.h         Header File


Authors Notes:
I origionally wrote lastx v1.0, but it was written very fast and very
poor.  Others (which knew C much better than I) ripped my code apart, or
actually threw it completely away, and basicly re-wrote lastx.

Purpose:
There have been many times when trying to track down a specific
login useing the 'last' command in solaris and have the users hostname/IP
address cut off.  The wtmp file does not retain the whole IP address.
Using this utility (lastx) it reads the wtmpx file and gives the whole
hostname/IP adresses.

Platforms:
Any Solaris box that uses the /var/adm/log/wtmpx.
Tested myself on Solaris 2.5.1 (Sparc).

Installation Notes:
Very Easy.  Run 'make; make install; make clean'

It will install the lastx binary to the /usr/local/bin directory with
owner of bin and group bin with permissions of 555 so anyone can use it.
I personally don't want users to access that, so I changed my permissions
on it to 550, owned by root, gid root.


Any Bugs/Questions/Comments/Patches/Ideas, Give me a holler:
Ryan Wyler  <ryanw () goodnet com>

=====  END OF README.TXT  =============================

===== 2nd file  -  Makefile  =============================

CC = gcc
RM = /bin/rm
INSTALL = /usr/sbin/install
CFLAGS = -ggdb -O2 -Wall
SRC = lastx.c
OBJ = lastx.o

lastx: $(OBJ)
        $(CC) $(CFLAGS) -o $@ $?

$(OBJ): $(SRC)
        $(CC) -c $? -o $@

install: lastx
        $(RM) -f /usr/local/bin/$?
        $(INSTALL) -s -c /usr/local/bin -m 555 -u bin -g bin $?

clean:
        $(RM) -f *.o core lastx

=====  END OF Makefile  =============================

===== 3rd file  -  lastx.c  =============================

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*  Lastx.c  v2.0    By Ryan Wyler  <ryanw () goodnet com>        */
/*                                                             */
/*  Discription:  Solaris wtmpx 'last logins' viewer           */
/*                                                             */
/*  This version was completely re-written from lastx.c v1.0   */
/*  It was re-written by a friend who decides to remain annon  */
/*                                                             */
/*  Changes:  In this version, you can read in different files */
/*  by placing a  -f <filename> in the command line.           */
/*  Also, opens /var/adm/log/wtmpx with O_RDONLY instead of    */
/*  O_RDWR, I got like 200 e-mails about that one.. :)         */
/*                                                             */
/*  Any questions, comments, or requests for re-posts email me */
/*                                                             */
/*                               Ryan Wyler                    */
/*                            ryanw () goodnet com                */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */


#include <stdio.h>
#include <string.h>
#include <utmpx.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>

#include "lastx.h"

static  int f;
static  char *Argv0, *User;

int main (int argc, char **argv)
{
  register int opt;
  struct utmpx utmp_ent;

  Argv0 = strrchr (*argv, '/');
  if (Argv0) Argv0++; else Argv0 = *argv;

  opterr = 0;
  while ((opt = getopt (argc, argv, "hdf:")) != EOF) {
    switch (opt) {
    case 'f':
      if ((f = open (optarg, O_RDONLY)) < 0) {
        (void) fprintf (stderr, "open: %s: %s\n", optarg, strerror(errno));
        exit(-1);
        /* NOTREACHED */
      }
      break;
    case 'h':
    default :
      print_version();
      usage();
      exit (-1);
      /* NOTREACHED */
    }
  }

  argc -= optind;
  argv += optind;

  if (argc > 0)
    User = strdup(*argv);

  if (!f)
    if ((f = open (_PATH_WTMP, O_RDONLY)) < 0) {
      perror(_PATH_WTMP);
      exit(-1);

    }

  setvbuf (stdout, NULL, _IONBF, 0);
  dup2 (1, 2);

  print_header ();

  while (read_tmp_entry (f, &utmp_ent))
    if (check_utmp (&utmp_ent)) pr_out (&utmp_ent);

  free (User);
  exit (0);
}

static void usage (void)
{
  printf("Usage: %s [ -hv ] [ -f file ] user\n", Argv0);
  printf("Options:\n    -h  Help\n      -f  Specify Other wtmpx file to use\n");
  return;
}

static void print_header (void)
{
  printf("Username IP/Hostname             Date\n");
}

static int read_tmp_entry (int fd, struct utmpx *utp)
{
  register int rv;

  rv = read (fd, (void*) utp, sizeof (*utp));
  if (rv < 1 || rv != sizeof (*utp)) {
    (void) fprintf (stderr, "read: %s\n", rv ? strerror(errno) : "EOF");
    return 0;
  }
  return rv;
}

inline static void pr_out (struct utmpx *utp)
{
  printf ("%-8.8s %-25.256s %-s\n", utp->ut_user, utp->ut_host,
    tv_time(&utp->ut_tv));
}

static char *tv_time (struct timeval *tp)
{
  static char *ct, *p;

  if (!ct) ct = (char *)calloc(1, 25);
  p = ctime(&tp->tv_sec);
  strncpy (ct, p, 24);
  ct[25] = 0;
  return (ct);
}

static int check_utmp (struct utmpx *utp)
{
  return (utp->ut_type == USER_PROCESS &&
    (!User || !strcmp(User, utp->ut_user)));
}

static void print_version(void)
{
  printf("lastx v2.0  -  Ryan Wyler <ryanw () goodnet com>\n\n", Argv0);
  return;
}

=====  END OF lastx.c  =============================

===== 4th file  - lastx.h  =============================

#ifndef LASTX_H
#define LASTX_H

#if defined(__STDC__)
#  define _PROTO_(p)            p
#else
#  define _PROTO_(p)
#endif

#if !defined(_PATH_WTMP)
#  define _PATH_WTMP            "/var/adm/wtmpx"
#endif
#if !defined (_PATH_UTMP)
#  define _PATH_UTMP            "/var/adm/utmpx"
#endif

extern  char            *optarg;
extern  int             optind, opterr;

inline
static void             pr_out          _PROTO_((struct utmpx *));

static void             usage           _PROTO_((void)),
                        print_header    _PROTO_((void)),
                        print_version   _PROTO_((void));

static int              read_tmp_entry  _PROTO_((int, struct utmpx *)),
                        check_utmp      _PROTO_((struct utmpx *));

static char             *tv_time        _PROTO_((struct timeval *));

#endif  /* LASTX_H */

=====  END OF lastx.h  =============================


       ____
      |  _ \ _   _  __ _ _ __
      | |_) | | | |/ _` | '_ \
      |  _ <| |_| | (_| | | | |
      |_| \_\\__, |\__,_|_| |_|
             |___/
    GoodNet System Administration
         warf () goodnet com



Current thread: