-- Transport Mechanism: Restart and main control -- -- [Indigo]<Grapevine>MS>Restart.mesa -- -- Andrew Birrell 20-Sep-82 9:25:11 -- DIRECTORY Ascii USING[ BS, ControlA, ControlC, ControlT, ControlV, ControlW, CR, DEL, ESC, SP, TAB], BodyDefs USING[ Connect, maxConnectLength, maxRNameLength, RName ], DisplayDefs USING[ DisplayOff, StopCursor ], DriverDefs USING[ freeQueue ], FrameDefs USING[ IsBound ], HeapDefs USING[ Compactor, HeapEndWrite, HeapRestart, HeapStartWrite ], IODefs USING[ GetInputStream, SetOutputStream ], ImageDefs USING[ BcdTime ], LocalNameDefs USING[ LocalName, ReadMSName, ReadRSName ], LogDefs USING[ DisplayNumber, EnableLogSpilling, SetTypescriptParameters, StatisticsOn, TypescriptOn, WriteChar, WriteLogEntry, WriteLine, WriteString ], NameInfoDefs USING[ GetConnect ], ObjectDirDefs USING[ Enumerate, ObjectNumber, UseObject ], PolicyDefs USING[ Operation, SetOperationAllowed, SetTelnetAllowed ], ProcessDefs USING[ Detach ], ProtocolDefs USING[ Init, SetTestingMode ], PupDefs USING[ AdjustBufferParms, GetPupPackageUseCount, PupPackageMake ], PupRouterDefs USING[ numberOfNetworks ], RestartDefs, StreamDefs USING[ DestroyKeyHandler, StreamHandle, StreamObject ], StringDefs USING[ AppendChar, AppendString, EquivalentString, StringBoundsFault ], TimeDefs USING[ AppendFullDayTime, UnpackDT ], VMDefs USING[ InitializeVM ]; Restart: PROGRAM IMPORTS DisplayDefs, DriverDefs, FrameDefs, HeapDefs, IODefs, ImageDefs, LocalNameDefs, LogDefs, NameInfoDefs, ObjectDirDefs, PolicyDefs, ProcessDefs, ProtocolDefs, PupDefs, PupRouterDefs, RestartDefs, StreamDefs, StringDefs, TimeDefs, VMDefs = BEGIN PutDisplay: PROCEDURE[ handle: StreamDefs.StreamHandle, char: UNSPECIFIED] = BEGIN LogDefs.WriteChar[char]; END; outStream: StreamDefs.StreamObject ← [reset: NIL, get: NIL, putback: NIL, put: PutDisplay, endof: NIL, destroy: NIL, link: NIL, body: Other[ type: 0, data: NIL ] ]; inStream: StreamDefs.StreamHandle = IODefs.GetInputStream[]; mail: BOOLEAN = FrameDefs.IsBound[RestartDefs.MailboxRestart]; reg: BOOLEAN = FrameDefs.IsBound[RestartDefs.RegRestart]; test: BOOLEAN = FrameDefs.IsBound[RestartDefs.Test]; WriteLine: PROCEDURE[s: STRING] = BEGIN LogDefs.WriteLogEntry[s]; LogDefs.WriteLine[s]; END; WriteVersion: PROCEDURE[where: {disk, screen}] = BEGIN s: STRING = [256]; StringDefs.AppendString[s, "Grapevine server starting. Version of "L]; TimeDefs.AppendFullDayTime[s, TimeDefs.UnpackDT[ImageDefs.BcdTime[]] ]; IF where = disk THEN LogDefs.WriteLogEntry[s] ELSE LogDefs.WriteLine[s]; END; testMode: BOOLEAN ← FALSE; testModeAllowed: BOOLEAN ← TRUE; -- may be reset from debugger -- KeepTestModeObject: PROCEDURE[obj: ObjectDirDefs.ObjectNumber] = BEGIN IF testModeAllowed THEN BEGIN IF NOT testMode THEN BEGIN ProtocolDefs.SetTestingMode[]; WriteLine["*** Testing mode ***"L]; ObjectDirDefs.UseObject[obj]; testMode ← TRUE; END; END ELSE WriteLine["*** Testing mode cancelled ***"L]; END; Confirm: PROC[prompt, real: STRING] RETURNS[BOOLEAN] = BEGIN -- Note: for security, this source file should contain only a one-way -- function of the password. However, it's actually only an idiot -- check, so using clear-text passwords in the source is ok. pwd: STRING = [16]; UNTIL inStream.endof[inStream] DO [] ← inStream.get[inStream] ENDLOOP; DO LogDefs.WriteString[prompt]; LogDefs.WriteString[" [Type password or DEL] "L]; pwd.length ← 0; DO c: CHARACTER = inStream.get[inStream]; SELECT c FROM Ascii.SP, Ascii.TAB, Ascii.CR, Ascii.ESC => EXIT; Ascii.BS, Ascii.ControlA => IF pwd.length > 0 THEN BEGIN pwd.length ← pwd.length - 1; LogDefs.WriteChar['\]; END; Ascii.ControlW => { pwd.length ← 0; LogDefs.WriteChar['←] }; Ascii.DEL, Ascii.ControlC => { LogDefs.WriteLine[" XXX"L]; RETURN[FALSE] }; ENDCASE => IF pwd.length < pwd.maxlength THEN BEGIN pwd[pwd.length] ← c; pwd.length ← pwd.length + 1; LogDefs.WriteChar['*]; END; ENDLOOP; IF StringDefs.EquivalentString[pwd, real] THEN { LogDefs.WriteLine[" ok"L]; RETURN[TRUE] }; LogDefs.WriteLine[" incorrect"L]; ENDLOOP; END; SetTestingMode: PROCEDURE = BEGIN IF NOT inStream.endof[inStream] THEN BEGIN c: CHARACTER = inStream.get[inStream]; IF c = Ascii.ControlT THEN BEGIN IF Confirm["Set testing mode?"L, "Botrytis"L] THEN HeapDefs.HeapEndWrite[HeapDefs.HeapStartWrite[testMode], KeepTestModeObject]; END; IF c = Ascii.ControlT OR c = Ascii.ControlV THEN BEGIN IF Confirm["Viticulturists entrance only?"L, "Viticulture"L] THEN { FOR op: PolicyDefs.Operation IN PolicyDefs.Operation DO PolicyDefs.SetOperationAllowed[op,FALSE] ENDLOOP; PolicyDefs.SetTelnetAllowed[]; LogDefs.WriteLogEntry["Viticulturists only"L] }; END; END; END; CheckTestMode: PROCEDURE[obj: ObjectDirDefs.ObjectNumber] RETURNS[ BOOLEAN ] = { KeepTestModeObject[obj]; RETURN[TRUE--found--] }; StartCompactor: PROC = { START HeapDefs.Compactor }; StartDisk: PROCEDURE = BEGIN Compactor: PROC = BEGIN WriteLine["Starting compactor"L]; ProcessDefs.Detach[FORK StartCompactor[]]; END; initHeap: BOOLEAN = START HeapDefs.HeapRestart[]; IF initHeap THEN Compactor[]; SetTestingMode[]; [] ← ObjectDirDefs.Enumerate[testMode, CheckTestMode]; ProtocolDefs.Init[]; START LocalNameDefs.LocalName[initHeap]; IF mail THEN BEGIN WriteLine["Restarting Steering-list Queues"L]; START RestartDefs.SLRestart[initHeap] --allow internal mail--; END; -- Registration server -- IF reg THEN BEGIN WriteLine["Restarting registration server database"L]; START RestartDefs.RegRestart[initHeap]; [] ← LocalNameDefs.ReadRSName[]; END; -- Mail Server -- IF mail THEN BEGIN WriteLine["Restarting mail server database"L]; START RestartDefs.MailboxRestart[initHeap]; [] ← LocalNameDefs.ReadMSName[]; END; -- Log spilling -- IF mail OR reg THEN BEGIN name: STRING = IF mail THEN LocalNameDefs.ReadMSName[].name ELSE LocalNameDefs.ReadRSName[].name; pwd: STRING = IF mail THEN LocalNameDefs.ReadMSName[].password ELSE LocalNameDefs.ReadRSName[].password; host: BodyDefs.Connect = [BodyDefs.maxConnectLength]; path: BodyDefs.Connect = [BodyDefs.maxConnectLength]; IF GetHostPath[name, host, path] THEN LogDefs.EnableLogSpilling[name, pwd, host, path] ELSE WriteLine["No log spilling enabled"L]; END; WriteLine["Disk restart complete"L]; IF test THEN START RestartDefs.Test; IF NOT initHeap THEN Compactor[]; END; GetHostPath: PROC[name: BodyDefs.RName, host, path: BodyDefs.Connect] RETURNS[BOOLEAN] = BEGIN logName: BodyDefs.RName = [BodyDefs.maxRNameLength]; StringDefs.AppendString[logName, "Log-"L]; StringDefs.AppendString[logName, name ! StringDefs.StringBoundsFault => GOTO cant]; SELECT NameInfoDefs.GetConnect[logName, logName] FROM individual => NULL; ENDCASE => GOTO cant; -- logName should be "[Ivy]<DMS>Log>" -- IF logName[0] # '[ THEN GOTO cant; FOR i: CARDINAL IN [1..logName.length) DO IF logName[i] = '] THEN EXIT; StringDefs.AppendChar[host, logName[i]]; REPEAT FINISHED => GOTO cant ENDLOOP; FOR i: CARDINAL IN [host.length+2..logName.length) DO StringDefs.AppendChar[path, logName[i]] ENDLOOP; IF path.length < 2 OR path[0] # '< OR path[path.length-1] # '> THEN GOTO cant; RETURN[TRUE] EXITS cant => RETURN[FALSE]; END; StartStats: PROCEDURE = BEGIN OPEN StringDefs; s: STRING = [256]; AppendString[s, IF testMode THEN "*** Testing: "L ELSE "Grapevine: "L]; IF reg THEN BEGIN AppendString[s, "Registration Server "L]; AppendString[s, LocalNameDefs.ReadRSName[].name ]; IF mail THEN AppendString[s, ", "L]; END; IF mail THEN BEGIN AppendString[s, "Mail Server "L]; AppendString[s, LocalNameDefs.ReadMSName[].name ]; END; LogDefs.StatisticsOn[s]; LogDefs.WriteLogEntry[s]; END; StartListeners: PROC = BEGIN START RestartDefs.Enquiry; WriteLine["Starting SL-queue readers"L]; START RestartDefs.ReadForward; START RestartDefs.MTPServer; START RestartDefs.ReadInput; WriteLine["Starting listeners"L]; IF reg THEN RESTART RestartDefs.RegRestart; IF mail THEN BEGIN START RestartDefs.ReceiveInput; START RestartDefs.ReceiveMail; START RestartDefs.ReadMail; START RestartDefs.MiscSoc; START RestartDefs.MSMail; RESTART RestartDefs.MTPServer; END; END; -- Main program -- DisplayDefs.DisplayOff[black]; DisplayDefs.StopCursor[]; LogDefs.SetTypescriptParameters[tsLines:3]; LogDefs.TypescriptOn[]; WriteVersion[screen]; IODefs.SetOutputStream[@outStream]; [] ← PupDefs.GetPupPackageUseCount[]; -- to start PupRouterCold! -- PupRouterDefs.numberOfNetworks ← 255; -- exclude 0; in PupRouterCold -- PupDefs.AdjustBufferParms[54--buffers--, 64--words--]; PupDefs.PupPackageMake[]; LogDefs.DisplayNumber["Free PUPs"L, [short[@DriverDefs.freeQueue.length]]]; VMDefs.InitializeVM[min:30--pages--, max:45--pages--]; WriteVersion[disk]; StartDisk[]; StreamDefs.DestroyKeyHandler[]; StartStats[]; StartListeners[]; WriteLine["Running"L]; END.