! Filestore Port killing program (posher AutoChop)
! MDP April'84
begin
include "managr:nsdefs.inc"
include "Inc:Fs.IMP"
include "Inc:Util.IMP"
include "managr:ns.inc"
own string (31) Sys Time = "",
Sys Date = ""
string (2) fn Hex 2(integer xx)
const byte array Hex Sym (0 : 15) = c
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
string (2) Frig = To String (Hex Sym ((Xx >> 4) & 15)) . c
To String (Hex Sym (Xx & 15))
result = String (Addr (Frig))
end
routine Format(string (255) Line)
string (80) This
cycle
if Length (Line) > 80 start
This = Sub String (Line, 1, 80)
Line = Sub String (Line, 81, Length (Line))
else
This = Line
Line = ""
finish
Print String (This)
New Line if Line # ""
repeat until Line = ""
end
routine Announce(string (80) What, integer Count)
Write (Count ,0)
Space
Print String (What)
Print Symbol ('s') if Count # 1
end
integer fn Day Difference (string (7) Lower, Upper)
string (2) Lo Hrs = Sub String (Lower, 1, 2),
Lo Min = Sub String (Lower, 4, 5)
string (2) Hi Hrs = Sub String (Upper, 1, 2),
Hi Min = Sub String (Upper, 4, 5)
integer Total
if Lo Hrs = Hi Hrs start
Total = StoI (Hi Min) - StoI (Lo Min)
else
Total = 60 * (S to I (Hi Hrs) - S to I (Lo Hrs))
Total = Total + (S to I (Hi Min) - S to I (Lo Min))
finish
result = Total
end
integer fn Time Difference (string (31) Time Rating)
string (15) Day
string (7) Tim
if Time Rating -> Day .(" "). Tim start ; finish
Tim = Sub String (Tim, 2, Length (Tim)) while Charno (Tim, 1) = ' '
if Sys Date = Day start
result = Day Difference (Tim, Sys Time)
else
result = 24 * 60 - Day Difference (Sys Time, Tim)
finish
end
integer fn Minimum Difference(string (31) One, Two)
integer I One,
I Two
Sys Time = Time if Sys Time = ""
Sys Date = Date if Sys Date = ""
I One = Time Difference (One)
I Two = Time Difference (Two)
result = I One if I One < I Two
result = I Two
end
record format User Fm (string (6) User Name, Directory,
string (21) Login Time,
byte Uno, Pno, Flags, Location,
short Difference)
routine Get Unos From FS(record (User Fm) array name Users (1 : *),
integer name Number of Users,
integer name Number of Internal Copies) ;! -- for Users
record (User Fm) name Element
string (19) User, Dir, Login
string (19) Read Time, Write Time
string (8) Today = Date
integer Id, Sym, Flag, Uno, Pno
integer nl flag = 0
integer tptr,tlen,taddr
routine Read Sym (integer name sym)
signal 9 if tptr = taddr+tlen
sym = byteinteger(tptr)
tptr = tptr+1
end
routine Skip Symbol
integer sym
read sym (sym)
end
integer fn Hex Sym (integer Sym)
result = Sym - '0' if '0' <= Sym <= '9'
result = Sym - 'A' + 10
end
routine Read Rest of (string (19) name What)
integer Sym
cycle
Read Sym (Sym)
nl flag = 1 and Sym = ' ' if sym = nl
exit if Sym = ' '
What = What . To String (Sym)
repeat
end
routine Skip Spaces (integer name Sym)
Sym = ' '
Read Sym (Sym) while Sym = ' '
end
routine Read Date (string (*) name Dat, integer name Sym)
Dat = To String (Sym)
Read Rest of (Dat)
Dat = Dat ." "
Skip Spaces (Sym)
Dat = Dat . To String (Sym)
Read Rest of (Dat)
end
on 9 start
-> End Load
finish
{ Print String ("In Get FS Unos..."); New Line
Sys Time = Time
Sys Date = Date
Number of Users = 0
Number of Internal Copies = 0
Connect File ("$:UNOS",0,taddr,tlen)
{ Print String ("File connected at addr = "); PHex (taddr)
{ Print String (" to of len = "); PHex (TLen); New Line
tptr = taddr
Read Sym (Sym) until Sym = Nl ;! skip ANON
! 6 -2 pub pub ---login------ -----read----- -----write----
cycle
Flag = 0
Skip Symbol ;! leading space
! -- Uno
Read Sym (Sym)
Read Sym (Uno)
if Sym # ' ' then Uno = 10 * (Sym - '0') + (Uno - '0') c
else Uno = Uno - '0'
! -- 2 Spaces
Skip Symbol
Skip Symbol
! -- Port Number
Read Sym (Sym)
if Sym = '-' start
Number of Internal Copies = Number of Internal Copies + 1
Read Sym (Sym) until Sym = Nl
continue
finish
Read Sym (Pno)
if Sym # ' ' then Pno = 10 * (Sym - '0') + (Pno - '0') c
else Pno = Pno - '0'
! -- 2 Spaces
Skip Symbol
Skip Symbol
! -- Terminal Address
Read Sym (Sym)
Read Sym (Id)
Id = 16 * Hex Sym (Sym) + Hex Sym (Id)
! -- 3 Spaces
Skip Symbol for Sym = 1, 1, 3 ;! skip upto spaces before user name
! -- Username
Skip Spaces (Sym)
User = To String (Sym)
Read Rest of (User)
if Charno (User, Length (User)) = '!' start
Flag = 1
Length (User) = Length (User) - 1
finish
Skip Spaces (Sym)
Dir = To String (Sym)
Read Rest of (Dir)
Skip Spaces (Sym)
Login = To String (Sym)
Read Rest of (Login)
Skip Spaces (Sym)
if Login # Today then Login = Login . " " . To String (Sym) c
else Login = To String (Sym)
Read Rest of (Login)
Skip Spaces (Sym)
Read Date (Read Time, Sym)
Skip Spaces (Sym)
Read Date (Write Time, Sym)
if nl flag = 0 start
Read Sym (Sym) until Sym = Nl
finish
Number of Users = Number of Users + 1
Element == Users (Number of Users)
Element_Uno = Uno
Element_Pno = Pno
Element_User Name = User
{ Print String ("Read user '".User."'");New Line
Element_Directory = Dir
Element_Login Time = Login
if 00<=id<=255 then element_location=id else c
Element_Location = 255
Element_Flags = Flag
Element_Difference = Minimum Difference (Read Time, Write Time)
repeat
End Load:
{ Print String ("Leaving Get FS Unos..."); New Line
Sys Time = ""
Sys Date = ""
end
constant string (6) Free Location = "*Free*"
constant integer Vax Station 1 = 16_03,
Vax Station 2 = 16_72
record format Port Fm (string (2) Local,
integer Remote Id,
string (2) Remote P,
integer Difference)
record (Port Fm) array Ports (1:48)
integer Number of Ports = 0
record (User Fm) array Users (1 : 48)
integer Number of Users = 0
byte integer Local S = L Dte,
Local P = L Sap,
Remote S = R Dte,
Remote P = R Sap,
Host = R Dte
routine Chop
byte Four = 12
Ether Write (FS Port, Four, 1)
cycle
repeat until Ack&1 << FS Port # 0
end
routine Alias (integer FS Station, FS Port No, APM Station, APM Port No)
Ethc = 15
T Wait
Ethc = 7
T Wait
Ethd = APM Station
T Wait
Fsport = APM Port No
Ether Open (FS Port, FS Station << 8 + FS Port No)
end
string (31) fn Sleep State (integer Minutes)
const string (31) array Comments (0:7) = c
"", "beginning to yawn ",
"drowsing ", "dropping off ",
"asleep ", "snoring gently ",
"fast asleep ", "dead to the world "
Minutes = Minutes // 10
Minutes = 0 if Minutes < 0 ;! ???
Minutes = 7 if Minutes > 7
result = Comments (Minutes)
end
Routine Get Table From FS
string (80) Line
string (19) Read Time, Write Time
string (2) Loc P, Rem P, Temp I
integer Rem I
record (Port Fm) name Port
integer fn Hex Char (integer Sym)
result = Sym - '0' if '0' <= Sym <= '9'
result = Sym - 'A' + 10
end
on 9 start
-> End Load
finish
Number of Ports = 0
Open Input (1, "$:Ports")
Select Input (1)
cycle
Read Line (Line)
Loc P = Sub String (Line, 2, 3)
Temp I = Sub String (Line, 6, 7)
Rem I = Hex Char (Charno (Temp I, 2))
Rem I = 16 * Hex Char (Charno (Temp I, 1)) + Rem I if Charno (Temp I, 1) # ' '
Rem P = Sub String (Line, 9, 10)
Read Time = Sub String (Line, 13, 26)
Write Time = Sub String (Line, 29, 42)
Number of Ports = Number of Ports + 1
Port == Ports (Number of Ports)
Port_Local = Loc P
Port_Remote Id = Rem I
Port_Remote P = Rem P
Port_Difference = 1{Minimum Difference (Read Time, Write Time)
repeat
End Load:
Close Input
Select Input (0)
end
record (Port Fm) name Port
record (User Fm) name User
string (255) Temp Res, Res, Parm = CLI Param
string (7) Whos Using, S Pno
record (ns lfm) data
integer Number of Dead = 0
integer Pno, Uno, Len, Nic
integer P L, P R, Sym, i, j, xno
Get Table From Fs
Get Unos From Fs (Users, Number of Users, Nic)
xno = open ns db
for Pno = 1,1, Number of Ports cycle
Port == Ports (Pno)
Res = ""
Res = Port_Local ." ".Hex2 (Port_Remote Id)." ".Port_Remote P." : "
Whos using = Free Location
for Uno = 1, 1, Number of Users cycle
User == Users (Uno)
if User_Pno < 10 then SPno = I To S (User_Pno, 1) c
else SPno = I To S (User_Pno, 0)
if Port_Local = S Pno start
Whos Using = User_User Name
exit
finish
repeat
Whos Using = " " . Whos Using while Length (Whos Using) < 6
Res = Res . Whos Using . " " . Sleep State (Port_Difference)
i = read ns db(xno, port_remote id!long, addr(data))
if i>=0 start
if data_inon = 'I' start
res=res." In "
elseif data_inon = 'O'
res=res." On "
elseif data_inon = 'A'
res=res." At "
finish
res=res."the " if data_room = 'T'
for j=31,-1,1 cycle ; exit if data_lname(j) > ' '; repeat
for i=1,1,j cycle ; res=res.tostring(data_lname(i)); repeat
res=res."'s room" if data_room = 'R'
else
res=res."On a mythical machine "
finish
Res = Res . " " while Length (Res) < 74
Res = Res . ":"
{ Print String (Res); newline
Prompt (Res)
Sym = Test Symbol until Sym = -1
Read Symbol (Sym) until Sym!' ' = 'n' or Sym!' ' = 'y' or Sym = Nl
if Sym ! ' ' = 'y' start
if Whos Using # Free Location start
Prompt ("That terminal is occupied, Are you sure : ")
P L = Test Symbol until P L = -1
Read Symbol (Pl) until Pl!' ' = 'n' or Pl!' ' = 'y' or Pl = Nl
else
P L = 'y'
finish
if P L! ' ' = 'y' start
P L = S To I (Port_Local)
P R = S To I (Port_Remote P)
Alias (Host, P L, Port_Remote Id, P R)
Chop
Alias (Remote S, Remote P, Local S, Local P)
Number of Dead = Number of Dead + 1
Number of Users = Number of Users - 1 if Whos Using # Free Location
finish
finish
Read Symbol (Sym) while Sym # Nl
repeat
close ns db(xno)
Announce ("port", Number of Ports)
Print String (" allocated with ")
Announce ("port", Number of Dead)
Print String (" killed and ")
Write (Number of Users, 0)
Print String (" now left in use.")
New Line
end of program