AUSAM/source/S/ac2.c

#
/*
 *	routines associated with wtmp records
 */

#include	"ac.h"


/*
 *	login
 *	=====
 */

login( up )
  register struct utmp *up;
{
	register struct u_ent	*ep;
	register struct tty	*ttyp;
	extern struct u_ent	*getuser();

  ep = getuser( up );

  if ( ep->ue_flags & LOGIN )
	ep->ue_multilogins++;
  else
	ep->ue_flags =| LOGIN;
  ep->ue_logins++;
  ep->ue_logons++;

  ttyp = gtty( up );
  if ( ttyp->t_userp )
  {
	if ( ttyp != BADTTY )
		warn( "tty multi-logon", up );
	logoff( ttyp, up );
  }
  ttyp->t_userp = ep;
  ttyp->t_logintime = up->u_logintime;
  ttyp->t_logons++;

  hourp->c_logons++;
  if ( working_day )
  {
	hourp->c_wd_logons++;
	ttyp->t_wd_logons++;
  }
  ttycount( ttyp );
  ttyprofil[ttylcount++].tp_ontime = up->u_logintime;
}



/*
 *	logout
 *	======
 */

logout( op )
  register struct otmp *op;
{
	register struct u_ent	*ep;
	register struct tty	*ttyp;
	extern long		cputimes();

  ttyp = gtty( op );
  if ( !(ep = ttyp->t_userp) )
  {
	if ( ttyp != BADTTY && op->o_uid )
		warn( "unexpected logoff", op );
	ep = getuser( op );
	ttycount( ttyp );
  }
  else
  {
	logoff( ttyp, op );
	if ( ep->ue_uid != op->o_uid && flg.p )
	{
		unsigned	uid = op->o_uid;

		warn( "wrong user logging off", op );
		op->o_uid = ep->ue_uid;
		warn( "should be", op );
		op->o_uid = uid;
		ep = getuser( op );
	}
  }

  ep->ue_cputime =+ cputimes( op );
  ep->ue_flags =| UPDATE;
}



/*
 *	logoff	 log user off a particular tty
 *	======
 */

logoff( ttyp, op )
  register struct tty *ttyp;
  register struct otmp *op;
{
	register struct u_ent	*ep = ttyp->t_userp;
	long			logtime;

  logtime = op->o_logofftime - ttyp->t_logintime;
  ttyp->t_logtime =+ logtime;
  ttyp->t_userp = 0;

  if ( ttyp->t_logintime < lasthour )
  {
  	hourp->c_logtime =+ op->o_logofftime - lasthour;
	if ( working_day )
	{
		hourp->c_wd_lgtime =+ op->o_logofftime - lasthour;
		ttyp->t_wd_time =+ op->o_logofftime - lasthour;
	}
  }
  else
  {
  	hourp->c_logtime =+ logtime;
	if ( working_day )
	{
		hourp->c_wd_lgtime =+ logtime;
		ttyp->t_wd_time =+ logtime;
	}
  }
  hourp->c_logoffs++;
  if ( working_day )
	hourp->c_wd_lgoffs++;

  if ( ttyp->t_logintime < (midnight - DAY) )
	dayp->d_logtime =+ op->o_logofftime - (midnight - DAY);
  else
	dayp->d_logtime =+ logtime;
  dayp->d_sessions++;

  sys.st_logtime =+ logtime;
  sys.st_sessions++;
  if ( working_day )
  {
	sys.st_wd_logtime =+ logtime;
	sys.st_wd_sessions++;
  }

  ttycount( ttyp );

  if ( --ttylcount < 0 )
  {
	warn( "-ve ttys ?", op );
	ttylcount = 0;
  }
  ttyprofil[ttylcount].tp_realtime =+ op->o_logofftime - ttyprofil[ttylcount].tp_ontime;
  if ( working_day )
	ttyprofil[ttylcount].tp_wd_realtime =+ op->o_logofftime - ttyprofil[ttylcount].tp_ontime;

  if ( --ep->ue_logins <= 0 )
  {
	if ( ep->ue_logins < 0 )	/* program bug ? */
	{
		warn( "user multi-logoff - program bug?", op );
		ep->ue_logins = 0;
	}
	ep->ue_flags =& ~LOGIN;
  }
  ep->ue_logtime =+ logtime;
  ep->ue_flags =| UPDATE;
}



/*
 *	async
 *	=====
 */

async( wp )
  register struct wtmp *wp;
{
	register struct u_ent	*ep;
	extern struct u_ent	*getuser();
	long			cput;
	extern long		cputimes();

  ep = getuser( wp );
  cput = cputimes( wp );
  sys.st_async =+ cput;
  if ( working_day )
  {
	sys.st_wd_async =+ cput;
	hourp->c_wd_async =+ cput;
  }
  hourp->c_async =+ cput;
  dayp->d_async =+ cput;
  ep->ue_asynctime =+ cput;
  ep->ue_cputime =+ cput;
  ep->ue_flags =| UPDATE;
}



/*
 *	update
 *	======
 */

update( dp )
  register struct dtmp *dp;
{
	long			change;

# ifdef	DEBUG
  if ( flg.y )
	warn( "update trace", dp );

# endif	DEBUG
# ifdef	TIME_TRACE
  print_times( "update", TT_ALL );

# endif	TIME_TRACE
  if ( !flg.z )
  {
	init( dp );
	return;
  }

  change = dp->d_newtime - dp->d_oldtime;

# ifdef	DEBUG
  if ( flg.y )
  {
	char	s[PTIMSIZ];

	syswarn( "update: boottime %s\t%screased by %s\n"
		,ctime( sys.st_boottime )
		,change < 0 ? "de" : "in"
		,ptime( change < 0 ? -change : change, s )
	);
  }
# endif

# ifdef	DEBUG
  if ( flg.y )
	syswarn( "update: boottime now %s", ctime( sys.st_boottime ) );
# endif

  if ( change < 0 )
  {
	do
		midnight =- DAY;
	while
		( midnight > dp->d_newtime );
	midnight =+ DAY;
	hour = midnight;

	do
		hour =- HOUR;
	while
		( hour > dp->d_newtime );

	if ( lasthour > hour )	/* hourly statistics ruined ! */
	{
		if ( flg.h )
			flg.h =| DATE_CHANGE;
		warn( "large negative date change", dp );
		set_week();
		nextmonth();
	}

	lasthour = hour;
	hour =+ HOUR;

	hourp = &clock[23 - (midnight - hour)/HOUR];
  }
  else
	if ( change >= DAY )
	{
		if ( dp->d_oldtime > lastprint && ( flg.d || dp->d_newtime > month ) )
		{
			print( dp->d_oldtime );
			lastprint =+ change;
		}
		if ( flg.h )
			flg.h =| DATE_CHANGE;
		fixuptime( dp );
	}
	else
		if ( hour <= dp->d_newtime )
			chime( dp, 1 );

  {
	register struct tty	*ttyp = ttys;

#	ifdef	DEBUG
	if ( flg.y )
		syswarn( "update in: hour %s", ctime( hour ) );
#	endif
	do
		if ( ttyp->t_userp )
			ttyp->t_logintime =+ change;
	while
		( ++ttyp < LAST_TTY );
  }
  {
	register struct tty_profil	*ttypp = ttyprofil;
	register			i = ttylcount;

	while ( i-- )
		(ttypp++)->tp_ontime =+ change;
  }

  sys.st_boottime =+ change;

#ifdef	DEBUG
  if ( flg.y )
	syswarn( "update out: hour %s\n", ctime( hour ) );

#endif
  timenow = dp->d_newtime;
# ifdef	TIME_TRACE

  print_times( "update", TT_ALL );
# endif	TIME_TRACE
}



/*
 *	boot
 *	====
 */

boot( sp )
  register struct stmp *sp;
{
	register struct tty	*ttyp = ttys;
	register		users = 0;
	unsigned		uid = 0;
	long			boottime = sp->s_boottime;

# ifdef	TIME_TRACE
  print_times( "boot", TT_ALL );

# endif	TIME_TRACE
  if ( !flg.z )
	init( sp );
  else
	if ( hour <= sp->s_boottime )
		chime( sp, 0 );

  sp->s_boottime = timenow;	/* if there has been a disaster, do the best we can,
				   and wait for "update" to fix the world */
# ifdef	DEBUG
  if ( flg.y )
	warn( "boot trace", sp );
# endif

  do
	if ( ttyp->t_userp )
	{
		if ( !uid )
			uid = ttyp->t_userp->ue_uid;
		users++;
		logoff( ttyp, sp );
	}
  while
	( ++ttyp < LAST_TTY );

  /*
  **	if only root logged on when system crashed - assume intentional !
  */
  if ( uid || (!flg.p && (users > 1)) )
  {
	syswarn( "CRASH: %d user%slogged on when system crashed on %s"
		,users
		,users > 1 ? "s " : " "
		,ctime( sp->s_boottime )
	       );
	sys.st_crashes++;
  }
  else
	sys.st_boots++;

  if ( working_day )
	sys.st_wd_uptime =+ sp->s_boottime - sys.st_boottime;
  sys.st_uptime =+ sp->s_boottime - sys.st_boottime;

  if ( boottime < timenow )
  {
	sp->d_newtime = boottime;
	sp->d_oldtime = timenow;
	update( sp );
  }

  sys.st_boottime = boottime;

  timenow = boottime;
# ifdef	DEBUG
  if ( flg.y )
  {
	char	s[PTIMSIZ];

	syswarn( "boot: uptime %s\n\n", ptime( sys.st_uptime, s ) );
  }
# endif
# ifdef	TIME_TRACE

  print_times( "boot", TT_ALL );
# endif	TIME_TRACE
}