home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1988, 1989 Philip L. Budne.
- * All rights reserved.
- *
- * This program may be freely distributed as long as this notice
- * and the above Copyright remain intact.
- *
- * The author makes no claims of suitability for use.
- */
-
- /*
- * Phil Budne @ BU/DSG
- *
- * prehistoric users list compiled into struct. machine
- * watching was a seperate program. ran on my 3b2.
- * 8/1/86 read .fido file
- * 1/87 check ppid
- * 8/14/87 read rwho files directly (used to popen rwho!)
- * 8/20/87 add beep again, add idletime
- * rework -- put found structure in target
- * report found users once -- now way to
- * track where someone is gone from. report idle.
- * 8/21/87 add machines, hungry
- * 4/19/88 look in HOME for .fido, quit if not found
- * stat WHODIR, keep list of files to avoid
- * re-reading spooldir constantly!
- * 8/6/88 convert to open mhash. malloc targets.
- * add stomp. remove BEEP, STOMP, MT, HOST, AT
- * use static filenamestrings.
- * 8/8/88! keep boottime and sendtime in struct machine.
- * report reboots.
- * 8/9/88 All dressed up. Ready to go!
- * 3/7/89 Calculate hours in saydown!!
- * Show idle machines!! (watch)
- * 5/10/89 Watch by terminal line (line). add output decorations.
- * 10/24/90 Add tick
- */
-
- /* do reverse video for machines? */
-
- # include <sys/types.h>
- # include <sys/stat.h>
- # ifdef NDIR
- # include "ndir.h"
- # else /* NDIR not defined */
- # include <sys/dir.h>
- # endif /* NDIR not defined */
- # include <strings.h>
- # include <stdio.h>
- # include <ctype.h>
- # include <protocols/rwhod.h> /* But not on 4.2 systems!! */
- # include <time.h>
-
- # define EOS '\0'
- extern char *malloc(); /* from libc */
-
- # define bool int
- # define TRUE 1
- # define FALSE 0
-
- # define INITFILE ".fido"
-
- # define DEF_BEEP FALSE
- # define DEF_STAMP TRUE
- # define DEF_MACHINES TRUE
- # define DEF_DOWNTIME 8 /* minutes (less than 4 is noisy) */
- # define DEF_IDLETIME 15 /* minutes */
-
- # define DEF_SLEEPTIME 60 /* seconds */
- # define MIN_SLEEPTIME 32
-
- # define DEF_TICK 0 /* default timestamp (minutes) */
- # define MAX_TICK 60 /* never allow tick over 1 hr */
-
- # define MAXBUF 132 /* various buffers */
-
- /* static lengths in target struct (fields from utmp) */
- # define MAXHST 33
- # define MAXUSR 9
- # define MAXTTY 9
-
- # define NUMFILES 100 /* grrr -- a hardwired limit!! */
- # define BPHOST 32 /* avg length for hostnames ick!! */
-
- struct target {
- enum { USER, LINE } type;
- char *host, *user;
- struct found { /* count of entries found in each state */
- int nidle, idle, hungry;
- } found[2]; /* now and before */
- struct target *tnext;
- };
- # define TOTAL(tp,t) ((tp)->found[t].idle + (tp)->found[t].nidle)
-
- struct target *targets; /* list of targets */
- struct target *lasttarget; /* last target created */
- int numt = 0; /* number of targets */
- int this = 0; /* toggling index (0/1) into found array */
-
- char wildhost[] = "*";
- # define WILDHOST wildhost /* empty host for targets */
-
- int beep = DEF_BEEP;
- int stamp = DEF_STAMP;
- int machines = DEF_MACHINES;
- int downtime = DEF_DOWNTIME * 60;
- int idletime = DEF_IDLETIME * 60;
- int sleeptime = DEF_SLEEPTIME;
- int watchall = FALSE;
- int tick = DEF_TICK;
-
- char nowstr[ 50 ]; /* for time stomping */
- time_t now; /* current time(3) */
-
- struct machine { /* hash table of machines */
- char name[40];
- enum { UP=1, DOWN=2 } state;
- time_t latest; /* last time seen up */
- int boottime, sendtime; /* from whod packet */
- struct machine
- *hnext, /* next in hash chain */
- *anext; /* next in list of all hosts */
- int busy[2]; /* has non-idle users (now and then) */
- char watch; /* watched flag */
- };
- struct machine *findmachine(), *newmachine(); /* forward */
-
- # define MHSIZE 101 /* small prime */
- struct machine *mhash[ MHSIZE ], *allmachines;
- int firstpass = TRUE;
-
- # if DEBUG > 0
- char *state_name[] = { "??", "UP", "DOWN" };
- # endif /* DEBUG > 0 */
-
- # define WHODIR "/usr/spool/rwho"
-
- # define ISHUNGRY(we) \
- ((we->we_utmp.out_line[sizeof(we->we_utmp.out_line)-1] & 0200) != 0 )
-
- # define CLEARHUNGRY(we) \
- we->we_utmp.out_line[sizeof(we->we_utmp.out_line)-1] &= ~0200
-
- time_t
- getnexttick( t, i )
- time_t t;
- int i; /* interval in minutes <= 60 */
- {
- struct tm *tm;
- int min;
-
- tm = localtime(&t);
- min = i * ((tm->tm_min / i) + 1); /* get next minute for tick */
- return( t + (min - tm->tm_min) * 60 - tm->tm_sec );
- }
-
- main() {
- int i;
- time_t nextscan, nexttick;
-
- if( !readinit( INITFILE ) ) { /* check current dir */
- extern char *getenv();
- char tname[ 1024 ], *hp;
-
- if( (hp = getenv("HOME")) == NULL ) { /* check 'home' */
- /* getpwuid(getuid()) */
- fprintf( stderr, "No ./.fido and HOME not set\n" );
- exit( 1 );
- } /* no HOME */
- sprintf( tname, "%s/%s", hp, INITFILE );
- if( !readinit( tname ) ) {
- fprintf( stderr, "No ./.fido or %s\n", tname );
- exit( 1 );
- } /* readinit failed */
- } /* no .fido in "." */
-
- # if DEBUG > 0
- dumpinit();
- # endif /* DEBUG > 0 */
-
- if( numt == 0 && !machines && tick == 0 ) {
- fprintf(stderr, "Nothing to do!!\n" );
- exit( 1 );
- } /* nothing to do!! */
-
- if( chdir( WHODIR ) < 0 ) {
- perror( WHODIR );
- exit( 1 );
- } /* chdir failed */
-
- nice( 10 ); /* be nice to real users */
-
- sleep( 1 ); /* wait for shell to prompt */
- putchar('\n'); /* get fresh line */
-
- time( &now ); /* get initial time */
- if( tick > 0 ) {
- nexttick = getnexttick( now, tick );
- }
- if( numt > 0 || machines )
- nextscan = now; /* FIX? */
-
- for( ; ; ) {
- int zzztime;
-
- if( tick > 0 && now >= nexttick ) { /* time to tick?? */
- if( beep )
- putchar('\007');
- fputs( ctime( &now ), stdout );
- nexttick = getnexttick( now, tick );
- }
-
- if( (numt > 0 || machines) && now >= nextscan ) {
- dowho(); /* prowl rwho spool dir */
- if( machines ) /* watching machines? */
- scan(); /* yell about them */
- this = !this; /* toggle found index */
- nextscan = now + sleeptime;
- }
-
- fflush( stdout );
-
- if( tick == 0 ) /* no ticks */
- sleeptime = nextscan - now; /* then only have scan to worry about */
- else { /* ticking.. */
- if( numt > 0 || machines ) /* doing both */
- sleeptime = (nextscan < nexttick) ?
- nextscan - now : nexttick - now;
- else
- sleeptime = nexttick - now;
- } /* ticking */
-
- sleep( sleeptime ); /* go to sleep */
- if( getppid() == 1 ) /* child of init? */
- exit( 1 ); /* quitting time */
- time( &now );
- } /* for ever */
- } /* main */
-
- dowho() { /* poke thru rwho spool */
- register int i;
- register struct target *tp;
-
- char **fp;
- struct whod wd;
- struct stat newstat;
- char buf[MAXBUF], user[MAXUSR], host[MAXHST], tty[MAXTTY];
-
- static int nfiles;
- static struct stat oldstat;
- static char *filenames[ NUMFILES ]; /* ACK!! hardwired limits! */
- static char filenamestrings[ NUMFILES * BPHOST ]; /* avoid malloc/free */
-
- if( stat( ".", &newstat ) < 0 )
- return;
-
- if( newstat.st_mtime != oldstat.st_mtime ) {
- DIR *dirp;
- struct direct *d;
- register char *dp;
-
- oldstat = newstat;
- # if DEBUG > 0
- puts("(re)reading RWHODIR");
- # endif /* DEBUG > 0 */
-
- if( (dirp = opendir( "." )) == NULL )
- return;
-
- nfiles = 0;
- fp = filenames;
- dp = filenamestrings;
- while( (d = readdir( dirp )) != NULL ) {
- register char *sp;
-
- if( strncmp( d->d_name, "whod.", 5 ) != 0 )
- continue;
-
- # if DEBUG > 4
- printf("readdir: %s\n", d->d_name );
- # endif /* DEBUG > 4 */
- if( nfiles == NUMFILES ) {
- fprintf( stderr, "Too many files!! Increase NUMFILES!!\n");
- break;
- } /* too many files */
-
- nfiles++;
- *fp++ = dp;
- sp = d->d_name;
- while( *dp++ = *sp++ )
- ;
- } /* while readdir */
- closedir( dirp );
- } /* rwhod mtime has changed */
-
- for( tp = targets, i = 0; i < numt; tp = tp->tnext, i++ ) {
- tp->found[this].hungry = 0;
- tp->found[this].nidle = 0;
- tp->found[this].idle = 0;
- } /* for i */
-
- if( stamp ) {
- strcpy( nowstr, ctime( &now ) );
- nowstr[ 16 ] = ' ';
- nowstr[ 17 ] = EOS; /* kill year and seconds */
- } /* stamping */
-
- for( fp = filenames, i = 0; i < nfiles; i++, fp++ ) {
- register struct whoent *we;
- struct machine *mp;
- int f, cc, down;
- time_t recvtime;
- int try;
-
- # ifdef USEFILETIME
- struct stat ftime;
- # endif /* USEFILETIME defined */
-
- # if DEBUG > 19
- printf("=== %s ===\n", *fp );
- # endif /* DEBUG > 19 */
-
- for( try = 0; try < 5; try++, sleep(1) ) {
- cc = -1;
- if( (f = open( *fp, 0 )) < 0 )
- continue; /* try to read again */
-
- cc = read( f, &wd, sizeof( wd ));
- # ifdef USEFILETIME
- fstat( f, &ftime );
- # endif /* USEFILETIME defined */
- close( f );
-
- cc -= sizeof( wd ) - sizeof ( wd.wd_we );
- # if DEBUG > 19
- printf("%d chars\n", cc );
- # endif /* DEBUG > 19 */
- if( cc < 0 ) {
- # if DEBUG > 0 && DEBUG < 20
- printf("%s: %d chars\n", wd.wd_hostname, cc );
- # endif /* DEBUG > 0 && DEBUG < 20 */
- continue; /* re-read file */
- } /* short file */
- else
- break;
- } /* for each try */
- if( cc < 0 )
- continue; /* re-read */
-
- # ifdef USEFILETIME
- recvtime = ftime.st_mtime;
- # else /* USEFILETIME not defined */
- recvtime = wd.wd_recvtime;
- # endif /* USEFILETIME not defined */
-
- down = now - recvtime;
- # if DEBUG > 19
- printf( "down %d\n", down );
- # endif /* DEBUG > 19 */
-
- if( wd.wd_hostname[0] == EOS ) {
- # if DEBUG > 0
- printf( "null hostname in file %s\n", *fp );
- # endif /* DEBUG > 0 */
- continue; /* re-read!? */
- } /* hostname empty */
-
- if( machines ) {
- if( (mp = findmachine( wd.wd_hostname )) != NULL ) {
- # if DEBUG > 10
- printf("found machine: %s\n", wd.wd_hostname);
- # endif /* DEBUG > 10 */
-
- /* filter out freaks */
- if( mp->boottime != 0 &&
- wd.wd_boottime - mp->boottime > 120 ) {
- sayreboot( mp );
- # if DEBUG > 0
- printf("new %d old %d diff %d\n",
- wd.wd_boottime,
- mp->boottime,
- wd.wd_boottime - mp->boottime );
- # endif /* DEBUG > 0 */
- } /* new boottime */
- } /* machine found */
- else
- mp = newmachine( wd.wd_hostname );
-
- mp->latest = recvtime; /* packet sendtime or file time */
- mp->boottime = wd.wd_boottime;
- mp->sendtime = wd.wd_sendtime;
- mp->busy[this] = FALSE; /* clear for this pass */
- } /* machines */
-
- if( down > downtime ) /* host is down? */
- continue;
-
- for( we = wd.wd_we; cc > 0 ; we++, cc -= sizeof( *we ) ) {
- int tcnt;
- int washungry;
- register char *cp, *dp;
-
- washungry = ISHUNGRY(we); /* save hungry bit */
- CLEARHUNGRY(we); /* clear to avoid bad comparisons */
-
- strncpy( user, we->we_utmp.out_name, 8 );
- strcpy( host, wd.wd_hostname );
- strcpy( tty, we->we_utmp.out_line );
-
- if( machines && we->we_idle <= idletime ) /* @@ Have widletime? */
- mp->busy[this] = TRUE; /* just flag as busy */
-
- # if DEBUG > 10
- printf("%s@%s %s idle %d\n", user, host, tty, we->we_idle );
- # endif /* DEBUG > 10 */
-
- for( tp = targets, tcnt = 0; tcnt < numt; tcnt++, tp = tp->tnext ) {
- if( ((tp->type == USER && strcmp( user, tp->user ) == 0) ||
- (tp->type == LINE && strcmp( tty, tp->user ) == 0)) ) {
-
- if( (dp = index( host, '.' )) != NULL )
- *dp = EOS; /* strip domains */
-
- # if DEBUG > 4
- # if DEBUG < 20
- printf("%s@%s %s idle %d\n",
- user, host, tty, we->we_idle );
- # endif /* DEBUG < 20 */
- printf("%s %d %d\n", tp->user,
- tp->found[this].nidle,
- tp->found[this].idle );
- # endif /* DEBUG > 4 */
-
- if( tp->host == WILDHOST || /* wild or */
- strcmp(host, tp->host) == 0 ) { /*matching host*/
- if( we->we_idle > idletime ) {
- tp->found[this].idle++;
- }
- else { /* not idle */
- if( tp->found[this].nidle++ == 0 && /*first*/
- tp->found[!this].nidle == 0 ) { /*none b4*/
- # if DEBUG > 0 && DEBUG < 5
- tprint( tp );
- # endif /* DEBUG > 0 && DEBUG < 5 */
- /* nothing before or, imbalance */
- if( tp->found[!this].idle == 0 ||
- TOTAL(tp,this) > TOTAL(tp,!this) )
- now_on( user, host, tty );
- else /* return from idleness */
- now_active( user, host, tty );
- } /* first non idle where none before */
- } /* not idle */
- if( washungry )
- if( tp->found[this].hungry++ == 0 &&
- tp->found[!this].hungry == 0 )
- now_hungry( user, host, tty );
- } /* matching host */
- goto nextwhoent;
- } /* matching user */
- } /* for all targets */
- nextwhoent: ;
- } /* for we */
-
- } /* for each file */
-
- for( tp = targets, i = 0; i < numt; i++, tp = tp->tnext ) {
- # if DEBUG > 49
- tprint( tp );
- # endif /* DEBUG > 49 */
- if( tp->found[!this].nidle > 0 ) { /* was here before */
- # if DEBUG > 4 && DEBUG < 50
- tprint( tp );
- # endif /* DEBUG > 4 && DEBUG < 50 */
- if( tp->found[this].nidle == 0 ) { /* no non idle users */
- # if DEBUG > 0 && DEBUG < 5
- tprint( tp );
- # endif /* DEBUG > 0 && DEBUG < 5 */
- if( tp->found[this].idle > 0 && /* have idle users */
- TOTAL(tp,this) == TOTAL(tp,!this) ) /* no net change */
- now_idle( tp );
- else
- now_gone( tp ); /* none idle or net change. */
- /* must have logged out */
- } /* no non-idle */
- } /* prev had non-idle */
- else if( tp->found[!this].idle > 0 ) { /* prev idle? */
- if( TOTAL(tp,this) == 0 ) { /* no current */
- # if DEBUG > 0 && DEBUG < 5
- tprint( tp );
- # endif /* DEBUG > 0 && DEBUG < 5 */
- now_gone( tp );
- }
- } /* here but idle before */
- } /* for tp */
- } /* do who */
-
- now_on( user, host, tty )
- char *user, *host, *tty;
- {
- stomp();
- printf("bow wow!! %s now on %s %s\n", user, host, tty );
- } /* now on */
-
-
- now_active( user, host, tty )
- char *user, *host, *tty;
- {
- stomp();
- printf("arf!! %s active on %s %s\n", user, host, tty );
- } /* now active */
-
- now_hungry( user, host, tty )
- char *user, *host, *tty;
- {
- stomp();
- printf("woof! %s hungry on %s %s\n", user, host, tty );
- } /* now hungry */
-
- now_idle( tp )
- struct target *tp;
- {
- stomp();
- printf("Zzzz! %s", tp->user );
- if( tp->host != WILDHOST ) {
- putchar('@');
- fputs( tp->host, stdout );
- } /* have host */
- puts(" is idle");
- } /* now idle */
-
- now_gone( tp )
- struct target *tp;
- {
- stomp();
- printf("Aroooo! %s", tp->user );
- if( tp->host != WILDHOST ) {
- putchar('@');
- fputs( tp->host, stdout );
- } /* have host */
- if( tp->type == USER )
- puts(" is gone");
- else
- puts(" is free");
- } /* now gone */
-
- now_sated( user, host )
- char *user, *host;
- {
- stomp();
- printf("Burp!! %s", user );
- fputs( user, stdout );
- if( host != WILDHOST ) {
- putchar('@');
- fputs( host, stdout );
- } /* have host */
- puts(" is sated!!");
- } /* now sated */
-
- bool
- checkflag( buf, name, ptr )
- char *name, *buf;
- bool *ptr;
- {
- int l;
-
- l = strlen( name );
- if( strncmp( name, buf, l ) == 0 )
- *ptr = TRUE;
- else if( buf[0] == 'n' && buf[1] == 'o' && strncmp( name, buf+2, l ) == 0 )
- *ptr = FALSE;
- else
- return( FALSE );
- return( TRUE );
- } /* checkflag */
-
- bool
- numarg( buf, name, ptr, scale )
- char *name, *buf;
- int *ptr, scale;
- {
- if( strncmp( name, buf, strlen( name ) ) == 0 ) {
- int i;
- if( sscanf( buf, "%*s %d", &i ) != 1 )
- fprintf( stderr, "fido: bad line: %s\n", buf );
- else
- *ptr = i * scale;
- return( TRUE );
- } /* matches */
- return( FALSE );
- } /* numarg */
-
- bool
- readinit( file )
- char *file;
- {
- FILE *f;
- char buf[ MAXBUF ];
-
- if( (f = fopen(file, "r")) == NULL )
- return( FALSE );
-
- while( fgets(buf, sizeof buf, f) != NULL ) {
- register char *cp;
-
- if( (cp = index(buf,'\n')) != NULL )
- *cp = EOS;
-
- # if DEBUG > 9
- printf("%s\n", buf );
- # endif /* DEBUG > 9 */
-
- if( buf[0] == '#' )
- continue;
-
- if( strncmp(buf, "user", 4) == 0 )
- r_user( buf );
- else if( strncmp(buf, "line", 4) == 0 )
- r_line( buf );
- else if( strncmp( buf, "watch", 5 ) == 0 )
- r_watch( buf );
- else if( checkflag(buf, "beep", &beep) )
- continue;
- else if( checkflag(buf, "machines", &machines) )
- continue;
- else if( checkflag(buf, "stamp", &stamp) )
- continue;
- else if( numarg(buf, "idletime", &idletime, 60) )
- continue;
- else if( numarg(buf, "downtime", &downtime, 60) )
- continue;
- else if( numarg(buf, "sleeptime", &sleeptime, 1) )
- continue;
- else if( numarg(buf, "tick", &tick, 1) )
- continue;
- else
- fprintf(stderr, "fido: bad line in %s: %s\n", file, buf );
- } /* while */
- if( sleeptime < MIN_SLEEPTIME )
- sleeptime = MIN_SLEEPTIME;
- if( tick > MAX_TICK )
- tick = MAX_TICK;
- fclose ( f );
- return( TRUE );
- } /* readinit */
-
- char *savestr( s )
- register char *s;
- {
- register char *t;
-
- while( *s != EOS && isspace( *s ) )
- s++;
- if( *s == EOS )
- return( "" );
-
- t = s;
- while( *t != EOS && !isspace( *t ) && *t != '\n' )
- t++;
- if( *t != EOS )
- *t = EOS;
-
- # if DEBUG > 10
- printf("savestr '%s'\n", s);
- # endif /* DEBUG > 10 */
-
- return( strcpy( malloc( strlen( s ) + 1 ), s) );
-
- } /* savestr */
-
- r_user( l )
- register char *l;
- {
- register char *cp;
- register struct target *tp;
-
- while( *l != EOS && !isspace( *l ) )
- l++;
-
- while( *l != EOS && isspace( *l ) )
- l++;
-
- if( *l == EOS )
- return;
-
- tp = (struct target *) malloc( sizeof( struct target ) );
- tp->type = USER;
- tp->tnext = NULL;
-
- if( targets == NULL )
- targets = tp;
- else
- lasttarget->tnext = tp;
-
- if( (cp = index(l, '@')) != NULL ) {
- *cp++ = EOS; /* blast @ to tie off user */
- if( *cp != EOS ) /* have host? */
- tp->host = savestr( cp ); /* save it */
- else /* none? */
- tp->host = WILDHOST; /* WTF -- save as wild */
- } /* have host */
- else
- tp->host = WILDHOST;
- tp->user = savestr( l );
-
- tp->found[0].idle = 0;
- tp->found[0].nidle = 0;
- tp->found[0].hungry = 0;
- tp->found[1].idle = 0;
- tp->found[1].nidle = 0;
- tp->found[1].hungry = 0;
-
- lasttarget = tp;
- numt++;
- } /* r_user */
-
- r_line( l )
- register char *l;
- {
- register char *cp;
- register struct target *tp;
-
- while( *l != EOS && !isspace( *l ) )
- l++;
-
- while( *l != EOS && isspace( *l ) )
- l++;
-
- if( *l == EOS )
- return;
-
- tp = (struct target *) malloc( sizeof( struct target ) );
- tp->type = LINE;
- tp->tnext = NULL;
-
- if( targets == NULL )
- targets = tp;
- else
- lasttarget->tnext = tp;
-
- if( (cp = index(l, '@')) != NULL ) {
- *cp++ = EOS; /* blast @ to tie off user */
- if( *cp != EOS ) /* have host? */
- tp->host = savestr( cp ); /* save it */
- else /* none? */
- tp->host = WILDHOST; /* WTF -- save as wild */
- } /* have host */
- else
- tp->host = WILDHOST;
- tp->user = savestr( l );
-
- tp->found[0].idle = 0;
- tp->found[0].nidle = 0;
- tp->found[0].hungry = 0;
- tp->found[1].idle = 0;
- tp->found[1].nidle = 0;
- tp->found[1].hungry = 0;
-
- lasttarget = tp;
- numt++;
- } /* r_line */
-
- r_watch( l )
- register char *l;
- {
- register struct machine *mp;
-
- while( *l != EOS && !isspace( *l ) )
- l++;
-
- while( *l != EOS && isspace( *l ) )
- l++;
-
- if( *l == EOS ) {
- watchall = TRUE;
- return;
- }
- if( (mp = findmachine( l )) == NULL )
- mp = newmachine( l );
- mp->watch = TRUE;
- } /* r_watch */
-
- dumpinit() {
- register int i;
- register struct target *tp;
-
- for( tp = targets, i = 0; i < numt; tp = tp->tnext, i++ )
- if( tp->host == WILDHOST )
- printf("%s\n", tp->user );
- else
- printf("%s@%s\n", tp->user, tp->host );
- } /* dumpinit */
-
- /**************** machine stuff ****************/
-
- # define SH 7
- # define WS 32
- unsigned
- hash( n )
- register char *n;
- {
- register unsigned l, i;
-
- i = l = 0;
- while( *n != EOS ) {
- i = ((i << SH) | (i >> (WS-SH))) ^ *n++;
- l++;
- } /* while not end of string */
- return( (i + l) % MHSIZE );
- } /* hash */
-
- struct machine *
- findmachine( n )
- char *n;
- {
- int h;
- register struct machine *mp;
-
- h = hash( n );
- for( mp = mhash[ h ]; mp != NULL; mp = mp->hnext )
- if( strcmp(mp->name, n) == 0 )
- return( mp );
- return( NULL );
- } /* findmachine */
-
- struct machine *
- newmachine( n )
- char *n;
- {
- int h;
- register struct machine *mp;
-
- mp = (struct machine *) malloc( sizeof( struct machine ) );
- strcpy(mp->name, n);
- mp->state = UP;
-
- mp->watch = watchall; /* get default */
- mp->busy[0] = mp->busy[1] = TRUE; /* assume is/was busy */
-
- mp->anext = allmachines; /* put in list of all machines */
- allmachines = mp;
-
- h = hash( n ); /* put in hash list */
- mp->hnext = mhash[ h ];
- mhash[ h ] = mp;
-
- if( !firstpass )
- saynew( mp );
-
- return( mp );
- } /* newmachine */
-
-
- scan() {
- register struct machine *mp;
- int i;
- static char *TF = "FT";
-
- for( mp = allmachines; mp != NULL; mp = mp->anext ) {
- # if DEBUG > 4
- printf("scan: %s (%s) busy: %c (%c)\n",
- mp->name, state_name[ (int)mp->state ],
- TF[mp->busy[this]], TF[mp->busy[!this]] );
- # endif /* DEBUG > 4 */
- /*
- * if /usr/spool/rwho is on another machine (via NFS) and our
- * clocks differ we get alot of up/down noise. there must be
- * a good way to dampen this!!
- *
- * perhaps keep a new state "may be down" as a cushion
- *
- * perhaps keep threshold per host and increase each time the
- * host comes "up" without having been rebooted (see
- * wd_boottime)
- */
- if( now - mp->latest > downtime ) { /* is down */
- if( mp->state != DOWN ) {
- saydown( mp, now - mp->latest );
- mp->state = DOWN;
- } /* new state: down */
- } /* is down */
- else { /* is up */
- if( mp->state != UP ) {
- sayup( mp );
- mp->state = UP;
- } /* new state: up */
-
- if(
- # if DEBUG <= 5
- !firstpass &&
- # endif /* DEBUG <= 5 */
- mp->watch && (mp->busy[this] ^ mp->busy[!this]) )
- if( mp->busy[this] )
- mach_busy( mp );
- else
- mach_free( mp );
- } /* is up */
- } /* for all machines */
- firstpass = FALSE;
- } /* scan */
-
- stomp() {
- if( beep )
- putchar('\007');
- if( stamp )
- fputs( nowstr, stdout );
- } /* stomp */
-
- saydown( mp, t )
- struct machine *mp;
- int t;
- {
- int d, h, m;
-
- stomp();
- printf("<<<<<<<<< %s is down (", mp->name );
- t /= 60; /* toss seconds */
-
- m = t % 60; /* get mins */
- t /= 60; /* toss mins */
-
- h = t % 24; /* get hours */
- t /= 24; /* toss hours */
-
- d = t % 7; /* get days */
- t /= 7; /* cast out days (leave weeks) */
-
- if( t > 0 ) printf("%dw", t );
- if( d > 0 ) printf("%dd", d );
- if( h > 0 ) printf("%dh", h );
- if( m > 0 ) printf("%dm", m );
- puts(")");
- } /* saydown */
-
- sayup( mp )
- struct machine *mp;
- {
- stomp();
- printf(">>>>>>>>> %s is up\n", mp->name );
- } /* sayup */
-
- saynew( mp )
- struct machine *mp;
- {
- stomp();
- printf("!!!!!!!!! new machine %s\n", mp->name );
- } /* saynew sayme */
-
- sayreboot( mp )
- struct machine *mp;
- {
- stomp();
- printf("~~~~~~~~~ %s rebooted\n", mp->name );
- } /* sayreboot */
-
- mach_free( mp )
- struct machine *mp;
- {
- stomp();
- printf("+++++++++ %s is free\n", mp->name );
- } /* machine idle */
-
- mach_busy( mp )
- struct machine *mp;
- {
- stomp();
- printf("--------- %s is busy\n", mp->name );
- } /* machine busy */
-
- # if DEBUG > 0
- tprint( tp )
- register struct target *tp;
- {
- printf("%s (%d %d %d) (%d %d %d)",
- tp->user,
-
- tp->found[this].nidle,
- tp->found[this].idle,
- tp->found[this].hungry,
-
- tp->found[!this].nidle,
- tp->found[!this].idle,
- tp->found[!this].hungry
- );
- if( TOTAL(tp,this) != TOTAL(tp,!this) )
- printf(" ***** net imbalance!! *****");
- puts("");
- } /* tprint */
- # endif /* DEBUG > 0 */
-