Leaf.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Loosely derived (after extensive discussions with Wobber) from Butterfield's LeafDefs of July 27, 1979 2:11 PM.
Levin: 3-Feb-82 9:26:38
Russ Atkinson: March 7, 1985 1:29:16 pm PST
DIRECTORY
Basics USING [BYTE],
PupTypes USING [PupSocketID, PupType];
Leaf: DEFINITIONS = BEGIN OPEN Basics;
Types and Related Constants --
LeafType: TYPE = MACHINE DEPENDENT {
error(0), open(1), close(2), delete(3), length(4), truncate(5), read(6), write(7), reset(8), noop(9), telnet(10), params(11), (31)};
LeafOp: TYPE = MACHINE DEPENDENT RECORD [
type(0:0..4): LeafType,
sense(0:5..5): {request, reply} ← request,
length(0:6..15): CARDINAL [0..532]];
openOp: LeafOp = [type: open, length: 2*SIZE[open RequestObject]];
closeOp: LeafOp = [type: close, length: 2*SIZE[close RequestObject]];
deleteOp: LeafOp = [type: delete, length: 2*SIZE[delete RequestObject]];
lengthOp: LeafOp = [type: length, length: 2*SIZE[length RequestObject]];
truncateOp: LeafOp = [type: truncate, length: 2*SIZE[truncate RequestObject]];
readOp: LeafOp = [type: read, length: 2*SIZE[read RequestObject]];
writeOp: LeafOp = [type: write, length: 2*SIZE[write RequestObject]];
resetOp: LeafOp = [type: reset, length: 2*SIZE[reset RequestObject]];
paramsOp: LeafOp = [type: params, length: 2*SIZE[params RequestObject]];
All strings in the reset and open ops have the form:
LeafString: TYPE = MACHINE DEPENDENT RECORD [
length: CARDINAL, text: ARRAY [0..0) OF CHARACTER];
Note: the op.length field for reset, open, and write must include the entire opSpecific body, including the variable length data that follows the fixed parts declared below.
Request: TYPE = LONG POINTER TO RequestObject;
OpenRequest: TYPE = LONG POINTER TO open RequestObject;
CloseRequest: TYPE = LONG POINTER TO close RequestObject;
DeleteRequest: TYPE = LONG POINTER TO delete RequestObject;
TruncateRequest: TYPE = LONG POINTER TO truncate RequestObject;
ReadRequest: TYPE = LONG POINTER TO read RequestObject;
WriteRequest: TYPE = LONG POINTER TO write RequestObject;
ResetRequest: TYPE = LONG POINTER TO reset RequestObject;
ParamsRequest: TYPE = LONG POINTER TO params RequestObject;
RequestObject: TYPE = MACHINE DEPENDENT RECORD [
op: LeafOp,
opSpecific:
SELECT COMPUTED LeafType FROM
params => [
packetDataBytes: CARDINAL, -- server's default is 532
fileLockTimeout: FiveSeconds ← 0, -- server's default is 10 minutes
connectionTimeout: FiveSeconds ← 0], -- server's default is 12 hours
reset => [
which: Resetee ← thisHost
primaryUserName string
primaryPassword string
],
open => [
handle: Handle ← noHandle,
read: BOOLEANTRUE, write, extend, multiple, create: BOOLEANFALSE,
vExplicit: {no, old, nextOrOld, any} ← any,
vDefault: {no, lowest, highest, next} ← highest,
leaderInfo, listMultiple: BOOLEANFALSE,
fill: [0..31] ← 0
primaryUserName string
primaryPassword string
secondaryUserName string
secondaryPassword string
fileName string
],
close, delete => [handle: Handle],
truncate => [handle: Handle, eofAddress: FileAddress],
read => [
handle: Handle, address: FileAddress, length: ByteCount,
rate: Rate ← anyRate],
write => [
handle: Handle, address: FileAddress, length: ByteCount,
writeBody:
SELECT OVERLAID * FROM
writeWords => [writeWords: ARRAY [0..0) OF WORD],
writeBytes => [writeBytes: PACKED ARRAY [0..0) OF BYTE],
writeChars => [writeChars: PACKED ARRAY [0..0) OF CHAR],
ENDCASE],
not presently used --
error => NULL,
noop => NULL,
not presently implemented --
length => [handle: Handle],
telnet => NULL,
ENDCASE];
openAns: LeafOp = [type: open, sense: reply, length: 2*SIZE[open AnswerObject]];
closeAns: LeafOp = [type: close, sense: reply, length: 2*SIZE[close AnswerObject]];
deleteAns: LeafOp = [type: delete, sense: reply, length: 2*SIZE[delete AnswerObject]];
lengthAns: LeafOp = [type: length, sense: reply, length: 2*SIZE[length AnswerObject]];
truncateAns: LeafOp = [type: truncate, sense: reply, length: 2*SIZE[truncate AnswerObject]];
readAns: LeafOp = [type: read, sense: reply, length: 2*SIZE[read AnswerObject]];
writeAns: LeafOp = [type: write, sense: reply, length: 2*SIZE[write AnswerObject]];
resetAns: LeafOp = [type: reset, sense: reply, length: 2*SIZE[reset AnswerObject]];
paramsAns: LeafOp = [type: params, sense: reply, length: 2*SIZE[params AnswerObject]];
Answer: TYPE = LONG POINTER TO AnswerObject;
OpenAnswer: TYPE = LONG POINTER TO open AnswerObject;
CloseAnswer: TYPE = LONG POINTER TO close AnswerObject;
DeleteAnswer: TYPE = LONG POINTER TO delete AnswerObject;
TruncateAnswer: TYPE = LONG POINTER TO truncate AnswerObject;
ReadAnswer: TYPE = LONG POINTER TO read AnswerObject;
WriteAnswer: TYPE = LONG POINTER TO write AnswerObject;
ResetAnswer: TYPE = LONG POINTER TO reset AnswerObject;
ParamsAnswer: TYPE = LONG POINTER TO params AnswerObject;
AnswerObject: TYPE = MACHINE DEPENDENT RECORD [
op: LeafOp,
opSpecific:
SELECT COMPUTED LeafType FROM
error => [error: IfsError, errorOp: LeafOp, handle: Handle],
reset => NULL,
params => [opp: CARDINAL, undefined: CARDINAL],
open => [handle: Handle, eofAddress: FileAddress],
close, delete, truncate => [handle: Handle],
read => [
handle: Handle, address: FileAddress, length: ByteCount,
readBody:
SELECT OVERLAID * FROM
readWords => [readWords: ARRAY [0..0) OF WORD],
readBytes => [readBytes: PACKED ARRAY [0..0) OF BYTE],
readChars => [readChars: PACKED ARRAY [0..0) OF CHAR],
ENDCASE],
write => [
handle: Handle, address: FileAddress, length: ByteCount, rate: Rate],
not presently expected --
noop => NULL,
not presently implemented --
length => [handle: Handle, eofAddress: FileAddress],
telnet => NULL,
ENDCASE];
FiveSeconds: TYPE = CARDINAL; -- units of five seconds; zero means server default
FileAddress: TYPE = MACHINE DEPENDENT RECORD [
opSpecific(0:0..4): OpSpecificFileAddress ← [read[]],
high(0:5..15): [0..2047], low(1:0..15): CARDINAL];
OpSpecificFileAddress: TYPE = MACHINE DEPENDENT RECORD [
SELECT COMPUTED LeafType FROM
open, length, truncate => [fill: [0..31] ← 0],
read, write =>
[mode: {anywhere, noHoles, dontExtend, checkExtend} ← anywhere,
newEOF: BOOLEANFALSE,
fill: [0..3] ← 0],
ENDCASE];
ByteCount: TYPE = CARDINAL;
Rate: TYPE = CARDINAL;
anyRate: Rate = 0;
Handle: TYPE = CARDINAL;
noHandle: CARDINAL = 0;
Resetee: TYPE = MACHINE DEPENDENT {thisHost(0), fileLocks(1), allHosts(177777B)};
IfsError: TYPE = MACHINE DEPENDENT {
ok(0),
nameMalformed(201), illegalChar(202), illegalStar(203), illegalVersion(204),
nameTooLong(205), illegalDIFAccess(206), fileNotFound(207), accessDenied(208),
fileBusy(209), dirNotFound(210), allocExceeded(211), fileSystemFull(212),
createStreamFailed(213), fileAlreadyExists(214), fileUndeletable(215),
userName(216), userPassword(217), filesOnly(218),
connectName(219), connectPassword(220),
brokenLeaf(1001), unimplementedOp(1010), badHandle(1011), fileTooLong(1012),
illegalTruncate(1013), illegalRead(1015), illegalWrite(1016), (177777B)};
Miscellaneous Declarations
leafSocket: PupTypes.PupSocketID = [0, 43B];
ptLeaf: PupTypes.PupType = LOOPHOLE[260B];
END.