-- Copyright (C) 1981, 1982, 1984, 1985 by Xerox Corporation. All rights reserved.
-- Restart.mesa, Transport Mechanism: Restart and main control --
-- HGM, 15-Sep-85 16:02:28
-- Brenda Hankins 23-Aug-84 10:39:20
-- Mark Johnson 18-Jan-82 13:28:02 --
-- Randy Gobbel 11-Aug-81 17:07:20 --
-- Andrew Birrell 30-Dec-81 15:15:26 --
-- Ted Wobber 1-Nov-82 13:37:42 --
DIRECTORY
Ascii USING [
BS, ControlA, ControlC, ControlT, ControlV, ControlW, CR, DEL, ESC, SP, TAB],
BodyDefs USING [Connect, maxConnectLength, maxRNameLength, RName],
Heap USING [systemZone],
HeapDefs USING [Compactor, HeapEndWrite, HeapRestart, HeapStartWrite],
LocalNameDefs USING [LocalName, ReadMSName, ReadRSName],
LogDefs USING [
EnableLogSpilling, ShowLine, StatisticsOn, TypescriptOn, WriteChar,
WriteLogEntry, WriteLine, WriteString],
LogPrivateDefs USING [tty],
NameInfoDefs USING [GetConnect],
ObjectDirDefs USING [Enumerate, ObjectNumber, UseObject],
PolicyDefs USING [Operation, SetOperationAllowed, SetTelnetAllowed],
Process USING [Detach],
ProtocolDefs USING [Init, SetTestingMode],
PupDefs USING [
AdjustBufferParms, GetPupPackageUseCount, PupPackageDestroy, PupPackageMake],
RestartDefs USING [
Enquiry, MailboxRestart, MiscSoc1, MiscSoc2, MSMail,
ReadForward1, ReadForward2, ReadInput1, ReadInput2, ReadMail,
ReceiveInput, ReceiveMail, RegRestartInit1, RegRestartInit2,
SLRestart, StartKeyWatcher, WatchDiskErrors, Test],
Runtime USING [GetBcdTime, IsBound],
String USING [AppendChar, AppendString, EquivalentString, StringBoundsFault],
System USING [switches],
Time USING [Append, Unpack],
TTY USING [CharsAvailable, GetChar],
VMDefs USING [InitializeVM];
Restart: PROGRAM
IMPORTS
Heap, HeapDefs, LocalNameDefs, LogDefs, LogPrivateDefs, NameInfoDefs, ObjectDirDefs,
PolicyDefs, Process, ProtocolDefs, PupDefs, RestartDefs, Runtime, String,
System, Time, TTY, VMDefs =
BEGIN
mail: BOOLEAN = Runtime.IsBound[LOOPHOLE[RestartDefs.MailboxRestart]];
reg: BOOLEAN = Runtime.IsBound[LOOPHOLE[RestartDefs.RegRestartInit1]];
test: BOOLEAN = Runtime.IsBound[LOOPHOLE[RestartDefs.Test]];
WriteVersion: PROCEDURE [where: {disk, screen}] =
BEGIN
log: LONG STRING ← Heap.systemZone.NEW[StringBody[128]];
String.AppendString[log, "Version of "L];
Time.Append[log, Time.Unpack[Runtime.GetBcdTime[]], TRUE];
IF where = disk THEN LogDefs.WriteLogEntry[log] ELSE LogDefs.WriteLine[log];
Heap.systemZone.FREE[@log];
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[];
LogDefs.ShowLine["*** Testing mode ***"L];
ObjectDirDefs.UseObject[obj];
testMode ← TRUE;
END;
END
ELSE LogDefs.ShowLine["*** 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];
DO
LogDefs.WriteString[prompt];
LogDefs.WriteString[" [Type password or DEL] "L];
pwd.length ← 0;
DO
c: CHARACTER = TTY.GetChar[LogPrivateDefs.tty];
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[134C]; 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 String.EquivalentString[pwd, real] THEN {
LogDefs.WriteLine[" ok"L]; RETURN[TRUE]};
LogDefs.WriteLine[" incorrect"L];
ENDLOOP;
END;
SetTestingMode: PROCEDURE =
BEGIN
c: CHARACTER ← 000C; -- NUL value
IF TTY.CharsAvailable[LogPrivateDefs.tty] # 0 THEN
c ← TTY.GetChar[LogPrivateDefs.tty];
IF System.switches['t] = down OR c = Ascii.ControlT THEN
BEGIN
IF Confirm["Set testing mode?"L, "Botrytis"L] THEN
HeapDefs.HeapEndWrite[
HeapDefs.HeapStartWrite[testMode], KeepTestModeObject];
END;
IF System.switches['t] = down OR System.switches['v] = down
OR 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;
CheckTestMode: PROCEDURE [obj: ObjectDirDefs.ObjectNumber] RETURNS [BOOLEAN] = {
KeepTestModeObject[obj]; RETURN[TRUE --found-- ]};
StartCompactor: PROC = {START HeapDefs.Compactor};
StartDisk: PROCEDURE =
BEGIN
Compactor: PROC =
BEGIN
LogDefs.ShowLine["Starting compactor"L];
Process.Detach[FORK StartCompactor[]];
END;
initHeap: BOOLEAN = START HeapDefs.HeapRestart[];
RestartDefs.WatchDiskErrors[];
IF initHeap THEN Compactor[];
SetTestingMode[];
[] ← ObjectDirDefs.Enumerate[testMode, CheckTestMode];
ProtocolDefs.Init[];
START LocalNameDefs.LocalName[initHeap];
IF mail THEN
BEGIN
LogDefs.ShowLine["Restarting SL Queues"L];
START RestartDefs.SLRestart[initHeap] --allow internal mail-- ;
RestartDefs.ReadForward1[];
END;
-- Registration server --
IF reg THEN
BEGIN
LogDefs.ShowLine["Restarting RServer database"L];
RestartDefs.RegRestartInit1[initHeap];
[] ← LocalNameDefs.ReadRSName[];
END;
-- Mail Server --
IF mail THEN
BEGIN
LogDefs.ShowLine["Restarting MServer database"L];
START RestartDefs.MailboxRestart[initHeap];
[] ← LocalNameDefs.ReadMSName[];
END;
-- Log spilling --
IF mail OR reg THEN
BEGIN
name: LONG STRING =
IF mail THEN LocalNameDefs.ReadMSName[].name
ELSE LocalNameDefs.ReadRSName[].name;
pwd: LONG 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 LogDefs.ShowLine["No log spilling enabled"L];
END;
LogDefs.ShowLine["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];
String.AppendString[logName, "Log-"L];
String.AppendString[logName, name ! String.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;
String.AppendChar[host, logName[i]];
REPEAT FINISHED => GOTO cant
ENDLOOP;
FOR i: CARDINAL IN [host.length + 2..logName.length) DO
String.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 String;
log: LONG STRING ← Heap.systemZone.NEW[StringBody[128]];
AppendString[log, IF testMode THEN "*** Testing: "L ELSE "Grapevine: "L];
IF reg THEN
BEGIN
AppendString[log, "Registration Server "L];
AppendString[log, LocalNameDefs.ReadRSName[].name];
IF mail THEN AppendString[log, ", "L];
END;
IF mail THEN
BEGIN
AppendString[log, "Mail Server "L];
AppendString[log, LocalNameDefs.ReadMSName[].name];
END;
RestartDefs.MiscSoc1[];
RestartDefs.ReadInput1[];
LogDefs.StatisticsOn[log];
LogDefs.WriteLogEntry[log];
Heap.systemZone.FREE[@log];
END;
StartListeners: PROC =
BEGIN
START RestartDefs.Enquiry;
LogDefs.ShowLine["Starting SL-queue readers"L];
RestartDefs.ReadInput2[];
RestartDefs.ReadForward2[];
LogDefs.ShowLine["Starting listeners"L];
IF reg THEN RestartDefs.RegRestartInit2[];
IF mail THEN
BEGIN
START RestartDefs.ReceiveInput;
START RestartDefs.ReceiveMail;
START RestartDefs.ReadMail;
RestartDefs.MiscSoc2[];
START RestartDefs.MSMail;
END;
RestartDefs.StartKeyWatcher[];
END;
-- Main program --
pupUseCount: CARDINAL;
LogDefs.TypescriptOn[];
WriteVersion[screen];
pupUseCount ← PupDefs.GetPupPackageUseCount[];
FOR i: CARDINAL IN [0..pupUseCount) DO PupDefs.PupPackageDestroy[] ENDLOOP;
PupDefs.AdjustBufferParms[bufferPoolSize: 40];
FOR i: CARDINAL IN [0..pupUseCount] DO [] ← PupDefs.PupPackageMake[] ENDLOOP;
VMDefs.InitializeVM[min: 30 --pages-- , max: 50 --pages, JRG suggestion-- ];
WriteVersion[disk];
StartDisk[];
StartStats[];
StartListeners[];
LogDefs.ShowLine["Running"L];
END.