/*
* WHO COMMAND--gives a listing of processes spun off by init.
* 
* Processes are divided into four categories:
*	'u'-Users who are logged in on the system
*	'l'-Lines on which "getty" has been spun off, yet no one has logged
*		in yet.  Note that WHO does not make a distinction between
*		the programs "login" and "getty" in giving its report.
*	'p'-Processes other than getty which have been spun off by init. 
*		(e.g., line printer daemon, alerter, update)
*	'd'-Dead lines.  This category includes a listing of all lines
*		on which a process was at one time active but was
*		subsequently killed by init without being respun.
*		(e.g., rc)
*	'r'-Run level is printed along with the time it was last changed
*	'b'-Instances of a hardware boot invoking /etc/init
*
*	'am i'-identifies the line id of the requestor
*	Format for use of this command:
*		who [-ulpdarb] [who file]
*		who am i
*
*	Where u, l, p, and d are as described above and a is
*	identical to all four.  The default who file is /etc/utmp.
*
*/
int	fout;
int	buf[256];
char uflag, lflag, pflag, dflag, rflag, wflag,bflag;
struct wline {
	char name[8];
	int ln;
	int time[2];
	int pid;
} ;
main(argc, argv)
int argc;
char *argv[];
{
	int fi;
	register struct wline *p;
	register i,n;
	char *s;
	s = "/etc/utmp";
	switch(argc)
	{
	case 1:
		uflag=1;
		goto go;
	case 2:
		if (*argv[1] != '-')
		{
			uflag=1;
			s=argv[1];
			goto go;
		}
	    setflags:
		while (*(++argv[1]))
			switch(*argv[1])
			{
			case 'u':
				uflag = 1;
				break;
			case 'l':
				lflag = 1;
				break;
			case 'p':
				pflag  = 1;
				break;
			case 'd':
				dflag = 1;
				break;
			case 'r':
				rflag = 1;
				break;
			case 'b':
				bflag = 1;
				break;
			case 'a':
				dflag=pflag=lflag=uflag=rflag=bflag=1;
				break;
			default:
				write(1,"bad flag\n", 9);
				exit();
			}
		break;
	case 3:
		if(argv[1][0] == 'a' && argv[1][1] == 'm'){
			wflag = 1;
			break;
		}
		s=argv[2];
		goto setflags;
	default:
		write(1, "arg count\n", 10);
		exit();
	}
go:
	fi = open(s,0);
	if (fi<0)
	{
		write(1, "cannot open who file\n", 21);
		exit();
	}
	fout = dup(1);
	close(1);
loop:
	n=read(fi,buf,512);
	if (n <= 0)
	{
		flush();
		exit();
	}
	for (p = &buf; (n =- 16) >= 0; p++)
	{
		if (p->ln == 0) continue;
		if (p->name[0] < 0)
		{
			p->name[0] =& ~0200;
			if(wflag && lnxx(0) == p->ln){
				putline(p);
				flush();
				exit();
			}
			if (uflag) putline(p);
			continue;
		}
		if (p->name[0] > 0)
		{
			if(rflag && p->ln == 'RL'){
				printf("RUN STATE = ");
				if(p->pid < 0)
					printf("SINGLE USER");
				else
					printf("%d",p->pid);
				printf("%-13.13s\n",ctime(p->time)+3);
				continue;
			}
			if (bflag && p->ln == '!B'){
				putline(p);
				continue;
			}
			if(p->ln == 'RL' || p->ln == '!B') continue;
			if (pflag) putline(p);
			continue;
		}
		if (p->pid)
		{
			if (lflag)
			{
				for (i=0; i<7; i++)
					p->name[i] = "LOGIN  "[i];
				putline(p);
			}
			continue;
		}
		if (dflag)
		{
			for (i=0; i<7; i++)
				p->name[i] = '*';
			putline(p);
			continue;
		}
	}
	goto loop;
}
putline(p)
struct wline *p;
{
	printf("%-8.8s ln%-2.2s%-13.13s%6l\n",
		p->name, &(p->ln), ctime(p->time)+3, p->pid);
}
