	.title	DISKUSE - Get disk quota usage for this user
;+
;The following software is furnished with no waranty expressed or implied,
;suitability of software is left for the user to decide.  All software is
;currently running at our site.  Please direct any questions or problems
;to:
;		Advanced Data Management
;		15-17 Main St.
;		P.O. Box 601
;		Kingston, N.J.
;		   Attn: Dave Leonard
;
; Author:
;	Dave Leonard, Advanced Data Management, 12-DEC-1980
;
; Revised:
;	20-may-1981, put in "day-quota-exceeded" check to not
;		cause problems with running jobs when other users login
;
; Restricions:
;	1) Right now, only the users login default disk/directory
;	are checked for quota enforcement, the routine should/could be
;	changed to sum up all usage on all disks.  This is being fixed.
;
;	2) All files owned by the UIC are counted towards the usage
;	count, this means all files on [0,0] (directories for example)
;	and all lost files are counted.	Thus the user may see some
;	discrepency between the number on his directory listing and
;	what the quota usage shows.  NOTE: File headers are also counted
;	in this total.  Thus one block/file surcharge is counted.
;
;	3) There is no convient way to get a breakdown of where all
;	the contributing files are.  i.e. what directory they are on.
;
; Usage:
;	First thing to do is to set up the QUOTA files for your site.
;	See the system managers guide (chapter 6) for more info on
;	running the DISKQUOTA utility.  Set the default([000,000]), to 
;	the max allowed, or 999999 blocks for both OVERDRAFT and PERMANANT.
;	Issue a REBUILD command, and then set the OVERDRAFT limit to
;	the actual quota assigned to each UIC.
;
;	(CAUTION - you must not have any users on your system while doing
;	the REBUILD as it write-locks the pack while it's in progress!!!)
;
;	To run this utility, you first must set the protection
;	on all the "[000000]QUOTA.SYS" files to allow write access
;	for all users.
;
;		$ SET PROTECTION ddcn:[000000]QUOTA.SYS/PROT=(WO:RW)
;
;	When this is done, the quota file IS WRITEABLE to ALL users, so
;	its a good idea to remove ALL priviledges from the image file
;	"[SYSEXE]DISKQUOTA.EXE" so users can't set their quota's up.
;
;		$ SET PROTECTION SYS$SYSTEM:DISKQUOTA.EXE/PROT=(WORLD)
;
;	Keep in mind that there needs to ba a QUOTA.SYS file set up on
;	all default login disks.
;
; Description:
;       DISKUSE - is a routine that gets run at login time.  Usually
;	by inserting the command 
;
;		$ RUN SYS$SYSTEM:DISKUSE
;
;	in the common login file for all users.  Its purpose
;	is to check the disk space used by the running UIC and compare
;	the space used with the number in the QUOTA.SYS file.  The 
;	QUOTA.SYS file has two entries, one for PERMANANT limit and one
;	for OVERDRAFT limit.  The scheme used here is to actually use
;	the number in the OVERDRAFT slot as the actual disk quota.  The
;	PERMANANT limit is usually set to twice the OVERDRAFT limit.
;	If the user has exceeded the disk blocks specified in the 
;	OVERDRAFT slot, his PERMANANT entry is reduced to the number
;	in the OVERDRAFT entry and the user is notified that his disk
;	usage is over the allowed limit.  This efectively lowers the boom 
;	on a user who uses a lot of temporary storage, and does not delete
;	his files after he is done.  It allows him to run up to double
;	his assigned quota before he is denied disk space.  
;
;	   At that time, when the user logs in, he is notified that he has
;	excluded his quota, and that he has one day to clean things up.
;	He will continue to get this message for one day, after that,
;	the actual diskquota will be set down to the overdraft limit.
;
;	   This scheme is considerably nicer to the user than DEC's 
;	hard and fast limits.
;
;	   If the user has logged on with excessive disk usage for more
;	than one day, he is restricted to his quota until he cleans up 
;	his directory and logs in again.  At that time, the usage is 
;	again checked, if it is below the allowed limit, (in the 
;	OVERDRAFT slot), the actual PERMANANT entry is set to twice 
;	the OVERDRAFT number and the user is notified that his quota 
;	has been lifted.
;
;-

	.enable		sup, debug
	.disable	global

	.library	/SYS$LIBRARY:LIB/

	$DQFDEF		; Disk Quota File block
	$FIBDEF		; File ID Block
	$IODEF		; I/O def's
	$JPIDEF		; Job Process Info

	.external	SYS$QIOW
	.external	LIB$PUT_OUTPUT

	.entry	DISKUSE, ^M<>

	$ASSIGN_S -				; assign channel to SYS$DISK
		DEVNAM=drive, -
		CHAN=channel
	blbs	r0, 10$				; go o.k. ?
	$exit_s	r0
10$:
	movab	fibblk, r10
	movw	#FIB$C_EXA_QUOTA, FIB$W_CNTRLFUNC(r10)	; EXAmine quota entry

	$GETJPI_S	ITMLST=items			; get [group,member]
	blbs	r0, 15$
	$exit_s	r0
;
;	get todays date
;
15$:
	$ASCTIM_S	, datedesc, , 
	blbs	r0, 17$
	$exit_s	r0
17$:
	movb	date, r11			; move in 10's digit
	bicl2	#^XFFFFFFF0, r11		; make digit
	mull3	#10, r11, bindate		; mul and stuff
	movb	date+1, r11			; move in 1's digit
	bicl2	#^XFFFFFFF0, r11		; make digit
	addl2	r11, bindate			; add it in

	movab	dqfblk, r11
	movw	member, DQF$L_UIC(r11)
	movw	group, DQF$L_UIC+2(r11)

;	$QIOW_S	-
;		CHAN=channel, -
;		FUNC=#IO$_ACPCONTROL, -
;		P1=fibdesc, -
;		P2=dqfdesc, -
;		P3=dqfblklen, -
;		P4=dqfdesc

	clrq	-(sp)
	pushaq	DQFDESC
	pushaw	DQFBLKLEN
	pushaq	DQFDESC
	pushaq	FIBDESC
	clrq	-(sp)
	pushaq	IOSB
	pushl	#IO$_ACPCONTROL
	movzwl	CHANNEL, -(sp)
	pushl	#0
	calls	#12, SYS$QIOW

	blbs	r0, 20$
	ret
20$:
	movl	iosb, r0
	blbs	r0, 30$
	$exit_s	r0
30$:
	$FAO_S	-
		faoline, -
		outlength, -
		outlinedesc, -
		P1=DQF$L_UIC+2(r11), -
		P2=DQF$L_UIC(r11), -
		P3=DQF$L_USAGE(r11), -
		P4=DQF$L_OVERDRAFT(r11)

	blbs	r0, 40$
	$exit_s	r0
40$:
	pushab	outlinedesc
	calls	#1, LIB$PUT_OUTPUT

	blbs	r0, 50$
	$exit_s	r0
50$:
	cmpl	DQF$L_USAGE(r11), DQF$L_OVERDRAFT(r11)	; exceede allowed ?
	bgtr	60$					; screw this guy
	ashl	#1, DQF$L_OVERDRAFT(r11), r9		; mult overdraft by 2
	cmpl	r9, DQF$L_PERMQUOTA(r11)		; all o.k. ?
	beql	51$
	movl	r9, DQF$L_PERMQUOTA(r11)		; set quota back up
	brw	65$
51$:
	ret						; usage was o.k.

;
; CONDITIONS:
;
; 1) If overdraft*2 is equal to permquota, then warning message has not
; started yet,  thus - give warning, and set permquota to overdraft*2+bindate
;
; 2) If overdraft*2+bindate is equal to permquota then just give warning
; message for today and don't change anything
;
; 3) If neither of the above two apply, then this guy has been over quota for
; more than one day, thus screw him now...
;

60$:
	clrl	r8					; clear flags register
	ashl	#1, DQF$L_OVERDRAFT(r11), r9		; mult overdraft by 2
	cmpl	r9, DQF$L_PERMQUOTA(r11)		; CONDITION #1 ???
	bneq	61$					; nope...
	incl	r8					; set flag to 1
61$:
	addl2	bindate, r9				; add on date
	cmpl	r9, DQF$L_PERMQUOTA(r11)		; CONDITION #2 ???
	bneq	62$					; nope...
	brw	warning					; yep
62$:
	tstl	r8					; condition 1 set ?
	beql	64$					; nope
	movb	r9, DQF$L_PERMQUOTA(r11)		; set warn date
	brb	65$
64$:
	movl	DQF$L_OVERDRAFT(r11), DQF$L_PERMQUOTA(r11); set quota down
	movl	#2, r8
65$:
	movab	fibblk, r10
	movw	#FIB$C_MOD_QUOTA, FIB$W_CNTRLFUNC(r10)	; MODify quota entry
	bisl	#FIB$M_MOD_PERM, FIB$L_CNTRLVAL(r10)	; the perm one...

;	$QIOW_S	-
;		CHAN=channel, -
;		FUNC=#IO$_ACPCONTROL, -
;		P1=fibdesc, -
;		P2=dqfdesc, -
;		P3=dqfblklen, -
;		P4=dqfdesc

	clrq	-(sp)
	pushaq	DQFDESC
	pushaw	DQFBLKLEN
	pushaq	DQFDESC
	pushaq	FIBDESC
	clrq	-(sp)
	pushaq	IOSB
	pushl	#IO$_ACPCONTROL
	movzwl	CHANNEL, -(sp)
	pushl	#0
	calls	#12, SYS$QIOW			; modify quota entry

	blbs	r0, 70$
	$exit_s	r0
70$:
	movl	iosb, r0
	blbs	r0, 80$
	$exit_s	r0
80$:						; notify that quota has changed
	cmpl	#1, r8				; just give warning ?
	bneq	81$
	brw	warning
81$:
	cmpl	DQF$L_OVERDRAFT(r11), DQF$L_PERMQUOTA(r11) ; set down or up ?
	beql	down

	movl	#512, outlength
	$FAO_S	-
		upline, -				; SET UP
		outlength, -
		outlinedesc, -
		P1=DQF$L_PERMQUOTA(r11)
	blbs	r0, 85$
	$exit_s	r0
85$:
	pushab	outlinedesc
	calls	#1, LIB$PUT_OUTPUT
	$exit_s	r0
down:
	movl	#512, outlength
	$FAO_S	-
		downline, -				; SET DOWN
		outlength, -
		outlinedesc, -
		P1=DQF$L_PERMQUOTA(r11)

	blbs	r0, 100$
	$exit_s	r0
100$:
	pushab	outlinedesc
	calls	#1, LIB$PUT_OUTPUT
	$exit_s	r0

warning:
	movl	#512, outlength
	$FAO_S	-
		warnline, -				; GIVE WARNING
		outlength, -
		outlinedesc, -
		P1=DQF$L_OVERDRAFT(r11)

	blbs	r0, 130$
	$exit_s	r0
130$:
	pushab	outlinedesc
	calls	#1, LIB$PUT_OUTPUT
	$exit_s	r0

	.psect	data, wrt
items:
	.word	4
	.word	JPI$_GRP
	.address	group
	.address	group_len

	.word	4
	.word	JPI$_MEM
	.address	member
	.address	member_len

	.long	0

group:
	.blkl	1
group_len:
	.blkl	1
member:
	.blkl	1
member_len:
	.blkl	1

faoline:
	.ascid	"!_Disk usage for [!OB,!OB]  !UL used / !UL maximum"

outlinedesc:
outlength:
	.long		512
	.address	outline
outline:
	.blkb	512

datedesc:
	.long		11
	.address	date
date:
	.blkb	11
bindate:
	.long	0

downline:
	.ascid	"!/***** READ THIS ***** -!/!_" -
		"You have exceeded your allowed maximum disk usage.!/!_" -
		"No files may be created until you reduce your usage to!/!_" -
		"less than !UL blocks.  This strict quota enforcement!/!_" -
		"will remain in affect until you reduce your usage."
upline:
	.ascid	"!/!_Formerly imposed disk quota's have been lifted.!/" -
		"!_Please try to curb excessive space usage."
warnline:
	.ascid	"!/***** READ THIS ***** -!/!_" -
		"You have exceeded your allowed maximum disk usage.!/!_" -
		"You have one day grace period to reduce your usage to!/!_" -
		"less than !UL blocks.  After this grace period, !/!_" -
		"quota enforcement will be instated until you reduce!/!_" -
		"your usage."

fibdesc:
	.long		FIB$C_LENGTH
	.address	fibblk

dqfdesc:
	.long		DQF$C_LENGTH
	.address	dqfblk
drive:
	.ascid	/SYS$DISK/		; drive to check usage on
channel:
	.blkw	1
iosb:
	.blkw	4
fibblk:
	.blkb	FIB$C_LENGTH
dqfblk:
	.blkb	DQF$C_LENGTH
dqfblklen:
	.address 1$
1$:
	.blkw	1

	.end	DISKUSE
