-- Transport Mechanism: Restart and main control --
-- [Indigo]<Grapevine>MS>Restart.mesa --
-- Andrew Birrell 20-Sep-82 9:25:11 --
-- Mike Schroeder 25-Jan-83 16:06:20 --
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, "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 SL Queues"L];
START RestartDefs.SLRestart[initHeap] --allow internal mail--;
END;
-- Registration server --
IF reg
THEN BEGIN
WriteLine["Restarting RServer database"L];
START RestartDefs.RegRestart[initHeap];
[] ← LocalNameDefs.ReadRSName[];
END;
-- Mail Server --
IF mail
THEN BEGIN
WriteLine["Restarting MServer 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.