-- File: FixBootFileDates.mesa, Last Edit: HGM, December 10, 1980 1:21 AM DIRECTORY Inline USING [LongDivMod], InlineDefs USING [BcplLongNumber, MesaToBcplLongNumber], Storage USING [String, FreeString], Time USING [Current], FormSW USING [ AllocateItemDescriptor, ClientItemsProcType, CommandItem, newLine, ProcType, StringItem], Tool USING [Create, MakeSWsProc, MakeFormSW], ToolWindow USING [TransitionProcType], UserTerminal USING [BlinkDisplay], Window USING [Handle], File USING [Capability, nullCapability], George, BootServerDefs USING [BootFileHeader]; FixBootFileDates: PROGRAM IMPORTS Inline, InlineDefs, Storage, Time, FormSW, Tool, UserTerminal, George = BEGIN filename: STRING ← NIL; form: Window.Handle; Init: PROCEDURE = BEGIN [] ← Tool.Create[ name: "BootFile Date Fixing Tool of December 9, 1980"L, makeSWsProc: MakeSWs, clientTransition: ClientTransition]; END; Smash: FormSW.ProcType = BEGIN old, temp, new: George.Handle ← NIL; buffer: PACKED ARRAY [0..512) OF [0..377B]; bfh: POINTER TO BootServerDefs.BootFileHeader = LOOPHOLE[@buffer]; creation: POINTER TO InlineDefs.BcplLongNumber = LOOPHOLE[@buffer + 10]; pages, bytes: CARDINAL; file, scratch: File.Capability ← George.NameToCapability[filename, 256]; IF file = File.nullCapability THEN BEGIN UserTerminal.BlinkDisplay[]; RETURN; END; old ← George.CreateInputStream[file]; scratch ← George.NameToCapability["FixBootFileDates$"L, 256]; [pages, bytes] ← Inline.LongDivMod[George.GetLength[old], 512]; George.SetIndex[old, 0]; -- Copy the whole file into a scratch file temp ← George.CreateOutputStream[scratch]; THROUGH [0..pages) DO IF George.GetWords[old, @buffer, 256] # 256 THEN ERROR; George.PutWords[temp, @buffer, 256]; ENDLOOP; IF George.GetWords[old, @buffer, bytes/2] # bytes/2 THEN ERROR; George.PutWords[temp, @buffer, bytes/2]; IF (bytes MOD 2) # 0 THEN George.PutByte[temp, George.GetByte[old]]; George.Destroy[old]; George.Destroy[temp]; -- Copy it back, and fixup the header temp ← George.CreateInputStream[scratch]; new ← George.CreateOutputStream[file]; IF George.GetWords[temp, @buffer, 256] # 256 THEN ERROR; IF creation↑ = [0, 0] THEN creation↑ ← bfh.timeStamp; bfh.timeStamp ← InlineDefs.MesaToBcplLongNumber[Time.Current[]]; George.PutWords[new, @buffer, 256]; -- Header or DiskBoot loader THROUGH [1..pages) DO IF George.GetWords[temp, @buffer, 256] # 256 THEN ERROR; George.PutWords[new, @buffer, 256]; ENDLOOP; IF George.GetWords[temp, @buffer, bytes/2] # bytes/2 THEN ERROR; George.PutWords[new, @buffer, bytes/2]; IF (bytes MOD 2) # 0 THEN George.PutByte[new, George.GetByte[temp]]; George.Destroy[temp]; George.Destroy[new]; END; MakeSWs: Tool.MakeSWsProc = BEGIN form ← Tool.MakeFormSW[window: window, formProc: MakeForm]; END; MakeForm: FormSW.ClientItemsProcType = BEGIN nParams: CARDINAL = 2; items ← FormSW.AllocateItemDescriptor[nParams]; items[0] ← FormSW.CommandItem[ tag: "Smash"L, proc: Smash, place: FormSW.newLine]; items[1] ← FormSW.StringItem[tag: "Filename"L, string: @filename]; RETURN[items, TRUE]; END; ClientTransition: ToolWindow.TransitionProcType = BEGIN SELECT TRUE FROM old = inactive => filename ← Storage.String[10*8]; new = inactive => Storage.FreeString[filename]; ENDCASE; END; Init[]; END.