! APM filestore File Statistics utilities
!Hacked JHB 24/6/86 to make it work for small disks (GIVE SUMMARY)
!Extended RWT 23/7/86 to get hitlists in decreasing order of blocks
include "Inc:FS.IMP"
include "Inc:UTIL.IMP"
include "SYSTEM:CONFIG.INC"
ownbytearray buffer(0 : 511)
ownbytename next
ownbytename last
routine do(integer what, string (31) param)
integer i
i = fcommr(what << 8, param, buffer(0), 512)
next == buffer(0)
last == next[i]
end
integerfn next sym
integer ch
result = -1 if next == last
ch = next
next == next[1]
result = ch
end
routine skip to(integer what)
integer ch
ch = next sym until ch = what
end
routine dump
integer ch
ch = next sym
while ch >= 0 cycle
print symbol(ch)
ch = next sym
repeat
end
string (31)fn next word
string (31) s
integer ch
s = ""
ch = next sym until ch > ' '
cycle
s = s . to string(ch)
ch = next sym
repeat until ch <= ' '
result = s
end
integerfn next integer
integer n, ch
n = 0
ch = next sym until '0' <= ch <= '9'
while '0' <= ch <= '9' cycle
n = 10 * n + ch - '0'
ch = next sym
repeat
result = n
end
ownstring (7)array users(1 : 128) = "***" (*)
routine get users(integer p)
integer i
do('¬', to string('0' + (p << 1)))
users(i) = next word for i = 1, 1, 64
do('¬', to string('0' + (p << 1) + 1))
users(i) = next word for i = 65, 1, 128
end
routine sort users(integer from, to)
string (7) d
integer l, u
label up, fi, fo, do
return if from >= to
l = from; u = to
d = users(u)
-> fi
up: l = l + 1; -> fo if l = u
fi: -> up unless users(l) >= d
users(u) = users(l)
do: u = u - 1; -> fo if l = u
-> do unless users(u) <= d
users(l) = users(u)
-> up
fo: users(u) = d
sort users(from, l - 1)
sort users(u + 1, to)
end
owninteger total files = 0
owninteger total extents = 0
owninteger total blocks = 0
routine show one(string (7) who)
integer files = 0, blocks = 0, extents = 0
return if who = "---" or who = "*bad*"
do('F', who . ",0")
printstring(who); spaces(8 - length(who))
skip to(':'); files = next integer
skip to(':'); extents = next integer
skip to(':'); blocks = next integer
if files = 0 start
printstring(" - - - -")
printstring(" - -")
else
write(files, 9); total files = total files + files
write(blocks, 9); total blocks = total blocks + blocks
write(extents, 9); total extents = total extents + extents
print(blocks / files, 7, 1)
print(extents / files, 7, 1)
print(blocks / extents, 7, 1)
finish
newline
end
routine give summary (integer first part, last part)
{jhb was here 24/6/86}
recordformat bitmap fm(bytearray b(0 : bitmap size))
record (bitmap fm)name bm
integer s, l, i, partno, j, total, total total
string (127) command = ""
byte x
!small disks will bomb out event 3 on reading past end of disk
on 3 start ; last part=partno-1; -> eod; finish
total total = 0
for partno = first part, 1, last part cycle
connect file("$:BITMAP." . to string(partno + '0'), 0, s, l)
bm == record(s)
total = 0
for i = 0, 1, bitmap size - 1 cycle
x = bm_b(i)
for j = 0, 1, 7 cycle
total = total + 1 if x & 1 # 0
x = x >> 1
repeat
repeat
printstring("Partition "); write(partno, 0)
printstring(" has "); write(total, 0)
printstring(" block"); printsymbol('s') if total # 1
printstring(" (")
print(100 * total / (bitmap size << 3), 0, 2)
printstring("%) used")
newline
total total = total total + total
repeat
eod:
return unless first part = 0 and last part#0
printstring("Grand total of "); write(total total, 0)
printstring(" blocks (")
print(100 * total total / (8 * bitmap size * (last part + 1)), 0, 2)
printstring("%) used")
newline
end
routine give details (integer first part, last part)
integer p, i
!Small disks will bomb out event 3 on reading ficticious partition
on 3 start ; return ; finish
newlines (2)
for p=first part, 1, last part cycle
total files = 0; total blocks = 0; total extents = 0
get users(p)
sort users(1, 128)
printstring("Partition "); write(p, 0)
printstring(" at "); printstring(time)
printstring(" on "); printstring(date)
newline
printstring("User Files Blocks Extents")
printstring(" B/F E/F B/E")
newline
printstring("--------------------------------------")
printstring("------------------------------")
newline
show one(users(i)) for i = 1, 1, 128
printstring("--------------------------------------")
printstring("------------------------------")
newline
printstring("Totals ")
if total files = 0 start
printstring("** none **")
else
write(total files, 9)
write(total blocks, 9)
write(total extents, 9)
print(total blocks / total files, 7, 1)
print(total extents / total files, 7, 1)
print(total blocks / total extents, 7, 1)
finish
newline
printstring(" Files Blocks Extents")
printstring(" B/F E/F B/E")
newline
print symbol (12) and newlines (2) if p#last part
repeat
end
routine give hitlist (integer first part, last part)
integer p, i
recordformat f(record (f)name l,r,string (7)name,
integer blocks,files,extents,partition)
record (f)name tree == nil
record (f)map add(record (f)name cell,tree)
result == cell if tree==nil
if cell_blocks<=tree_blocks start
tree_l == add(cell,tree_l)
else
tree_r == add(cell,tree_r)
finish
result == tree
end
routine print(record (f)name t,integer mask)
returnif t==nil
print(t_r,mask)
if 1<<t_partition&mask#0 start
printstring(t_name); spaces(8-length(t_name))
write(t_files,9); write(t_blocks,9); write(t_extents,9)
write(t_partition,3) if mask<0; newline
finish
print(t_l,mask)
end
routine get one(string (7) who)
integer files, blocks, extents
record (f)name r
return if who = "---" or who = "*bad*"
do('F', who . ",0")
skip to(':'); files = next integer
skip to(':'); extents = next integer
skip to(':'); blocks = next integer
returnif files=0
r == new(r); r = 0; r_name = who; r_partition = p
r_blocks = blocks; r_files = files; r_extents = extents
tree == add(r,tree)
end
routine get some(integer p)
integer i
on 3 start ; return ; finish
get users(p)
sort users(1, 128)
get one(users(i)) for i = 1,1,128
newlines (2)
printstring("Partition "); write(p, 0)
printstring(" at "); printstring(time)
printstring(" on "); printstring(date)
newline
printstring("User Files Blocks Extents")
newline
print(tree,1<<p)
print symbol (12) and newlines (2) if p#last part
end
get some(p) for p = first part, 1, last part
unless first part = last part start
printsymbol(12); newlines(2)
printstring("All partitions"); newline
printstring("User Files Blocks Extents Partition")
newline
print(tree,-1)
finish
end
begin
const integer summary=0,full=1,hitlist=2
integer i, p, first part, last part
byte mode
string (127) output
p = -1
define int param ("Partition", p, pam major)
output = ":T"
define param ("Output", output, pam new group + pam major)
mode = summary
define enum param ("Summary,Full,Hitlist", mode, pam major)
process parameters (cliparam)
mode = summary if mode=0
if P<0 or P>last partition start
first part = 0
last part = last partition
else
first part = P
last part = P
finish
open output(3, output); select output(3)
if mode=summary start
give summary (first part, last part)
elseif mode=full
give details (first part, last part)
else
give hitlist (first part, last part)
finish
close output
end of program