DIRECTORY Buttons, ConvertUnsafe USING [ToRope], Directory USING [Error, Lookup], File USING [Capability, read, Unknown], MessageWindow USING [Append, Blink, Clear, Confirm], Rope, --using lots TemporaryBooting, --using lots UserProfile USING [Line], UserTerminal USING [BlinkDisplay], VBootOps USING [], ViewerClasses USING [Viewer], ViewerOps USING [EnumerateViewers, EnumProc], ViewerTools USING [GetSelectionContents], Volume; --using lots VBoot: CEDAR MONITOR IMPORTS Buttons, ConvertUnsafe, Directory, File, MessageWindow, Rope, TemporaryBooting, UserProfile, UserTerminal, ViewerOps, ViewerTools, Volume EXPORTS VBootOps SHARES File = BEGIN OPEN Rope; MyData: TYPE = REF MyDataRep; MyDataRep: TYPE = RECORD [name: ROPE, volID: Volume.ID, file: BOOL _ FALSE]; nullSwitches: SwitchesArray _ ALL[FALSE]; Switches: TYPE = REF SwitchesArray; SwitchesArray: TYPE = PACKED ARRAY [0..36) OF BOOL _ ALL[FALSE]; GetSwitches: PROC [name: ROPE] RETURNS [Switches] = { sw: ROPE _ UserProfile.Line[name.Concat["Switches"]]; switches: Switches _ NEW[SwitchesArray _ nullSwitches]; SetSwitches[sw, switches]; RETURN [switches]; }; SetSwitches: PROC [sw: ROPE, switches: Switches] = { FOR i: INT IN [0..sw.Length[]) DO c: CHAR _ sw.Fetch[i]; si: CARDINAL _ 0; SELECT c FROM IN['0..'9] => switches^[c-'0] _ TRUE; IN['A..'Z] => switches^[10+(c-'A)] _ TRUE; IN['a..'z] => switches^[10+(c-'a)] _ TRUE; ENDCASE; ENDLOOP; }; BootProc: Buttons.ButtonProc = TRUSTED { viewer: ViewerClasses.Viewer ~ NARROW[parent]; data: MyData _ NARROW[clientData]; IF SomethingWorthSaving[] THEN RETURN; Buttons.SetDisplayStyle[viewer, $BlackOnGrey]; IF data.file THEN BootFromFile[data] ELSE IF data.volID = Volume.nullID THEN TemporaryBooting.BootButton[LOOPHOLE[GetSwitches[data.name]^]] ELSE TemporaryBooting.BootFromVolume[data.volID, LOOPHOLE[GetSwitches[data.name]^]]; Buttons.SetDisplayStyle[viewer, $BlackOnWhite]; }; BasicCedarDorado: Buttons.ButtonProc = { viewer: ViewerClasses.Viewer ~ NARROW[parent]; IF SomethingWorthSaving[] THEN RETURN; Buttons.SetDisplayStyle[viewer, $BlackOnGrey]; BootFromFileName["BasicCedarDorado"]; Buttons.SetDisplayStyle[viewer, $BlackOnWhite]; }; SomethingWorthSaving: PROC RETURNS[BOOLEAN] = BEGIN dirty: BOOLEAN _ FALSE; CheckDirty: ViewerOps.EnumProc = {dirty _ v.newVersion OR v.newFile OR dirty}; ViewerOps.EnumerateViewers[CheckDirty]; IF dirty THEN { MessageWindow.Blink[]; IF ~MessageWindow.Confirm["Confirm discard of edits . . . "] THEN { MessageWindow.Append["boot aborted."]; RETURN[TRUE]}}; RETURN[FALSE]; END; BootFromFile: PROC [data: MyData] = BEGIN BootFromFileName[ViewerTools.GetSelectionContents[]]; END; BootFromFileName: PUBLIC PROC [file: ROPE] = TRUSTED BEGIN ENABLE BEGIN TemporaryBooting.InvalidParameters => {MessageWindow.Append["Not a boot file: ", TRUE]; GOTO putName}; File.Unknown => {MessageWindow.Append["File unknown: ", TRUE]; GOTO putName}; Directory.Error => {MessageWindow.Append["Directory search failed: ", TRUE]; GOTO putName}; END; cap: File.Capability; sw: ROPE; switches: VBoot.Switches; i: INT; IF Rope.Length[file]=0 THEN {UserTerminal.BlinkDisplay[]; RETURN}; IF (i _ Rope.Find[file, "/"]) # -1 THEN {sw _ Rope.Substr[base: file, start: i + 1]; file _ Rope.Substr[base: file, len: i]}; IF ~Rope.Equal[Rope.Substr[file, Rope.Length[file]-5,5],".boot",FALSE] THEN file _ Rope.Cat[file, ".boot"]; cap _ [Directory.Lookup[LOOPHOLE[Rope.Flatten[file]]].fID, File.read]; TemporaryBooting.MakeBootable[cap, 1]; switches _ GetSwitches["File"]; SetSwitches[sw, switches]; TemporaryBooting.BootFromFile[cap, 1, LOOPHOLE[switches^]]; EXITS putName => MessageWindow.Append[file]; END; buttonsCreated: BOOL _ FALSE; BootButtonsProc: ENTRY Buttons.ButtonProc = BEGIN IF ~ buttonsCreated THEN BEGIN viewer: ViewerClasses.Viewer ~ NARROW[parent]; MakeBootButtons[]; buttonsCreated _ TRUE; END; END; MakeBootButtons: PROC = { name: ROPE; volID: Volume.ID _ Volume.nullID; types: Volume.TypeSet _ ALL[TRUE]; data: MyData ; MessageWindow.Clear[]; -- so can put up buttons faster data _ NEW[MyDataRep _ [name: "Alto", volID: volID]]; [] _ Buttons.Create[info: [name: "Alto"], proc: BootProc, clientData: data, guarded: TRUE]; data _ NEW[MyDataRep _ [name: "File", volID: volID, file: TRUE]]; [] _ Buttons.Create[info: [name: "File"], proc: BootProc, clientData: data, guarded: TRUE, fork: TRUE]; data _ NEW[MyDataRep _ [name: "Basic", volID: volID, file: TRUE]]; [] _ Buttons.Create[info: [name: "Basic"], proc: BasicCedarDorado, clientData: data, guarded: TRUE, fork: TRUE]; DO volName: STRING _ [Volume.maxNameLength]; volID _ Volume.GetNext[volID, types]; IF volID = Volume.nullID THEN EXIT; TRUSTED {Volume.GetLabelString[volID, volName]}; TRUSTED {name _ ConvertUnsafe.ToRope[volName]}; data _ NEW[MyDataRep _ [name: name, volID: volID, file: FALSE]]; [] _ Buttons.Create[info: [name: name], proc: BootProc, clientData: data, guarded: TRUE]; ENDLOOP; }; [] _ Buttons.Create[info: [name: "Boot"], proc: BootButtonsProc]; END. δVBoot.mesa Russ Atkinson, January 20, 1982 8:57 pm McGregor, October 27, 1982 4:01 pm Dan Swinehart, March 8, 1982 8:16 am Roy Levin, June 11, 1982 4:53 pm Warren Teitelman, June 25, 1982 2:16 pm Last Edited by: Maxwell, January 3, 1983 1:42 pm must be bitwise equivalent to TemporaryBooting.Switches first 10 elements are switches 0..9 last 26 elements are switches A..Z (or a..z) SetSwitches was broken out as separate procedure so can be called on switches that are typed in. Boot file starts at page 1 for a leader page file Now issue a message and await confirmation to boot June 21, 1982 4:58 pm W. Teitelman. Removed switches field from data. Arranged for switches to be computed at time of boot in order to allow user to have changed his profile and/or logged in as somebody else before booting. Broke BootFromFileName out from BootFromFile so possible to write a program which boots from a specific file. Added ability to specify switches with file name, e.g. basiccedardorado/d ΚV– "Mesa" style˜J˜JšΟc ™ Jš'™'Jš"™"Jš$™$Jš ™ Jš'™'J™0J™šΟk ˜ J˜Jšœžœ ˜Jšœ žœ˜ Jšœžœ˜'Jšœžœ!˜4Jšœ ˜Jšœ ˜Jšœ žœ˜Jšœ žœ˜"Jšœ žœ˜Jšœžœ ˜Jšœ žœ˜-Jšœ žœ˜)Jšœ ˜J˜—šœž œžœ8˜TJšœQ˜QJšžœ ˜Jšžœ˜ Jšœžœžœ˜J˜Jšœžœžœ ˜šœ žœž˜Jš œžœžœžœžœ˜3J˜J˜—Jšœžœžœ˜)J˜Jšœ žœžœ˜#Jšœžœžœžœ žœžœžœžœ˜AJš7™7Jš#™#Jš,™,J˜—šΟn œžœžœžœ˜5Jšœžœ-˜5Jšœžœ˜7J˜Jšžœ˜J˜J˜J˜—Jš`™`šŸ œžœžœ˜7šžœžœžœž˜!Jšœžœ˜Jšœžœ˜šžœž˜ Jšžœžœ˜%Jšžœ#žœ˜*Jšžœ#žœ˜*Jšžœ˜—Jšžœ˜J˜J˜——šœžœ˜(Jšœžœ ˜.Jšœžœ ˜"Jšžœžœžœ˜&J˜.Jšžœ žœ˜$šžœžœ˜"Jšžœžœ˜C—Jšžœ-žœ˜TJ˜/J˜J˜—˜(Jšœžœ ˜.Jšžœžœžœ˜&Jšœ.˜.J˜%J˜/J˜—J˜šŸœžœžœžœ˜-Jšž˜Jšœžœžœ˜Jšœ7žœ žœ˜NJ˜'šžœžœ˜J˜šžœ;žœ˜CJ˜&Jšžœžœ˜——Jšžœžœ˜Jšžœ˜J˜—šŸ œžœžœ˜*J˜5Jšžœ˜J˜—š Ÿœžœžœžœž œ˜;šžœž˜ JšœQžœžœ ˜fJšœ8žœžœ ˜MJšœFžœžœ ˜[—Jšžœ˜J˜Jšœžœ˜ J˜šœžœ˜Jšžœžœžœ˜B—Jšžœ!žœV˜}šžœ>žœž˜KJ˜Jšœžœ&˜FJ˜&Jš1™1Jš2™2J˜J˜Jšœ&žœ ˜;Jšžœ'˜,Jšžœ˜J˜——Jšœžœžœ˜J˜šœžœž˜1šžœžœž˜Jšœžœ ˜.J˜Jšœžœ˜Jšžœ˜—Jšžœ˜J˜—šŸœžœ˜Jšœžœ˜ Jšœžœ˜!Jšœžœžœ˜"J˜J˜Jšœ˜6J˜Jšœžœ+˜5JšœUžœ˜[J˜Jšœžœ0žœ˜AJšœUžœžœ˜gJ˜Jšœžœ1žœ˜BJšœ^žœžœ˜pJ˜šž˜Jšœ žœ˜)J˜%Jšžœžœžœ˜#Jšžœ)˜0Jšžœ(˜/Jšœžœ.žœ˜@JšœSžœ˜YJšžœ˜J˜—J˜J˜—J˜AJ˜Jšžœ˜J˜Jš˜™˜J˜J˜J˜—…—Κ