// IfsScavDump.bcpl // Copyright Xerox Corporation 1979, 1980, 1981 // Last modified June 2, 1981 2:50 PM by Taft get "Streams.d" get "IfsFiles.decl" get "BTree.decl" external [ // outgoing procedures DumpLPT; DumpTree // incoming procedures GetLpteIfsName; GetLpteIfp; GetLpteDIFRec; GetLptFa OpenLPT; EnumerateLPT; CloseLPT; GetLptHome; GetLpteType OpenDisk; CloseDisk; Scratch; DirEntryLength OpenFile; Closes; Resets; Puts Ws; Wss; PutTemplate; ReadBlock; GetCurrentFa Allocate; CallSwat; TruePredicate; Zero OpenFPTree; CloseIFSTree; MapTree InitCmd; GetFile; Confirm UNPACKDT; WRITEUDT // incoming statics sysZone; scratchDisk ] static [ onlyDIFs; printTreeStructure; printFileIDs ] structure String [ length byte; char↑1,1 byte ] // These routines dump the contents of Scavenger.lpt and Ifs.dir. // They are mostly useful for debugging the scavenger, but may be // of use in getting an independant opinion on the contents of the // system directory. //---------------------------------------------------------------------------- let DumpLPT() be //---------------------------------------------------------------------------- [ if scratchDisk eq 0 then unless Scratch(nil) return let ok, list, lpt = true, 0, 0 if ok then [ lpt = OpenLPT("IfsScavenger.lpt", false) Resets(lpt) GetCurrentFa(lpt, GetLptFa(lpt)) ] if ok then [ let cs = InitCmd(100, 5); if cs ne 0 then [ Ws("*NWhat shall I call the output file on DP0? ") list = GetFile(cs, ksTypeWriteOnly, charItem) onlyDIFs = Confirm(cs, "*NDo you want just page usage info? ") printFileIDs = not onlyDIFs Puts(cs, $*N) Closes(cs) ] if cs eq 0 then ok = false ] if ok then [ PrintHome(list, GetLptHome(lpt)) EnumerateLPT(lpt, InterpretLPT, list) ] if lpt ne 0 then CloseLPT(lpt, false) if list ne 0 then Closes(list) ] //---------------------------------------------------------------------------- and InterpretLPT(lpt, lpte, list) be //---------------------------------------------------------------------------- if GetLpteType(lpte) eq dvTypeFile then unless onlyDIFs & GetLpteDIFRec(lpte) eq 0 do PrintInfo(list, GetLpteIfsName(lpte), GetLpteIfp(lpte), GetLpteDIFRec(lpte)) //---------------------------------------------------------------------------- and DumpTree() be //---------------------------------------------------------------------------- [ let ok, disk, tree, list = true, 0, 0, 0 disk = OpenDisk("*NWhich disk is it on? ") if disk eq 0 then ok = false if ok then [ let fp = vec lFP; Zero(fp, lFP) let ifsDir = OpenFile("Ifs.dir", ksTypeReadOnly, 0, 0, fp, 0, 0, 0, disk) test ifsDir ne 0 ifso Closes(ifsDir) ifnot [ Ws("*NI can't open *"Ifs.dir*"") ok = false ] if ok then tree = OpenFPTree(fp, disk, CallSwat, DirEntryLength, false) ] if ok then [ let cs = InitCmd(200, 5); if cs ne 0 then [ Ws("*NWhat shall I call the output file on DP0? ") list = GetFile(cs, ksTypeWriteOnly, charItem) onlyDIFs = Confirm(cs, "*NDo you want just page usage info? ") printTreeStructure = onlyDIFs? false, Confirm(cs,"*nShow the tree structure? ") printFileIDs = onlyDIFs? false, Confirm(cs,"*nShow the file IDs? ") Closes(cs) ] if cs eq 0 then ok = false ] if ok then [ let home = OpenFile("Ifs.home", ksTypeReadOnly, 0, 0, 0, 0, 0, 0, disk) test home eq 0 ifso [ Ws("*NI can't open *"Ifs.home*"") ok = false ] ifnot [ let h = vec lenHome test ReadBlock(home, h, lenHome) eq lenHome ifso PrintHome(list, h) ifnot [ Ws("*NMalformed home block") ok = false ] Closes(home) ] ] if ok then MapTree(tree, 0, InterpretTree, list, TruePredicate, true) if list ne 0 then Closes(list) if tree ne 0 then CloseIFSTree(tree) if disk ne 0 then CloseDisk(disk, true) ] //---------------------------------------------------------------------------- and InterpretTree(dr, list, pathStk) = valof //---------------------------------------------------------------------------- [ unless onlyDIFs & dr>>DR.type ne drTypeDIF do [ if printTreeStructure then [ let pse = lv pathStk>>PS.PSE↑(pathStk>>PS.PathStkTop) let indentString = selecton pathStk>>PS.PathStkTop into [ case 1: "" case 2: " " case 3: " " default: " " // never happens ] if pse>>PSE.Offset eq Rec1Offset then PutTemplate(list, "$S[Page $OB, $OB words free]*n", indentString, pse>>PSE.PageNo, (dr - offset BTE.Record/16 - Rec1Offset)>>BTP.FreeWords) Wss(list, indentString) ] PrintInfo(list, lv dr>>DR.pathName, lv dr>>DR.fp, (dr>>DR.type eq drTypeDIF? dr+dr>>DR.length-lenDIFRec, 0)) ] resultis true ] //---------------------------------------------------------------------------- and PrintHome(stream, home) be //---------------------------------------------------------------------------- [ PutTemplate(stream, "*NFile system name *"$S*", ID *"$S*"", lv home>>Home.name, lv home>>Home.id) PutTemplate(stream, "*Ntype $S, num units $D, created ", selecton home>>Home.type into [ case ifsTypePrimary: "primary" case ifsTypeBackup: "backup" default: "unknown" ], home>>Home.numUnits) let utv = vec 10 UNPACKDT(lv home>>Home.created, utv) WRITEUDT(stream, utv, true) Wss(stream, "*n*n") ] //---------------------------------------------------------------------------- and PrintInfo(stream, pathName, fp, difRec) be //---------------------------------------------------------------------------- // I recommend an 8pt fixed pitch font when listing this output [ test onlyDIFs ifnot Wss(stream, pathName) ifso for i = 2 to pathName>>String.length-3 do Puts(stream, pathName>>String.char↑i) if printFileIDs % onlyDIFs then [ let padding = onlyDIFs? 20,45 test pathName>>String.length gr padding ifso Wss(stream, " ") ifnot for i = pathName>>String.length to padding do Puts(stream, $*S) ] if printFileIDs then PutTemplate(stream, "$EUO;$UO, un $UO vda $UO", lv fp>>IFP.serialNumber, fp>>IFP.version, @lv fp>>IFP.unit, fp>>IFP.page) if difRec ne 0 then PutTemplate(stream, " $5EUD pages used out of $5EUD", lv difRec>>DIFRec.diskPageUsage, lv difRec>>DIFRec.diskPageLimit) Puts(stream, $*N) ]