
;     Valerie Caro    COINS Research Computer Facility
;     UNIVERSITY OF MASSACHUSETTS/ AMHERST, MA 01003 

		.title grpsub - Subroutines for AQUOTA.SYS access

;+++++
; MODULE DESCRIPTION
;
;      This module contains subroutines for accessing the AQUOTA
; file. This file contains the GROUP database. This includes the group
; quota allocated and the total used.
;
;+++++



	$rmsdef
	$rabdef
	$fabdef

; GRPDATA record offsets

grp_t_name		=0		;offset to grpname
grp_l_quota		=8		;offset to quota
grp_l_used		=12		;offset to used
grp_c_size		=16		;total size of record
grp_c_namelen		=8		;length of name


		.psect grpsub_rms,rd,wrt,noexe,long
		.sbttl GRPDATA RMS Static Data

grpfab::	$fab 	dnm=<sys$disk:[000000]aquota.sys>,-
			fna=disk_str,-
			fac=<GET,PUT,UPD,DEL>,-
			shr=<PUT,GET,DEL,UPD,UPI,MSE>,-
			org=IDX,-
			rfm=FIX,-
			mrs=grp_c_size,-
			fop=<CIF>,-
			bks=2,-
			xab=key0

key0:		$xabkey	ref=0,-
			pos=grp_t_name,-
			siz=grp_c_namelen,-
			nxt=0


grprab::	$rab	fab=grpfab,-
			ubf=grpbuf,-
			usz=grpbuf_size,-
			kbf=grpkey,-
			ksz=grpkey_size,-
			rbf=grpbuf,-
			rsz=grp_c_size

; READ/WRITE BUFFER SPACE

disk_str:
	.blkb	32

grpbuf_size=16
grpbuf::		.blkb grpbuf_size

grpkey_size=8
grpkey::		.blkb grpkey_size


grpopen::		.long 0			;initialized flag for grp


		.sbttl grp_open

;+++++
; FUNCTION
;
;     This routine opens AQUOTA.SYS using RMS.
;
;+++
; INPUT PARAMETERS
;
;     none.
;
;+++
; OUTPUT PARAMETERS
;
;     none.
;
;+++++



		.psect grpsub_cod,rd,nowrt,exe

	disk_string	=4

		.entry grp_open,^M<r2,r3,r4,r5,r6,r7>


	
	tstl	disk_string(ap)			;check name
	beql	5$ 				;skip if none
	movq	@disk_string(ap),r6		;get descriptor
	cvtwl	r6,r6				;save length
	movc3	r6,(r7),disk_str		;move it
	movb	r6,grpfab+fab$b_fns  		; set file name size

5$:	$create	fab=grpfab			;open/create it
	blbs	r0,10$				;skip if ok
	ret					;return with error

10$:	$connect 	rab=grprab		;connect it
	blbs	r0,20$				;skip if ok
	ret					;return with error

20$:	movl	#1,grpopen			;set initialized flag
	movl	#1,r0				;set ok status
	ret

		.sbttl grp_close - close the grpdata file

;+++++
; FUNCTION
;
;     Close the AQUOTA file and set the flag to indicate closed.
;
;+++
; INPUT PARAMETERS
;
;     none.
;
;+++
; IMPLICIT INPUTS
;
;     RMS DATABASE
;        GRPOPEN flag
;
;+++
; OUTPUT PARAMETERS
;
;     none.
;
;+++
; IMPLICIT OUTPUTS
;
;     the AQUOTA file is disconnected and closed
;
;+++++



		.entry grp_close,^M<>

	$close	fab=grpfab
	blbs	r0,10$
	ret				;back if error

10$:	clrl	grpopen			;clear open flag
	movl	#1,r0			;set ok
	ret


		.sbttl grp_get_by_name

;+++++
; FUNCTION
;
;     This routine fetches a record form the AQUOTA file using the
; group name as a key.
;
;+++
; INPUT PARAMETERS
;
;     grp_get_key 	address of descriptor for USERNAME
;
;+++
; OUTPUT PARAMETERS
;
;     The buffer at: grpBUF is filled with the record.
;
;+++
; STATUS
;
;     RMS status is returned in R0.
;
;+++++

grp_get_key		=4



		.entry grp_get_by_name,^M<r2,r3,r4,r5>

	blbs	grpopen,10$			;skip if file open

	calls	#0,grp_open			;otherwise open the grp
	blbs	r0,10$
	ret

10$:	$rab_store	rab=grprab,-
			krf=#0,-
			ksz=#grpkey_size,-
			rac=KEY			;set access mode
	movq	@grp_get_key(ap),r0		;fetch key descriptor
	movc5	r0,(r1),#32,#grpkey_size,grpkey		;move with zero fill

	$get	rab=grprab			;fetch the record
	ret					;return with status


		.sbttl grp_get_next_name

;+++++
; FUNCTION
;
;     This routine gets the next record from AQUOTA by GRPNAME.
;
;+++
; INPUT PARAMETERS
;
;     none.
;
;+++
; OUTPUT PARAMETERS
;
;     name		group's name
;     quota		group's quota allocated
;     used		group's quota used
;
;+++++

next_name_name	=4
next_name_quota	=8
next_name_used	=12




		.entry grp_get_next_name,^M<>

	blbs	grpopen,10$

	calls	#0,grp_open
	blbs	r0,10$
	ret

10$:	$rab_store	rab=grprab,-
			krf=#0,-
			ksz=#grpkey_size,-
			rac=SEQ

	$get	rab=grprab
	blbs	r0,20$
	ret

; Copy data to passed parameters

20$:	pushl	next_name_used(ap)
	pushl	next_name_quota(ap)
	pushl	next_name_name(ap)
	calls	#4,copy_grp_info

	ret

		.sbttl grp_get_info

;+++++
; FUNCTION
;
;     This routine searches the grp file for a given name and returns
;	1) grpname
;	3) group quota 
;	4) group quota used
;
;+++
; INPUT PARAMETERS
;
;     name		group name (1-8) chars
;
;+++
; OUTPUT PARAMETERS
;
;     name		group name
;     quota		group's disk quota 
;     used		group's disk quota used
;
;+++++

get_info_name		=4
get_info_quota		=8
get_info_used		=12




		.entry grp_get_info,^M<>


	pushl	get_info_name(ap)
	calls	#1,grp_get_by_name			;get the record
	blbs	r0,10$					;skip if ok
	ret						;return an error

10$:	pushl	get_info_used(ap)
	pushl	get_info_quota(ap)
	pushl	get_info_name(ap)
	calls	#4,copy_grp_info

	ret

		.sbttl copy_grp_info

;+++++
; FUNCTION
;
;     This routine returns :
;	1) grpname
;	3) disk quota 
;	4) disk quota used
;
;     from the current AQUOTA record.
;
;+++
; INPUT PARAMETERS
;
;     none.
;
;+++
; OUTPUT PARAMETERS
;
;     name	group name
;     quota	quota for group 
;     used	quota for group used
;
;+++++

copy_name		=4
copy_quota		=8
copy_used		=12



		.entry copy_grp_info,^M<r2,r3,r4,r5,r6,r7,r8,r11>

	moval	grpbuf,r11			;setup addr of record buffer

; return grpname

	movq	@copy_name(ap),r7		;get desc for grpname
	movc5	#grp_c_namelen,grp_t_name(r11),#32,r7,(r8)

; return quota 

	movl	grp_l_quota(r11),@copy_quota(ap)	;do quota

; return quota used

	movl	grp_l_used(r11),@copy_used(ap)	;do used

	movl	#1,r0				;set ok
	ret


		.sbttl grp_upd_by_name

;+++++
; FUNCTION
;
;     The group record is found.
;     The record in GRPBUF is updated and the record is replaced.
;
;+++
; INPUT PARAMETERS
;
;     name		group name
;     quota		quota of group 
;     used		quota of group used
;
;+++
; OUTPUT PARAMETERS
;
;	none
;+++++

upd_name_name		=4
upd_name_quota		=8
upd_name_used		=12



		.entry grp_upd_by_name,^M<r2,r3,r9,r10,r11>

	pushl	upd_name_name(ap)
	calls	#1,grp_get_by_name			;get the record
	blbs	r0,20$					;skip if ok
	ret						;return an error

; Move in the passed values

20$:	moval	grpbuf,r9				;setup GRPBUF
	tstl	upd_name_quota(ap)			;see if quota updated
	beql	30$					;skip if not
	movl	@upd_name_quota(ap),grp_l_quota(r9)	;copy quota

30$:	tstl	upd_name_used(ap)			;see if update used
	beql	40$					;skip if not
	movl	@upd_name_used(ap),grp_l_used(r9)	;copy used

40$:	calls	#0,grp_update				;call update routine
	ret

		.sbttl grp_update

;+++++
; FUNCTION
;
;     Write out a modified record to the current record cell using values
; in the GRPBUF buffer. Access is KEY with whatever ROP is present (ignored).
;
;+++
; INPUT PARAMETERS
;
;     none.
;+++
; IMPLICIT INPUTS
;
;     RMS DATA and GRPBUF
;+++
; OUTPUT PARAMETERS
;
;     none.
;+++
; IMPLICIT OUTPUTS
;
;     the record is written to the AQUOTA file.
;+++++



		.entry grp_update,^M<>

; Insure proper access modes by setting them

	$rab_store	rab=grprab,-
			rac=KEY

; Write out the record

	$update	rab=grprab
	blbs	r0,20$					;skip if ok
	ret

20$:	movl	#1,r0					;set ok
	ret


		.sbttl grp_del_by_name

;+++++
; FUNCTION
;
;     This routine searches the grp file for a given name and deletes it.
;
;+++
; INPUT PARAMETERS
;
;     del_user_name		group name (1-8) chars
;
;+++
; OUTPUT PARAMETERS
;
;+++++

del_user_name		=4




		.entry grp_del_by_name,^M<>


	pushl	del_user_name(ap)
	calls	#1,grp_get_by_name			;get the record
	blbs	r0,10$					;skip if ok
	ret						;return an error

; Insure proper access modes by setting them

10$:	$rab_store	rab=grprab,-
			rac=KEY

; Delete the record

	$delete	rab=grprab
	blbs	r0,20$					;skip if ok
	ret

20$:	movl	#1,r0
	ret


		.sbttl grp_put

;+++++
; FUNCTION
;
;     Move passed values into the buffer and put a new record in the file
; such that keys are entered for it.
;
;+++
; INPUT PARAMETERS
;
;     name		group name (required)
;     quota		group quota(optional) 
;     used		group quota used (optional)
;
;+++
; IMPLICIT INPUTS
;
;     RMS DATA 
;+++
; OUTPUT PARAMETERS
;
;     none.
;+++
; IMPLICIT OUTPUTS
;
;     New record added to AQUOTA file.
;
;+++++

put_name		=4
put_quota		=8
put_used		=12


		.entry grp_put,^M<r2,r3,r4,r5,r9,r10,r11>

	moval	grpbuf,r11			;setup buffer addr
	movc5	#0,(r11),#0,#grp_c_size,(r11)	;clear record

; Check require parameters. Move them if present. otherwise reject.

	tstl	put_name(ap)			;check name
	beql	error_ret			;skip if bad
	movq	@put_name(ap),r9		;get descriptor
	cvtwl	r9,r9				;save length
	movc5	r9,(r10),#32,#grp_c_namelen,-
		(r11)				;move it

	tstl	put_quota(ap)			;check quota
	beql	10$				;skip to next if not
	movl	@put_quota(ap),grp_l_quota(r11) ;move otherwise

10$:	tstl	put_used(ap)			;check used
	beql	20$				;skip to next if not
	movl	@put_used(ap),grp_l_used(r11) 	;move otherwise

20$:	$rab_store	rab=grprab,-		;setup rab
			rsz=#grp_c_size,-
			rac=KEY
	$put		rab=grprab		;put it
	blbc	r0,error_ret			;skip on error
	movl	#1,r0				;set ok
	ret

error_ret:
	clrl	r0				;set error
	ret

	.end
