FileMgr Operations
ReadFileOp:
PUBLIC
PROC [mnt: ServerData, xnsFile: OpenFile, filePosition, nBytes:
CARD, to:
POINTER]
RETURNS [bytesRead:
INT ← 0] ~ {
range: FilingP10V5.ByteRange ~ [filePosition, nBytes];
Sink: CrRPC.BulkDataSink ~
TRUSTED {
block: Basics.UnsafeBlock ~ [to, 0, nBytes];
abort ← checkAbort[h];
bytesRead ← s.UnsafeGetBlock[block];
};
RetrieveBytesOp[mnt, xnsFile.fileH, range, Sink];
};
WriteFileOp:
PUBLIC
PROC [mnt: ServerData, xnsFile: OpenFile, filePosition, nBytes:
CARD, from:
POINTER]
RETURNS [bytesWritten:
INT ← 0] ~ {
range: FilingP10V5.ByteRange ~ [filePosition, nBytes];
Source: CrRPC.BulkDataSource ~
TRUSTED {
block: Basics.UnsafeBlock ~ [from, 0, nBytes];
abort ← checkAbort[h];
s.UnsafePutBlock[block];
bytesWritten ← nBytes;
};
ReplaceBytesOp[mnt, xnsFile.fileH, range, Source];
};
CloseFileOp:
PUBLIC
PROC [mnt: ServerData, xnsFile: OpenFile] ~ {
IF ( mnt.session #
NIL )
THEN CloseOp[mnt, xnsFile.fileH];
we don't have to close files after a logout!
CloseInternal[mnt];
};
OpenFileOp:
PUBLIC
PROC [mnt: ServerData, fullFName: PFSNames.
PATH]
RETURNS [xnsFile: OpenFile ←
NIL] ~ {
withSlash: ROPE ~ XNSFilingNames.UnparseName[fullFName];
newFile: ROPE ~ RemoveLeadingSlash[withSlash];
newFile: ROPE ~ PFS.RopeFromPath[fullFName];
attributes: AttributeSequence ~ BuildAttribute[newFile, Interpreted.pathname.ORD];
fileH: FilingP10V5.Handle ~ OpenOp[mnt, attributes];
now: BasicTime.GMT ~ BasicTime.Now[];
xfile: OpenFile ~ NEW[OpenFileObject ← [fileH, now]];
OpenInternal[mnt];
xnsFile ← xfile;
??? XNSFilingOpsImpl.FindFile ???
};
Remote Operations
LogonOp:
PUBLIC
PROC [server:
ROPE]
RETURNS [mnt: ServerData ←
NIL] ~ {
qualified: XNSCHName.Name; add: XNS.Address;
LogonOpInner:
PROC ~ {
name: ROPE ~ XNSCHName.RopeFromName[qualified];
address: REF XNS.Address ~ NEW[XNS.Address ← add];
crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, address];
Strong Authentication logic
realId: XNSAuth.Identity ~ UserCredentials.GetIdentity[];
conversation: XNSAuth.Conversation ~ XNSAuth.Initiate[realId, qualified];
credentials: XNSAuth.Credentials ~ XNSAuth.GetCredentials[conversation];
verifier: XNSAuth.Verifier; session: REF FilingP10V5.Session; timeToLive: CARD32;
XNSAuth.SetRecipientHostNumber[conversation, address.host];
verifier ← XNSAuth.GetNextVerifier[conversation];
session ← NEW[Session ← FilingP10V5.Logon[crH, qualified, credentials, verifier]];
session.verifier ← XNSAuth.GetNextVerifier[conversation];
timeToLive ← FilingP10V5.Continue[crH, session^];
XNSAuth.Refresh[conversation, timeToLive];
CrRPC.DestroyClientHandle[crH];
mnt ← NEW[ServerDataObject ← [name, qualified, address, conversation, session, timeToLive, FilingP10V5.nullHandle, ]];
};
[qualified, add] ← XNSCH.LookupAddressFromRope[server];
IF ( add = XNS.unknownAddress ) THEN GOTO NoCanDo;
LogonOpInner[];
EXITS
NoCanDo => { ERROR };
MountRootOp:
PUBLIC
PROC [mnt: ServerData] ~ {
CrRPC.Error, AuthenticationError, SessionError, ServiceError,
XNSAuth.AuthenticationError, XNSAuth.CallError
crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, mnt.address];
mnt.session.verifier ← XNSAuth.GetNextVerifier[mnt.tkt];
mnt.root ← FilingP10V5.Open[crH, nullAttributes, FilingP10V5.nullHandle, nullControls, mnt.session^];
CrRPC.DestroyClientHandle[crH];
};
ContinueOp:
PUBLIC
PROC [mnt: ServerData] ~ {
crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, mnt.address];
mnt.session.verifier ← XNSAuth.GetNextVerifier[mnt.tkt];
mnt.admin.trTTL ← mnt.timeToLive ← FilingP10V5.Continue[crH, mnt.session^];
XNSAuth.Refresh[conversation: mnt.tkt, seconds: mnt.admin.trTTL];
CrRPC.DestroyClientHandle[crH];
};
OpenOp:
PUBLIC
PROC [mnt: ServerData, attributes: AttributeSequence]
RETURNS [fileH: FilingP10V5.Handle] ~ {
crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, mnt.address];
fileH ← FilingP10V5.Open[h: crH, attributes: attributes, directory: mnt.root, controls: nullControls, session: mnt.session^];
CrRPC.DestroyClientHandle[crH];
};
OpenFIDOp:
PUBLIC
PROC [mnt: ServerData, fid: FileID]
RETURNS [fileH: FilingP10V5.Handle] ~ {
crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, mnt.address];
attributes: AttributeSequence ← NEW[AttributeSequenceObject[1]];
attributes[0] ← [type: InterpretedAttributeType.fileID.ORD, value: EncapsulateFileID[fid]];
mnt.session.verifier ← XNSAuth.GetNextVerifier[mnt.tkt];
fileH ← FilingP10V5.Open[h: crH, attributes: attributes, directory: FilingP10V5.nullHandle, controls: nullControls, session: mnt.session^];
CrRPC.DestroyClientHandle[crH];
};
ListOp:
PUBLIC
PROC [mnt: ServerData, fileH: FilingP10V5.Handle, types: AttributeTypeSequence, scope: ScopeSequence, listing: CrRPC.BulkDataSink] ~ {
crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, mnt.address];
mnt.session.verifier ← XNSAuth.GetNextVerifier[mnt.tkt];
FilingP10V5.List[crH, fileH, types, scope, listing, mnt.session^];
CrRPC.DestroyClientHandle[crH];
};
QuickInfoOp:
PUBLIC
PROC [mnt: ServerData, fileH: FilingP10V5.Handle, types: AttributeTypeSequence]
RETURNS [info: Info] ~ {
crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, mnt.address];
text: REF TEXT;
mnt.session.verifier ← XNSAuth.GetNextVerifier[mnt.tkt];
[info.version, info.bytes, info.created, info.fileType, text, info.fID, info.isDir, info.numKids] ← QuickFilingP10V5.QuickGetAttributes[crH, fileH, types, mnt.session^];
info.pathName ← Rope.FromRefText[text];
RefText.ReleaseScratch[text];
CrRPC.DestroyClientHandle[crH];
};
DeleteOp:
PUBLIC
PROC [mnt: ServerData, fileH: FilingP10V5.Handle] ~ {
crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, mnt.address];
mnt.session.verifier ← XNSAuth.GetNextVerifier[mnt.tkt];
FilingP10V5.Delete[h: crH, file: fileH, session: mnt.session^];
CrRPC.DestroyClientHandle[crH];
};
CloseOp:
PUBLIC
PROC [mnt: ServerData, fileH: FilingP10V5.Handle] ~ {
crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, mnt.address];
FilingP10V5.Close[h: crH, file: fileH, session: mnt.session^];
CrRPC.DestroyClientHandle[crH];
};
RetrieveBytesOp:
PUBLIC
PROC [mnt: ServerData, file: FilingP10V5.Handle, range: FilingP10V5.ByteRange, sink: CrRPC.BulkDataSink] ~ {
crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, mnt.address];
FilingP10V5.RetrieveBytes[crH, file, range, sink, mnt.session^];
CrRPC.DestroyClientHandle[crH];
};
ReplaceBytesOp:
PUBLIC
PROC [mnt: ServerData, file: FilingP10V5.Handle, range: ByteRange, source: CrRPC.BulkDataSource] ~ {
crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, mnt.address];
FilingP10V5.ReplaceBytes[crH, file, range, source, mnt.session^];
CrRPC.DestroyClientHandle[crH];
};
LogoffOp:
PUBLIC
PROC [mnt: ServerData] ~ {
ENABLE
PFS.Error => {
GOTO GiveUp };
SessionError, AuthenticationError, CrRPC.Error
IF ( mnt.session = NIL ) THEN RETURN;
{
session: REF Session ~ mnt.session;
address: REF XNS.Address ~ mnt.address;
crH: CrRPC.Handle ~ CrRPC.CreateClientHandle[$CMUX, address];
FilingP10V5.Logoff[h: crH, session: session^];
CrRPC.DestroyClientHandle[crH];
};
mnt.session ← NIL;
EXITS GiveUp => { NULL };
};
Filing Utils
openTime: CARD;
startO, endO: CARD;
FindFile:
PROC [mnt: ServerData, file:
ROPE, wantedTime: BasicTime.
GMT, op: Op]
RETURNS [fileH: FilingP10V5.Handle ← FilingP10V5.nullHandle, info: Info, withKids:
BOOL] = {
Note: EnumProc ~ {
IF ( wantedTime # eInfo.created )
THEN
RETURN;
check if this is (not) the one
fileH ← OpenFIDOp[mnt, eInfo.fID];
info ← eInfo;
continue ← FALSE;
};
timeSearch: BOOL ~ ( wantedTime # BasicTime.nullGMT );
newFile: ROPE ← ConvertFSNameToXNS[file, op];
attributes: AttributeSequence ← BuildAttribute[newFile, Interpreted.pathname.ORD];
startO ← BasicTime.GetClockPulses[];
fileH ← OpenOp[mnt, attributes];
IF ( fileH # FilingP10V5.nullHandle )
THEN {
endO ← BasicTime.GetClockPulses[];
openTime ← BasicTime.PulsesToMicroseconds[endO] - BasicTime.PulsesToMicroseconds[startO];
info ← InfoFromOpenFile[mnt, fileH, op];
withKids ← ( ( info.isDir ) AND ( info.numKids # 0 ) );
IF ( ( NOT timeSearch ) OR ( wantedTime = info.created ) ) THEN { RETURN };
};
Any file found didn't meet the create time requested.
So, we need to do an enumerate to find a file matching it
CloseOp[mnt, fileH];
fileH ← FilingP10V5.nullHandle;
IF ( timeSearch )
THEN {
since it is a timeSearch we need to do an enumerate
pattern: PFSNames.PATH ~ ConvertToPattern[BangStarFile[file], $enumerate];
EnumerateOp[mnt, pattern, Note, op];
endO ← BasicTime.GetClockPulses[];
openTime ← BasicTime.PulsesToMicroseconds[endO] - BasicTime.PulsesToMicroseconds[startO];
IF ( fileH # FilingP10V5.nullHandle ) THEN RETURN;
};
ERROR;
};
infoTime: CARD;
startE, endE: CARD;
InfoFromOpenFile:
PROC [mnt: ServerData, fileH: FilingP10V5.Handle, op: Op]
RETURNS [info: Info] = {
types: AttributeTypeSequence ~ GetCedarATS[op];
attributes: AttributeSequence ~ FilingP10V5.GetAttributes[crH, fileH, types, mnt.session^];
[...] ← InfoFromAttributeSequence[attributes];
startE ← BasicTime.GetClockPulses[];
info ← QuickInfoOp[mnt, fileH, types];
endE ← BasicTime.GetClockPulses[];
infoTime ← BasicTime.PulsesToMicroseconds[endE] - BasicTime.PulsesToMicroseconds[startE];
};
AttributeTypeSequences (fixed)
deleteATS: AttributeTypeSequence;
enumerateATS: AttributeTypeSequence;
enumerateNamesATS: AttributeTypeSequence;
retrieveATS: AttributeTypeSequence;
storeATS: AttributeTypeSequence;
GetCedarATS:
PROC [op: Op]
RETURNS [attributes: AttributeTypeSequence] = {
attributes ←
SELECT op
FROM
delete => deleteATS,
enumerate => enumerateATS,
enumerateNames => enumerateNamesATS,
rename => enumerateATS,
retrieve => retrieveATS,
store => storeATS,
ENDCASE => ERROR;
};
MakeCedarATS:
PROC
RETURNS [delete, enumerate, enumerateNames, retrieve, store: AttributeTypeSequence] ~ {
CardAT: PROC [iat: InterpretedAttributeType]
RETURNS [card: CARD32] ~ INLINE { card ← iat.ORD };
delete ← NEW[AttributeTypeSequenceObject[6]];
enumerate ← NEW[AttributeTypeSequenceObject[8]];
enumerateNames ← NEW[AttributeTypeSequenceObject[2]];
retrieve ← NEW[AttributeTypeSequenceObject[5]];
store ← NEW[AttributeTypeSequenceObject[1]];
delete[0] ← CardAT[createdOn];
delete[1] ← CardAT[fileID];
delete[2] ← CardAT[isDirectory];
delete[3] ← CardAT[numberOfChildren];
delete[4] ← CardAT[version];
delete[5] ← CardAT[pathname];
enumerate[0] ← CardAT[createdOn];
enumerate[1] ← CardAT[dataSize];
enumerate[2] ← CardAT[name];
enumerate[3] ← CardAT[pathname];
enumerate[4] ← CardAT[type];
enumerate[5] ← CardAT[isDirectory];
enumerate[6] ← CardAT[version];
enumerate[7] ← CardAT[fileID];
enumerateNames[0] ← CardAT[pathname];
enumerateNames[1] ← CardAT[isDirectory];
retrieve[0] ← CardAT[createdOn];
retrieve[1] ← CardAT[dataSize];
retrieve[2] ← CardAT[version];
retrieve[3] ← CardAT[pathname];
retrieve[4] ← CardAT[fileID];
store[0] ← CardAT[version];
};