;
DISK_QUOTA.MAR get disk quota information
.title Determine Quota
;-----------------------------------------------------------------------------
;| Glenn Fleming Oct 10,1985 |
;| Call from higher languages : status = quota(disk,uic,usage,perm,overdraft)|
;-----------------------------------------------------------------------------
; QUOTA macro subroutine. This routine expects 5 arguments:
;
; (1) diskname on which to check quota -- passed by character string
; descriptor. The max. length for the string is 32 bytes. If a null
; argument is supplied the diskname used will be the one associated
; with the calling routine.
; (2) uic to check -- integer passed by reference. If a null argument
; is supplied the uic assoicated with the calling routine is used.
; If the uic is specified with a value of "0", the uic associated with
; the calling routine is used, and returned to the calling routine.
; NOTE: The uic number is the process UIC in standard longword
; format. For more imformation, see $GETJPI system service call.
;
; (3) disk_usage -- integer passed by reference. Returns number
; of blocks currently used.
;
; (4) Perm_quota -- integer passed by reference. Returns permanent
; disk quota for the uic.
;
; (5) Overdraft -- integer passed by reference. Returns overdraft
; for uic on disk.
;
; If disk_usage, perm_quota, and overdraft are all NULL arguments
; then the call is treated as a NULL call and the status value
; of SS$_INSFARG is returned. NOTE: if the user does not wish
; to obtain a given value, a NULL argument must be specified in
; the call to the routine for that value. Failure to do so will cause
; a SS$_INSFARG status value to be returned. Successful completion
; is indicated by a return of SS$_NORMAL to the calling routine,
; otherwise the appropiate error code is returned. It is the
; responsibility of the calling routine to take the necessary action
; to detect and handle an error.
;
; EXAMPLE CALLS
;
; (A) FORTRAN
; integer uic,usage,perm,overdraft
; character diskname*32
; ...
; ...
; (1) status = quota(diskname,uic,usage,perm,overdraft)
; Complete call.
; (2) status = quota(,,usage,perm,overdraft)
; Defaults to current disk, and UIC of calling routine.
; (3) status = quota(,,usage,,)
; Defaults to current disk and UIC of calling routine and
; returns only the usage.
;
; (B) C
; struct vaxstring {
; int len;
; char *str;
; }descr;
; char device[32];
; int status,uic,usage,perm,overdraft;
; ...
; ...
; descr.str = device;
; descr.len = strlen(device);
; (1) status = quota(&descr,&uic,&usage,&perm,&overdraft);
; (2) status = quota(&descr,&uic,0,0,0);
; Treated as a NULL call.
; (3) status = quota(&descr,&uic);
; Insufficient arguments status returned.
;
; (C) PASCAL
; type diskspec = packed array[1..32] of char;
; var diskname: diskspec;
; status,uic,usage,perm,overdraft:integer;
;
; function quota (%stdescr diskname:diskspec; var uic,usage,perm,
; overdraft:integer):integer;extern;
; begin
; ...
; ...
; (1) status := quota( diskname,uic,usage,perm,overdraft);
; (2) uic := 91252; (* invalid uic being specified *)
; status := quota(diskname,uic,usage,perm,overdraft);
; if the uic is not valid then the values returned will
; be "0", and the status code is SS$_NORMAL.
;-----------------------------------------------------------------------------
; 21-May-1990 Joe Ward - Added pushr and popr around call to $dassgn_s to
; allow the return value from the call to $qiow_s to
; be passed back. Otherwise, status codes such as
; no quota on device (%x3D4) were not passed back
; correctly.
;-----------------------------------------------------------------------------
.library \sys$library:lib.mlb\
$DQFDEF
$FIBDEF
quotablock: .blkb DQF$C_LENGTH ; IO manual 1-39
fibblock: .blkb FIB$C_LENGTH ; IO manual 1-4
uic_list: .blkl 3 ; descriptor for GETJPI call
fibdescr: .blkq 1 ; descriptor for FIB block
quotadescr: .blkq 1 ; descriptor for QUOTA block
devicedescr: .blkq 1 ; device descriptor
devnam: .blkb 32 ; address for device name
default_disk: .ascii /SYS$DISK/ ; default diskname
channel: .blkw 1 ; chan for disk
uic: .blkl 1 ; loc for storing and returning UIC
counter: .blkb 1 ; arg counter to check last 3 args
outlen: .blkl 1 ; number of chars after str$trim
retlen: .word 1 ; return len for getjpi descriptor
iosb: .blkq 1
; fast linkage subroutine to get the uic. Stack not used .
getuic:: movw #4,uic_list ;4 byte buffer len
movw #JPI$_UIC,uic_list+2 ; itemcode
moval uic,uic_list+4 ; bufferaddr;
moval retlen,uic_list+8 ; return length addr
$getjpiw_s itmlst=uic_list
cmpl #SS$_NORMAL,r0 ; successful return?
beql 10$ ; success return to main
brw ret_pt ;return to calling routine
10$: rsb ; else return to quota
; start of macro routine to get quotas
mec_get_diskquota::
quota:: .word 0
cmpl #5,(ap) ; argument count on call frame
beql test_stack ; called with correct # args
movl #SS$_INSFARG,r0
brw ret_pt ; return insufficient args
test_stack:
tstl 12(ap)
bneq ok_usage
incb counter ; usage arg not there
ok_usage:
tstl 16(ap)
bneq ok_perm
incb counter ; perm quota arg not there
ok_perm:
tstl 20(ap)
bneq check_counter
incb counter ; overdraft arg not there
check_counter:
cmpl #3,counter ; if nothing there then quit
bneq get_stack ; else at last return arg
movl #SS$_INSFARG,r0
brw ret_pt ;return to caller
get_stack:
tstl 4(ap)
beql no_devnam ;no device descriptor
movl 4(ap),r1
movl (r1),devicedescr ;len of buffer
movl 4(r1),devicedescr+4 ;bufferaddr
brb ok_device ;go around no_devnam
no_devnam:
moval default_disk,devicedescr+4
movl #8,devicedescr ;default length
ok_device:
pushal outlen ; determine # of bytes
pushal devicedescr
pushal devicedescr
calls #3,g^str$trim ;get length of string
movl outlen,devicedescr ; move length in to descriptor
tstl 8(ap) ; is uic present?
beql 15$ ; absent
tstl @8(ap) ; is the value 0?
beql 15$ ; no value get it
movl @8(ap),uic ; user supplied value-how thoughtful!
brb 20$
15$:
jsb getuic ; else get it
20$:
movw #FIB$C_EXA_QUOTA,fibblock+FIB$W_CNTRLFUNC;move control function
moval fibblock,fibdescr+4 ; move block into descriptor
movl #FIB$C_LENGTH,fibdescr
movl uic,quotablock+4 ; move uic we want into quotablock
moval quotablock,quotadescr+4 ;setup quota descriptor
movl #DQF$C_LENGTH,quotadescr; length of quota block
$assign_s devnam=devicedescr,-
chan=channel
cmpl #SS$_NORMAL,r0 ; successful?
beql 30$
brw ret_pt ;return error in assign
30$:
movaq quotadescr,r0
$qiow_s chan=channel,-
func=#IO$_ACPCONTROL,- ; IO func code
iosb=iosb,-
p1=fibdescr,- ;address of fibdescr
p2=r0,- ;address of quotadescr
p4=r0
cmpl #SS$_NORMAL,iosb ; status code
beql 35$
movl iosb,r0 ; move status to return reg
brw ret_pt ; return to calling routine
35$:
cmpl #SS$_NORMAL,r0 ; check status of call itself
beql 40$ ; usually same as iosb
brw ret_pt ;return error in qiow
40$:
tstl 12(ap) ; was usage arg present?
beql 60$
movl quotablock+8,@12(ap) ; return usage value
60$:
tstl 16(ap) ; was permquota arg present?
beql 70$
movl quotablock+12,@16(ap) ; return permquota value
70$:
tstl 20(ap) ; was overdraft arg present?
beql 80$
movl quotablock+16,@20(ap) ; return overdraft value
80$:
tstl 8(ap) ; was uic arg present?
beql finish ; if not then don't return it
movl uic,@8(ap) ; else return value of
finish:
ret_pt:
tstw channel ; see if the channel was assnd
beql 10$
pushr #^M ; save return status of $qiow_s
$dassgn_s chan=channel ; deassign the channel
popr #^M ; restore return status of $qiow_s
; ignore return status of $dassgn_s
10$:
ret
.end