// CopyDiskCmd.bcpl // Copyright Xerox Corporation 1979, 1980, 1981, 1982 // Last modified July 21, 1982 7:04 PM by Boggs get "AltoDefs.d" get "CopyDisk.decl" external [ // outgoing procedures InitCopyDiskCmd; GetNamePass // incoming procedures from OS and packages Block; Dismiss; InitializeContext; SetTimer; TimerHasExpired Allocate; Free; Min; ReturnFrom; CallersFrame MoveBlock; Zero; DefaultArgs; Enqueue Endofs; Puts; Resets; Gets; PutTemplate ExtractSubstring; StringCompare; CopyString CreateKeywordTable; InsertKeyword EnumerateKeywordTable; LookupKeyword // incoming procedures from other parts of CopyDisk GetNumber; GetString; Confirm Wss; MakeSS; DoIt; Ding // outgoing statics connName; connPass; userName; userPass // incoming statics bootFlag; checkFlag; debugFlag; compressFlag ctxQ; CtxRunning; sysZone; writeProtectFlag keys; dsp; comCm; compareErrors; seriousErrors UserName; UserPassword; controlLock ] static [ connName; connPass; userName; userPass kbdKT ] structure String [ length byte; char↑1,1 byte ] //---------------------------------------------------------------------------- let InitCopyDiskCmd() be //---------------------------------------------------------------------------- [ Enqueue(ctxQ, InitializeContext(Allocate(sysZone, 400), 400, Command)) kbdKT = CreateKeywordTable(11, 1) InsertKeyword(kbdKT, "Check")!0 = KbdCheck InsertKeyword(kbdKT, "Compare")!0 = KbdCompare InsertKeyword(kbdKT, "Compress")!0 = KbdCompress InsertKeyword(kbdKT, "Connect")!0 = KbdConnect InsertKeyword(kbdKT, "Copy")!0 = KbdCopy InsertKeyword(kbdKT, "Debug")!0 = KbdDebug InsertKeyword(kbdKT, "Help")!0 = KbdHelp InsertKeyword(kbdKT, "Login")!0 = KbdLogin if (table [ 61014b; 1401b ])()<<VERS.eng gr 3 then InsertKeyword(kbdKT, "Partition")!0 = KbdPartition InsertKeyword(kbdKT, "Quit")!0 = KbdQuit InsertKeyword(kbdKT, "WriteProtect")!0 = KbdWriteProtect if UserName>>String.length ne 0 then userName = ExtractSubstring(UserName) if UserPassword>>String.length ne 0 then userPass = ExtractSubstring(UserPassword) ] //---------------------------------------------------------------------------- and Command() be //a context //---------------------------------------------------------------------------- [ // ignore subsys name and global switches let temp = ReadParam(true); if temp ne 0 then Free(sysZone,temp) let srcDisk = ReadParam(true) if srcDisk then Cli(srcDisk) // may return... controlLock = idle Kbd() // never returns ] //---------------------------------------------------------------------------- and Cli(srcDisk) = valof //---------------------------------------------------------------------------- // CmdError forces a return from this frame back to Command which calls Kbd. [ controlLock = user PutTemplate(dsp, "*N**Copy $S ", srcDisk) let fromOK = StringCompare(srcDisk, "from") if fromOK eq 0 % fromOK eq -2 then [ Free(sysZone, srcDisk); srcDisk = ReadParam() ] let src = MakeSS(srcDisk, false) Free(sysZone, srcDisk) if src eq 0 then CmdError() let snkDisk = ReadParam() let toOK = StringCompare(snkDisk, "to") if toOK eq 0 % toOK eq -2 then [ Free(sysZone, snkDisk); snkDisk = ReadParam() ] let snk = MakeSS(snkDisk, true) Free(sysZone, snkDisk) if snk eq 0 then CmdError(src) let tp = Compatible(src, snk); if tp eq 0 then CmdError(src, snk) unless AreYouSure(src, snk) do CmdError(src, snk, tp) if DoIt(src, snk, true, tp) then if checkFlag then DoIt(src, snk, false, tp) PrintErrors(src, snk) Free(sysZone, tp) (snk>>SS.destroy)(snk) (src>>SS.destroy)(src) finish ] //---------------------------------------------------------------------------- and CmdError(src, snk, tp; numargs na) be //---------------------------------------------------------------------------- [ if na gr 0 & src then (src>>SS.destroy)(src) if na gr 1 & snk then (snk>>SS.destroy)(snk) if na gr 2 & tp then Free(sysZone, tp) ReturnFrom(CallersFrame()) ] //---------------------------------------------------------------------------- and ReadParam(dontEcho; numargs na) = valof //---------------------------------------------------------------------------- [ if comCm eq 0 resultis 0 if na eq 0 then dontEcho = false let string = vec 127 let char = 0 string>>String.length = 0 [ //name if Endofs(comCm) break char = Gets(comCm); unless dontEcho do Puts(dsp, char) if string>>String.length eq 0 & char eq $*S loop if char eq $*N % char eq $*S % char eq $/ break string>>String.length = string>>String.length +1 string>>String.char↑(string>>String.length) = char ] repeat let resString = string>>String.length ne 0 ? ExtractSubstring(string), 0 string>>String.length = 0 if char eq $/ then [ //switches if Endofs(comCm) break char = Gets(comCm); unless dontEcho do Puts(dsp, char) if char eq $*N % char eq $*S break if char ne $/ then [ string>>String.length = string>>String.length +1 string>>String.char↑(string>>String.length) = char ] ] repeat // switches are currently ignored (global switches are read elsewhere) resultis resString ] //---------------------------------------------------------------------------- and Kbd() be //---------------------------------------------------------------------------- [ while controlLock eq server do [ //ignore type-in unless Endofs(keys) do [ Ding(dsp); Resets(keys) ] Dismiss(10) ] Wss(dsp, "*N**") Block() repeatwhile Endofs(keys) & controlLock eq 0 if controlLock eq 0 then [ controlLock = user let key = 0 [ key = GetString(0, key, editEcho+editAppend, CmdList) if key eq 0 break let tableKey = nil let kte = LookupKeyword(kbdKT, key, lv tableKey) test kte eq 0 ifso Ding(dsp) ifnot [ for i = key>>String.length+1 to tableKey>>String.length do Puts(dsp, tableKey>>String.char↑i) Free(sysZone, key) (kte!0)() //execute command break ] ] repeat controlLock = idle ] ] repeat //---------------------------------------------------------------------------- and CmdList() be //---------------------------------------------------------------------------- [ Wss(dsp, "? one of the following:*N") let count = 0 EnumerateKeywordTable(kbdKT, PrintCmd, lv count) Wss(dsp, "*N**") ] //---------------------------------------------------------------------------- and PrintCmd(kte, kt, key, lvCount) be //---------------------------------------------------------------------------- [ unless @lvCount eq 0 do Wss(dsp, ", ") Wss(dsp, key) test @lvCount eq 5 ifso [ @lvCount = 0; Puts(dsp, $*N) ] ifnot @lvCount = @lvCount +1 ] //---------------------------------------------------------------------------- and KbdQuit() be finish //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- and KbdDebug() be //---------------------------------------------------------------------------- [ debugFlag = not debugFlag PutTemplate(dsp, "ging printout $S", (debugFlag? "ON", "OFF")) ] //---------------------------------------------------------------------------- and KbdCheck() be //---------------------------------------------------------------------------- [ checkFlag = not checkFlag test checkFlag ifso Wss(dsp, "ing ON - compare after copying") ifnot Wss(dsp, "ing OFF - all bets are off") ] //---------------------------------------------------------------------------- and KbdWriteProtect() be //---------------------------------------------------------------------------- [ writeProtectFlag = not writeProtectFlag test writeProtectFlag ifso Wss(dsp, "ion ON - remote CopyDisks can't overwrite local disks") ifnot Wss(dsp, "ion OFF - remote CopyDisks can overwrite local disks") ] //---------------------------------------------------------------------------- and KbdCompress() be //---------------------------------------------------------------------------- [ compressFlag = not compressFlag test compressFlag ifso Wss(dsp, "ion ON - free pages not transmitted or compared") ifnot Wss(dsp, "ion OFF - perform bit-for-bit copies and compares") ] //---------------------------------------------------------------------------- and KbdHelp() be //---------------------------------------------------------------------------- [ Wss(dsp, "*NI copy disk packs -- either between two disk drives on the local") Wss(dsp, "*N machine, or between a local disk and a remote disk. The remote") Wss(dsp, "*N disk may even be an Interim File System.*N") Wss(dsp, "*NThe syntax of disk names is: [HostName]DiskName. 'HostName' may") Wss(dsp, "*N be e.g. 'Ivy' or '3#17#', and may be omitted for a local disk.") Wss(dsp, "*N 'DiskName' is e.g. 'BFS', 'DP0', or '<BasicDisks>NonProg.bfs'.") ] //---------------------------------------------------------------------------- and KbdLogin() be //---------------------------------------------------------------------------- [ GetNamePass(" user: ", lv userName, lv userPass) if userName>>String.length ne 0 then MoveBlock(UserName, userName, Min(userName>>String.length/2+1, UserName!-1)) if userPass>>String.length ne 0 then MoveBlock(UserPassword, userPass, Min(userPass>>String.length/2+1, UserPassword!-1)) ] //---------------------------------------------------------------------------- and KbdConnect() be //---------------------------------------------------------------------------- GetNamePass(" to directory: ", lv connName, lv connPass) //---------------------------------------------------------------------------- and GetNamePass(prompt, lvName, lvPass) = valof //---------------------------------------------------------------------------- [ @lvName = GetString(prompt, @lvName, editEcho+editReplace) if @lvName ne 0 then [ @lvPass = GetString(" password: ", @lvPass, editReplace) resultis @lvPass ] resultis false ] //---------------------------------------------------------------------------- and KbdPartition() be //---------------------------------------------------------------------------- [ let currentPartition = (table [ 61037b; 1401b ])(0) let newPartition = GetNumber(" number: ", currentPartition) let result = (table [ 61037b; 1401b ])(newPartition) if result eq -1 & newPartition ne currentPartition then bootFlag = true ] //---------------------------------------------------------------------------- and KbdCopy() be KbdDoIt(true) //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- and KbdCompare() be KbdDoIt(false) //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- and KbdDoIt(copyFlag) be //---------------------------------------------------------------------------- // CmdError forces a return from this frame back to Kbd. [ let srcDisk = GetString(copyFlag? " from ", " ") if srcDisk eq 0 then CmdError() let src = MakeSS(srcDisk, false) Free(sysZone, srcDisk) if src eq 0 then CmdError() let snkDisk = GetString(copyFlag? "*N Copy to ", "*NAgainst ") if snkDisk eq 0 then CmdError(src) let snk = MakeSS(snkDisk, copyFlag) Free(sysZone, snkDisk) if snk eq 0 then CmdError(src) let tp = Compatible(src, snk); if tp eq 0 then CmdError(src, snk) if copyFlag unless AreYouSure(src, snk) do CmdError(src, snk, tp) let ok = copyFlag? DoIt(src, snk, true, tp), true if ok & (not copyFlag % checkFlag) then DoIt(src, snk, false, tp) PrintErrors(src, snk) Free(sysZone, tp) (src>>SS.destroy)(src) (snk>>SS.destroy)(snk) ] //---------------------------------------------------------------------------- and AreYouSure(src, snk) = valof //---------------------------------------------------------------------------- [ if snk>>SS.type eq ssNetLog resultis true PutTemplate(dsp, "*N*NCopying onto $S will destroy its old contents.", snk>>SS.device) let ok = Confirm("*NAre you sure this is what you want to do?") if ok then [ Dismiss(500) //5 sec Resets(keys) ok = Confirm("*N*NAre you still sure?") ] resultis ok ] //---------------------------------------------------------------------------- and Compatible(src, snk) = valof //---------------------------------------------------------------------------- // returns xferParams or 0 [ let srcType = src>>SS.dp>>CD.diskParams.diskType let snkType = snk>>SS.dp>>CD.diskParams.diskType if srcType ne 0 & snkType ne 0 & srcType ne snkType then [ Wss(dsp, "*NDisk types are incompatible"); resultis 0 ] let xferParams = src>>SS.compatible(src, snk) Free(sysZone, snk>>SS.dp) snk>>SS.dp = Allocate(sysZone, src>>SS.dp>>CD.length) MoveBlock(snk>>SS.dp, src>>SS.dp, src>>SS.dp>>CD.length) resultis xferParams ] //---------------------------------------------------------------------------- and PrintErrors(src, snk) be //---------------------------------------------------------------------------- [ if compareErrors then PutTemplate(dsp, "*N$UD Data compare errors", compareErrors) Wss(dsp, "*NDone. ") test seriousErrors % compareErrors ifso PutTemplate(dsp, "But DO NOT trust $S.", snk>>SS.device) ifnot PutTemplate(dsp, "$S and $S are identical.", src>>SS.device, snk>>SS.device) ]