/*
     Lastx v1.0    Written by Ryan Wyler  (ryanw@goodnet.com)

    
Decription:

    A 'last' type utility for Solaris which displays the full information
for the users.

Why:

    The version of Solaris which I run here (Solaris 2.5 Sparc) does not
log the whole IP of the users in the file that 'last' uses to display the
information (/var/adm/tmpx).  But it does store the full IP in the
/var/adm/wtmpx file.  So this program helps me to findout where people are
logging in from A LOT easier.  

Disclamer:

    If this breaks something.. don't come crying to me.. I'm not
    responsable for nutin.. 


Distibution:

     Feel Free to distribute this to whom ever can make use of this util.
     It has helped me out a ton. :)

     I have not added in any comments due to lack of time.  Sorry.
     I welcome comments/Suggestions to make it better if you care to send
     any.  Otherwise, use at will.

*/

#include <stdio.h>
#include <utmpx.h>
#include <sys/types.h>
#include <fcntl.h>
#define WTMP "/var/adm/wtmpx"
#define UTMP "/var/adm/utmpx"

void nl()
{
  printf("\n");
}

void main(argc,argv)
int argc;
char *argv[];
{
  struct utmpx utmp_ent;
  char *date="",*ch,user;
  int f,count=0,all=0,debug=0,x=1,success=0,other_file=0,help=0,done=0;

  nl();
  printf(" Lastx v1.0    Written by Ryan Wyler (ryanw@goodnet.com)");
  nl();
  nl();
  if(argc>1)
    if(strcmp(argv[1],"-h")==0) {
      help=1;
      done=1;
    }
  if((argc > 1)&&(!done)) {
    do {
      if(strcmp(argv[x],"-a")==0)
        all=1;
      else
        if(strcmp(argv[x],"-d")==0)
          debug=1;
        else
          if(strcmp(argv[x],"-f")==0) {
            other_file=1;
            if(argc>x+1) {
              x++;
              if((f=open(argv[x],O_RDWR))>=0)
                success=1;
              else
                printf("  Error:  Check filename/path for '%s'\n\n",argv[x]);
            } else
              printf("  Error:  -f specified, but no filename followed -f\n\nexiting...\n");
          } else
              strcpy(&user,argv[x]);
      x++;
    } while(x < argc);
  }
  if((argc > 1)&&(!done)) {
    if(all==1) {
      if(other_file==0)
        if((f=open(WTMP,O_RDONLY))>=0)
          success=1;
        else 
          printf("  Error:  Check filename/path:  %s\n\n",WTMP);
      if(success==1) {
        while(read(f,&utmp_ent,sizeof(utmp_ent)))
          if(strncmp(utmp_ent.ut_user,".",1)!=0) {
              if(count==0)
                printf("  User        IP Address         (to see time specify specific user)\n");
              printf("  %s  %s\n",utmp_ent.ut_user,utmp_ent.ut_host);
              count++;
          }
        nl();
        printf("There were %i records listed",count);
        nl();
        close(f);  
      }
    } else {
      if(debug==1) {
        if(other_file==0)
          if((f=open(WTMP,O_RDONLY))>=0)
            success=1;
          else 
            printf("  Error:  Check filename/path:  %s\n\n",WTMP);
        if(success==1) {
          while(read(f,&utmp_ent,sizeof(utmp_ent))) {
              if(count==0)
                printf("  User        IP Address           Time)\n");
			  date = ctime(&utmp_ent.ut_xtime);
              printf("  %s  %s  %s",utmp_ent.ut_user,utmp_ent.ut_host,date);
              count++;
            }
          nl();
          fprintf(stderr,"There were %i records listed",count);
          nl();
          close(f);  
        }
      } else {
        if(other_file==0)
          if((f=open(WTMP,O_RDONLY))>=0)
            success=1;
          else 
            printf("  Error:  Check filename/path:  %s\n\n",WTMP);
        if(success==1) {
          while(read(f,&utmp_ent,sizeof(utmp_ent)))
            if(!strcmp(utmp_ent.ut_name, &user)) {  
                if(count==0)
                  printf("  User        IP Address             Time\n");
                date = ctime(&utmp_ent.ut_xtime);
                date[strlen(date)-1] = '\0'; 
                printf("  %s  %s  %s\n",utmp_ent.ut_user,utmp_ent.ut_host,date);
               count++;
              }
          nl();
          printf("There were %i records listed",count);
          nl();
          close(f);  
        }
      }
    }
  } else {
    printf("   Usage: %s <-h | -a | -d | [username]> <-f [filename]>",argv[0]);
    nl();
    printf(" Options:  -a     Display all users");
    nl();
    printf("           -d     Display all Entrys");
    nl();
    printf("           user   Displays entries for only that user");
    nl();
    printf("           -f     Specify a specific wtmpx file to use");
    nl(); 
    printf("           -h     Extended help (examples) %i",help);
    nl(); nl();
    if(help==1) {
      printf(" Examples:");
      nl();
      printf("   %s ryanw",argv[0]);
      nl();
      printf("     Shows all logins for ryanw");
      nl(); nl();
      printf("   %s -a",argv[0]);
      nl();
      printf("     Shows all records in wtmpx file");
      nl(); nl();
      printf("   %s -d",argv[0]);
      nl();
      printf("     Shows even MORE records in wtmpx file");
      nl(); nl();
      printf("   %s -f /var/adm/backup/wtmp.1 ryanw",argv[0]);
      nl();
      printf("     Shows all logins of user ryanw in file /var/adm/backup/wtmp.1");
      nl(); nl();
      printf("   %s -a -f <filename>",argv[0]);
      nl();
      printf("     Shows all records in <filename>");
      nl();
    }
  }
  exit(0);
}