[net.sources] Enhanced who with idle-time

kimcm@olamb.UUCP (Kim Chr. Madsen) (09/05/86)

[ Never eat anything bigger than your head! ]

For what it's worth I have made a Yet-Another-Who-Program, with the following
enhancements to the standard who:

	* It gives you nice little headers telling you the meaning
	  of each colomn.
	* It tells you how many users are on the system right now.
	* It tells you how long time any user has left his keyboard
	  untouched. (originally this was used to a timeout program.)
	* It indicates the invoking user with a asterix on the tty-entry
	  on which the call was made. (nice little feature if you're 
	  logged in more than once).


The program is tested to run under UNIX SVR2 and XENIX III.

					Best Regards
					Kim Chr. Madsen
					kimcm@olamb.UUCP
------------------------------CUT HERE---------------------------------------
/*
 *
 * Defines some characteristics about the system.
 *
 * use this if you miss the ident.h header file.
 * install in /usr/include/local/ident.h
 *
 * (c) 1986 by Kim Chr. Madsen at AmbraSoft A/S.
 */

static char	*myname = "AT&T 3B2/400"; /* change to your machinetype */

-----------------------------CUT AGAIN---------------------------------------

/*
 * who - YAWP
 *
 * Call:
 *	who
 *	who am I
 *	who are you
 *
 * Programmed by:
 *	Kim Chr. Madsen, AmbraSoft A/S.
 *	June 16 1986
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <ctype.h>
#include <signal.h>
#include <utmp.h>
#include <fcntl.h>
#include <pwd.h>
#include <time.h>
#include <local/ident.h>

#define	UTMP	"/etc/utmp"	/* Name of utmp file		*/
#define	TTYLEN	   8		/* Length of tty entry in utmp	*/
#define	NAMELEN	   8		/* Length of name entry in utmp	*/
#define	BUF	  50

main(argc,argv)
int	argc;
char	*argv[];
{
	extern struct passwd	*getpwnam();
	extern void		p_time();
	extern void		whoami();
	extern void		whoareyou();
	char			device[BUF];
	int			fd;
	int			users  = 0;
	long			clock;
	struct stat		statbuf;
	struct utmp		entry;

	if (strcmp(argv[0],"whoami") == 0) whoami();
	if (argc==3) {
		if (strcmp(argv[2],"i")==0 || strcmp(argv[2],"I")==0) 
			whoami();
		if (strcmp(argv[2],"you")==0 || strcmp(argv[2],"You")==0)
			whoareyou();
	}
	if ((fd=open(UTMP,O_RDONLY)) < 0) {
		fprintf(stderr,"Cannot open utmp");
		exit(1);
	}

	printf("USER:   TTY:    ON SINCE:    IDLETIME:\n");
	while (read(fd,&entry,sizeof(entry)) > 0) {
		if (getpwnam(entry.ut_name) == NULL)
			continue; /* Not a user process! */
		sprintf(device,"/dev/%s",entry.ut_line);
		if (stat(device,&statbuf) < 0) {
			fprintf(stderr,"Cannot stat ",device);
			exit(2);
		}
		users++;
		time(&clock);
		printf("%s\t%s\t",entry.ut_name,entry.ut_line);
		p_time(entry.ut_time,0);
		p_time(clock-statbuf.st_atime,1);
		if (strcmp(entry.ut_name,getlogin()) == 0 &&
		    strcmp(device,ttyname(2)) == 0) printf(" *");
		putchar('\n');
	}
	printf("No. of users: %d\n",users);
	if (close(fd) < 0) {
		fprintf(stderr,"cannot close");
		exit(3);
	}
}

void p_time(sec,mode)
long	sec;
short	mode;
{
	long			min, hour, day;
	extern struct tm	*localtime();
	struct tm		*clock;

	if (mode) {
		min  =  sec/60;
		sec  -= min*60;
		hour =  min/60;
		min  -= hour*60;
		day  =  hour/24;
		hour -= day*24;
		if (day)    printf("%d %s and ",day,(day>1)?"days":"day");
		if (hour)   printf("%2d:",hour); else printf("   ");
		if (min<10) printf("0%d:",min);  else printf("%d:",min);
		if (sec<10) printf("0%d",sec); else printf("%d",sec);
	} else {
		clock = localtime(&sec);
		switch (clock->tm_mon) {
			case  0:	printf("Jan "); break;
			case  1:	printf("Feb "); break;
			case  2:	printf("Mar "); break;
			case  3:	printf("Apr "); break;
			case  4:	printf("May "); break;
			case  5:	printf("Jun "); break;
			case  6:	printf("Jul "); break;
			case  7:	printf("Aug "); break;
			case  8:	printf("Sep "); break;
			case  9:	printf("Oct "); break;
			case 10:	printf("Nov "); break;
			case 11:	printf("Dec "); break;
		}
		printf("%2d ",clock->tm_mday);
		printf("%2d:",clock->tm_hour);
		if (clock->tm_min<10) printf("0%d ",clock->tm_min);  
		else printf("%d ",clock->tm_min);
	}
}

void whoami()
{
	extern struct passwd	*getpwuid();
	struct passwd		*buf;
	extern int		getuid();
	extern int		geteuid();
	extern int		getgid();
	extern int		getegid();
	int			i;
	int			uid;
	int			euid;

	if ((uid=getuid()) < 0) {
		fprintf(stderr,"Something is rotten uid = %d\n",uid);
		exit(1);
	}
	if ((buf = getpwuid(uid)) == (struct passwd *) NULL) {
		fprintf(stderr,"Go away you don't exist...\n");
		exit(1);
	}

	if ((euid=geteuid()) != uid) {
		if (euid<0) {
		    printf("I see you have a problem your euid is %d\n",euid);
		    printf("and that should be next to impossible!!!\n");
		    printf("But your login name is: %s\n",getlogin());
		    exit(1);
		}
		printf("You seems to have a split-personality, but here\n");
		printf("are the informations I could gather:\n\n");
	} else {
		printf("In case you suffer of amnesia, I can only give you\n");
		printf("the following informations:\n\n");
	}
	printf("uid:   %d\n",uid);
	if (euid != uid) printf("euid:  %d\n",euid);
	printf("gid:   %d\n",getgid());
	if (getgid() != getegid()) printf("egid:  %d\n",getegid());
	printf("login: %s\n",getlogin());
	printf("name:  ");
	for (i=0;buf->pw_gecos[i] != '\0' && buf->pw_gecos[i] != ','; i++) 
		putchar(buf->pw_gecos[i]);
	putchar('\n');
	exit(0);
}

void whoareyou()
{
	printf("The information avaiable of the machine is:\n\n");
	printf("%s\n",myname);
	exit(0);
}