AUSAM/source/S/ac4.c
#
/*
* various subroutines in alphabetical order
*/
#include <local-system>
#include "ac.h"
#include <passwd.h>
/*
* bycpu return reverse order of two user cpu times
* =====
*/
int bycpu( p1, p2 )
struct u_ent **p1, **p2;
{
if ( (*p1)->ue_cputime < (*p2)->ue_cputime )
return( 1 );
return( -1 );
}
/*
* bylog return reverse order of two user logged times
* =====
*/
int bylog( p1, p2 )
struct u_ent **p1, **p2;
{
if ( (*p1)->ue_logtime < (*p2)->ue_logtime )
return( 1 );
return( -1 );
}
/*
* bylogons return reverse order of two user logon counts
* ========
*/
int bylogons( p1, p2 )
struct u_ent **p1, **p2;
{
if ( (*p1)->ue_logons < (*p2)->ue_logons )
return( 1 );
return( -1 );
}
/*
* byname return order of two user names
* ======
*/
int byname( p1, p2 )
struct u_ent **p1, **p2;
{
register char *s1 = (*p1)->ue_namep;
register char *s2 = (*p2)->ue_namep;
register c;
while ( c = (*s2++|040) )
if ( c != (*s1++|040) )
if ( c > (*--s1|040) )
return( -1 ); /* 1 < 2 */
else
return( c ); /* 1 > 2 */
return( *s1 ); /* 1 >= 2 */
}
/*
* byuid return order of two user ids
* =====
*/
int byuid( p1, p2 )
struct u_ent **p1, **p2;
{
if ( (*p1)->ue_uid > (*p2)->ue_uid )
return( 1 );
return( -1 );
}
/*
* chime keep trace of time changes - hour-day-month
* =====
*/
chime( dp, date_change )
register struct dtmp *dp;
register date_change;
{
do
{
{
register struct tty *ttyp = ttys;
do
{
ttyp->t_flags =& ~NEWHR;
if ( !date_change && ttyp->t_userp )
if ( ttyp->t_logintime < lasthour )
{
hourp->c_ttys++;
hourp->c_logtime =+ HOUR;
if ( working_day )
{
hourp->c_wd_ttys++;
hourp->c_wd_lgtime =+ HOUR;
ttyp->t_wd_time =+ HOUR;
}
}
else
{
hourp->c_logtime =+ hour - ttyp->t_logintime;
if ( working_day )
{
hourp->c_wd_lgtime =+ hour - ttyp->t_logintime;
ttyp->t_wd_time =+ hour - ttyp->t_logintime;
}
}
}
while
( ++ttyp < LAST_TTY );
}
if ( !date_change )
{
register struct tty_profil *ttpp;
for ( ttpp = &ttyprofil[ttylcount-1] ; ttpp >= ttyprofil ; ttpp-- )
{
long uptime = hour - ttpp->tp_ontime;
ttpp->tp_realtime =+ uptime;
if ( working_day )
ttpp->tp_wd_realtime =+ uptime;
ttpp->tp_ontime = hour;
}
}
if ( !date_change ) /* && sys.st_boottime >= lasthour && sys.st_boottime < hour ) */
{
sys.st_uptime =+ hour - sys.st_boottime;
if ( working_day )
sys.st_wd_uptime =+ hour - sys.st_boottime;
sys.st_boottime = hour;
# ifdef DEBUG
if ( flg.y )
{
char s[PTIMSIZ];
syswarn( "chime: uptime %s\n", ptime( sys.st_uptime, s ) );
}
# endif
}
lasthour = hour;
hour =+ HOUR;
if ( hour > midnight )
{
if ( !date_change )
{
register struct tty *ttyp = ttys;
long last_day = midnight - DAY;
do
if ( ttyp->t_userp )
{
if ( ttyp->t_logintime < last_day )
dayp->d_logtime =+ DAY;
else
dayp->d_logtime =+ midnight - ttyp->t_logintime;
dayp->d_sessions++;
}
while
( ++ttyp < LAST_TTY );
}
if ( flg.d )
print( midnight );
if ( hour > month )
{
if ( !flg.d )
print( month );
nextmonth();
#ifdef DEBUG
if ( flg.y )
syswarn( "chime - midnight: %s", ctime( midnight ) );
#endif
}
midnight =+ DAY;
hourp = clock;
if ( hour > week )
{
week =+ WEEK;
dayp = sennight;
}
else
dayp++;
dayp->d_weeks++;
# ifdef DAY_TRACE
printf( "DAY %d = %d\n", dayp-sennight, dayp->d_weeks );
# endif DAY_TRACE
# ifdef TIME_TRACE
print_times( "chime", TT_HOUR );
# endif TIME_TRACE
}
else
hourp++;
if ( hourp >= &clock[W_HOUR_IN] && hourp < &clock[W_HOUR_OUT]
&& dayp >= &sennight[W_DAY_IN-1] && dayp < &sennight[W_DAY_OUT-1]
)
working_day = 1;
else
working_day = 0;
}
while
( hour <= dp->d_newtime );
}
/*
* copystring allocate new string area and copy string into it
* ==========
*/
char *copystring( string )
char *string;
{
register char *s, *ns;
register i;
char *new;
extern char *ualloc();
for ( i = 1 , s = string ; *s++ && (!flg.o || i <= 8) ; i++ );
new = ns = ualloc( i );
for ( s = string ; i-- ; )
*ns++ = *s++;
if ( flg.o )
*--ns = 0;
return( new );
}
/*
* cputimes update system cputimes and return total
* ========
*/
long cputimes( op )
register struct otmp *op;
{
long t;
if ( !flg.o )
{
sys.st_syscpu =+ op->o_systime;
sys.st_usercpu =+ op->o_usertime;
t = op->o_systime + op->o_usertime;
if ( working_day )
{
sys.st_wd_syscpu =+ op->o_systime;
sys.st_wd_usercpu =+ op->o_usertime;
hourp->c_wd_cputime =+ t;
}
hourp->c_cputime =+ t;
dayp->d_cputime =+ t;
return( t );
}
else
return( 0 );
}
/*
* fixuptime bring time variables up to date
* =========
*/
fixuptime( dp )
register struct dtmp *dp;
{
# ifdef TIME_TRACE
print_times( "fixuptime", TT_ALL );
# endif TIME_TRACE
while ( midnight <= dp->d_newtime )
midnight =+ DAY;
hour = midnight - DAY;
lasthour = hour - HOUR;
hourp = &clock[-1];
set_week();
chime( dp, 1 );
nextmonth();
# ifdef TIME_TRACE
print_times( "fixuptime", TT_ALL );
# endif TIME_TRACE
}
/*
* getuser if user can't be found in hash table,
* ======= allocate a new user structure, and enter it in the table
*/
struct u_ent *getuser( up )
register struct utmp *up;
{
register struct u_ent *ep;
register hashval = uhash( up->u_u_id );
struct pwent pen;
char sbuf[SSIZ];
extern char *ualloc(), *copystring();
if ( !flg.p )
{
static struct u_ent everyman;
return( &everyman );
}
if ( ep = uhasht[hashval] )
do
if ( up->u_u_id == ep->ue_uid )
return( ep );
while
( ep = ep->ue_next );
nu_ents++;
ep = ualloc( sizeof *ep );
/*
* initialise structure elements in order of declaration
*/
ep->ue_next = uhasht[hashval];
uhasht[hashval] = ep;
pen.pw_uid = ep->ue_uid = up->u_u_id;
ep->ue_flags = 0;
ep->ue_logins = 0;
ep->ue_multilogins = 0;
ep->ue_logons = 0;
if ( ( !flg.o && getpwlog( &pen, sbuf, SSIZ ) < 0 )
|| ( flg.o && ( !up->u_u_name[0] || up->u_type != U_TYPE ) )
)
{
warn( "unrecognised user", up );
ep->ue_namep = copystring( "????????" );
}
else
if ( flg.p )
{
ep->ue_namep = copystring( flg.o ? up->u_u_name : pen.pw_strings[LNAME] );
# ifdef USER_NAMES
if ( !flg.o )
{
ep->ue_firstname = copystring( pen.pw_strings[FIRSTNAME] );
ep->ue_lastname = copystring( pen.pw_strings[LASTNAME] );
}
# endif USER_NAMES
}
ep->ue_asynctime = 0;
ep->ue_cputime = 0;
ep->ue_logtime = 0;
return( ep );
}
/*
* nextmonth calculate end of current month
* =========
*/
nextmonth()
{
register i,j;
register day = (midnight - 1)/DAY;
int f = 0;
int mon = 0;
extern int dysize(), dmsize[];
# ifdef TIME_TRACE
print_times( "nextmonth", TT_MONTH );
# endif TIME_TRACE
#ifdef DEBUG
if ( flg.y )
syswarn( "nextmonth in hour: %s", ctime( hour ) );
#endif
for ( i = 1970 ; day >= 0 ; i++ )
{
j = dysize( i );
day =- j; mon =+ j;
}
day =+ j; mon =- j;
if ( j == 366 ) /* leap year */
f++;
for ( i = 0 ; day >= 0 ; i++ )
{
j = dmsize[i];
if ( f && i == 1 ) /* february */
j++;
day =- j; mon =+ j;
}
month = mon*DAY;
#ifdef DEBUG
if ( flg.y )
syswarn( "nextmonth out month: %s", ctime( month ) );
#endif
# ifdef TIME_TRACE
print_times( "nextmonth", TT_MONTH );
# endif TIME_TRACE
}
#ifdef TIME_TRACE
struct timetable time_table[]
{
{ "year", &year }
,{ "month", &month }
,{ "week", &week }
,{ "midnight", &midnight }
,{ "hour", &hour }
,{ "lasthour", &lasthour }
,{ "timenow", &timenow }
,{ "lastprint", &lastprint }
,{ "boot time", &sys.st_boottime}
};
#define NTIMES ((sizeof time_table)/(sizeof time_table[0]))
/*
* print_times print out trace of time values
* ===========
*/
print_times( s, only )
char *s;
register only;
{
register struct timetable *p;
if ( flg.y )
{
printf( "TIME TRACE in %s:\n", s );
for ( p = &time_table[only >= NTIMES ? 0 : only] ; p < &time_table[NTIMES] ; p++ )
{
printf( "\t%s:%20t%s", p->t_name, ctime( *p->t_timep ) );
if ( only )
break;
}
}
}
#endif TIME_TRACE
/*
* set_week calculate end of current week and set "dayp"
* ========
*/
set_week()
{
extern int *localtime();
register weekday = localtime( midnight-1 )[6] - 1;
# ifdef TIME_TRACE
print_times( "set_week", TT_WEEK );
# endif TIME_TRACE
if ( weekday < 0 )
weekday = 6; /* Sunday */
dayp = &sennight[weekday];
dayp->d_weeks++;
week = midnight + DAY * (6 - weekday);
# ifdef TIME_TRACE
print_times( "set_week", TT_WEEK );
# endif TIME_TRACE
}
/*
* syswarn general warning on file 2
* =======
*/
syswarn( s, a1, a2, a3, a4, a5 )
{
register of;
extern fout;
if ( !flg.n )
{
flush();
of = fout;
fout = 2;
printf( s, a1, a2, a3, a4, a5 );
flush();
fout = of;
}
}
/*
* ttycount count a tty if first time it has been used in current hour
* ========
*/
ttycount( ttyp )
register struct tty *ttyp;
{
if ( !(ttyp->t_flags & NEWHR) )
{
hourp->c_ttys++;
if ( working_day )
hourp->c_wd_ttys++;
ttyp->t_flags =| NEWHR;
}
}
/*
* ualloc allocate new area, if none left, attempt garbage collection from hash table
* ======
*/
char *ualloc( n )
{
char *s;
extern char *alloc();
loop:
if ( (s = alloc(n)) == -1 )
{
# ifdef GARBAGE_COLLECTION
register struct u_ent *ep, **bp, **hp;
for ( hp = &uhasht[HASHSIZ-1] ; hp >= uhasht ; --hp )
if ( ep = *hp )
{
bp = hp;
do
if ( (ep->ue_flags & (LOGIN|UPDATE)) == 0 )
{
nu_ents--;
*bp = ep->ue_next;
free( ep->ue_namep );
free( ep );
goto loop;
}
while
( bp = &ep->ue_next , ep = ep->ue_next );
}
# endif GARBAGE_COLLECTION
flg.n = 0;
syswarn( "%s: not enough memory!\n", name );
exit( -1 );
}
return( s );
}
/*
* warn accounting record related warning
* ====
*/
warn( s, up )
char *s;
register struct utmp *up;
{
register c;
register type;
extern char *ctime();
if ( flg.o && up->u_u_id == 0xffff )
return;
switch ( type = up->u_type )
{
case U_TYPE: type = 'U'; break;
case O_TYPE: type = 'O'; break;
case W_TYPE: type = 'W'; break;
case S_TYPE: type = 'S'; break;
case D_TYPE: type = 'D'; break;
default: switch ( type =+ ' ' )
{
case 'U': case 'O': case 'W': case 'S': case 'D':
type =| 040;
}
}
syswarn( "Warning: %s;\n\ttype:'%c' tty:'%c' uid:%-5l %s"
,s
,type
,(c = up->u_ttyid) ? c : '?'
,up->u_u_id
,ctime( up->u_logintime )
);
}
/*
* wd_elapsed return working day time during period
* ==========
*/
long wd_elapsed( time1, time2 )
long time1, time2;
{
register hour;
register wd;
int timeout;
int day;
time1 =- w_days_lost * DAY;
{
register *tp;
extern int *localtime();
tp = localtime( time1 );
if ( tp[6] >= W_DAY_IN && tp[6] < W_DAY_OUT )
{
wd = 1;
if ( tp[2] >= W_HOUR_IN && tp[2] < W_HOUR_OUT )
{
timeout = tp[1] * 60 + tp[0];
time1 =- timeout;
}
else
timeout = 0;
}
else
{
wd = 0;
timeout = 0;
}
timeout =+ w_days_lost * ((W_HOUR_OUT-W_HOUR_IN)*HOUR);
hour = tp[2];
day = tp[6];
tp = localtime( time2-1 );
if ( tp[6] >= W_DAY_IN && tp[6] < W_DAY_OUT && tp[2] >= W_HOUR_IN && tp[2] < W_HOUR_OUT )
timeout =+ HOUR - 1 - (tp[1]*60 + tp[0]);
}
{
register wh = 0;
for ( ; time1 < time2 ; time1 =+ HOUR )
{
if ( hour >= W_HOUR_IN && hour < W_HOUR_OUT && wd )
wh++;
if ( hour++ == 23 )
{
hour = 0;
if ( day++ == 7 ) /* Sunday */
day = 1; /* Monday */
if ( day >= W_DAY_IN && day < W_DAY_OUT )
wd = 1;
else
wd = 0;
}
}
return( wh * 3600L - timeout );
}
}