AUSAM/source/S/ac3.c

#
/*
 *	the print routines
 */

#include	<local-system>
#include	"ac.h"

#define	FF	putchar( flg.f ? '\014' : '\n' )



/*
 *	print	the monolithic print routine - all data printed here are zeroed
 *	=====
 */

print( now )
  long now;
{
	char		sa1[PTIMSIZ], sa2[PTIMSIZ], sa3[PTIMSIZ], sa4[PTIMSIZ];
	char		sa5[PTIMSIZ], sa6[PTIMSIZ], sa7[PTIMSIZ], sa8[PTIMSIZ];
	extern char	*ptime(), *itoa();
	static char	**day[]
	{
		"Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
		"Saturday", "Sunday"
	};

# ifdef	DEBUG
  if ( flg.y )
	syswarn( "\nPRINT: %s\n", ctime( now ) );
# endif

  if ( now <= lastprint )
	return;

  /*
   *	time range
   */

  if ( (now - lastprint + DAY-1)/DAY > 1 )
  {
	pday( lastprint );
	printf( " - " );
  }
  else
	printf( "%s ", day[dayp - sennight] );

  pday( now-1 );
  putchar( '\n' );

  if ( w_days_lost )
  {
	printf( "\nNote: %d working days lost this month\n", w_days_lost );
	lastprint =+ w_days_lost * DAY;	/** GLITCHY - also in "wd_elapsed()" **/
  }

  /*
   *	people
   */

  if ( flg.p )
  {
	register struct u_ent	*ep, **hp;
	struct u_ent		**people = ualloc( nu_ents * (sizeof *people) );
	int			persons = 0;
	unsigned		logons = 0;
	long			logtotal = 0;
	long			cputotal = 0;
	long			asynctotal = 0;
	float			f;

	printf( "\n  PEOPLE\nlogons  logged  average    cpu    %%cpu   async   name\n" );

	for ( hp = uhasht ; hp < &uhasht[HASHSIZ] ; hp++ )
		if ( ep = *hp )
			do
				if ( ep->ue_flags & (UPDATE|LOGIN) )
				{
					if ( ep->ue_flags & LOGIN )
					{
						register struct tty	*ttyp;

						for ( ttyp = ttys ; ttyp < LAST_TTY ; ttyp++ )
							if ( ep == ttyp->t_userp )
								ep->ue_logtime =+ now - max( lastprint, ttyp->t_logintime );
					}

					people[persons++] = ep;
				}
			while
				( ep = ep->ue_next );

	qsort( people, persons, (sizeof *people), porder );

	for ( hp = people ; hp < &people[persons] ; hp++ )
	{
		ep = *hp;

		if ( !flg.i || ep->ue_uid == individual )
		{
#			ifdef	USER_NAMES
			printf( "%5l  %s  %s  %s %5.1f  %s  %s%61t%s %s\n"
#			else	USER_NAMES
			printf( "%5l  %s  %s  %s %5.1f  %s  %s\n"
#			endif	USER_NAMES
				,ep->ue_logons
				,ptime( ep->ue_logtime, sa1 )
				,ptime( ep->ue_logons ? ep->ue_logtime/ep->ue_logons : 0L, sa2 )
				,ptime( ep->ue_cputime/HZ, sa3 )
				,ep->ue_logtime ? ( (f = (100. * ep->ue_cputime)/(ep->ue_logtime * HZ.)) > 999.9 ? 0. : f ) : 0.
				,ptime( ep->ue_asynctime/HZ, sa4 )
				,porder == byuid ? itoa( ep->ue_uid ) : ep->ue_namep
#				ifdef	USER_NAMES
				,ep->ue_firstname
				,ep->ue_lastname
#				endif	USER_NAMES
			      );
			logons =+ ep->ue_logons;
			logtotal =+ ep->ue_logtime;
			cputotal =+ ep->ue_cputime;
			asynctotal =+ ep->ue_asynctime;
			ep->ue_logons = 0;
			ep->ue_logtime = 0;
			ep->ue_cputime = 0;
			ep->ue_asynctime = 0;
			ep->ue_flags =& ~UPDATE;
		}
	}

	free( people );

	if ( !flg.i )
		printf( "------------------------------------------------------------\n%5l  %s  %s  %s %5.1f  %s  %d\n"
			,logons
			,ptime( logtotal, sa1 )
			,ptime( logons ? logtotal/logons : 0L, sa2 )
			,ptime( cputotal/HZ, sa3 )
			,logtotal ? ( (f = (100. * cputotal)/(logtotal * HZ.)) > 999.9 ? 0. : f ) : 0.
			,ptime( asynctotal/HZ, sa4 )
			,persons
		      );

	FF;
  }

  /*
   *	ttys
   */

  if ( flg.t )
  {
	register struct tty	*ttyp;
	register struct u_ent	*ep;
	register unsigned	nttys = 0;
	unsigned		logons = 0;
	long			logtotal = 0;
	unsigned		wd_logons = 0;
	long			wd_logtotal = 0;

	printf( "\n  TTYS%30tworking day\ntty logons  logged  average  logons  logged  average\n" );

	for ( ttyp = ttys ; ttyp < LAST_TTY ; ttyp++ )
		if ( (ep = ttyp->t_userp) || ttyp->t_logtime )
		{
			long	logtime = ttyp->t_logtime;

			if ( ep )
				logtime =+ now - max( lastprint, ttyp->t_logintime );

			nttys++;
			printf( " %c  %5l  %s  %s  %5l  %s  %s\n"
				,ttyp - ttys
				,ttyp->t_logons
				,ptime( logtime, sa1 )
				,ptime( ttyp->t_logons ? logtime/ttyp->t_logons : 0L, sa2 )
				,ttyp->t_wd_logons
				,ptime( ttyp->t_wd_time, sa3 )
				,ptime( ttyp->t_wd_logons ? ttyp->t_wd_time/ttyp->t_wd_logons : 0L, sa4 )
			      );
			logons =+ ttyp->t_logons;
			logtotal =+ logtime;
			wd_logons =+ ttyp->t_wd_logons;
			wd_logtotal =+ ttyp->t_wd_time;
			ttyp->t_logons = 0;
			ttyp->t_logtime = 0;
			ttyp->t_wd_logons = 0;
			ttyp->t_wd_time = 0;
		}

	printf( "----------------------------------------------------\n%2d  %5l  %s  %s  %5l  %s  %s\n"
		,nttys
		,logons
		,ptime( logtotal, sa1 )
		,ptime( logons ? logtotal/logons : 0L, sa2 )
		,wd_logons
		,ptime( wd_logtotal, sa3 )
		,ptime( wd_logons ? wd_logtotal/wd_logons : 0L, sa4 )
	      );

	FF;
  }

  /*
  **	tty profile
  */

  if ( flg.u )
  {
	register struct tty_profil	*ttp;
	register			i;
	extern long			wd_elapsed();
	long				wdtotal = wd_elapsed( lastprint, now );
	long				realtotal = now - lastprint;
	long				ex_realtot = 0;
	long				ex_wdtot = 0;

	printf( "\n  TTY PROFILE\n%10ttotal%20tworking day\nttys  incl%% excl%%  incl%% excl%%\n" );

	for ( ttp = &ttyprofil[ttylcount-1] ; ttp >= ttyprofil ; ttp-- )
	{
		long		uptime = now - ttp->tp_ontime;

		ttp->tp_realtime =+ uptime;
		if ( working_day )
			ttp->tp_wd_realtime =+ uptime;
		ttp->tp_ontime = now;
	}

	for ( i = 0 , ttp = ttyprofil ; ttp->tp_realtime ; )
	{
		ttp++;	i++;
	}

	for ( ; --ttp >= ttyprofil ; i-- )
	{
		printf( "%3d   %5.1f %5.1f  %5.1f %5.1f\n"
			,i
			,(100. * ttp->tp_realtime)/realtotal
			,(100. * (ttp->tp_realtime - ex_realtot))/realtotal
			,wdtotal ? (100. * ttp->tp_wd_realtime)/wdtotal : 0.
			,wdtotal ? (100. * (ttp->tp_wd_realtime - ex_wdtot))/wdtotal : 0.
		      );
		ex_realtot = ttp->tp_realtime;
		ttp->tp_realtime = 0;
		ex_wdtot = ttp->tp_wd_realtime;
		ttp->tp_wd_realtime = 0;
	}

	printf( "  0   100.0 %5.1f  100.0 %5.1f\n"
		,(100. * (realtotal - ex_realtotal))/realtotal
		,wdtotal ? (100. * (wdtotal - ex_wdtot))/wdtotal : 0.
	      );

	FF;
  }

  /*
   *	hourly averages
   */

  if ( flg.h )
  {
	register		i;
	register struct Hour	*cp;
	unsigned		days = (now - lastprint + DAY-1)/DAY;
	unsigned		w_days;
	extern long		wd_elapsed();
#	ifdef	CHISTOGRAM
	long			logmax;
	long			scale;
#	endif	CHISTOGRAM
	static char		header[]	"ttys logons logoffs  logged average   cpu     async";

	w_days = (wd_elapsed( lastprint, now ) + (3600L * (W_HOUR_OUT-W_HOUR_IN) - 1))
			/ (3600L * (W_HOUR_OUT-W_HOUR_IN));
	if ( w_days == 0 )
		w_days = 1;	/* because of divide by zero, ho hum */

	if ( now != midnight )
	{
		register struct tty	*ttyp;

		for ( ttyp = ttys ; ttyp < LAST_TTY ; ttyp++ )
			if ( ttyp->t_userp )
				if ( ttyp->t_logintime < lasthour )
				{
					hourp->c_ttys++;
					hourp->c_logtime =+ now - lasthour;
					if ( working_day )
					{
						hourp->c_wd_ttys++;
						hourp->c_wd_lgtime =+ now - lasthour;
					}
				}
				else
				{
					hourp->c_logtime =+ now - ttyp->t_logintime;
					if ( working_day )
						hourp->c_wd_lgtime =+ now - ttyp->t_logintime;
				}
	}

	if ( flg.h & DATE_CHANGE )
	{
		flg.h =& ~DATE_CHANGE;
		printf( "\n*** large date change during this period! ***\n" );
	}

	printf( "\n  HOURLY AVERAGES:%63t(and for working days only)\ntime  : %s   %s\n", header, header );

#	ifdef	CHISTOGRAM
	for ( logmax = CHISTCOLS , cp = clock ; cp < &clock[24] ; cp++ )
		if ( cp->c_logtime > logmax )
			logmax = cp->c_logtime;

	scale = logmax/CHISTCOLS;

#	endif	CHISTOGRAM
	for ( i = 0, cp = clock ; i < 24 ; i++, cp++ )
	{
#		ifdef	CHISTOGRAM
		int	j;

#		endif	CHISTOGRAM
		printf( "%2d-%-2d : %4.1f   %4.1f   %4.1f  %s %s %s  %s  %4.1f   %4.1f   %4.1f  %s %s %s  %s\n"
			,i ,i+1
			,(cp->c_ttys * 1.)/days
			,(cp->c_logons * 1.)/days
			,(cp->c_logoffs * 1.)/days
			,ptime( cp->c_logtime/days, sa1 )
			,ptime( cp->c_logoffs ? cp->c_logtime/cp->c_logoffs : 0L, sa2 )
			,ptime( cp->c_cputime/(days * HZ), sa3 )
			,ptime( cp->c_async/(days * HZ), sa4 )
			,(cp->c_wd_ttys * 1.)/w_days
			,(cp->c_wd_logons * 1.)/w_days
			,(cp->c_wd_lgoffs * 1.)/w_days
			,ptime( cp->c_wd_lgtime/w_days, sa5 )
			,ptime( cp->c_wd_lgoffs ? cp->c_wd_lgtime/cp->c_wd_lgoffs : 0L, sa6 )
			,ptime( cp->c_wd_cputime/(w_days * HZ), sa7 )
			,ptime( cp->c_wd_async/(w_days * HZ), sa8 )
		      );

#		ifdef	CHISTOGRAM
		for ( j = cp->c_logtime/scale + 1 ; --j ; )
			putchar( '-' );
		printf( "*\n" );

#		endif	CHISTOGRAM
		cp->c_ttys = 0;
		cp->c_logons = 0;
		cp->c_logoffs = 0;
		cp->c_logtime = 0;
		cp->c_cputime = 0;
		cp->c_async = 0;
		cp->c_wd_ttys = 0;
		cp->c_wd_logons = 0;
		cp->c_wd_lgoffs = 0;
		cp->c_wd_lgtime = 0;
		cp->c_wd_cputime = 0;
		cp->c_wd_async = 0;
	}

	if ( days > 1 )
		printf( "\nNote: period covers %d days.\n", days );

	FF;
  }

  /*
  **	daily averages
  */

  if ( flg.e )
  {
	register		i;
	register struct Day	*dp;

	if ( now != midnight )
	{
		register struct tty	*ttyp;
		long			last_day = midnight - DAY;

		for ( ttyp = ttys ; ttyp < LAST_TTY ; ttyp++ )
			if ( ttyp->t_userp )
			{
				if ( ttyp->t_logintime < last_day )
					dayp->d_logtime =+ now - last_day;
				else
					dayp->d_logtime =+ now - ttyp->t_logintime;
				dayp->d_sessions++;
			}
	}

	printf( "\n  DAILY AVERAGES:\n%12tsessions  logged average     cpu   async  weeks\n" );

	for ( i = 0 , dp = sennight ; i < 7 ; i++ , dp++ )
	{
		printf( "%s%12t%8l %s %s %s %s%7d\n"
			,day[i]
			,dp->d_sessions/dp->d_weeks
			,ptime( dp->d_weeks ? dp->d_logtime/dp->d_weeks : 0L, sa1 )
			,ptime( dp->d_sessions ? dp->d_logtime/dp->d_sessions : 0L, sa2 )
			,ptime( dp->d_weeks ? dp->d_cputime/(dp->d_weeks*HZ) : 0L, sa3 )
			,ptime( dp->d_weeks ? dp->d_async/(dp->d_weeks*HZ) : 0L, sa4 )
			,dp->d_weeks
		      );

		dp->d_weeks = 0;
		dp->d_sessions = 0;
		dp->d_logtime = 0;
		dp->d_cputime = 0;
		dp->d_async = 0;
	}

	FF;
  }

  /*
   *	system
   */

  if ( flg.s )
  {
	long		wd_time, wd_elapsed();
	static char	*logged_s	"  Access\n%l terminal sessions logged %s (average: %s).\n";
	static char	*cput_s		"  Cpu Usage\n%s cpu time: %s system, %s user - (%.1f%% idle);\n";
	static char	*async_s	" of which %.1f%% was consumed by asynchronous processes,\n and %.1f%% was spent in the system.\n";
	long		uptime = now - sys.st_boottime;

	sys.st_boottime = now;
	sys.st_uptime =+ uptime;
	if ( working_day )
		sys.st_wd_uptime =+ uptime;

	printf( "\n  SYSTEM\nAvailable: %s (%.1f%% uptime"
		,ptime( sys.st_uptime, sa1 )
		,(100. * sys.st_uptime)/(now - lastprint)
	      );
	if ( sys.st_boots || sys.st_crashes )
	{
		printf( " with " );
		if ( sys.st_boots )
		{
			printf( "%d reboo%s"
				,sys.st_boots
				,(sys.st_boots>1) ? "ts" : "t"
			      );
			sys.st_boots = 0;
			if ( sys.st_crashes )
				printf( " and " );
		}
		if ( sys.st_crashes )
		{
			printf( "%d cras%s"
				,sys.st_crashes
				,(sys.st_crashes > 1) ? "hes" : "h"
			      );
			sys.st_crashes = 0;
		}
	}
	printf( ").\n" );

	printf( logged_s
		,sys.st_sessions
		,ptime( sys.st_logtime, sa1 )
		,ptime( sys.st_sessions ? sys.st_logtime/sys.st_sessions : 0L, sa2 )
	      );
	sys.st_sessions = 0;
	sys.st_logtime = 0;

	if ( !flg.o )
	{
		long	totcpu = sys.st_syscpu + sys.st_usercpu;

		printf( cput_s
			,ptime( totcpu/HZ, sa1 )
			,ptime( sys.st_syscpu/HZ, sa2 )
			,ptime( sys.st_usercpu/HZ, sa3 )
			,sys.st_uptime ? 100. - (totcpu*100.)/(sys.st_uptime*HZ) : 0.
		      );
	
		printf( async_s
			,totcpu ? (100. * sys.st_async)/totcpu : 0.
			,totcpu ? (100. * sys.st_syscpu)/totcpu : 0.
		      );
	
		sys.st_syscpu = 0;
		sys.st_usercpu = 0;
		sys.st_async = 0;
	}

	sys.st_uptime = 0;

	if ( wd_time = wd_elapsed( lastprint, now ) )
	{
		printf( "\n  WORKING DAY (%s - %s, %2d:00-%2d:00)\nAvailable: %s ( %.1f%% uptime ).\n"
			,day[W_DAY_IN-1]
			,day[W_DAY_OUT-2]
			,W_HOUR_IN
			,W_HOUR_OUT
			,ptime( sys.st_wd_uptime, sa1 )
			,(100.* sys.st_wd_uptime)/wd_time
		      );

		printf( logged_s
			,sys.st_wd_sessions
			,ptime( sys.st_wd_logtime, sa1 )
			,ptime( sys.st_wd_sessions ? sys.st_wd_logtime/sys.st_wd_sessions : 0L, sa2 )
		      );
		sys.st_wd_sessions = 0;
		sys.st_wd_logtime = 0;

		if ( !flg.o )
		{
			long	totcpu = sys.st_wd_syscpu + sys.st_wd_usercpu;

			printf( cput_s
				,ptime( totcpu/HZ, sa1 )
				,ptime( sys.st_wd_syscpu/HZ, sa2 )
				,ptime( sys.st_wd_usercpu/HZ, sa3 )
				,sys.st_wd_uptime ? 100. - (totcpu*100.)/(sys.st_wd_uptime*HZ) : 0.
			      );
			printf( async_s
				,totcpu ? (100. * sys.st_wd_async)/totcpu : 0.
				,totcpu ? (100. * sys.st_wd_syscpu)/totcpu : 0.
			      );

			sys.st_wd_syscpu = 0;
			sys.st_wd_usercpu = 0;
			sys.st_wd_async = 0;
		}

		sys.st_wd_uptime = 0;
	}

	{
		register struct tty	*ttyp = ttys;
		register		users = 0;

		do
			if ( ttyp->t_userp )
				users++;
		while
			( ++ttyp < LAST_TTY );

		if ( users )
			printf( "\nNote: %d user%scurrently logged on.\n"
				,users
				,(users > 1) ? "s " : " "
			      );
	}

	FF;
  }

  lastprint = now;
}



/*
 *	pday	print day in form "mmm nn"
 *	====
 */

pday( now )
  long now;
{
	register char	*s;
	register	i;
	extern char	*ctime();

  s = ctime( now );
  for ( i = 4 ; i < 10 ; i++ )
	putchar( s[i] );
}




int	zero;		/* TRUE if value printed is zero */

/*
 *	ptime	put time in string in form "nnnXnnY" where X&Y can be any of 'd', 'h', 'm', 's'
 *	=====
 */

char *ptime( time, sp )
  long time;
  char *sp;
{
	struct { int hiword; unsigned loword; };
	char	s[8];

  if ( time < 0 )
	goto negativ;

  {
	register	trac, sepc, divn;

	sepc = 'm';	trac = 's';
	divn = 60;

	if ( time > 3599 )	/* more than 60 mins. */
	{
		trac = sepc;
		sepc = 'h';
		time =/ 60;

#ifdef	TIME_IN_DAYS
		if ( time > 10080 )	/* more than 1 week */
		{
			trac = sepc;
			sepc = 'd';
			divn = 24;
			time =/ 60;

			if ( time > 23999 )	/* more than 1000 days */
				trac = 0;
		}
#else
		if ( time > 59999L )	/* more than 1000 hours */
			trac = 0;
#endif	TIME_IN_DAYS
	}

	zero = 1;

	if ( !trac )
	{
		time =/ divn;
		if ( time.hiword )
			goto overflo;
		ptn( time.loword, s, 6 );
		s[6] = sepc;
	}
	else
	{
		unsigned	t;

		ptn( (t=time/divn), s, 3 );
		s[3] = zero ? ' ' : sepc;
		ptn( (t=time%divn), &s[4], 2 );
		s[6] = zero ? '0' : trac;
	}
	s[7] = 0;
  }
  {
	register char	*cp1, *cp2;

	cp1 = s;
out:
	for ( cp2=sp ; *cp2++ = *cp1++ ; );
	return( sp );

negativ:
	cp1 = "negativ";
	goto out;
overflo:
	cp1 = "overflo";
	goto out;
  }
}



/*
 *	ptn	put a decimal number into string with leading spaces
 *	===
 */

char *ptn( t, s, n )
  register unsigned t,n;
  register char *s;
{
  if ( --n )
	s = ptn( t/10, s, n );
  if ( (t =% 10) || !zero )
  {
	zero = 0;
	*s++ = t + '0';
  }
  else
	*s++ = ' ';
  return( s );
}




/*
**	itoa	convert integer to fixed length ascii string
**	====
*/

char *itoa( i )
{
	static char	s[6];

	if ( i )
	{
		zero = 1;
		ptn( i, s, 5 );
		return( s );
	}
	else
		return( "    0" );
}