/* Xkernel version 1.5 */

/*
** xdm-login-accounting
**
** Make an entry in /var/adm/wtmp (or whatever) so that we can tell
** when people logged in via xterms...
**
** At the same time check to make sure the user's shell is in
** /etc/shells.  If it is NOT, syslog an error message and exit with
** non-zero exit status; otherwise, perform the wtmp accounting and
** exit zero.
**
** Does not check for things like whether the person actually logged
** in or anything like that...
**
** Seth Robertson
** seth@ctr.columbia.edu
**
** Mostly tested on Sun4 SunOS 4.1.1, but should be fairly portably
** aside from path names
**
** I feel like throwing it in the public domain today.
*/

#include <stdio.h>
#include <utmp.h>
#include <pwd.h>
#include <unistd.h>
/* #include <lastlog.h> */
#include <bsd/utmp.h>

#define WTMP "/var/adm/wtmp"	   /* Location of wtmp accounting file */
#define LASTLOG "/var/adm/lastlog" /* location of lastlog accounting file */

char *Usage = "Usage: %s <-login|-logout> <User> <Display>\n";

main(argc,argv)
int argc;
char *argv[];
{
  FILE *wtmp,*lastlog;
  struct utmp record;
  struct lastlog ll;
  char login;
  char *user;
  char *cshell,*getusershell();
  struct passwd *pwent;
  int i,success,userid;
  unsigned long t;

  for(i=0;i<sizeof(record);i++)
    ((char *)&record)[i]=0;

  if (argc != 4)
    {
      fprintf(stderr,Usage,argv[0]);
      exit(1);
    }

  /* Are we logging in or out? */

  if (!strcmp(argv[1],"-login"))
    {
      login = 1;
    }
  else if (!strcmp(argv[1],"-logout"))
    {
      login = 0;
    }
  else
    {
      fprintf(stderr,Usage,argv[0]);
      exit(1);
    }

  if (login)
    {
      user = argv[2];
      
      /* Check to see if user's shell is valid */
      
      if ((pwent = getpwnam(user)) == NULL)
	{
	  fprintf(stderr,"No such user?!?!  How is this possible?\n");
	  exit(2);
	}
      
      while ((cshell = getusershell()) && strcmp(cshell,pwent->pw_shell)) ;
      
      if (!cshell)
	{
	  fprintf(stderr,"Shell is NOT valid.  Naughty naughty\n");
	  exit(3);
	}      
    }

  wtmp = fopen(WTMP,"a");
  if(!wtmp)
    {
      fprintf(stderr,"Cannot open wtmp\n");
      exit(4);
    }

  /*
   * Well, I suppose we must use $DISPLAY for this since we do not
   * have an otherwise unique name--we aren't allocating a pty
   * like normal.  This is probably not the best idea...
   */
  strncpy(record.ut_line,argv[3],sizeof(record.ut_line));

  (void)time(&record.ut_time);

  if (login)
    {
      /* record User name */
      strncpy(record.ut_name,user,sizeof(record.ut_name));

      /* record Remote host name $DISPLAY */
      strncpy(record.ut_host,argv[3],sizeof(record.ut_host));

      (void)time(&ll.ll_time);
      strncpy(ll.ll_line,"Xdisplay",sizeof(ll.ll_line));
      strncpy(ll.ll_host,argv[3],sizeof(ll.ll_host));

      lastlog = fopen(LASTLOG,"r+");
      if(lastlog)
	 {
	   userid = pwent->pw_uid;
	   fseek(lastlog,28*userid,0);
	   
	   success=fwrite(&ll,sizeof(ll),1,lastlog);
	   
	   if(!success)
	     {
	       fprintf(stderr,"Error writing to lastlog\n");
	       exit(4);
	     }

	   fclose(lastlog);
	 }
    }
  
  exit(!fwrite(&record,sizeof(record),1,wtmp));
}

