{ Routines to allow access to files on another filestore } { Genealogy: RWT begat eftp, } { and RDW ripped off bits for the first version of sethost, } { and FDC expanded it somewhat } %include "INC:UTIL.IMP" %include "INC:FS.IMP" %own %short free port = 3 { THESE NEXT TWO PROCEDURES ARE RIPPED OFF FROM EFTP, THANKS RAINER} %predicate gotack(%integer port) ! Wait for ACK and return TRUE. ! Return FALSE if fed up waiting. %integer bit,deadline bit = 1<deadline %false %end %predicate gotdtx(%integer port) ! Wait for DTX and TRUE. FALSE when fed up %integer bit,deadline bit = 1<deadline %false %end { Crummy language doesn't allow constant record arrrays } { Back to FORTRAN-speak } %constant %integer Max Fs = 5 %constant %string (16) %array FNames(1:Max Fs) = "Alpha", "Bravo", "Charlie", "Portable", "Vax" %constant %integer %array FNumbers(1:Max Fs) = 16_14, 16_15, 16_1B, 16_3F, 16_72 {---------- FILESTORE NAME ----------} %external %string (255) %function Filestore Name (%integer n) %integer i %for i = 1, 1, Max Fs %cycle %result = FNames(i) %if FNumbers(i) = n %repeat %result = "Unknown" %end {Filestore Name} {---------- FILESTORE NUMBER ----------} %external %integer %function Filestore Number (%string (*) %name Fs) %integer i %predicate Prefix Match(%string (*) %name s1, s2) { Does s1 match a prefix of s2 ? } %integer i %false %if Length(s1) > Length(s2) %for i = 1, 1, Length(s1) %cycle %false %if (charno(s1, i) ! 32) # (charno(s2, i) ! 32) %repeat %true %end { Prefix Match } %for i = 1, 1, Max Fs %cycle %result = FNumbers(i) %if Prefix Match(Fs, FNames(i)) %repeat %signal 10, 0, 1, "Filestore ".Fs." unknown" %end {Filestore Number} {---------- CURRENT HOST ----------} { Returns a token which identifies the current host. } %external %integer %function Current Host %result = (lsap << 16) ! userno %if fsport = lsap %signal 3, 9, 99, "fsport and lsap differ !" %end {---------- SELECT HOST ----------} { Switches to the filestore identified by 'token'. } { 'token' must have been returned by Current Host or Connect to Host. } %external %routine Select Host(%integer token) userno = token & 16_FFFF lsap = token >> 16 fsport = lsap %end {---------- CONNECT TO HOST ----------} { Given a generalised directory name, this function logs on to it } { and returns a token which can be used in calls to Select Host, } { and which must be used in a call to Disconnect Host before the } { caller terminates. It is the caller's responsibility to save } { Current Host before calling this function and reselect it before } { terminating. } { = ::, / { :::, { = Alpha / Bravo / Charlie / Portable / Vax { = Up to 6 alphanumerics { = Any string { Filestore Name default to Bravo, Directory Name defaults to PUB } { and Password defaults to "". } { Events: 10 0 1 - Unknown filestore } { Events: 10 0 2 - No response from filestore } { 10 0 3 - Illegal connect attempted } %external %integer %function Connect to Host(%string (255) GDir) %string (255) Name, Dir Pass %integer Number, i %byte facil = 2 %byte %array buff(0:63) %label dunparsin Name = "" Dir Pass = "" -> dunparsin %if GDir = "" %if GDir -> Name.("::").Dir Pass %start -> dunparsin %if Length(Dir Pass) = 0 { e.g. B:: } -> dunparsin %if Dir Pass -> Name.(":").Dir Pass { ::B:D } -> dunparsin { B::D or ::B } %else Dir Pass = GDir %finish dunparsin: Name = "Bravo" %if Length(Name) = 0 Number = Filestore Number(Name) %if Number # RDTE %or Dir Pass # "" %start Dir Pass = "PUB" %if Length(Dir Pass) = 0 etheropen(free port, Number << 8) etherwrite(free port, facil, 1) %if %not gotack(free port) %and gotdtx(free port) %then %c %signal 10, 0, 2, "No response from ".Name."::" i = etherread(free port, buff(0), 64) %if i # 2 %or buff(1) # 10 %or buff(0) < '0' %then %c %signal 10, 0, 3, "Illegal Connect attempted to ".Name."::" buff(0) = buff(0) - '0' etheropen(free port, (Number << 8) ! buff(0)) lsap = free port fsport = lsap userno = fcomm('L0', Dir Pass) free port = free port + 1 %finish %result = Current Host %end {---------- DISCONNECT HOST ----------} { Disconnect from the host identified by 'token' } %external %routine Disconnect Host(%integer Token) %byte eot = 12 %byte port port = Token >> 16 %return %if port = 1 { don't disconnect from boot port } etherwrite(port, eot, 1) { do not worry about not getting ack that would only screw us up } etherclose(port) %end