/* nusers.c */ /* * This file contains two procedures which are useful for * non-intrusive workstation farming. * * getload() is a very slow call to "uptime", which gives * the CPU load. As it's slow, this can't be called often. * * nonidleusers() is written by Pablo Funes, 16 October 1997. * This returns the number of non-idle users (good name, huh?) * currently logged on. A user is considered idle if they * haven't typed anything for five minutes (299 seconds). * This can be misleading becausing using a textedit editor or * netscape for 5 minutes will give the same result, but those * programs aren't CPU intensive so they probably won't mind if * a low-priority job starts up while they edit/surf. * * A commented-out main() is at the bottom, for testing. */ #include #include #include #include #include #include #include #include float getload(void) { /* This checks the CPU load on the machine it's */ /* running on. It does this with a call to the */ /* unix program "uptime". This is a slow way */ /* to do it, but the alternative is to read */ /* the pseudofile /proc/kmem, something which */ /* is inherently non-portable. So only use */ /* getload() sparingly, to avoid loading a CPU. */ char cmd[100], dummychar; int dummyint; FILE *inpipe; float thisload; extern FILE *popen(); extern int pclose(FILE *); /* Start of getload(). */ sprintf(cmd, "nice uptime"); inpipe = popen(cmd, "r"); fscanf(inpipe, "%d:%d", &dummyint, &dummyint); /* Time. */ fscanf(inpipe, "%c", &dummychar); /* am or pm? */ fscanf(inpipe, "m up %d days, %d:%d, %d users, load average: ", &dummyint, &dummyint, &dummyint, &dummyint); fscanf(inpipe, "%f", &thisload); pclose(inpipe); if( (thisload < 0.0) || (thisload > 100.0) ) { /* Must be an error reading, return a guess. */ thisload = 0.4; } return(thisload); } /* End getload(). */ int nonidleusers(void) { int count; int fd; /* File descriptor. */ struct stat statbuf; struct utmp u; char s[200]; time_t tim; int i; /* Begin nonidleusers(). */ fd = open(UTMP_FILE, O_RDONLY); if (fd < 0) { close(fd); return(fd); } count=0; while ( read(fd, &u, sizeof(u)) == sizeof(u) ) { if (u.ut_type == USER_PROCESS) { sprintf(s, "/dev/%s", u.ut_line); /* printf("getting info on %s\n",s); */ i = stat(s, &statbuf); if (i == -1) { close(fd); return(-1); } /* printf("stat returned %d\n"); */ time(&tim); /* printf("%-8s curtime %d modtime %d idletime %d\n", u.ut_user, tim, statbuf.st_mtime, tim-statbuf.st_mtime); */ if ( tim-statbuf.st_mtime < 299 ) /* Wait 5 minutes. */ count ++; } } /* End while. */ close(fd); /* Clean up file descriptor, otherwise multiple calls */ /* will crash the program when it runs out of handles. */ return(count); } /* End of nonidleusers(). */ /* Stub program for testing. */ /* void main(void) { printf("There are %d non idle users\n", nonidleusers() ); printf("CPU load is %f\n", cpuload() ); } *//* End of main(). */ /* End of nusers.c */