// IfsLeafRare.bcpl - Leaf Rare - SWAPPABLE // Copyright Xerox Corporation 1979, 1980, 1981 // Last modified November 25, 1981 6:33 PM by Taft get ecBuddingLeaf, ecBrokenLeaf, ecIllegalLeafTruncate from "IfsLeafErrors.decl"; get "IfsLeaf.decl"; get "IfsSequin.decl"; external [ //outgoing procedures BuddingLeaf; DeleteLeaf; DoNothingLeaf; LeafError; ParamsLeaf; ResetLeaf; TruncateLeaf; //incoming procedures AnswerSetOp; CallersFrame; CheckHandle; SetModeLength; CloseFH; DeleteFileFromFD; DoubleDifference; Free; Umin; FreeLeafVMem; FreePointer; LeafLogin; MoveBlock; NextLockedSequin; ReturnFrom; SequinDestroy; SequinReset; StringCompare; Zero; //incoming statics CtxRunning; leafOpLim; lenPup; system; ] manifest portOffset = offset Sequin.port/16; //---------------------------------------------------------------------------- let BuddingLeaf(sequin, answerPBI, op) = LeafError(answerPBI, op, ecBuddingLeaf) //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- and DoNothingLeaf(requestSequin, answerPBI, op) = valof //---------------------------------------------------------------------------- [ AnswerSetOp(answerPBI, op, 2*lenLeafAnswer); resultis leafOpComplete; ] //---------------------------------------------------------------------------- and ResetLeaf(requestSequin, answerPBI, op) = valof //---------------------------------------------------------------------------- [ // All opCodes to 'broken leaf' sequins get passed here....filter them. let leafstring = lv op>>ResetRequest.strings; let ui = vec lenUserInfo; let ec = (op>>Op.code ne opReset? ecBrokenLeaf, LeafLogin(lv leafstring, ui)); CtxRunning>>RSCtx.userInfo = system; if ec ne 0 then resultis LeafError(answerPBI, op, ec); // Note that no resetOps work unless login is successful. let unam = ui>>UserInfo.userName; FreePointer(lv requestSequin>>Sequin.unam, lv ui>>UserInfo.connName); requestSequin>>Sequin.unam = unam; let allHosts = false; switchon op>>ResetRequest.resetOp into [ case resetAllHosts: allHosts = true; default: [ let sequin = 0; [ // Loop through sequin queue. sequin = NextLockedSequin(sequin); if sequin eq 0 then break; let samePort = requestSequin!portOffset eq sequin!portOffset; unless samePort % allHosts do loop; unless StringCompare(unam, sequin>>Sequin.unam) eq 0 do [ if samePort then SequinReset(sequin); loop; ] // Close all files on this sequin. // The only reason that this is done here is that "reset" // might be used to close handles on an open connection. [ let fh = sequin>>Sequin.fhQ.head; if fh eq 0 break; CloseFH(sequin, fh); ] repeat if sequin ne requestSequin then SequinDestroy(sequin); ] repeat ] // fall through case resetBrokenLeaf: requestSequin>>Sequin.brokenLeaf = false; endcase; ] AnswerSetOp(answerPBI, op, 2*lenLeafAnswer); resultis leafOpComplete; ] //---------------------------------------------------------------------------- and ParamsLeaf(sequin, answerPBI, op) = valof //---------------------------------------------------------------------------- [ switchon op>>Op.length/2 into [ case 4: if op>>ParamsRequest.connTimeout ne 0 then sequin>>Sequin.connTimeout = op>>ParamsRequest.connTimeout; case 3: if op>>ParamsRequest.lockTimeout ne 0 then sequin>>Sequin.lockTimeout = Umin(op>>ParamsRequest.lockTimeout, defaultLockTimeout); case 2: [ if op>>ParamsRequest.pupDataBytes ne 0 then sequin>>Sequin.pupDataBytes = Umin(op>>ParamsRequest.pupDataBytes, 2*lenPup-pupOvBytes); ] default: endcase; ] AnswerSetOp(answerPBI, op, 2*lenLeafAnswer); resultis leafOpComplete; ] //---------------------------------------------------------------------------- and DeleteLeaf(sequin, answerPBI, op) = valof //---------------------------------------------------------------------------- [ let fh = CheckHandle(sequin, answerPBI, op); let ec = DoTruncate(fh, 0); if ec eq 0 then [ let fd = fh>>FH.fd; FreeLeafVMem(fd, fh>>FH.lvmd); fh>>FH.lvmd = 0; CtxRunning>>RSCtx.userInfo = lv fh>>FH.ui; ec = DeleteFileFromFD(fd); CtxRunning>>RSCtx.userInfo = system; CloseFH(sequin, fh); ] if ec ne 0 resultis LeafError(answerPBI, op, ec); AnswerSetOp(answerPBI, op, 2*lenLeafAnswer); resultis leafOpComplete; ] //---------------------------------------------------------------------------- and TruncateLeaf(sequin, answerPBI, op) = valof //---------------------------------------------------------------------------- [ let fh = CheckHandle(sequin, answerPBI, op); let ec = DoTruncate(fh, lv op>>FileRequest.address); if ec ne 0 then resultis LeafError(answerPBI, op, ec); AnswerSetOp(answerPBI, op, 2*lenLeafAnswer); resultis leafOpComplete; ] //---------------------------------------------------------------------------- and DoTruncate(fh, address) = valof //---------------------------------------------------------------------------- [ let op = vec writeRequestOv/2; Zero(op, writeRequestOv/2); if address ne 0 then MoveBlock(lv op>>FileRequest.address, address, size LeafAddress/16); op>>FileRequest.address.newEOF = true; op>>FileRequest.address.mode = checkExtend; resultis (SetModeLength(op, fh, true)? 0,ecIllegalLeafTruncate); ] //---------------------------------------------------------------------------- and LeafError(answerPBI, op, ec) = valof //---------------------------------------------------------------------------- [ let answer = AnswerSetOp(answerPBI, op, 2*lenErrorAnswer); answer>>ErrorAnswer.op.code = opError; answer>>ErrorAnswer.error = ec; answer>>ErrorAnswer.errorOp = @op; answer>>ErrorAnswer.handle = @(op+1); resultis leafOpError; ]