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

		.title Utldquota - utility routines for disk quotas
		.ident /v01.0/

;+++++
; MODULE DESCRIPTION
;
;     This module contains subroutines that access the disk quota 
; data maintained by the ACP.
;
;
;+++++

	.library	/SYS$LIBRARY:LIB.MLB/
;	INCLUDES

	$fibdef
	$iodef
	$dqfdef



		.sbttl macros


; Macro to allocate a block and its descriptor on the stack

	.macro alloc_by_descr	blocksize
	..blocksize=blocksize+8
	subl2	#..blocksize,sp
	movc5	#0,(sp),#0,#..blocksize,(sp)
	movl	#blocksize,(sp)
	moval	8(sp),4(sp)
	.endm	alloc_by_descr

; Macro to allocate FIB,INPUT and OUTPUT blocks

	.macro alloc_blocks fibd=r11,fib=r10,iblkd=r9,-
			    iblk=r8,oblkd=r7,oblk=r6,iosb=r5
	alloc_by_descr	fib$c_length
	moval	(sp),fibd			;save fibdesc pointer
	moval	8(sp),fib			;save fib pointer
	alloc_by_descr	dqf$c_length		;input block
	moval	(sp),iblkd			;save iblkdesc pointer
	moval	8(sp),iblk			;save iblk pointer
	alloc_by_descr	dqf$c_length		;output blk
	moval	(sp),oblkd			;save oblkdesc pointer
	moval	8(sp),oblk			;save oblk pointer
	subl2	#8,sp				;iosb
	moval	(sp),iosb			;save iosb pointer
	.endm	alloc_blocks

; Macro to call ACP

	.macro call_acp	chanoff,fibd=r11,iblkd=r9,oblkd=r7,xiosb=r5
	$qiow_s	chan=@chanoff(ap),-
		func=#io$_acpcontrol,-
		iosb=(xiosb),-
		p1=(fibd),-
		p2=iblkd,-
		p4=oblkd
	.endm	call_acp


			.sbttl utl_get_dquota
			.psect utl_code,rd,nowrt,exe

;+++++
; FUNCTION
;
;     This routine returns the number of blocks permitted and the
; number of blocks allocated for a particular disk and uic.
;
;+++
; INPUT PARAMETERS
;
;      get_dquota_chan	channel for disk to check
;      get_dquota_uic	UIC to check
;
;+++
; OUTPUT PARAMETERS
;
;     get_dquota_quota	# of blocks permitted by quota
;     get_dquota_used  # of blocks already allocated
;
;+++++


	
get_dquota_chan		=4
get_dquota_uic		=8
get_dquota_quota	=12
get_dquota_used		=16




		.entry utl_get_dquota,^M<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>

	alloc_blocks				;allocate temporary blocks

; Setup inp IBLK and FIB values

	movw	#fib$c_exa_quota,fib$w_cntrlfunc(r10)	;set to get qta info
	movl	@get_dquota_uic(ap),dqf$l_uic(r8)	;setup UIC in inp IBLK

; Ask ACP for the information

	call_acp	get_dquota_chan
	blbc	r0,GET_EXIT				;skip if error
	blbs	(r5),10$				;skip if ok
	movzwl	(r5),r0					;setup error
	brw	GET_EXIT

10$:	movl	dqf$l_permquota(r6),-
		@get_dquota_quota(ap)			;return QUOTA
	movl	dqf$l_usage(r6),-
		@get_dquota_used(ap)			;return USAGE

GET_EXIT:
	ret


			.sbttl utl_get_dquota_seq

;+++++
; FUNCTION
;
;     This routine returns the number of blocks permitted and the
; number of blocks allocated for a particular disk and uic.
;
;+++
; INPUT PARAMETERS
;
;      first_flag	flag to indicate first call
;      get_dquota_chan	channel for disk to check
;
;+++
; OUTPUT PARAMETERS
;
;     get_dquota_uic	UIC 
;     get_dquota_quota	# of blocks permitted by quota
;     get_dquota_used  # of blocks already allocated
;
;+++++


	
get_seq_wcc		=4
get_dquota_chan		=8
get_dquota_uic		=12
get_dquota_quota	=16
get_dquota_used		=20



		.entry utl_get_dquota_seq,^M<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>

	alloc_blocks				;allocate temporary blocks

; Setup inp IBLK and FIB values

	movw	#fib$c_exa_quota,fib$w_cntrlfunc(r10)	;set to get qta info
;match all uic's
	bisl3	#fib$m_all_mem,#fib$m_all_grp, fib$l_cntrlval(r10)
	movl	@get_seq_wcc(ap),fib$l_wcc(r10)		; set position context

	movl	@get_dquota_uic(ap),dqf$l_uic(r8)	;setup UIC in inp IBLK


; Ask ACP for the information

	call_acp	get_dquota_chan
	blbc	r0,NEW_EXIT				;skip if error
	blbs	(r5),20$				;skip if ok
	movzwl	(r5),r0					;setup error
	brw	NEW_EXIT

20$:	movl	dqf$l_permquota(r6),-
		@get_dquota_quota(ap)			;return QUOTA
	movl	dqf$l_usage(r6),-
		@get_dquota_used(ap)			;return USAGE
	movl	dqf$l_uic(r6),@get_dquota_uic(ap)	;return UIC 
	movl	fib$l_wcc(r10),@get_seq_wcc(ap)		;return position context


NEW_EXIT:
	ret

		.sbttl utl_mod_dquota

;+++++
; FUNCTION
;
;     This routine sets the disk quota value on a disk to a particular
; value.
;
;+++
; INPUT PARAMETERS
;
;     mod_dquota_chan	channel for disk to set
;     mod_dquota_uic	uic to set quota for
;     mod_dquota_quota	quota value to set
;
;+++
; OUTPUT PARAMETERS
;
;     mod_dquota_used	number of blocks used
;
;+++++

mod_dquota_chan		=4
mod_dquota_uic		=8
mod_dquota_quota	=12
mod_dquota_used		=16




		.entry utl_mod_dquota,^M<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>

	alloc_blocks					;allocate blocks

; setup input block

	movw	#fib$c_mod_quota,fib$w_cntrlfunc(r10)	;set MOD
	movl	#fib$m_mod_perm,fib$l_cntrlval(r10)	;set mod bits
	movl	@mod_dquota_uic(ap),dqf$l_uic(r8)	;set UIC in inblk
	movl	@mod_dquota_quota(ap),-
		dqf$l_permquota(r8)			;set quota in iblk
	divl3	#10,dqf$l_permquota(r8),-
		dqf$l_overdraft(r8)			;set overdraft

; call acp

	call_acp	mod_dquota_chan
	blbc	r0,mod_exit
	blbs	(r5),10$				;skip if no iosb err
	movzwl	(r5),r0					;set err
	brw	mod_exit

10$:	movl	dqf$l_usage(r6),-
		@mod_dquota_used(ap)			;return usage

MOD_EXIT:
	ret


		.sbttl utl_add_dquota

;+++++
; FUNCTION
;
;     UTL_ADD_DQUOTA adds an entry to the relevant disk quota file.
;
;+++
; INPUT PARAMETERS
;
;     add_dquota_chan	channel of disk to add on
;     add_dquota_uic	UIC to add
;     add_dquota_quota	quota to add
;
;+++
; OUTPUT PARAMETERS
;
;     add_dquota_used	blocks currently used
;
;+++++

add_dquota_chan			=4
add_dquota_uic			=8
add_dquota_quota		=12
add_dquota_used			=16




		.entry utl_add_dquota,^M<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>

	alloc_blocks				;allocate temporary blocks

; setup input parameters

	movw	#fib$c_add_quota,-
		fib$w_cntrlfunc(r10)		;set function
	movl	@add_dquota_uic(ap),-
		dqf$l_uic(r8)			;set UIC in iblk
	movl	@add_dquota_quota(ap),-
		dqf$l_permquota(r8)		;set permquota
	divl3	#10,dqf$l_permquota(r8),-
		dqf$l_overdraft(r8)		;set overdraft

; call acp

	call_acp	add_dquota_chan
	blbc	r0,add_exit
	blbs	(r5),10$			;skip if no iosb err
	movzwl	(r5),r0				;set err
	brw	add_exit

10$:	movl	dqf$l_usage(r6),-
		@add_dquota_used(ap)		;return usage

ADD_EXIT:
	ret

		.sbttl utl_rem_dquota

;+++++
; FUNCTION
;
;     UTL_REM_DQUOTA removes a disk quota entry from the relevant
; disk's quota file.
;
;+++
; INPUT PARAMETERS
;
;     rem_dquota_chan	channel of disk
;     rem_dquota_uic	uic to remove
;     rem_dquota_quota	quota value (ignored)
;     
;+++
; OUTPUT PARAMETERS
;
;     rem_dquota_used	current usage
;
;+++++

rem_dquota_chan		=4
rem_dquota_uic		=8
rem_dquota_quota	=12
rem_dquota_used		=16




		.entry utl_rem_dquota,^M<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>

	alloc_blocks				;allocate temporary blocks

; setup input parameters

	movw	#fib$c_rem_quota,-
		fib$w_cntrlfunc(r10)		;set function
	movl	@rem_dquota_uic(ap),-
		dqf$l_uic(r8)			;set uic

; call acp

	call_acp	rem_dquota_chan
	blbc	r0,rem_exit
	blbs	(r5),10$			;skip if no iosb err
	movzwl	(r5),r0				;set error
	brw	rem_exit

10$:	movl	dqf$l_usage(r6),-
		@rem_dquota_used(ap)		;return usage
	movl	#1,r0				;set ok

REM_EXIT:
	ret


	.end

	.end
