	.title	who
	.ident	/2.1/
;	1/14/85		PRB
;	changed for VMS 4.0 filespec format with rooted directories
;	3/15/85		PRB
;	make terminal name fields longer for virtual terminals
;	8/14/85		dj
;	added search for input username, added "what" mode to search for
;	input image (indicated by % as the first parameter)

	$iodef
	$jpidef
	$ssdef
	.psect	data,noexe,rd,wrt
footer1:	.ascid	*!/      VAX/VMS Interactive Users - total = !UL*
footer2:	.ascid	  /      !ASday !AS !AD, !AD  !UL:!AD !AD/
list:	
dayweek_l:	.long	0			;desc of weekday
month_l:	.long	0			;desc of month
		.long	2			;day (desc)
		.address day
		.long	4			;year (desc)
		.address year
hour_l:		.long	0			;hour (value)
		.long	2			;minutes (desc)
		.address minute
		.long	2			;pm or am (desc)
		.address pm_or_am
pm_or_am:	.ascii	/ m/
line1:	.ascid	/                                                            /
line2:	.ascid	/                                                            /
header1:.ascid	/ where        who       when                    what                      pid/
header2:.ascid	/--------  ------------  -----  ---------------------------------------  --------/

whichday:.long	0
timenow:.long	23
	.address -
		timestr
timestr:				;23 bytes
day:	.blkb	2			;day of month	(dd)
	.blkb	1			;-
month:	.blkb	3			;month (mmm)
	.blkb	1			;-
year:	.blkb	4			;year (yyyy)
	.blkb	1			;blank
hour:	.blkb	2			;hour (hh)
	.blkb	1			;:
minute:	.blkb	2			;minutes (mm)
	.blkb	6			;:ss.cc
weekday:.ascid	/   Mon/
	.ascid	/  Tues/
	.ascid	/Wednes/
	.ascid	/ Thurs/
	.ascid	/   Fri/
	.ascid	/ Satur/
	.ascid	/   Sun/
monthlist:.ascii	/JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC/
months:	.ascid	/  January/
	.ascid	/ February/
	.ascid	/    March/
	.ascid	/    April/
	.ascid	/      May/
	.ascid	/     June/
	.ascid	/     July/
	.ascid	/   August/
	.ascid	/September/
	.ascid	/  October/
	.ascid	/ November/
	.ascid	/ December/

wildpid:.long	-1
items:	.word	8
	.word	jpi$_terminal
	.address	terminal
	.address	terminal_s
	.word	12
	.word	jpi$_username
	.address	username
	.address	username_s
	.word	4
	.word	jpi$_pid
	.address	pid
	.long	0
	.word	128
	.word	jpi$_imagname
	.address	image
	.address	image_s
	.word	8
	.word	jpi$_logintim
	.address	login
	.address	login_s
	.long	0
;
badname:.ascii	/ADA/
ttname:		.ascid  /tt/
ttchan:		.word	0
pidstr:		.ascid	/!XL/
piddesc:	.long	8
		.address pidbuf
pid:		.long	0
login:		.blkl	2
login_s:	.long	0
terminal_s:	.long	0
terminal:	.blkb	8
username_s:	.long	0
imagedescr:	.long	128
		.address image
image:		.blkb	128
image_s:	.long	0
loginbuf:	.ascid		/           /
loginbuf_s:	.word	0
;
;
;
exelen:		.word	0
exewidth:	.word	39
exedescr:	.long	39
		.address	exe
outbuflen:	.long	endbuf-outbuf
		.address	outbuf
outbuf:
location:	.blkb	8
location_size=.-location
		.ascii	/  /
username:	.blkb	12
		.ascii	/  /
logintime:	.ascii /     /
		.ascii	/  /
exe:		.blkb	39
exe_size=.-exe
		.ascii	/  /
pidbuf:		.blkb	8
endbuf:

input_string_desc:
	.long		input_string_size
	.address	input_string
input_string:	.ascii	/                 /	;name or image
input_string_size=.-input_string

length: .blkw	1				;length of user name
what_length:					;length of image name
	.blkw	1
who_flag:					;if 1 then look for name
	.byte	0
what_flag:					;if 1 then look for image
	.byte	0

	.psect	code,exe,pic,rd,nowrt
	.entry	who,^M<r2,r3,r4,r5,r6>

	pushaw	length
	pushl	#0
	pushab	input_string_desc
	calls	#3,g^lib$get_foreign		;get name/image to search for
	blbs	r0,test_length			;did it work? If not then exit.
	brw	error

test_length:
	tstw	length				;see if a name was entered
	beql	lets_start			;if not then get all users
	cmpc3	#1,input_string,-		;see if they typed "what"
		#^a/%/
	bneq	set_who_flag
	subw3	#2,length,-			;set "what" length
		what_length
	bleq	lets_start			;if no input then show all
	movb	#1,what_flag			;else set "what" flag
	moval	input_string,r7
	addl2	#2,r7				;change address of input string
	brw	lets_start

set_who_flag:
	movb	#1, who_flag

lets_start:
	clrl	r6			;total count
	pushal	header1			
	calls	#1,G^lib$put_output	;print header 1
	pushal	header2
	calls	#1,G^lib$put_output	;print header 2
loop:	$getjpiw_s	-		;get process info
		efn=#1,-
		pidadr=wildpid,-
		itmlst=items
	blbs	r0,check_name
	cmpw	r0,#ss$_nopriv
	beql	loop
	cmpw	r0,#ss$_suspended
	beql	loop
	cmpw	r0,#ss$_nomoreproc
	bneq	10$
	brw	done
10$:	bsbw	error

check_name:
	tstb	who_flag		;see if we are in "who" search mode
	beql	check_image		;if not then check "what" search mode
	cmpc3	length,input_string,-	;see if we have the requested name
		username
	beql	display			;if name is right then display
	brw	loop			;if not right then get another one

check_image:
	tstb	what_flag		;see if we are in "what" search mode
	beql	display			;if not then show all
	matchc	what_length,-		;see if we have the requested image
		(r7),#128,image
	beql	display			;if image is right then display
	brw	loop			;if not right then get another one
	
display:
	movl	terminal_s,r4		;is there a terminal associated?
	bneq	20$			;yes
	brw	skip			;no, not interactive
20$:	movab	location,r3
	movl	#location_size,r0
21$:	movb	#^A/ /,(r3)+
	sobgtr	r0,21$
	cmpl	r4,#8
	bleq	22$
	movl	#8,r4
22$:	movab	terminal,r1
	movab	location,r2
	movc3	r4,(r1),(r2)
	incl	r6			;up total count
	$fao_s	ctrstr=pidstr,-		;format pid into ascii
		outbuf=piddesc,-
		p1=pid
	$asctim_s	-		;convert login time to ascii
		timlen=loginbuf_s,-
		timbuf=loginbuf,-
		timadr=login,-
		cvtflg=#1		;time only
	movzwl	loginbuf,r0
	subl2	#6,r0			;leave out seconds etc
	movl	loginbuf+4,r1
	movc3	r0,(r1),logintime	;move to output buffer

	movab	exe,r3
	movl	#exe_size,r0		;length of image name
clear:	movb	#^A/ /,(r3)+		;clear exe area in output buffer
	sobgtr	r0,clear
	tstl	image_s			;no current image
	beql	print
	matchc	#3,badname,image_s,image
	beql	print
	pushaw	exelen
	pushaw	exewidth
	pushab	exedescr
	pushab	imagedescr
	calls	#4,G^lib$trim_filespec
print:	movl	outbuflen,r0
	movab	outbuf,r1
;
;	convert all to lower case
;
cvt:	cmpb	(r1),#^A/A/	
	blss	30$			;<A
	cmpb	(r1),#^A/Z/
	bgtr	30$			;>Z
	addb2	#32,(r1)		;convert to lower
30$:	incl	r1
	sobgtr	r0,cvt
	pushal	outbuflen
	calls	#1,G^lib$put_output	;print it out
skip:	brw	loop			;get next process
;
;	format footer
;
done:
	$fao_s	ctrstr=footer1,-	;convert total to ascii
		outbuf=line1,-
		p1=r6
	pushal	line1
	calls	#1,G^lib$put_output	;print footer 1
	$asctim_s	-		;get current time
		timbuf=timenow
	pushal	whichday
	calls	#1,G^lib$day		;get days since NOV 17,1858
	movl	whichday,r0
	addl	#2,r0		;account for NOV 17,1858 being a Wednesday
	clrl	r1		;only 32 bits
	ediv	#7,r0,r0,r1	;r0 number of weeks, r1 day of week
	movab	weekday,r0
90$:	tstl	r1		;index into week list
	beql	100$
	addl2	#14,r0		;next day in week, 14 is length of each .ascid
	decl	r1		;- for weekdays
	brb	90$
100$:	movl	r0,dayweek_l	;put in list for FAOL
;
;	convert 3 letter month to full name
;

	matchc	#3,month,#36,monthlist	;r2=#bytes left in monthlist
	divl2	#3,r2
	subl3	r2,#12,r2	;get month index, jan=1
	movab	months-17,r0	;17 is length of each .ascid for month
110$:	addl2	#17,r0		;next month
	sobgtr	r2,110$
	movl	r0,month_l	;put in list for FAOL
;
	movb	#^A/a/,pm_or_am	;assume am
	cmpb	#^A/ /,hour	;is first char blank?
	bneq	120$		;no
	movb	#^A/0/,hour	;yes, change to 0
120$:	clrl	r0
	clrl	r1
	subb3	#^A/0/,hour,r0
	subb3	#^A/0/,hour+1,r1
	mull2	#10,r0
	addl2	r0,r1		;r1 has hours in 24 hour format
	cmpl	r1,#12		;>12
	blss	am		;no, am is fine
	subl2	#12,r1		;get hours after 12
	movb	#^A/p/,pm_or_am	;and use pm
;
am:	tstl	r1		;is it 0?
	bneq	130$		;no
	movl	#12,r1		;yes, change 0 to 12
130$:	movl	r1,hour_l	;put in list for FAOL
	$faol_s	ctrstr=footer2,-	;format date etc
		outbuf=line2,-
		prmlst=list
	pushal	line2		;and print it all
	calls	#1,G^lib$put_output
error:
	$exit_s
	.end	who
