2ame\HandleMessage.plmserver2?cPePeZ$MEDIUM OPTIMIZE(3)
$TITLE('HandleMessage.plm  Server stub for HandleMessage procedure')

HandleMessageStub:DO;

DECLARE lOk LITERALLY '0';

HandleMessage:PROCEDURE(w) WORD PUBLIC;
DECLARE w WORD;
	RETURN lOk;
END HandleMessage;

END HandleMessageStub;

t values in each sort of server.
  A pure system service uses lRespond.  An asynchronous server uses lOk.
  lForward and lPass are used by oneway and twoway filters, respectively.

  Timer and HandleMessage always return lOk.
  HandleRespond returns lRespc
Initialize.plmserver
?cQeQe$$MEDIUM OPTIMIZE(3)
$TITLE('Initialize.plm  Server stub for Initialize procedure')

InitializeStub:DO;

Initialize:PROCEDURE PUBLIC;
END Initialize;

END InitializeStub;

@_pOO po _P??
0P	0 op@		'?p1?4	;oETUp^ @eoPegOj0vO wpz|00B	Start.plmserverB?cQeQe<	$MEDIUM OPTIMIZE(3)
$TITLE('Start.plm  Server stub for Start procedure')

StartStub:DO;

Start:PROCEDURE PUBLIC;
END Start;

END StartStub;

ialize;

END InitializeStub;

@_pOO po _P??
0P	0 op@		'?p1?4	;oETUp^ @eoPegOj0vO wpz|0HV2.3plm.flsserverT	UcQeQem6TServer.plm
Initialize.plm
Start.plm
HandleRespond.plm
HandleMessage.plm
Timer.plm
Cleanup.plm
LogMessage.plm
og)
$INCLUDE(:f0:CTOSLib.edf)

DECLARE pConfig POINTER EXTERNAL
	,config BASED pConfig SysConfigType;


LogMessage:PROCEDURE(pbMessage, cbMessage) WORD REENTRANT GLOBAL;
DECLARE 
	 pbMessage POINTER
	,cbMessage WORD
	,erc ErcType
	,LogMsg STRUCTURE (
		 TextCode WORD				* value to indicate text msg to Plog *
		,cbText WORD
		,rgbText (100) BYTE);

	IF config.hardwareType < FpType
		THEN LogMsg.Text7(HANDLERESPOND.OBJserver+GdQeQe6lHANDLERESPONDSTUBWPLM86 V2.3032687 17:03:3<STACKMEMORYCODEDATACONSTHANDLERESPONDSTUB_CODEDGROUPh@
HH	TD
K
HANDLERESPONDDU]tx	TIMER.OBJserver1GdQeQeY	TIMERSTUBPLM86 V2.3032687 17:03:44STACKMEMORYCODEDATACONSTTIMERSTUB_CODEDGROUPh@
HHTD
K
RQTIMETIMERDbtwU]t}w
ServerGen.libserverwKcQedf$aServerPLM86 V2.3011287 11:55:2X1STACKMEMORYCODEDATACONSTSERVER_CODEDGROUPh@AHH]TD$
KCRASHIFERCNOTOK6JPCONFIGPTIMEPASCBWVERSION	EXCHSERVE
FCONVERTTOSYS\J*INITJ	DEINSTALLPROCESSMESSAGEt	ALLOCEXCHCHANGEPRIORITYCHECKCHECKERCCONVERTTOSYSCRASHDEALLOCEXCH	ERROREXITEXITFORWARDREQUEST
GETPSTRUCTUREOPENRTCLOCK	OSVERSIONQUERYREQUESTINFO
REQUESTDIRECTRESPONDSENDSERVERQ	SETMSGRETWAITKILLPROCESS
EXITANDREMOVE	RGSERVERQNSERVERQRGRQEXCHRQTIME
INITIALIZESTARTTIMER
HANDLEREQUEST
HANDLERESPOND
HANDLEMESSAGECLEANUP$D\EInstallation failed6UF	tP]V+JUPPPXPX@PPPXPPPX$uGTVPP>
bttPPFF;sFPPP^FF\s)X	tPPP6XFF;sFt6| 
rPP6^6P6F>
btt]VV
16V;FKVPT_mpsxVVVVVVVVVV	V$+6=VC\NRUV[\eVksx{QUQFF	w0uvLLFuZ](,48CHSUQFF	wF9u9uLFuP]+5EVJgUQFF	wu	Fu]6PPP*2V8V@\UQ>
bttFF;s4PP6^P6Fc6P	u
P$uG$s6P6>	r7P6PP6TwPX]sV3\>BEVK\Y\aVm\tVzVV	V\V\V\VU9>u9u>
bttNsP>uFs6ZZLG;uSSFsSZGSP6ZZFw.Z;bhHG
u+JVuF^FuGS|vSlSG
u+JVuF^FuG6SvSP6]*V2@CV HNW_joVVV\\\\\\V$)V
1:AEkxVV\^:J6PPPZs3\

VV \0\p
XA
InitializePLM86 V2.3011287 11:56:09STACKMEMORYCODEDATACONSTINITIALIZESTUB_CODEDGROUPzh@HH	TD
K
INITIALIZEaD	U]bt	StartPLM86 V2.3011287 11:56:04STACKMEMORYCODEDATACONSTSTARTSTUB_CODEDGROUPh@HH	TD
KSTARTD	U]bt(
TimerPLM86 V2.3011287 11:56:24STACKMEMORYCODEDATACONSTTIMERSTUB_CODEDGROUPh@
HHTD
K
RQTIMETIMERDbtwU]t*
HandleRespondPLM86 V2.3011287 11:56:1<STACKMEMORYCODEDATACONSTHANDLERESPONDSTUB_CODEDGROUPh@
HH	TD
K
HANDLERESPONDDU]t ,
HandleMessagePLM86 V2.3011287 11:56:2<STACKMEMORYCODEDATACONSTHANDLEMESSAGESTUB_CODEDGROUPh@
HH	TD
K
HANDLEMESSAGEDU]t,.
	CleanupPLM86 V2.3011287 11:56:36STACKMEMORYCODEDATACONSTCLEANUPSTUB_CODEDGROUPjh@HH	TD
KCLEANUPQD	U]bt80
LogMessagePLM86 V2.3011287 11:56:41STACKMEMORYCODEDATACONSTLOGMSG_CODEDGROUPh@LHH	T|D
K
LOGMESSAGElWRITELOGPCONFIGDPUj 
sFFFFvFFPFP]C	BVtD2P40=B8'+I	EXCHSERVEPROCESSMESSAGECleanupStartPCONFIG
HandleRespond
Timer	StartLogMessage
\6dpJA*F.[5N=iUvWVERSIONCRASHIFERCNOTOK
HandleMessageTimer	
Initialize
FCONVERTTOSYSPTIMERQTIME	INITPASCB
LogMessage
	DEINSTALLHandleMessageServerInitializeCleanupHandleRespond
h8
COPYRIGHT 1980, 1985, 1986 CONVERGENT TECHNOLOGIES, INC.
ALL RIGHTS RESERVED

THIS PROGRAM IS FURNISHED UNDER A LICENSE RESTRICTING ITS USE SOLELY FOR THE
OPERATION OF A DESIGNATED COMPUTER FOR A PARTICULAR PURPOSE, AND MAY NOT BE
COPIED OR OTHERWISE USED WITHOUT THE PRIOR WRITTEN CONSENT OF CONVERGENT
TECHNOLOGIES, INC.  TITLE TO AND OWNERSHIP OF THE PROGRAM, INCLUDING ITS SOURCE
CODE, SHALL AT ALL TIMES REMAIN IN CONVERGENT TECHNOLOGIES.

LIBRARY: ServerGen.lib
VERSION: x1.0 (Monday January 12, 1987, 11:t:57)
<e	
Server.plmservere	q<cQeyf n=$MEDIUM OPTIMIZE(3)
$TITLE('Server  Routines for writing correct system service')

SERVER:DO;

$RESET(Debug)
$INCLUDE(:f0:SysCom.edf)

$SET(PcbType)
$SET(RqType)
$SET(TrbType)
$SET(SysConfigType)
$INCLUDE(:f0:CTOSStructures.edf)

$SET(AllocExch, DeallocExch, OpenRTClock)
$SET(Respond, Request, Wait, Check, ForwardRequest, Send, RequestDirect)
$SET(QueryRequestInfo, ServeRq, ConvertToSys)
$SET(ChangePriority)
$SET(Exit, ErrorExit, SetMsgRet, CheckErc, Crash)
$SET(GetpStructure, OsVersion)
$INCLUDE(:f0:CTOSL?ib.edf)

KillProcess:PROCEDURE(pid) ErcType EXTERNAL;
	DECLARE pid WORD;
END KillProcess;

ExitAndRemove:PROCEDURE EXTERNAL;END;

CrashIfErcNotOk: PROCEDURE(erc) PUBLIC;
	DECLARE erc ErcType;
	IF erc <> ercOk 
		THEN CALL Crash(erc);
END CrashIfErcNotOk;

$SET(RqErc)
$INCLUDE(:f0:Erc.edf)

DECLARE GLOBAL LITERALLY 'PUBLIC';

*	GetpStructure case values	*
DECLARE
	 lGetpExParDesc			LITERALLY '0'
	,lGetpCharMap			LITERALLY '1'
	,lGetpVCB				LITERALLY '2'
	,lGetpAscb				LITERALLY '3'
	,lGetpVLPB				LITERALLYA '4'
	,lGetpBcb				LITERALLY '5'
	,lGetpTypeAhead			LITERALLY '6'
	,lGetpRgpVidMemLine		LITERALLY '7'
	,lGetpRgLineMap			LITERALLY '8'
	,lGetpContextStatus		LITERALLY '9'
	;

DECLARE FpType LITERALLY '10';				* 1st SRP board hardware type *
DECLARE StubRqCode LITERALLY '7462H';		* 'tb' *

$SUBTITLE('Initialization')
$EJECT

DECLARE pConfig POINTER PUBLIC, pTime POINTER PUBLIC;
DECLARE config BASED pConfig SysConfigType;

DECLARE  pASCB POINTER PUBLIC
	,Ascb BASED pASCB STRUCTURE(waste(64) BYTE, cbName BCYTE, rgName(30) BYTE)
	;

DECLARE wVersion WORD PUBLIC;
DECLARE exchServe ExchType PUBLIC;
DECLARE fConvertToSys FLAG PUBLIC INITIAL (1);

* External data are defined in the userwritten module. *
DECLARE rgServeRq(1) WORD EXTERNAL
	,nServeRq WORD EXTERNAL
	,rgRqExch(1) WORD EXTERNAL
	;

* The following two external symbols may be omitted from user program. *
DECLARE rqTime TrbType EXTERNAL
	,prqTime POINTER INITIAL (@rqTime)
	;

* Local variables for server main program. *

DECLARE pRq POINTER
	,rq BEASED pRq RqType
	;

DECLARE rgRcb(10) STRUCTURE(pRq POINTER, exchResp ExchType)
	,exchNil LITERALLY '0'
	;

DECLARE poPcbRun POINTER AT(ATpoPcbRun)
	,oPcbRun BASED poPcbRun OFFSET
	,pPcbRun POINTER
	,pcbRun BASED pPcbRun PcbType
	;

DECLARE erc ErcType
	,wRet WORD
	;


* External procedures are defined in the userwritten module.
   All routines except HandleRequest may be omitted.
   Link errors for omitted routines are harmless.
*
Initialize:PROCEDURE EXTERNAL;END;
Start:PROCEDURE EXTERNAL;END;
Timer:PRGOCEDURE(pRq) WORD EXTERNAL;
	DECLARE pRq POINTER;
END;
HandleRequest:PROCEDURE(pRq) WORD EXTERNAL;
	DECLARE pRq POINTER;
END;
HandleRespond:PROCEDURE(pRq) WORD EXTERNAL;
	DECLARE pRq POINTER;
END;
HandleMessage:PROCEDURE(w) WORD EXTERNAL;
	DECLARE w WORD;
END;
Cleanup:PROCEDURE EXTERNAL;END;


Init: PROCEDURE REENTRANT GLOBAL;
	DECLARE iRq WORD
	,rqInfo STRUCTURE(exch WORD, lsc WORD)
	;

	* Address some interesting structures.
   	   Their pointers are public so user gets them without effort. *
	erc=GetpSItructure(lGetpAscb, 0, @pASCB);
	erc=OsVersion(@wVersion);
	erc=GetpStructure(ATpSysTime, 0, @pTime);
	erc=GetpStructure(ATpConfiguration, 0, @pConfig);
	IF config.fMultiPartition = 0			* Single Partition only *
		THEN pPcbRun=BUILD$PTR(SELECTOR$OF(poPcbRun),oPcbRun);

	CALL CheckErc(AllocExch(@exchServe));

	* Use the userdefined structures, if present. *

	IF RqTime.rqCode <> StubRqCode
		THEN DO;
			rqTime.exchResp=exchServe;
			CALL CheckErc(OpenRTClock(@rqTime));
		END;

	iRq=0;
	DO WHILE iRq < nSKerveRq;
		CALL CheckErc(QueryRequestInfo(rgServeRq(iRq),@rqInfo, SIZE(rqInfo)));
		rgRqExch(iRq)=rqInfo.exch;
		iRq=iRq+1;
	END;

	CALL Initialize;

	* Don't ConvertToSys if flag set *
	IF fConvertToSys 
		THEN DO;
			erc=ConvertToSys;
			IF erc <> ercOk 
				THEN CALL CheckErc(SetMsgRet(@('Installation failed'),19));
			CALL ErrorExit(erc);
		END;

	iRq=0;
	DO WHILE iRq < nServeRq;
		* if exch is served on SRP, first unserve it *
		IF rgRqExch(iRq) <> 0 AND config.hardwareType >= FpType
			THEN CALL CrM	ashIfErcNotOk(ServeRq(rgServeRq(iRq),0));
		CALL CrashIfErcNotOk(ServeRq(rgServeRq(iRq),exchServe));
		iRq=iRq+1;
	END;

	CALL Start;

	IF RqTime.rqCode <> StubRqCode
		THEN DO;
			rqTime.cEvents=0;
			rqTime.counter=rqTime.counterReload;
		END;
END Init;


* Find a free Rcb and register the rq in it. *
AllocRcb:PROCEDURE(pRq) REENTRANT;
	DECLARE pRq POINTER, rq BASED pRq RqType
		,iRcb WORD
		;
	DO iRcb=0 TO LAST(rgRcb);
		IF rgRcb(iRcb).exchResp = exchNil 
			THEN DO;
				rgRcb(iRcb).exchResp=rq.exchResO
p;
				rq.exchResp=exchServe;
				rgRcb(iRcb).pRq=pRq;
				RETURN;
			END;
	END;
wRet=wRet OR 10h;*Cause to deinstall*
END AllocRcb;


* Find the Rcb for the rq and restore the rq. Free the Rcb. *
RestoreRcb:PROCEDURE(pRq) REENTRANT;
	DECLARE pRq POINTER, rq BASED pRq RqType
		,iRcb WORD
		;
	DO iRcb=0 TO LAST(rgRcb);
		IF rgRcb(iRcb).pRq = pRq THEN DO;
			rq.exchResp=rgRcb(iRcb).exchResp;
			rgRcb(iRcb).exchResp=exchNil;
			RETURN;
			END;
		END;
	CALL Crash(ercInconsistency);
END RestoreRcb;


* ChecRk if any Rcb active.  If so, wait for respond to rq. *
FlushRcb:PROCEDURE REENTRANT;
	DECLARE iRcb WORD
		;
	DO FOREVER;
		DO iRcb=0 TO LAST(rgRcb);
			IF rgRcb(iRcb).exchResp <> exchNil 
				THEN GOTO WaitForAnotherRq;
		END;
		RETURN;*No more rcb in use.*

		WaitForAnotherRq:
		CALL CheckErc(Wait(exchServe, @pRq));
		CALL ProcessMessage(FALSE);
	END;*FOREVER*
END FlushRcb;


DeInstall:PROCEDURE REENTRANT GLOBAL;
	DECLARE iRq WORD;

	IF RqTime.rqCode <> StubRqCode
		THEN rqTime.counter=0;				*Turn ofTf*
	iRq=0;
	DO WHILE iRq < nServeRq;
		CALL CrashIfErcNotOk(ServeRq(rgServeRq(iRq),0));
		CALL CrashIfErcNotOk(ServeRq(rgServeRq(iRq),rgRqExch(iRq)));
		iRq=iRq+1;
	END;

	CALL FlushRcb;

	DO WHILE Check(exchServe,@pRq) = ercOk;
		CALL ProcessMessage(FALSE);
	END;

	CALL Cleanup;

	*VP*
	IF config.fMultiPartition = 3 THEN CALL ExitAndRemove;
	*MP*
	IF config.fMultiPartition THEN CALL Exit;
	*SP with KillProcess*
	CALL CrashIfErcNotOk(DeallocExch(exchServe));
	IF wVersion >= 0900h 
		THEN CALL CrashIfV
ErcNotOk(KillProcess(oPcbRun));
	*SP, old*
	CALL CrashIfErcNotOk(ChangePriority(0FFh));
	erc=Wait(pcbRun.exchgSync,@pRq);*forever*

END Deinstall;


ProcessMessage:PROCEDURE(fNewRqOk) REENTRANT GLOBAL;
	DECLARE fNewRqOk FLAG, wCase WORD, iRqExch WORD, rqExch ExchType;

	IF pRq = pRqTime AND RqTime.rqCode <> StubRqCode
		THEN 
			IF fNewRqOk 
				THEN wRet=Timer(pRq);
				ELSE wRet=0;				*Ok, don't deinstall*

	ELSE IF SELECTOR$OF(pRq) = 0 THEN
		IF fNewRqOk
			THEN wRet=HandleMessage(OFFSET$OF(pRq));
(X			ELSE wRet=0;					*Ok, don't deinstall*
	ELSE DO;
		IF rq.exchResp = exchServe 
			THEN DO;
				CALL RestoreRcb(pRq);
				wRet=HandleRespond(pRq);
			END;
		ELSE IF fNewRqOk 
			THEN wRet=HandleRequest(pRq);
		ELSE DO;							*new rq not ok, deinstalling*
			rq.ercRet=ercServiceNotAvail;
			CALL CrashIfErcNotOk(Respond(pRq));
			wRet=0;
			END;

		wCase=wRet AND 0Fh;

		IF wCase <= 3
			THEN DO CASE wCase;
				*0  no action*;
				*1  Respond*
					CALL CrashIfErcNotOk(Respond(pRq));
				*2  For4Zward*DO;
					IF (iRqExch := FINDW (@rgServeRq, rq.rqCode, nServeRq)) 
						= 0FFFFh 
						THEN rqExch=0;
						ELSE rqExch=rgRqExch(iRqExch);
					IF rqExch = 0 
						THEN DO;
							rq.ercRet=ercServiceNotAvail;
							CALL CrashIfErcNotOk(Respond(pRq));
						END;
					ELSE 
						CALL CrashIfErcNotOk(ForwardRequest(rqExch,pRq));
					END;
				*3  Pass*DO;
					*Diddle rq.exchResp to come back to us.*
					CALL AllocRcb(pRq);
					IF (iRqExch:=FINDW(@rgServeRq,rq.rqCode,nServeRq)) =0FFFFh
						@\THEN rqExch=0;
						ELSE rqExch=rgRqExch(iRqExch);
					IF rqExch = 0 
						THEN DO;
							rq.ercRet=ercServiceNotAvail;
							* To HandleRespond *
							CALL CrashIfErcNotOk(Send(exchServe,pRq));
							END;
						ELSE 
							CALL CrashIfErcNotOk(RequestDirect(rqExch,pRq));
					END;
			END;* CASE *
	END;
END ProcessMessage;


$SUBTITLE('Main program')
$EJECT

*	Main program	*

CALL Init;

DO FOREVER;
	CALL CheckErc(Wait(exchServe, @pRq));
	CALL ProcessMessage(TRUE);
	IF SHR(wRet,4) 
		THEN CALL^L DeInstall;

END;*DO FOREVER*


END SERVER;
*LOG:

102885 JA Created
11785 JA Megaframe
1386 TB Fixed Megaframe, Added LogMessage, Removed font
121186 TB PMode, Removed video
122286 TB Moved LogMessage to separate module
*
(SELECTOR$OF(poPcbRun),oPcbRun);

	CALL CheckErc(AllocExch(@exchServe));

	* Use the userdefined structures, if present. *

	IF RqTime.rqCode <> StubRqCode
		THEN DO;
			rqTime.exchResp=exchServe;
			CALL CheckErc(OpenRTClock(@rqTime));
		END;

	iRq=0;
	DO WHILE iRq < nSX)LogMessage.plmserver	UcQeg
da$MEDIUM OPTIMIZE(3)
$TITLE('LogMessage  Routine that correctly logs a text string')

LogMsg:DO;

$RESET(Debug)

$SET(SysConfigType)
$INCLUDE(:f0:CTOSStructures.edf)

$SET(WriteLog)
$INCLUDE(:f0:CTOSLib.edf)

DECLARE FpType LITERALLY '10';				* 1st SRP board hardware type *

DECLARE pConfig POINTER EXTERNAL
	,config BASED pConfig SysConfigType;

$EJECT

LogMessage:PROCEDURE(pbMessage, cbMessage) WORD REENTRANT PUBLIC;
DECLARE 
	 pbMessage POINTER
	,cbMessage WORD
	,erc ErcType
	,LogMsg STRUCTURE (
		 TextpcCode WORD				* value to indicate text msg to Plog *
		,cbText WORD
		,rgbText (100) BYTE);

	IF config.hardwareType < FpType
		THEN LogMsg.TextCode = 0;
		ELSE LogMsg.TextCode = 0FFF7h;
	LogMsg.cbText = cbMessage;
	CALL MOVB (pbMessage, @LogMsg.rgbText, cbMessage);
	RETURN (WriteLog(@LogMsg, cbMessage + 4));

END LogMessage;

END LogMsg;

* LOG:
 *
 *	122286 TB Created 
 *
cbRecord WORD
*** WARNING 83 IN 5 (LINE 9), NEAR 'WRITELOG': PROCEDURE CONTAINS NO EXECUTABLE STATEMENTS
   6   1      DECLARE p|e	i)LegaleseservercReRef	
COPYRIGHT 1980, 1985, 1986 CONVERGENT TECHNOLOGIES, INC.
ALL RIGHTS RESERVED

THIS PROGRAM IS FURNISHED UNDER A LICENSE RESTRICTING ITS USE SOLELY FOR THE
OPERATION OF A DESIGNATED COMPUTER FOR A PARTICULAR PURPOSE, AND MAY NOT BE
COPIED OR OTHERWISE USED WITHOUT THE PRIOR WRITTEN CONSENT OF CONVERGENT
TECHNOLOGIES, INC.  TITLE TO AND OWNERSHIP OF THE PROGRAM, INCLUDING ITS SOURCE
CODE, SHALL AT ALL TIMES REMAIN IN CONVERGENT TECHNOLOGIES.

VERSION: x1.0 (Monday January 12, 1987, 11:53)
h
	LibServerGen.flsserver	?c'Re'Remi
Server.obj
Initialize.obj
Start.obj
Timer.obj
HandleRespond.obj
HandleMessage.obj
Cleanup.obj
LogMessage.obj
og)
$INCLUDE(:f0:CTOSLib.edf)

DECLARE pConfig POINTER EXTERNAL
	,config BASED pConfig SysConfigType;


LogMessage:PROCEDURE(pbMessage, cbMessage) WORD REENTRANT GLOBAL;
DECLARE 
	 pbMessage POINTER
	,cbMessage WORD
	,erc ErcType
	,LogMsg STRUCTURE (
		 TextCode WORD				* value to indicate text msg to Plog *
		,cbText WORD
		,rgbText (100) BYTE);

	IF config.hardwareType < FpType
		THEN LogMsg.Textk1

Fooserver.runserverPLM1
MraQeAflGW
'@P ,,
*cVer x1.0217 Linker x11.012019:04.(IOSp;920yytO@P@? 
O

KN
nB^k
2V]1BKhw31vyKybyyTtuvypU6FQPP6]U^^O^^W^^W]UG$rPPPPP*P>PPP]UPDP	P]U+^W;r(w9^Y^G]U+r+^wP68]UMPPRPPPPPdPPRPPmmP	u,6SPPPP$6
4P6]J6rPPPsUF	tP]UPPP4$P$@PPP4$PPP4$$uG P(P>4btt0*P1PFF;sFPPP^FFi(s)b$	t|PPP6$
FF;sFt6| 
rPcP6^6cP6F>4btt.,*]UQFF	w0uvLLFut]UQFF	wF9u9uLFuP]UQFF	wu	Fu]6PPPUQ>4btt*FF;s4PcP6^cP6Fc6P	u
Pd$uKG$s6)P6>	r7P6P
DP6 wP$]U9>u9u>4bttNsP>uFs6LG;uSSvFsSGS<P6Fw.Z;bhHG
u+JVuF^FuGS<|vS$lSG
u+JVuF^FuG6SvSP6]U]U]UF>@tP
]Uu]U
vFP,F	ujvN^YsPP
P^SvN,F0PPFP4F	uFy^G
ZWFGF]UQ^SvFv
]U
F	tv$SuFPF	ufFFu.^SvFPF	uF;Fues PvP^SvN,F7vPNQPF	uF^GvFYF]U3Zrt]U3 L;Wt]a0123456789ABCDEFOS must be MultiPartitionInstallation completeFooServer[sys]<sys>OpenNames.dat[sys]<sys>OpenNames.datInstallation failed${	x1.0217 erc xxxxh
*bt}	$
0
LIBRARY: ServerGen.lib
VERSION: x1.0 (Monday January 12, 1987, 11:57)
LIBRARY: ctos.lib
VERSION: x11.01308713:34 (friday january 30, 1987, 15:16)
<\YF
FooServer.plmserverPLMF8ocReg H$MEDIUM OPTIMIZE(3)
$TITLE('FooServer.plm  Server using standard library')

FooServer:DO;

* $INCLUDE(:f0:SysCom.edf) *
* $INCLUDE(:f0:Erc.edf) *
$INCLUDE(:f1:ServerGen.edf)

$SET(Beep, AllocMemorySL)
$SET(CreateFile, OpenFile, CloseFile, Write)
$SET(Exit, ErrorExit, ErrorExitString, CheckErc, Crash, SetMsgRet)
$SET(Send, SetPartitionName)
$INCLUDE(:f0:CTOSLib.edf)

DECLARE
	 ercOK LITERALLY '0'
	,ercNotImplemented LITERALLY '7'
	;

* Structures defined by every server  *

DECLARE 
	* array of requTests to be served *
	rgServeRq(*) WORD PUBLIC DATA(4,97)

	* number of words in rgServeRq *
	,nServeRq WORD PUBLIC DATA(2)

	* scratch space for deinstall, 1 word per rqCode in rgServeRq *
	,rgRqExch(2) WORD PUBLIC
	;

* Optional structure *
*DECLARE prqTime POINTER PUBLIC;
*DECLARE rqTime BASED prqTime TrbType;*


* Routine for interrupt to call to send a message to the server.*
PokeServer:PROCEDURE(w) PUBLIC;
	DECLARE w WORD;

	CALL CrashIfErcNotOk(Send(exchServe,BUILD$PTR(0,w)));
END PokeServer;

* FooServer specific declarations *
DECLARE pBuf POINTER PUBLIC
	,rgBuffer BASED pBuf(1024) BYTE
	,ib WORD
	,postScript(*) BYTE INITIAL(' erc xxxxh',10)
	,ibHexErc LITERALLY '5'
	,erc ErcType
	;

* FooServer local subroutines *
ConvertWHex:PROCEDURE(w,o) REENTRANT;
DECLARE w WORD
	, o OFFSET
	, rgb BASED o (4) BYTE
	, rgHex(*) BYTE DATA('0123456789ABCDEF');

	rgb(3)=rgHex(w AND 0Fh);
	rgb(2)=rgHex(SHR(LOW(w),4));
	rgb(1)=rgHex(HIGH(w) AND 0Fh);
	rgb(0)=rgHex(SHR(HIGH(w),4));
END ConvertWHex;

*Stalndard routines that may be present in all servers.*

Initialize:PROCEDURE PUBLIC;
*This procedure is called after requests are verified but
  before requests are actually served.  All OS calls are valid here.
  Do error checking, memory or exchange allocation, config file reading,
  extraction of arguments from the command form etc.*

*This example server checks the OS type, then allocates and clears a buffer
  for use during the processing of requests.*
IF NOT sysConfig.fMultiPartition THEN
	CALL ErroxrExitString(ercNotImplemented,
				@('OS must be MultiPartition'),25);

CALL CheckErc(AllocMemorySL(SIZE(rgBuffer),@pBuf));
ib=0;
CALL SETB(0,pBuf,SIZE(rgBuffer));

* Set message to be printed upon successful installation  *
CALL CheckErc(SetMsgRet(@('Installation complete'), 21));
END Initialize;


*Requests have been served.  Installation succeeds or fails.
  From now on all routines must use RequestDirect to issue OS calls listed
  in rgServeRq above, issuing the rqs to the exchange recorded in rgRqExch.
  Other requests may still be issued via procedural interface (by name).

  Some OS calls now no longer work after ConvertToSys.  System services have
  no video structures so calls to VAM or VDM are illegal (PutFrameChars etc).
  In SinglePartition os,
	memory allocationdeallocation is illegal,
	exchange allocation is illegal,
	files must be opened using OpenFileLL,
	interrupt routines may no longer be set,
	bytestreams are not supported.
  In MultiPartition os,
	memory deallocation will work, then the memory may be reallocated,
	 but longlived memory is gone,
	exchanges may be freely allocated,
	files operate normally,
	interrupt routines may be setreset normally,
	bytestreams are supported.
*


* Optional*
* This procedure is called once after installation.  Do things that need
 * not occur unless installation is successful, such as starting the timer.
 *
Start:PROCEDURE PUBLIC;
	*rqTime.counter=rqTime.counterReload;*

	erc = SetPartitionName(0, @('FooServer'), 9);
END Start;


*The following four routines are called as messages are received.
  Only one routine is ever called at once, i.e. no problems with
  reentrancy, recursion or semaphores.

  Each routine returns a word which may have the following values 
	lOk		the routine discharged the request itself; do nothing
	lRespond	the request has been processed, respond to the user
	lForward	the request should be forwarded to the regular handler
	lPass		like lForward, but when it is done call HandleRespond
	lOkDeinstall	like lOk; also deinsta	ll the service
	lRespondDeinstall like lRespond; also deinstall the service
	lForwardDeinstall like lForward; also deinstall the service

  HandleRequest would return different values in each sort of server.
  A pure system service uses lRespond.  An asynchronous server uses lOk.
  lForward and lPass are used by oneway and twoway filters, respectively.

  Timer and HandleMessage always return lOk.
  HandleRespond returns lRespond or maybe lOk.

  The Deinstall values are the same as the regular values exc
ept after
  discharging the request, the system service unserves the requests, flushes
  the exchange and exits.
 *


* Optional*
* Timer:PROCEDURE(pRq) WORD PUBLIC;
* *rqTimer has counted down to 0.  See OS call OpenRTClock.*
* DECLARE pRq POINTER;
* RETURN lOk;
* END;
**


HandleRequest:PROCEDURE(pRq) WORD PUBLIC;
*An original request has been issued whose request code field matches
  one of those in the rgServeRq array.  Perform applicationsspecific
  operations.  Fields of the request block based on the pointer pRq
  that may be changed are 
	rq.ercRet	error code to be returned to caller
	rq.pb>		response buffer(s) pointed to by the request block
  Any request block field may be examined.  See Operating System, VOL 1
  for a description of request blocks.
*
DECLARE pRq POINTER
	,rq BASED pRq RqType
	;

*This example server records the name of every file opened, until its
  name buffer is full.  It then deinstalls.  This is a twoway filter.*
IF SIZE(rgBuffer)ib >= rq.s0 THEN DO;
	CALL MOVB(rq.p0,@rgBuffer(ib),rq.s0);
	ib=ib+rq.s0;
	RETURN lPass;*We wish to see the error code upon Respond*
	END;
ELSE RETURN lForwardDeinstall;*No more room for names, exit*

END;


HandleRespond:PROCEDURE(pRq) WORD PUBLIC;
*A request block has come back via Respond.  It was previously received
  at HandleRequest, which returned with the code lPass.  The request was
  passed to the normal receiver of that request, which completed it and
  Responded back to us.  This routine may now examine the results o
f the
  operation, and then must let the request be Responded.*
DECLARE pRq POINTER
	,rq BASED pRq RqType
	;

*This example server records the error code returned from any open.*
IF SIZE(rgBuffer)ib >= SIZE(postScript) THEN DO;
	CALL ConvertWHex(rq.ercRet,.postScript(ibHexErc));
	CALL MOVB(@postScript,@rgBuffer(ib),SIZE(postScript));
	ib=ib+SIZE(postScript);
	RETURN lRespond;*all done with this request forever*
	END;
ELSE RETURN lRespondDeinstall;*No more room for text, exit*
END;


* Optional*
* HandleMessage:PROCEDURE(w) WORD PUBLIC;
* *An interrupt routine has sent a oneword message to the server.
*   This message may be a data byte or word, or it may indicate some
*   condition such as buffer full.
*   The interrupt routine cannot make requests, so it must poke the
*   server somehow, and the server makes the requests.
* 
*   The interrupt routine could have set a flag that is checked by the
*   server, but then the flag would have to be polled, e.g. every 110th
*   second the timer routine could check the flag.  Sending a message
*   usually is a better solution because the condition is noticed instantly,
*   also without using any processor time for polling.*
* DECLARE w WORD;
* RETURN lOk;
* END HandleMessage;
**


Cleanup:PROCEDURE PUBLIC;
*The server is deinstalling.  The requests have been served back to their
  original destinations.  All requests pending have been discharged.
  The server process is about to disappear.  Do any final operations
  such as writing a log entry or flushing a buffer.
  It is ok to issue requests by name that this server had been serving.*

DECLARE fh FhType, cbWrite WORD;
*This example server writes the name buffer to a preexisting file.*
	erc = CreateFile(@('[sys]<sys>OpenNames.dat'), 23, 0, 0, 512);
	IF OpenFile(@fh, @('[sys]<sys>OpenNames.dat'), 23, 0, 0, 'mm') = ercOK 
		THEN DO;
			erc=Write(fh,pBuf,SIZE(rgBuffer),0,@cbWrite);
			erc=CloseFile(fh);
		END;
	CALL CrashIfErcNotOk(Beep);
END;



END FooServer;
*LOG:
102885 JA Created
81286 TB Removed font support
*nglived memory is gone,
	exchanges may be freely allocated,
	files operate normally,
	interrupt routines may be setreset normally,
	bytestreams are supported.
*


* Optional*
* This procedure is called once after installation.  Do things that need
 * not occur unless installation is successful, such as starting the timer.
 *
Start:PROCEDURE PUBLIC;
	*rqTime.counter=rqTime.counterReload;*

	erc = SetPartitionName(0, @('FooServer'), 9);
END Start;


*The followi
T	FooServer.cserverc	ocQeQed 
* FooServer.c  Test server using the Server.lib.  Stores a buffer of open
 * 		file specs, then writes them to a file and deinstalls. 
 *
 * Log:
 *	102885 JA Created  PLM
 *	2786 TB Converted to C
 *

include ServerGen.h

* applicationspecific definitions *
define RQOPENFILE 				4
define RQOPENFILELL 		   97
define IBHEXERC				5
define ERCNOTIMPLEMENTED		7
define BUFFERSIZE			 512
define BUFFERSIZEL			 512L
define NULL			(char *)0


* Structures defined by every server *
unsigned rg,
ServeRq[] = { RQOPENFILE, RQOPENFILELL };
unsigned nServeRq = 2;

* scratch space for deinstall, 1 word per rqCode in rgServeRq *
unsigned rgRqExch[2];


* Application specific declarations *
char *pBuf;
int  ib, erc;
char postScript[] =  erc xxxxh\n;

* Application local subroutines *
char rgHex[] = 0123456789ABCDEF;

ConvertWHex(w, pRet)
WORD w;
char pRet[];
{
	int i;

	for(i = 3; i >= 0; i) {
		pRet[i] = rgHex[w  0xF];
		w = w >> 4;
	}
}


* Standard routines that may be present in all serv8
ers. *

Initialize()
* This procedure is called after requests are verified but
 * before requests are actually served.  All OS calls are valid here.
 * Do error checking, memory or exchange allocation, config file reading,
 * extraction of arguments from the command form etc.
 *
 * This example server checks the os type, then allocates and clears a buffer
 * for use during the processing of requests.
 *
{
	if(pConfig>partitionType == 0)
		ErrorExitString(ERCNOTIMPLEMENTED, OS must be MultiPartition, D
25);
	CheckErc(AllocMemorySL(BUFFERSIZE, pBuf));
	*pBuf = 0;							* nullterminate buffer *
	
	* Set message to be printed upon successful installation  *
	CheckErc(SetMsgRet(Installation complete., 22));
}


* Requests have been served.  Installation succeeds or fails.
 * From now on all routines must use RequestDirect to issue OS calls listed
 * in rgServeRq above, issuing the rqs to the exchange recorded in rgRqExch.
 * Other requests may still be issued via procedural interface (by name).
 *
 P
* Some OS calls now no longer work after ConvertToSys.  System services have
 * no video structures so calls to VAM or VDM are illegal (PutFrameChars etc).
 * In SinglePartition os,
 *		memory allocationdeallocation is illegal,
 *		exchange allocation is illegal,
 *		files must be opened using OpenFileLL,
 *		interrupt routines may no longer be set,
 *		bytestreams are not supported.
 *  In MultiPartition os,
 *		memory deallocation will work, then the memory may be reallocated,
 *		 but longlived memory \
is gone,
 *		exchanges may be freely allocated,
 *		files operate normally,
 *		interrupt routines may be setreset normally,
 *		bytestreams are supported.
 *


* Optional:
 *
 * This procedure is called once after installation.  Do things that need
 *  not occur unless installation is successful, such as starting the timer.
 *
 Start()
 {
 *		rqTime.counter = rqTime.counterReload; *

		CheckErc(SetPartitionName(0, FooServer, 9));
 }
 

* The following four routines are called as messages are receih
ved.
 * Only one routine is ever called at once, i.e. no problems with
 * reentrancy, recursion or semaphores.
 *
 * Each routine returns a WORD which may have the following values 
 *		lOk				the routine discharged the request itself; do nothing
 *		lRespond		the request has been processed, respond to the user
 *		lForward		the request should be forwarded to the regular handler
 *		lPass			like lForward, but when it is done call HandleRespond
 *		lOkDeinstall	like lOk; also deinstall the service
 *		lRespt
ondDeinstall like lRespond; also deinstall the service
 *		lForwardDeinstall like lForward; also deinstall the service
 *
 * HandleRequest would return different values in each sort of server.
 * A pure system service uses lRespond.  An asynchronous server uses lOk.
 * lForward and lPass are used by oneway and twoway filters, respectively.
 *
 * Timer and HandleMessage always return lOk.
 * HandleRespond returns lRespond or maybe lOk.
 *
 * The Deinstall values are the same as the regular values except af
	ter
 * discharging the request, the system service unserves the requests, flushes
 * the exchange and exits.
 *


* Optional
 *
 * rqTimer has counted down to 0.  See OS call OpenRTClock.
 * Timer(pRq)
 * char *pRq;
 * {
 * 		return(lOk);
 * }
 *


HandleRequest(pRq)
* An original request has been issued whose request code field matches
 * one of those in the rgServeRq array.  Perform applicationsspecific
 * operations.  Fields of the request block based on the pointer pRq
 * that may be changed are 

 *		pRq>ercRet		error code to be returned to caller
 *		pRq>pb>		response buffer(s) pointed to by the request block
 * Any request block field may be examined.  See Operating System, VOL 1
 * for a description of request blocks.
 *
struct RqType *pRq;
{
	* This example server records the name of every file opened, until its
	 *  name buffer is full.  It then deinstalls.  This is a twoway filter.
	 *
	if(BUFFERSIZE  ib >= pRq>s0) {
		strncpy(pBuf + ib, pRq>p0, pRq>s0);
		ib += pRq>s0;
		return(lP
ass);
	} else
		return(lForwardDeinstall);
}


HandleRespond(pRq)
* A request block has come back via Respond.  It was previously received
 * at HandleRequest, which returned with the code lPass.  The request was
 * passed to the normal receiver of that request, which completed it and
 * Responded back to us.  This routine may now examine the results of the
 * operation, and then must let the request be Responded.
 *
struct RqType *pRq;
{
	* This example server records the error code returned from any op
en. *
	if(BUFFERSIZE  ib >= sizeof(postScript)) {
		ConvertWHex(pRq>ercRet, postScript[IBHEXERC]);
		strncpy(pBuf + ib, postScript, strlen(postScript));
		ib += strlen(postScript);
		return(lRespond);
	} else
		return(lRespondDeinstall);
}


* Optional
 * HandleMessage(w)
 *   An interrupt routine has sent a oneword message to the server.
 *   This message may be a data byte or word, or it may indicate some
 *   condition such as buffer full.
 *   The interrupt routine cannot make requests, so it mu

st poke the
 *   server somehow, and the server makes the requests.
 * 
 *   The interrupt routine could have set a flag that is checked by the
 *   server, but then the flag would have to be polled, e.g. every 110th
 *   second the timer routine could check the flag.  Sending a message
 *   usually is a better solution because the condition is noticed instantly,
 *   also without using any processor time for polling.
 *
 * WORD w;
 * {
 * 		return(lOk);
 * }
 *


Cleanup()
* The server is deinstalling
.  The requests have been served back to their
 * original destinations.  All requests pending have been discharged.
 * The server process is about to disappear.  Do any final operations
 * such as writing a log entry or flushing a buffer.
 * It is ok to issue requests by name that this server had been serving.
 *
{
	WORD fh, cbWrite;

	* This example server writes the name buffer to a file. *
	CreateFile([sys]<sys>OpenNames.dat, 23, NULL, 0, BUFFERSIZEL);
	if(OpenFile(fh, [sys]<sys>OpenNames.dat, 
23, NULL, 0, 0x6D6D)) {
		Write(fh, pBuf, BUFFERSIZE, 0L, cbWrite);
		CloseFile(fh);
	}
	beep();
}
so calls to VAM or VDM are illegal (PutFrameChars etc).
 * In SinglePartition os,
 *		memory allocationdeallocation is illegal,
 *		exchange allocation is illegal,
 *		files must be opened using OpenFileLL,
 *		interrupt routines may no longer be set,
 *		bytestreams are not supported.
 *  In MultiPartition os,
 *		memory deallocation will work, then the memory may be reallocated,
 *		 but longlived memory g
SERVER.OBJserver
FdPePe
YSERVERPLM86 V2.3032687 17:02:2S1STACKMEMORYCODEDATACONSTSERVER_CODEDGROUPh@AHH]TD$
KCRASHIFERCNOTOK6JPCONFIGPTIMEPASCBWVERSION	EXCHSERVE
FCONVERTTOSYS\J*INITJ	DEINSTALLPROCESSMESSAGEt	ALLOCEXCHCHANGEPRIORITYCHECKCHECKERCCONVERTTOSYSCRASHDEALLOCEXCH	ERROREXITEXITFORWARDREQUEST
GETPSTRUCTUREOPENRTCLOCK	OSVERSIONQUERYREQUESTINFO
REQUESTDIRECTRESPONDSENDSERVERQ	SETMSGRETWAITKILLPROCESS
EXITANDREMOVE	RGSERVERQNSERVERQRGRQEXCHRQTIME
INITIALIZESTARTTIMER
HANDLEREQUEST
HANDLERESPOND
HANDLEMESSAGECLEANUP$D\EInstallation failed6UF	tP]V+JUPPPXPX@PPPXPPPX$uGTVPP>
bttPPFF;sFPPP^FF\s)X	tPPP6XFF;sFt6| 
rPP6^6P6F>
btt]VV
16V;FKVPT_mpsxVVVVVVVVVV	V$+6=VC\NRUV[\eVksx{QUQFF	w0uvLLFuZ](,48CHSUQFF	wF9u9uLFuP]+5EVJgUQFF	wu	Fu]6PPP*2V8V@\UQ>
bttFF;s4PP6^P6Fc6P	u
P$uG$s6P6>	r7P6PP6TwPX]sV3\>BEVK\Y\aVm\tVzVV	V\V\V\VU9>u9u>
bttNsP>uFs6ZZLG;uSSFsSZGSP6ZZFw.Z;bhHG
u+JVuF^FuGS|vSlSG
u+JVuF^FuG6SvSP6]*V2@CV HNW_joVVV\\\\\\V$)V
1:AEkxVV\^:J6PPPZs3\

VV \0\p
XA({Y	START.OBJserverFdQeQe\4	STARTSTUBPLM86 V2.3032687 17:02:14STACKMEMORYCODEDATACONSTSTARTSTUB_CODEDGROUPh@HH	TD
KSTARTD	U]bt@J	Obj.flsserver	q	Uc
Qe
QemLServer.obj
Initialize.obj
Start.obj
Timer.obj
HandleRespond.obj
HandleMessage.obj
Cleanup.obj
LogMessage.obj
og)
$INCLUDE(:f0:CTOSLib.edf)

DECLARE pConfig POINTER EXTERNAL
	,config BASED pConfig SysConfigType;


LogMessage:PROCEDURE(pbMessage, cbMessage) WORD REENTRANT GLOBAL;
DECLARE 
	 pbMessage POINTER
	,cbMessage WORD
	,erc ErcType
	,LogMsg STRUCTURE (
		 TextCode WORD				* value to indicate text msg to Plog *
		,cbText WORD
		,rgbText (100) BYTE);

	IF config.hardwareType < FpType
		THEN LogMsg.TextX
INITIALIZE.OBJserver
FdQeQedINITIALIZESTUB2PLM86 V2.3032687 17:02:19STACKMEMORYCODEDATACONSTINITIALIZESTUB_CODEDGROUPzh@HH	TD
K
INITIALIZEaD	U]btpf	
Backup.flsserverf	cQeQe5|Cleanup.plm
HandleMessage.plm
HandleRespond.plm
Initialize.plm
Lib.fls
LibServerGen.fls
LogMessage.plm
Lst.fls
Obj.fls
Server.plm
ServerGen.edf
ServerGen.h
ServerGen.lib
Source.fls
Start.plm
Timer.plm
V2.3plm.fls
<ServerPLM>FooServer.plm
<ServerPLM>ServerGen.edf
<ServerC>FooServer.C
<ServerC>ServerGen.h
 op@		'?p1?4	;oETUp^ @eoPegOj0vO wpz|0XLOGMESSAGE.OBJserver Gd{Qe{QeGLOGMSGPLM86 V2.3032687 17:03:11STACKMEMORYCODEDATACONSTLOGMSG_CODEDGROUPh@LHH	T|D
K
LOGMESSAGElWRITELOGPCONFIGDPUj 
sFFFFvFFPFP]C	BVtP

Source.flsserver
b	UcQeQemServer.plm
Initialize.plm
Start.plm
HandleRespond.plm
HandleMessage.plm
Timer.plm
Cleanup.plm
LogMessage.plm
og)
$INCLUDE(:f0:CTOSLib.edf)

DECLARE pConfig POINTER EXTERNAL
	,config BASED pConfig SysConfigType;


LogMessage:PROCEDURE(pbMessage, cbMessage) WORD REENTRANT GLOBAL;
DECLARE 
	 pbMessage POINTER
	,cbMessage WORD
	,erc ErcType
	,LogMsg STRUCTURE (
		 TextCode WORD				* value to indicate text msg to Plog *
		,cbText WORD
		,rgbText (100) BYTE);

	IF config.hardwareType < FpType
		THEN LogMsg.Text[6Lib.flsserverW.?cQeQeaServerGen.lib
\Cleanup.plmserver?cReRe$MEDIUM OPTIMIZE(3)
$TITLE('Cleanup.plm  Server stub for Cleanup procedure')

CleanupStub:DO;

Cleanup:PROCEDURE PUBLIC;
END Cleanup;

END CleanupStub;

espond:PROCEDURE(pRq) WORD PUBLIC;
DECLARE pRq POINTER;
	RETURN lRespond;
END HandleRespond;

END HandleRespondStub;


* DECLARE pRq POINTER;
* RETURN lOk;
* END;
**


HandleRequest:PROCEDURE(pRq) WORD PUBLIC;
*An original request has been issued whose request code field matches
  one of those in the rgServeRq array.  Perform applicationsspecific
 HANDLEMESSAGE.OBJserverFd(Re(ReHANDLEMESSAGESTUBmPLM86 V2.3032687 17:02:2<STACKMEMORYCODEDATACONSTHANDLEMESSAGESTUB_CODEDGROUPh@
HH	TD
K
HANDLEMESSAGEDU]t=
Fooserver.symserverPLM=RraPePeVid*,)
H1
P(46=(E1=6L@0T4G6O6oK6Z<oZ<<>dJUF_tNunvTvZyxy7B\aipfwikoq(*@'B7(MKILLPROCESSGetPartitionHandleSERVERQc	OSVERSIONERROREXITSTRINGSETPARTITIONNAME$6o,ZKaUi@v
HANDLERESPONDWAITFORWARDREQUEST$
REQUESTDIRECT
ALLOCMEMORYSL*QUERYREQUESTINFO
EXITANDREMOVEKINITJCHECKERC	RGSERVERQPTIMEWVERSION0TpZ=_wL4*EiSTART
HANDLEREQUESTRESPOND<CHANGEPRIORITY
DCONVERTTOSYSb	CLOSEFILE
OPENFILE
CREATEFILECRASHEXITPROCESSMESSAGENSERVERQsbVerRunPCONFIGRQTIME*<kN(<1\6TFfqyCLEANUPdSENDOPENRTCLOCK1DEALLOCEXCH)BEEP4WRITE$
GETUSERNUMBER	DEINSTALLTIMER
FatalErrorFPROTECTEDMODEPBUFPASCB	EXCHSERVEH)ZGxndO1=
POKESERVER
INITIALIZEiCHECK	ALLOCEXCH(GetPartitionStatus
AllocMemoryLL,	ERROREXIT
CRASHIFERCNOTOK6
SETPSTRUCTUREN,
GETPSTRUCTURE4
HANDLEMESSAGE	SETMSGRETFRmosRGRQEXCH
FCONVERTTOSYS(
fDevelopement@Ttuvy::<?r<
O<_<o<
\<<<<m<	<d<>?>
O>_>o>> >>w>z>	>T 
 rksttvvq|		
(*
@
?*cWjCLEANUPdWaitLongSetPathQuietKbdForSwap
SetFileStatusSet386TrapHandlerRemoveKeyedQueueEntry
xCloseRTClockReadOpen	SignonRJEpUnLockVideoForModify6
ReuseAlias>?l[

FOOSERVER.OBJserverPLM
cReRex	FOOSERVERPLM86 V2.3021787 13:37:34STACKMEMORYCODEDATACONSTFOOSERVER_CODEDGROUPh@H{HTD
K	RGSERVERQNSERVERQRGRQEXCH
POKESERVERMPBUF+G
INITIALIZEiSTART
HANDLEREQUEST
HANDLERESPONDCLEANUPd;PCONFIG	EXCHSERVECRASHIFERCNOTOK
ALLOCMEMORYSLBEEPCHECKERC	CLOSEFILE
CREATEFILEERROREXITSTRINGOPENFILESEND	SETMSGRETSETPARTITIONNAMEWRITEaDaR erc xxxxh
r0123456789ABCDEFOS must be MultiPartitionInstallation complete
DFooServerrM[sys]<sys>OpenNames.datd[sys]<sys>OpenNames.datU6FQPP]^
VVOU^^O^^W^^W]6

 2As_iUG$rPPPPPP>PPP](V	+V1V9=FOVUVrUPDP	P
]V
XIU+^W;r(w9^Y^G]<
7	EU+r+^wP68](2dUMPPRPPPP
PdPPRPPmmP	u,6SPPPP
6
P]7 V(EV
OSafVkorVwzVVtZServerGen.hNewserverUfWfWf	* ServerGen.h  ServerGen constants and structures for C programs *

* Return values indicating how to handle requests  *
define lOk 					0
define lRespond 				1
define lForward				2
define lPass					3
define lOkDeinstall		 0x10
define lRespondDeinstall	 0x11
define lForwardDeinstall	 0x12

* CTOSian typedef equivalents *
typedef unsigned char BYTE;
typedef unsigned int  ErcType;
typedef unsigned int  FhType;
typedef unsigned char FlagType;
typedef unsigned long LfaType;
typedef unsigned long QUAD;
typedef unsigned int  WORD;

struct SysConfigType {
	BYTE fill[12];
	WORD cPcb
		,cExch
		,CLinkBlk
		,cLinkBlkRes
		,cTrb
		,cIob
		,cFcb
		,cVhb
		,cUcb
		,cUfb;
	BYTE HardwareType
		,ClusterCnfg
		,fNoFileSystem
		,fCommIop
		,partitionType;
};
extern struct SysConfigType *pConfig;		* from Server.obj *

struct RqType {
	BYTE sCntInfo;
	BYTE RtCode;
	BYTE nReqPbCb;
	BYTE nRespPbCb;
	WORD userNum;
	WORD exchResp;
	WORD ercRet;
	WORD rqCode;
	WORD fh;
	WORD LfaTypeLow;
	WORD LfaTypeHigh;
	BYTE *p0;
	WORD s0;
	BYTE *p1;
	WORD s1;
	BYTE *p2;
	WORD s2;
	BYTE *p3;
	WORD s3;
};

struct TrbType {
	WORD counter
		,counterReload
		,cEvents
		,exchResp
		,ercRet
		,rqCode;
};

struct SysTimeType {
	BYTE ticks;
	BYTE tenths;
	WORD seconds;
	WORD dayTimes2;
};
extern struct SysTimeType *pTime;			* from Server.obj *

struct AscbType {
	WORD fhSwapFile;
	BYTE *pVLPB
		,fExecScreen
		,fChkBoot;
	WORD ercRet;
	BYTE *pbMsgRet;
	WORD cbMsgRet;
	BYTE reserved[6];
	BYTE fTermination
		,fVacate;
	WORD oLastTask;
	BYTE fExecFont
		,bActionCode;
	WORD cParMemArray;
	BYTE rgbReservedforBatch1[15]
		,rgbReservedforMail[19]
		,sbUserName[31]
		,sbPassWORD[13]
		,sbCmdFile[79]
		,rgbReservedforBatch2[93]
		,fColor
		,rgbColorBytes[8]
		,reserved2[15];
};
extern struct AscbType *pASCB;				* from Server.obj *

 (iAmpersand + 1);
    END;

* Check if device spec is either [comm] or [ptr] *
IF (UlCmpb(@CommSpec, @bFileSpec(1), 4) = ONES) THEN
	fPtr = FALSE;
ELSE IF (UlCmpb(@PtrSpec, @bFileSpec(1), 3) = ONES) THEN
    fPtr = g
ServerGen.edfserver_?PefY* ServerGen.h  ServerGen constants and structures for PLM programs *

* Return values indicating how to handle requests  *
DECLARE
	 lOk LITERALLY '0'
	,lRespond LITERALLY '1'
	,lForward LITERALLY '2'
	,lPass LITERALLY '3'
	,lOkDeinstall LITERALLY '10h'
	,lRespondDeinstall LITERALLY '11h'
	,lForwardDeinstall LITERALLY '12h'
	;

* CTOS types *
DECLARE
	 ErcType LITERALLY 'WORD'
	,FhType LITERALLY 'WORD'
	,FlagType LITERALLY 'BYTE'
	,LfaType LITERALLY 'DWORD'
	,Offset LITERALLY 'WORD'
	,QUAD LITERALLY 'DWORD'
	;


* public structures from Server *
DECLARE
	 AscbType LITERALLY 'STRUCTURE(Ascb_1 Ascb_2 Ascb_3 Ascb_4 Ascb_5 Ascb_6)'
	,sAscb LITERALLY '304'
	,ASCB_1 LITERALLY '
		 fhSwapFile WORD
		,pVLPB POINTER
		,fExecScreen BYTE
		,fChkBoot BYTE
		,ercRet WORD
		,pbMsgRet POINTER
		,cbMsgRet WORD
	',ASCB_2 LITERALLY '
		,DtModeID BYTE
		,DtModeYmd BYTE
		,DtModeTim BYTE
		,DtModeFmt BYTE
		,reserved (2) BYTE
		,fTermination FlagType
		,fVacate FlagType
	',ASCB_3 LITERALLY '
		,oLastTask OFFSET
		,fExecFont BYTE
		,bActionCode BYTE
		,cParMemArray WORD
		,ALSignature WORD
		,fhContext FhType
		,fDollarContext FlagType
	',ASCB_4 LITERALLY '
		,pExitRunFileBuf POINTER
		,pbPassedData POINTER
		,cbPassedData WORD
		,sbNodeMail (13) BYTE
		,qMailId QUAD
		,naMailServer WORD
		,sbUserName (31) BYTE
	',ASCB_5 LITERALLY '
		,sbUserPswd (13) BYTE
		,sbCmdFile(79) BYTE
		,cbExitRunFile BYTE
		,ExitRunFile(78) BYTE
		,cbPswd BYTE
		,Pswd(12) BYTE
		,priority BYTE
	',ASCB_6 LITERALLY '
		,fColor FlagType
		,rgbColorBytes (8) BYTE
		,reserved2 (15) BYTE
	'
;


DECLARE RqType LITERALLY 'STRUCTURE(
	 sCntlInfo WORD
	,nReqPbCb BYTE
	,nRespPbCbPb BYTE
	,userNum WORD
	,respExch WORD
	,ercRet WORD
	,rqCode WORD
	,fh FhType
	,lfaLow WORD
	,lfaHigh WORD
	,p0 POINTER
	,s0 WORD
	,p1 POINTER
	,s1 WORD
	,p2 POINTER
	,s2 WORD
	,p3 POINTER
)';

DECLARE SysConfigType_1 LITERALLY '
	 SystemBuildType byte
	,OsType byte
	,SaMinLL word
	,SaCurrLL word
	,SaCurrSL word
	,SaMaxSL word
	,SaMemMax word
	,cPcb word
	,cExch word
	,cLinkBlk word
	,cLinkBlkRes word
';
DECLARE SysConfigType_2 LITERALLY '
	 cTrb word
	,cIob word
	,cFcb word
	,cVhb word
	,cUcb word
	,cUfb word
	,HardwareType byte
	,ClusterConfiguration byte
	,fNoFileSystem byte
	,fCommIOP byte
	,fMultipartition byte
';
DECLARE SysConfigType_3 LITERALLY '
	 reserved byte
	,nParDesc word
	,oRgUcb word
	,oRgOExUcb word
	,userNumVid word
	,userNumKbd word
';
DECLARE SysConfigType LITERALLY 'STRUCTURE(
	 SysConfigType_1
	,SysConfigType_2
	,SysConfigType_3
)';

DECLARE SysTimeType LITERAL LY 'STRUCTURE(
	 ticks BYTE 						* count down from 5 or 6 to 0 *
	,hundredMsec BYTE 					* 0  9 *
	,seconds WORD						* 0  43199 *
	,dayTimes2 WORD						* 0  65355 *
	,cksm WORD
)';

DECLARE TrbType LITERALLY 'STRUCTURE(
	 counter WORD
	,counterReload WORD
	,cEvents WORD
	,exchResp WORD
	,ercRet WORD
	,rqCode WORD
)';


* The following variables are in Server.obj *
DECLARE  pTime POINTER EXTERNAL
	,sysTime BASED pTime SysTimeType

	,pConfig POINTER EXTERNAL
	,sysConfig BASED pConfig SysConfigT,ype

	,pASCB POINTER EXTERNAL
	,Ascb BASED pASCB AscbType

	,wVersion WORD EXTERNAL

	,exchServe WORD EXTERNAL
	;

* Server public procedure *
CrashIfErcNotOk: PROCEDURE(erc) EXTERNAL;
DECLARE erc ErcType;
END CrashIfErcNotOk;

8Lst.flsserver	UcQeQem\DServer.lst
Initialize.lst
Start.lst
Timer.lst
HandleRespond.lst
HandleMessage.lst
Cleanup.lst
LogMessage.lst
P$H	Timer.plmserver0?c{Qe{QeM\$MEDIUM OPTIMIZE(3)
$TITLE('Timer.plm  Server stub for Timer procedure')

TimerStub:DO;

DECLARE lOk LITERALLY '0';
DECLARE StubRqCode LITERALLY '7462H';			* 'tb' *
DECLARE rqTime (6) WORD PUBLIC INITIAL (0, 0, 0, 0, 0, StubRqCode);

Timer:PROCEDURE(pRq) WORD PUBLIC;
DECLARE pRq POINTER;
	RETURN lOk;
END Timer;

END TimerStub;

@		'?p1?4	;oETUp^ @eoPegOj0vO wpz|0h'aCLEANUP.OBJserverGdReRet(
CLEANUPSTUBPLM86 V2.3032687 17:03:36STACKMEMORYCODEDATACONSTCLEANUPSTUB_CODEDGROUPjh@HH	TD
KCLEANUPQD	U]bt*XKHandleRespond.plmserverK[?c(Re(Re+$MEDIUM OPTIMIZE(3)
$TITLE('HandleRespond.plm  Server stub for HandleRespond procedure')

HandleRespondStub:DO;

DECLARE lRespond LITERALLY '0';

HandleRespond:PROCEDURE(pRq) WORD PUBLIC;
DECLARE pRq POINTER;
	RETURN lRespond;
END HandleRespond;

END HandleRespondStub;


* DECLARE pRq POINTER;
* RETURN lOk;
* END;
**


HandleRequest:PROCEDURE(pRq) WORD PUBLIC;
*An original request has been issued whose request code field matches
  one of those in the rgServeRq array.  Perform applicationsspecific
 