-- File: Leaf.mesa -- Last edited by Levin: 3-Feb-82 9:26:38 -- Loosely derived (after extensive discussions with Wobber) from Butterfield's -- LeafDefs of July 27, 1979 2:11 PM. 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 => [op: 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.