-- File: Leaf.mesa
-- Last edited by Levin: 5-Feb-81 15:38:47
-- Last edited by Gobbel: 27-Jul-81 19:16:00
-- Loosely derived (after extensive discussions with Wobber) from Butterfield's
-- LeafDefs of July 27, 1979 2:11 PM.
-- last edited by Hankins: 24-Jul-84 14:42:15 Klamath conversion (op => o)
DIRECTORY
Environment USING [Byte],
PupTypes USING [PupSocketID, PupType];
Leaf: DEFINITIONS =
BEGIN
-- 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: BOOLEAN ← TRUE,
write, extend, multiple, create: BOOLEAN ← FALSE,
vExplicit: {no, old, nextOrOld, any} ← any,
vDefault: {no, lowest, highest, next} ← highest,
leaderInfo, listMultiple: BOOLEAN ← FALSE,
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 Environment.Byte],
writeChars => [writeChars: PACKED ARRAY [0..0) OF CHARACTER],
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 => [o: 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 Environment.Byte],
readChars => [readChars: PACKED ARRAY [0..0) OF CHARACTER],
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: BOOLEAN ← FALSE,
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.