;Alto->8086 small-c compiler rev 2.0 C←CODE SEGMENT $INCLUDE(8086LIB.D) $INCLUDE(rpcpktstreams.DEC) ASSUME CS:C←CODE, DS:C←DATA ; #include <Queue.h> ; extern struct ExportInstance exportTable[1]; ; extern int used; /* # current exports */ ; extern struct PktConversationID *firstConversation; ; extern int GetConnectionState(); ; extern int IdleReceive(); ; extern struct Queue *myCtxQ; ; extern union Machine myHost; ; extern int *mySoc; ; extern int PktExchange(); ; extern int rpct; ; extern int CallFailed; ; extern int CONT(); ; extern int RejectUnbound; ; extern int RejectProtocol; ; extern SendPup(); ; extern struct PBI *GetPBI(); ; extern int DoubleEq(); ; extern int MultEq(); ; extern CurrentContext(); ; extern Block(); ; extern Enqueue(); ; extern int *Unqueue(); ; extern int DoubleComp(); ; extern int DoubleDiff(); ; extern int DoubleInc(); ; extern Move2(); ; extern int StringSize(); ; extern int *GetFixed(); ; extern MoveBlock(); ; extern Zero(); ; extern int apply(); ; static int idlerAckCount; ; static int idlerRequeueCount; ; int MisusedConversation; ; struct ConnectionData { ; struct ConnectionData *next; ; struct ConnectionID id; ; struct CallCount callCt; ; struct ConversationObject *conv; }; ; struct ConnectionData *connections[0]; ; struct CalleeState { ; struct CalleeState *next; ; num callee; /* PSB.PSBIndex */ ; struct Header *state; }; ; struct Queue callees; /* pointer to CalleeState */ ; int lastCallDest[0]; /* ARRAY {0..maxPSB;}; OF PSB */ ; static RecordCallDest(header) struct Header *header;{ lastCallDest[header->destPSB] = header->srcePSB; }; ←RecordCallDest: PUSH BP MOV BP,SP PUSH BX ; BX ← ←header POP BX PUSH BX MOV CX,[BX+4] MOV BX,←lastCallDest SAL CX ADD BX,CX ; CX ← ←header POP CX PUSH CX MOV DI,CX MOV CX,[DI+6] MOV [BX],CX MOV SP,BP POP BP RET; ; StartCall(callPkt, interface, localConversation) ←StartCall: ; struct PBI *callPkt; ; struct ImportInstance *interface; ; struct Conversation *localConversation; { PUSH BP MOV BP,SP PUSH CX PUSH BX ; int myPSB; ; struct Header *header; ; struct RPCCtx *CtxRunning; ADD SP,0FFFAX ; CtxRunning = CurrentContext(); CALL ←CurrentContext ; ←CtxRunning ← BX POP DX PUSH BX ; myPSB = CtxRunning->user.myPSB; ; BX ← ←CtxRunning POP BX PUSH BX MOV CX,[BX+26] ; ←myPSB ← CX MOV [BP-6],CX ; header = callPkt->pup; ; BX ← ←callPkt MOV BX,[BP+4] MOV CX,[BX+6] ; ←header ← CX MOV [BP-8],CX ; header->destHost = interface->host; ; BX ← ←header MOV BX,[BP-8] ; DI ← ←interface MOV DI,[BP-2] MOV CX,[DI] MOV [BX+8],CX ; header->destSoc.LS = rpcSocket; ; BX ← ←header MOV BX,[BP-8] MOV BYTE PTR [BX+13],01EX ; header->destPSB = lastCallDest[myPSB]; ; BX ← ←header MOV BX,[BP-8] ; CX ← ←myPSB MOV CX,[BP-6] MOV AX,←lastCallDest SAL CX ADD CX,AX MOV DI,CX MOV CX,[DI] MOV [BX+4],CX ; callPkt->convHandle = localConversation; ; BX ← ←callPkt MOV BX,[BP+4] ; CX ← ←localConversation MOV CX,[BP-4] MOV [BX+4],CX ; if (localConversation == unencrypted) ; BX ← ←localConversation MOV BX,[BP-4] OR BX,BX JNZ X1 ; Move2(&header->conv, firstConversation); ; BX ← ←header MOV BX,[BP-8] ADD BX,014X PUSH BX MOV BX,←firstConversation POP CX CALL ←Move2 ; else { JR X2 X1: ; Move2(&header->conv, &localConversation->id.count); ; BX ← ←header MOV BX,[BP-8] ADD BX,014X ; CX ← ←localConversation MOV CX,[BP-4] ADD CX,4 XCHG BX,CX CALL ←Move2 ; if (localConversation->id.originator.w == myHost.w) ; BX ← ←localConversation MOV BX,[BP-4] MOV CX,[BX+2] MOV BX,WORD PTR ←myHost CMP CX,BX JNZ X3 ; header->conv.fields &= notCalleeMask; /* header->conv.originator = caller */ ; BX ← ←header MOV BX,[BP-8] AND WORD PTR [BX+22],0FF7FX ; else if (header->destHost.w == localConversation->id.originator.w) JR X4 X3: ; BX ← ←header MOV BX,[BP-8] MOV CX,[BX+8] ; BX ← ←localConversation MOV BX,[BP-4] MOV AX,[BX+2] CMP CX,AX JNZ X5 ; header->conv.fields |= calleeField; /* header->conv.originator = callee */ ; BX ← ←header MOV BX,[BP-8] OR WORD PTR [BX+22],080X ; else ERROR(MisusedConversation); }; JR X6 X5: X6: X4: X2: ; header->pktID.activity = myPSB; ; BX ← ←header MOV BX,[BP-8] ; CX ← ←myPSB MOV CX,[BP-6] MOV [BX+24],CX ; header->pktID.pktSeq = 0; /* => new call -- */ ; BX ← ←header MOV BX,[BP-8] MOV WORD PTR [BX+30],0 ; MoveBlock(&header->callSpec.dispatcherDet, &interface->dispatcherDet, lenDispatcherDetails); ; BX ← ←header MOV BX,[BP-8] ADD BX,020X PUSH BX ; BX ← ←interface MOV BX,[BP-2] ADD BX,4 PUSH BX MOV BX,4 POP CX CALL ←MoveBlock POP DX ; Block(); }; CALL ←Block MOV SP,BP POP BP RET; ; int/* returnLength: */ ; Call(pkt, callLength, maxReturnLength) ←Call: ; struct PBI *pkt; int callLength, maxReturnLength; { PUSH BP MOV BP,SP PUSH CX PUSH BX ; int returnLength; ; struct Header *recvdHeader; ADD SP,0FFFCX ; recvdHeader = pkt->pup; ; BX ← ←pkt MOV BX,[BP+4] MOV CX,[BX+6] ; ←recvdHeader ← CX POP DX PUSH CX ; returnLength = PktExchange(pkt, callLength, maxReturnLength, calling); ; BX ← ←pkt MOV BX,[BP+4] PUSH BX ; BX ← ←callLength MOV BX,[BP-2] PUSH BX MOV BX,2 ; CX ← ←maxReturnLength MOV CX,[BP-4] CALL ←PktExchange ADD SP,4 ; ←returnLength ← BX MOV [BP-6],BX ; RecordCallDest(recvdHeader); ; BX ← ←recvdHeader POP BX PUSH BX CALL ←RecordCallDest ; switch (recvdHeader->callSpec.outcome) { ; BX ← ←recvdHeader POP BX PUSH BX MOV CX,[BX+32] JR X7 ; case unbound: SIGNAL(CallFailed, unbound); X9: MOV BX,1 MOV CX,←CallFailed CALL ←SIGNAL ; case result: break; X10: JR X8 ; case protocol: SIGNAL(CallFailed, runtimeProtocol); X11: MOV BX,0FX MOV CX,←CallFailed CALL ←SIGNAL ; default: SIGNAL(CallFailed, runtimeProtocol); }; /* call failed, somehow, maybe a signal */ X12: MOV BX,0FX MOV CX,←CallFailed CALL ←SIGNAL JR X8 X7: MOV AL,CH OR AL,AL JNZ X12 MOV AL,CL CMP AL,1 JZ X9 CMP AL,0 JZ X10 CMP AL,4 JZ X11 JR X12 X8: ; SetupResponse(recvdHeader); ; BX ← ←recvdHeader POP BX PUSH BX CALL ←SetupResponse ; if ((recvdHeader->type.fields)&eomField) SIGNAL(CallFailed, runtimeProtocol); ; BX ← ←recvdHeader POP BX PUSH BX MOV AL,[BX+3] AND AL,010X OR AL,AL JZ X13 MOV BX,0FX MOV CX,←CallFailed CALL ←SIGNAL X13: ; return returnLength; }; ; BX ← ←returnLength MOV BX,[BP-6] MOV SP,BP POP BP RET; ; GenerateIdlerResponse(recvd) struct PBI *recvd; { /* Ack */ ←GenerateIdlerResponse: PUSH BP MOV BP,SP PUSH BX ; struct PBI *ackPkt; ; struct Header *header; ; struct Header *recvdHeader; ; num workerPSB; ADD SP,0FFF8X ; ackPkt = GetPBI(mySoc); MOV BX,←mySoc CALL ←GetPBI ; ←ackPkt ← BX MOV [BP-4],BX ; header = ackPkt->pup; ; BX ← ←ackPkt MOV BX,[BP-4] MOV CX,[BX+6] ; ←header ← CX MOV [BP-6],CX ; recvdHeader = recvd->pup; ; BX ← ←recvd MOV BX,[BP-2] MOV CX,[BX+6] ; ←recvdHeader ← CX MOV [BP-8],CX ; workerPSB = recvdHeader->destPSB; /* as adjusted by FindCallee */ ; BX ← ←recvdHeader MOV BX,[BP-8] MOV CX,[BX+4] ; ←workerPSB ← CX POP DX PUSH CX ; ++idlerAckCount; INC ←idlerAckCount ; SetupResponse(recvdHeader); ; BX ← ←recvdHeader MOV BX,[BP-8] CALL ←SetupResponse ; MoveBlock(header, recvdHeader, lenHeader); ; BX ← ←header MOV BX,[BP-6] PUSH BX MOV BX,014X ; CX ← ←recvdHeader MOV CX,[BP-8] CALL ←MoveBlock POP DX ; header->type.fields = typeAck; ; BX ← ←header MOV BX,[BP-6] MOV BYTE PTR [BX+3],062X ; header->srceHost.w = myHost.w; ; BX ← ←header MOV BX,[BP-6] MOV CX,WORD PTR ←myHost MOV [BX+14],CX ; header->srceSoc.LS = rpcSocket; ; BX ← ←header MOV BX,[BP-6] MOV BYTE PTR [BX+19],01EX ; header->srcePSB = workerPSB; ; BX ← ←header MOV BX,[BP-6] ; CX ← ←workerPSB POP CX PUSH CX MOV [BX+6],CX ; SendPup(ackPkt); Block(); }; /* hit it hard, and wish it well. */ ; BX ← ←ackPkt MOV BX,[BP-4] CALL ←SendPup CALL ←Block MOV SP,BP POP BP RET; ; static EnqueueForNewPSB(recvd) struct PBI *recvd; { ←EnqueueForNewPSB: PUSH BP MOV BP,SP PUSH BX ; struct PBI *pupPkt; ; struct Header *header, *recvdHeader; ADD SP,0FFFAX ; pupPkt = GetPBI(mySoc); MOV BX,←mySoc CALL ←GetPBI ; ←pupPkt ← BX MOV [BP-4],BX ; header = pupPkt->pup; ; BX ← ←pupPkt MOV BX,[BP-4] MOV CX,[BX+6] ; ←header ← CX MOV [BP-6],CX ; recvdHeader = recvd->pup; ; BX ← ←recvd MOV BX,[BP-2] MOV CX,[BX+6] ; ←recvdHeader ← CX POP DX PUSH CX ; ++idlerRequeueCount; INC ←idlerRequeueCount ; MoveBlock(header, recvdHeader, (Swab(recvdHeader->length)>>1)); ; BX ← ←header MOV BX,[BP-6] PUSH BX ; DI ← ←recvdHeader MOV DI,[BP-8] MOV BX,[DI] CALL ←Swab SHR BX ; CX ← ←recvdHeader MOV CX,[BP-8] CALL ←MoveBlock POP DX ; EnqueueAgain(pupPkt); }; ; BX ← ←pupPkt MOV BX,[BP-4] CALL ←EnqueueAgain MOV SP,BP POP BP RET; ; static AddCallee(stateBlock) struct CalleeState *stateBlock; { Enqueue(&callees, stateBlock); }; ←AddCallee: PUSH BP MOV BP,SP PUSH BX ; BX ← ←stateBlock POP BX PUSH BX LEA CX,←callees CALL ←Enqueue MOV SP,BP POP BP RET; ; static RemoveCallee(stateBlock) struct CalleeState *stateBlock; { ←RemoveCallee: PUSH BP MOV BP,SP PUSH BX ; if (Unqueue(&callees, stateBlock)==0) SIGNAL(ERROR, 0); Block(); }; ; BX ← ←stateBlock POP BX PUSH BX LEA CX,←callees CALL ←Unqueue OR BX,BX JNZ X14 XOR BX,BX MOV CX,2 CALL ←SIGNAL X14: CALL ←Block MOV SP,BP POP BP RET; ; static int /* BOOLEAN */ ; FindCallee(given) struct Header *given; { ←FindCallee: PUSH BP MOV BP,SP PUSH BX ; struct CalleeState *p; ; struct Header *stateHeader; ADD SP,0FFFCX ; p = (struct CalleeState *) callees.head; MOV BX,WORD PTR ←callees ; ←p ← BX MOV [BP-4],BX ; while (p) { X15: ; BX ← ←p MOV BX,[BP-4] OR BX,BX JZ X16 ; stateHeader = p->state; ; BX ← ←p MOV BX,[BP-4] MOV CX,[BX+4] ; ←stateHeader ← CX POP DX PUSH CX ; if (MultEq(&stateHeader->conv, /* works because callCt follows ConvCt */ ; &given->conv, lenPktConversationID+1+lenCallCount)) { ; BX ← ←stateHeader POP BX PUSH BX ADD BX,014X PUSH BX ; BX ← ←given MOV BX,[BP-2] ADD BX,014X PUSH BX MOV BX,5 POP CX CALL ←MultEq POP DX OR BX,BX JZ X17 ; given->destPSB = p->callee; ; BX ← ←given MOV BX,[BP-2] ; CX ← ←p MOV CX,[BP-4] MOV DI,CX MOV CX,[DI+2] MOV [BX+4],CX ; Block(); CALL ←Block ; return true; }; MOV BX,0FFFFX MOV SP,BP POP BP RET; X17: ; p = p->next; }; ; DI ← ←p MOV DI,[BP-4] MOV BX,[DI] ; ←p ← BX MOV [BP-4],BX JR X15 X16: ; Block(); CALL ←Block ; return false; }; XOR BX,BX MOV SP,BP POP BP RET; ; ForgetConnections() { ←ForgetConnections: PUSH BP MOV BP,SP ; int i; ; struct ConnectionData *connection; ; struct ConnectionData *next; ; for (i=0; i<128; ++i) { ADD SP,0FFFAX MOV WORD PTR [BP-2],0 X20: ; BX ← ←i MOV BX,[BP-2] CMP BX,080X JGE X19 JR X18 X21: INC WORD PTR [BP-2] JR X20 X18: ; connection = connections[i]; ; BX ← ←i MOV BX,[BP-2] MOV CX,←connections SAL BX ADD BX,CX MOV CX,[BX] ; ←connection ← CX MOV [BP-4],CX ; while (connection) { X22: ; BX ← ←connection MOV BX,[BP-4] OR BX,BX JZ X23 ; next = connection->next; ; DI ← ←connection MOV DI,[BP-4] MOV BX,[DI] ; ←next ← BX POP DX PUSH BX ; connection = next; }; ; BX ← ←next POP BX PUSH BX ; ←connection ← BX MOV [BP-4],BX JR X22 X23: ; connections[i]=0; }; }; ; BX ← ←i MOV BX,[BP-2] MOV CX,←connections SAL BX ADD BX,CX MOV WORD PTR [BX],0 JR X21 X19: MOV SP,BP POP BP RET; ; static int RemC(nil1, nil2, seal) ←RemC: ; int nil1, nil2; struct Seal1 *seal; { RemoveCallee(seal->data[0]); return CONTINUE; }; PUSH BP MOV BP,SP PUSH CX PUSH BX ; BX ← ←seal POP BX PUSH BX ADD BX,4 MOV CX,[BX] MOV BX,CX CALL ←RemoveCallee MOV BX,4 MOV SP,BP POP BP RET; ; ServerMain() { ←ServerMain: PUSH BP MOV BP,SP ; int myPSB; ; struct PBI *myPkt; ; struct Header *recvdHeader; ; struct CalleeState *myStateBlock; ; struct Seal1 s1; ; struct Seal s2; ; struct Seal s4; ; struct Seal1 s3; ; int /* BOOL */ decrypted, newPkt; ; int newLength; ; int ackLen; ; struct ConnectionData *connection; ; struct ConnectionID id; ; int /*BOOL*/ ok; ; struct DispatcherDetails *target; ; struct ExportInstance *instance; ; int resultLength, *rout, hint; ; int argv[4]; ; struct CallCount aCall; ; struct Conversation *conv; ; struct RPCCtx *CtxRunning; ; int lll; /* Some sort of length */ ; int oldDest; /* PsbIndex */ ; int /*BOOL*/ knownCallee; ADD SP,0FFB0X ; CtxRunning = CurrentContext(); CALL ←CurrentContext ; ←CtxRunning ← BX MOV [BP-74],BX ; myPSB = CtxRunning->user.myPSB; ; BX ← ←CtxRunning MOV BX,[BP-74] MOV CX,[BX+26] ; ←myPSB ← CX MOV [BP-2],CX ; myPkt = GetPBI(mySoc) MOV BX,←mySoc CALL ←GetPBI ; ←myPkt ← BX MOV [BP-4],BX ; recvdHeader = myPkt->pup; ; BX ← ←myPkt MOV BX,[BP-4] MOV CX,[BX+6] ; ←recvdHeader ← CX MOV [BP-6],CX ; myStateBlock = (struct CalleeState *) GetFixed(lenCalleeState); MOV BX,3 CALL ←GetFixed ; ←myStateBlock ← BX MOV [BP-8],BX ; myStateBlock->callee = myPSB; ; BX ← ←myStateBlock MOV BX,[BP-8] ; CX ← ←myPSB MOV CX,[BP-2] MOV [BX+2],CX ; myStateBlock->state = recvdHeader; ; BX ← ←myStateBlock MOV BX,[BP-8] ; CX ← ←recvdHeader MOV CX,[BP-6] MOV [BX+4],CX ; newPkt = (decrypted = (newLength = 0)); MOV WORD PTR [BP-34],0 MOV WORD PTR [BP-30],0 MOV WORD PTR [BP-32],0 ; myStateBlock->next = 0; ; BX ← ←myStateBlock MOV BX,[BP-8] MOV WORD PTR [BX],0 ; connection = 0; MOV WORD PTR [BP-38],0 ; s1.data[0] = (s3.data[0] = (int) myStateBlock); ; BX ← ←myStateBlock MOV BX,[BP-8] ; ←s3+4 ← BX MOV [BP-24],BX ; ←s1+4 ← BX MOV [BP-10],BX ; while (true) { X24: ; DISABLE(&s1); DISABLE(&s2); DISABLE(&s3); DISABLE(&s4); ;&←s1 LEA BX,[BP-14] CALL ←DISABLE ;&←s2 LEA BX,[BP-18] CALL ←DISABLE ;&←s3 LEA BX,[BP-28] CALL ←DISABLE ;&←s4 LEA BX,[BP-22] CALL ←DISABLE ; if (newPkt == 0) { ; BX ← ←newPkt MOV BX,[BP-32] OR BX,BX JNZ X26 ; IdleReceive(myPkt, maxPupWords); MOV BX,065X ; CX ← ←myPkt MOV CX,[BP-4] CALL ←IdleReceive ; newPkt = true; decrypted = false; MOV WORD PTR [BP-32],0FFFFX MOV WORD PTR [BP-30],0 ; if ((recvdHeader->type.fields&classField) == call ; && ((recvdHeader->type.fields&ackField) !=0)) newPkt = newPkt; }; ; BX ← ←recvdHeader MOV BX,[BP-6] MOV AL,[BX+3] AND AL,7 OR AL,AL JNZ X28 ; BX ← ←recvdHeader MOV BX,[BP-6] MOV AL,[BX+3] AND AL,8 OR AL,AL JZ X28 MOV AL,1 JR X29 X28: XOR AL,AL X29: OR AL,AL JZ X27 ; BX ← ←newPkt MOV BX,[BP-32] ; ←newPkt ← BX MOV [BP-32],BX X27: X26: ; Move2(&id.conv, &recvdHeader->conv); ; BX ← ←recvdHeader MOV BX,[BP-6] ADD BX,014X ;&←id LEA CX,[BP-46] CALL ←Move2 ; id.caller = recvdHeader->srceHost; ; BX ← ←recvdHeader MOV BX,[BP-6] MOV CX,[BX+14] ; ←id+4 ← CX MOV [BP-42],CX ; id.activity = recvdHeader->srcePSB; ; BX ← ←recvdHeader MOV BX,[BP-6] MOV CX,[BX+6] ; ←id+6 ← CX MOV [BP-40],CX ; Block(); CALL ←Block ; connection = connections[(Swab(id.caller.w ↑ id.activity)) & 127]; ; BX ← ←id+6 MOV BX,[BP-40] ; CX ← ←id+4 MOV CX,[BP-42] XOR CX,BX MOV BX,CX CALL ←Swab AND BX,07FX MOV CX,←connections SAL BX ADD BX,CX MOV CX,[BX] ; ←connection ← CX MOV [BP-38],CX ; while (connection) { X30: ; BX ← ←connection MOV BX,[BP-38] OR BX,BX JZ X31 ; if (MultEq(&id.conv, &connection->id.conv, lenPktConversationID+1) && ; recvdHeader->srcePSB == connection->id.activity) { ;&←id LEA BX,[BP-46] PUSH BX ; BX ← ←connection MOV BX,[BP-38] INC BX INC BX PUSH BX MOV BX,3 POP CX CALL ←MultEq POP DX OR BX,BX JZ X33 ; BX ← ←recvdHeader MOV BX,[BP-6] MOV CX,[BX+6] ; BX ← ←connection MOV BX,[BP-38] MOV AX,[BX+8] CMP CX,AX JNZ X33 MOV AL,1 JR X34 X33: XOR AL,AL X34: OR AL,AL JZ X32 ; myPkt->convHandle = connection->conv; ; BX ← ←myPkt MOV BX,[BP-4] ; CX ← ←connection MOV CX,[BP-38] MOV DI,CX MOV CX,[DI+14] MOV [BX+4],CX ; if (decrypted == false) { ; BX ← ←decrypted MOV BX,[BP-30] OR BX,BX JNZ X35 ; if (connection->conv != unencrypted) { ; BX ← ←connection MOV BX,[BP-38] MOV CX,[BX+14] OR CX,CX JZ X36 ; ok = DecryptPkt(recvdHeader, myPkt->convHandle, &newLength); ; BX ← ←recvdHeader MOV BX,[BP-6] PUSH BX ; BX ← ←myPkt MOV BX,[BP-4] MOV CX,[BX+4] ;&←newLength LEA BX,[BP-34] CALL ←DecryptPkt POP DX ; ←ok ← BX MOV [BP-48],BX ; decrypted=true; MOV WORD PTR [BP-30],0FFFFX ; if (ok==false) goto CallerPhoney; }; ; BX ← ←ok MOV BX,[BP-48] OR BX,BX JNZ X37 JMP ←CallerPhoney X37: ; else { newLength = (Swab(recvdHeader->length) >>1) - pktLengthOverhead; JR X38 X36: ; DI ← ←recvdHeader JR $+5 X31: JMP X39 MOV DI,[BP-6] MOV BX,[DI] CALL ←Swab SHR BX ADD BX,0FFEBX ; ←newLength ← BX MOV [BP-34],BX ; decrypted=true; }; }; MOV WORD PTR [BP-30],0FFFFX X38: X35: ; if (recvdHeader->pktID.activity != recvdHeader->srcePSB) goto CallerPhoney; ; BX ← ←recvdHeader MOV BX,[BP-6] MOV CX,[BX+24] ; BX ← ←recvdHeader MOV BX,[BP-6] MOV AX,[BX+6] CMP CX,AX JZ X40 JMP ←CallerPhoney X40: ; if ((recvdHeader->type.fields&classField) != call) goto CallerOld; ; BX ← ←recvdHeader MOV BX,[BP-6] JR $+5 X32: JMP X42 MOV AL,[BX+3] AND AL,7 OR AL,AL JZ X41 JMP ←CallerOld X41: ; if (DoubleComp(&recvdHeader->pktID.callCt, &connection->callCt)>0) { ; BX ← ←recvdHeader MOV BX,[BP-6] ADD BX,01AX ; CX ← ←connection MOV CX,[BP-38] ADD CX,0AX XCHG BX,CX CALL ←DoubleComp CMP BX,0 JLE X43 ; if (recvdHeader->pktID.pktSeq != swapped1) goto CallerPhoney; ; BX ← ←recvdHeader MOV BX,[BP-6] MOV CX,[BX+30] MOV BX,CX CMP BX,0100X JZ X44 JMP ←CallerPhoney X44: ; Move2(&connection->callCt, &recvdHeader->pktID.callCt); ; BX ← ←connection MOV BX,[BP-38] ADD BX,0AX ; CX ← ←recvdHeader MOV CX,[BP-6] ADD CX,01AX XCHG BX,CX CALL ←Move2 ; AddCallee(myStateBlock); ; BX ← ←myStateBlock MOV BX,[BP-8] CALL ←AddCallee ; goto CallerNew; }; JMP ←CallerNew ; else goto CallerOld; }; X43: JMP ←CallerOld X42: ; connection = connection->next; }; ; DI ← ←connection MOV DI,[BP-38] MOV BX,[DI] ; ←connection ← BX MOV [BP-38],BX JMP X30 X39: ; if ((recvdHeader->type.fields&classField) == call) goto CallerUnknown; else goto CallerOld; ; BX ← ←recvdHeader MOV BX,[BP-6] MOV AL,[BX+3] AND AL,7 OR AL,AL JNZ X45 JMP ←CallerUnknown X45: JMP ←CallerOld ; SIGNAL(ERROR, 0); /* no where to go! */ XOR BX,BX MOV CX,2 CALL ←SIGNAL ←CallerNew: ; CallerNew: { ; Block(); CALL ←Block ; target = &recvdHeader->callSpec.dispatcherDet; ; BX ← ←recvdHeader MOV BX,[BP-6] ADD BX,020X ; ←target ← BX MOV [BP-50],BX ; SetupResponse(recvdHeader); ; BX ← ←recvdHeader MOV BX,[BP-6] CALL ←SetupResponse ; if (((hint=Swab(target->dispatcherHint)) >= used) || ; ((instance = &exportTable[hint]) != instance) || ; (!DoubleEq(&target->dispatcherID, &instance->id))) { ; BX ← ←target MOV BX,[BP-50] MOV CX,[BX+6] MOV BX,CX CALL ←Swab ; ←hint ← BX MOV [BP-58],BX MOV CX,←used CMP BX,CX JGE X48 ; BX ← ←hint MOV BX,[BP-58] LEA CX,←exportTable MOV AX,012X IMUL AX,BX ADD AX,CX ; ←instance ← AX MOV [BP-52],AX ; BX ← ←instance MOV BX,[BP-52] CMP AX,BX JNZ X50 ; BX ← ←target MOV BX,[BP-50] INC BX INC BX ; CX ← ←instance MOV CX,[BP-52] INC CX INC CX XCHG BX,CX CALL ←DoubleEq OR BX,BX JNZ X49 X50: MOV AL,1 JR X51 X49: XOR AL,AL X51: OR AL,AL JZ X47 X48: MOV AL,1 JR X52 X47: XOR AL,AL X52: OR AL,AL JZ X46 ; recvdHeader->callSpec.outcome = unbound; resultLength = 0; }; ; BX ← ←recvdHeader MOV BX,[BP-6] MOV WORD PTR [BX+32],1 MOV WORD PTR [BP-54],0 ; else { JR X53 X46: ; rout = instance->dispatcher; ; BX ← ←instance MOV BX,[BP-52] MOV CX,[BX+6] ; ←rout ← CX MOV [BP-56],CX ; ENABLE(UNWIND, &RemC, &s3); MOV BX,1 PUSH BX ;&←s3 LEA BX,[BP-28] MOV CX,OFFSET ←RemC CALL ←ENABLE POP DX ; if (ENABLE(RejectUnbound, &CONT, &s4)) { MOV BX,←RejectUnbound PUSH BX ;&←s4 LEA BX,[BP-22] MOV CX,OFFSET ←CONT CALL ←ENABLE POP DX OR BX,BX JZ X54 ; recvdHeader->callSpec.outcome = unbound; resultLength = 0; }; ; BX ← ←recvdHeader MOV BX,[BP-6] MOV WORD PTR [BX+32],1 MOV WORD PTR [BP-54],0 ; else if (ENABLE(RejectProtocol, &CONT, &s2)) { JR X55 X54: MOV BX,←RejectProtocol PUSH BX ;&←s2 LEA BX,[BP-18] MOV CX,OFFSET ←CONT CALL ←ENABLE POP DX OR BX,BX JZ X56 ; recvdHeader->callSpec.outcome = protocol; resultLength = 0; }; ; BX ← ←recvdHeader MOV BX,[BP-6] MOV WORD PTR [BX+32],4 MOV WORD PTR [BP-54],0 ; else if (ENABLE(CallFailed, &RemC, &s1)) { newPkt=false; continue; }; JR X57 X56: MOV BX,←CallFailed PUSH BX ;&←s1 LEA BX,[BP-14] MOV CX,OFFSET ←RemC CALL ←ENABLE POP DX OR BX,BX JZ X58 MOV WORD PTR [BP-32],0 JMP X24 ; else { X58: ; argv[0] = (int) myPkt; ; BX ← ←myPkt MOV BX,[BP-4] ; ←argv ← BX JR $+5 X53: JMP X59 MOV [BP-66],BX ; argv[1] = newLength; ; BX ← ←newLength MOV BX,[BP-34] ; ←argv+2 ← BX MOV [BP-64],BX ; argv[2] = (int) connection->conv; ; BX ← ←connection MOV BX,[BP-38] MOV CX,[BX+14] ; ←argv+4 ← CX MOV [BP-62],CX ; argv[3] = (int) instance->dispatcherArgs; ; BX ← ←instance MOV BX,[BP-52] MOV CX,[BX+8] ; ←argv+6 ← CX MOV [BP-60],CX ; resultLength= apply(argv, rout, 4); }; ;&←argv LEA BX,[BP-66] PUSH BX MOV BX,4 ; CX ← ←rout MOV CX,[BP-56] CALL ←apply POP DX ; ←resultLength ← BX MOV [BP-54],BX X57: X55: ; DISABLE(&s2); DISABLE(&s3); DISABLE(&s4); ;&←s2 LEA BX,[BP-18] CALL ←DISABLE ;&←s3 LEA BX,[BP-28] CALL ←DISABLE ;&←s4 LEA BX,[BP-22] CALL ←DISABLE ; }; X59: ; RemoveCallee(myStateBlock); ; BX ← ←myStateBlock MOV BX,[BP-8] CALL ←RemoveCallee ; if (ENABLE(CallFailed, &CONT, &s1)) newPkt=false; MOV BX,←CallFailed PUSH BX ;&←s1 LEA BX,[BP-14] MOV CX,OFFSET ←CONT CALL ←ENABLE POP DX OR BX,BX JZ X60 MOV WORD PTR [BP-32],0 ; else { JR X61 X60: ; newLength = PktExchange(myPkt, resultLength, serverDataLength, endCall); ; BX ← ←myPkt MOV BX,[BP-4] PUSH BX ; BX ← ←resultLength MOV BX,[BP-54] PUSH BX MOV BX,3 MOV CX,076X CALL ←PktExchange ADD SP,4 ; ←newLength ← BX MOV [BP-34],BX ; newPkt = (newLength >= 0); }; ; BX ← ←newLength MOV BX,[BP-34] CMP BX,0 JL X62 MOV BX,1 JR X63 X62: XOR BX,BX X63: ; ←newPkt ← BX MOV [BP-32],BX X61: ; if (newPkt) decrypted = true; ; BX ← ←newPkt MOV BX,[BP-32] OR BX,BX JZ X64 MOV WORD PTR [BP-30],0FFFFX X64: ; continue;}; JMP X24 ←CallerUnknown: ; CallerUnknown: { ; Block(); CALL ←Block ; ok = (ENABLE(CallFailed, &CONT, &s1) == false && ; GetConnectionState(decrypted, myPkt, &id, &aCall, &conv, &lll) == true); MOV BX,←CallFailed PUSH BX ;&←s1 LEA BX,[BP-14] MOV CX,OFFSET ←CONT CALL ←ENABLE POP DX OR BX,BX JNZ X65 ; BX ← ←decrypted MOV BX,[BP-30] PUSH BX ; BX ← ←myPkt MOV BX,[BP-4] PUSH BX ;&←id LEA BX,[BP-46] PUSH BX ;&←aCall LEA BX,[BP-70] PUSH BX ;&←lll LEA BX,[BP-76] ;&←conv LEA CX,[BP-72] CALL ←GetConnectionState ADD SP,8 CMP BX,0FFFFX X65: JNZ X66 MOV BX,1 JR X67 X66: XOR BX,BX X67: ; ←ok ← BX MOV [BP-48],BX ; if (ok) { ; BX ← ←ok MOV BX,[BP-48] OR BX,BX JZ X68 ; if (newPkt == false) SIGNAL(ERROR, 0); ; BX ← ←newPkt MOV BX,[BP-32] OR BX,BX JNZ X69 XOR BX,BX MOV CX,2 CALL ←SIGNAL X69: ; if (decrypted == false) { decrypted = true; newLength = lll; }; ; BX ← ←decrypted MOV BX,[BP-30] OR BX,BX JNZ X70 MOV WORD PTR [BP-30],0FFFFX ; BX ← ←lll MOV BX,[BP-76] ; ←newLength ← BX MOV [BP-34],BX X70: ; NoteConnection(&id, &aCall, conv); }; ;&←id LEA BX,[BP-46] PUSH BX ; BX ← ←conv MOV BX,[BP-72] ;&←aCall LEA CX,[BP-70] CALL ←NoteConnection POP DX ; else newPkt = false; JR X71 X68: MOV WORD PTR [BP-32],0 X71: ; continue ; }; JMP X24 ←CallerPhoney: ; CallerPhoney: /* ignorable packet */ ; newPkt = false; continue; MOV WORD PTR [BP-32],0 JMP X24 ←CallerOld: ; CallerOld: { ; Block(); CALL ←Block ; oldDest = recvdHeader->destPSB; ; BX ← ←recvdHeader MOV BX,[BP-6] MOV CX,[BX+4] ; ←oldDest ← CX MOV [BP-78],CX ; knownCallee = ((decrypted == true) && (FindCallee(recvdHeader) != 0)); ; BX ← ←decrypted MOV BX,[BP-30] CMP BX,0FFFFX JNZ X72 ; BX ← ←recvdHeader MOV BX,[BP-6] CALL ←FindCallee OR BX,BX JZ X72 MOV AL,1 JR X73 X72: XOR AL,AL X73: XOR AH,AH ; ←knownCallee ← AX POP DX PUSH AX ; if ((knownCallee==true) && (recvdHeader->destPSB != oldDest)) { ; BX ← ←knownCallee POP BX PUSH BX CMP BX,0FFFFX JNZ X75 ; BX ← ←recvdHeader MOV BX,[BP-6] MOV CX,[BX+4] ; BX ← ←oldDest MOV BX,[BP-78] CMP CX,BX JZ X75 MOV AL,1 JR X76 X75: XOR AL,AL X76: OR AL,AL JZ X74 ; if (decrypted) { ; BX ← ←decrypted MOV BX,[BP-30] OR BX,BX JZ X77 ; if (myPkt->convHandle == unencrypted) ; BX ← ←myPkt MOV BX,[BP-4] MOV CX,[BX+4] OR CX,CX JNZ X78 ; ackLen = pktLengthOverhead + newLength; ; BX ← ←newLength MOV BX,[BP-34] ADD BX,015X ; ←ackLen ← BX MOV [BP-36],BX ; else ackLen = EncryptPkt(myPkt, newLength); JR X79 X78: ; BX ← ←newLength MOV BX,[BP-34] ; CX ← ←myPkt MOV CX,[BP-4] CALL ←EncryptPkt ; ←ackLen ← BX MOV [BP-36],BX X79: ; recvdHeader->length = Swab(ackLen << 1); }; ; BX ← ←ackLen MOV BX,[BP-36] SAL BX CALL ←Swab MOV CX,BX ; BX ← ←recvdHeader MOV BX,[BP-6] MOV [BX],CX X77: ; EnqueueForNewPSB(myPkt); }; ; BX ← ←myPkt MOV BX,[BP-4] CALL ←EnqueueForNewPSB ; else { JR X80 X74: ; if ((recvdHeader->type.fields&ackField) && ; ((recvdHeader->type.fields&eomField) == 0) && ; (((recvdHeader->type.fields&classField) == xtraData) || (knownCallee==true))) { ; BX ← ←recvdHeader MOV BX,[BP-6] MOV AL,[BX+3] AND AL,8 OR AL,AL JZ X82 ; BX ← ←recvdHeader MOV BX,[BP-6] MOV AL,[BX+3] AND AL,010X OR AL,AL JNZ X83 ; BX ← ←recvdHeader MOV BX,[BP-6] MOV AL,[BX+3] AND AL,7 CMP AL,1 JZ X85 ; BX ← ←knownCallee POP BX PUSH BX CMP BX,0FFFFX X85: X84: X83: JNZ X82 MOV AL,1 JR X86 X82: XOR AL,AL X86: OR AL,AL JZ X81 ; if ((!decrypted) || (myPkt->convHandle == unencrypted)) ; BX ← ←decrypted MOV BX,[BP-30] OR BX,BX JZ X89 ; BX ← ←myPkt MOV BX,[BP-4] MOV CX,[BX+4] OR CX,CX X89: X88: JNZ X87 ; ackLen = pktLengthOverhead; MOV WORD PTR [BP-36],015X ; else ackLen = EncryptPkt(myPkt, 0); JR X90 X87: XOR BX,BX ; CX ← ←myPkt MOV CX,[BP-4] CALL ←EncryptPkt ; ←ackLen ← BX MOV [BP-36],BX X90: ; recvdHeader->length = Swab(ackLen << 1); ; BX ← ←ackLen MOV BX,[BP-36] SAL BX CALL ←Swab MOV CX,BX ; BX ← ←recvdHeader MOV BX,[BP-6] MOV [BX],CX ; GenerateIdlerResponse(myPkt); }; }; ; BX ← ←myPkt MOV BX,[BP-4] CALL ←GenerateIdlerResponse X81: X80: ; newPkt=false; MOV WORD PTR [BP-32],0 ; continue; }; }; /* endloop */ }; JMP X24 X25: MOV SP,BP POP BP RET; ; static int one[2]; ; static NoteConnection(id, callCt, conv) ←NoteConnection: ; struct ConnectionID *id; ; struct CallCount *callCt; ; struct Conversation *conv; { PUSH BP MOV BP,SP PUSH CX PUSH BX ; struct ConnectionData *dataPtr; ; struct ConnectionData *connection; ADD SP,0FFFCX ; dataPtr = ; (struct ConnectionData *) &connections[(Swab(id->caller.w ↑ id->activity)) & 127]; ; BX ← ←id MOV BX,[BP+4] MOV CX,[BX+4] ; BX ← ←id MOV BX,[BP+4] MOV AX,[BX+6] XOR CX,AX MOV BX,CX CALL ←Swab AND BX,07FX MOV CX,←connections SAL BX ADD BX,CX ; ←dataPtr ← BX MOV [BP-6],BX ; connection = dataPtr->next; ; DI ← ←dataPtr MOV DI,[BP-6] MOV BX,[DI] ; ←connection ← BX POP DX PUSH BX ; while (connection) { /* SELECT TRUE FROM .. */ X91: ; BX ← ←connection POP BX PUSH BX OR BX,BX JZ X92 ; if (MultEq(id, &connection->id, lenConnectionID)) return; /* Already there!? -- */ ; BX ← ←id MOV BX,[BP+4] PUSH BX ; BX ← ←connection MOV BX,[BP-8] INC BX INC BX PUSH BX MOV BX,4 POP CX CALL ←MultEq POP DX OR BX,BX JZ X93 MOV SP,BP POP BP RET; X93: ; dataPtr = connection; ; BX ← ←connection POP BX PUSH BX ; ←dataPtr ← BX MOV [BP-6],BX ; connection = dataPtr->next; }; /* endloop */ ; DI ← ←dataPtr MOV DI,[BP-6] MOV BX,[DI] ; ←connection ← BX POP DX PUSH BX JR X91 X92: ; connection = (struct ConnectionData *) GetFixed(lenConnectionData); MOV BX,8 CALL ←GetFixed ; ←connection ← BX POP DX PUSH BX ; connection->next = 0; ; BX ← ←connection POP BX PUSH BX MOV WORD PTR [BX],0 ; MoveBlock(&connection->id, id, lenConnectionID); ; BX ← ←connection POP BX PUSH BX INC BX INC BX PUSH BX MOV BX,4 ; CX ← ←id MOV CX,[BP+4] CALL ←MoveBlock POP DX ; Move2(&connection->callCt, callCt); ; BX ← ←connection POP BX PUSH BX ADD BX,0AX PUSH BX ; BX ← ←callCt MOV BX,[BP-2] POP CX CALL ←Move2 ; DoubleDiff(&connection->callCt, one); ; BX ← ←connection POP BX PUSH BX ADD BX,0AX PUSH BX LEA BX,←one POP CX CALL ←DoubleDiff ; connection->conv = conv; ; BX ← ←connection POP BX PUSH BX ; CX ← ←conv MOV CX,[BP-4] MOV [BX+14],CX ; dataPtr->next = connection; Block(); }; ; BX ← ←dataPtr MOV BX,[BP-6] ; CX ← ←connection POP CX PUSH CX MOV [BX],CX CALL ←Block MOV SP,BP POP BP RET; ; SetupResponse(header) struct Header *header; { ←SetupResponse: PUSH BP MOV BP,SP PUSH BX ; header->destHost = header->srceHost; ; BX ← ←header POP BX PUSH BX ; CX ← ←header POP CX PUSH CX MOV DI,CX MOV CX,[DI+14] MOV [BX+8],CX ; header->destSoc.LS = rpcSocket; ; BX ← ←header POP BX PUSH BX MOV BYTE PTR [BX+13],01EX ; header->destPSB = header->srcePSB; ; BX ← ←header POP BX PUSH BX ; CX ← ←header POP CX PUSH CX MOV DI,CX MOV CX,[DI+6] MOV [BX+4],CX ; header->callSpec.outcome = result; Block(); }; ; BX ← ←header POP BX PUSH BX MOV WORD PTR [BX+32],0 CALL ←Block MOV SP,BP POP BP RET; ; StreamInitialize() { ←StreamInitialize: PUSH BP MOV BP,SP ; one[0] = swapped1; MOV ←one,0100X ; lastCallDest = GetFixed(maxPSB+1); MOV BX,010X CALL ←GetFixed MOV ←lastCallDest,BX ; connections = (struct ConnectionData **) GetFixed(128); MOV BX,080X CALL ←GetFixed MOV ←connections,BX ; MisusedConversation = CODE(); }; CALL ←CODE MOV ←MisusedConversation,BX MOV SP,BP POP BP RET; ; StreamRestart() {ForgetConnections()}; ←StreamRestart: PUSH BP MOV BP,SP CALL ←ForgetConnections MOV SP,BP POP BP RET; ; Externals Declared Here PUBLIC ←MisusedConversation PUBLIC ←connections PUBLIC ←callees PUBLIC ←lastCallDest PUBLIC ←StartCall PUBLIC ←Call PUBLIC ←SetupResponse PUBLIC ←GenerateIdlerResponse PUBLIC ←ForgetConnections PUBLIC ←ServerMain PUBLIC ←StreamInitialize PUBLIC ←StreamRestart C←CODE ENDS ; Number of Bytes of Code = 096EX, (2414)