def fsLoadBootBlocks(self, hostFilename): """Load the boot blocks from the specified file.""" f = open(hostFilename, "rb") for n in range(rtNumBootBlocks): self.fsBootBlocks[n] = rt11util.readBlocks(f) f.close()
def _fsReadHomeBlock(self, f): """Parse the home block (block 1)""" if self.fsVerbose: print "_fsReadHomeBlock():" blk = rt11util.readBlocks(f, 1, 1) # TO DO: Block replacement table, etc. self.fsPackClustSize = rt11util.rtWord(blk, 0722) self.fsFirstDirSeg = rt11util.rtWord(blk, 0724) self.fsSysVersion = rt11util.rtWord(blk, 0726) self.fsVolumeId = blk[0730:0744] self.fsOwnerName = blk[0744:0760] self.fsSystemId = blk[0760:0774] self.fsFileList = [] self.fsDataBlocks = 0 if (self.fsFirstDirSeg == 0x0000) or (self.fsFirstDirSeg == 0x2020): # Have seen VAX-11/730 console tapes with spaces or zeros in place of # fsPackClustSize, fsFirstDirSeg and fsSysVersion. # So if first dir segment is 0x2020, assume this is such an image # and assume a hopefully sane default. self.fsFirstDirSeg = 6 if self.fsVerbose: print " Overriding bogus fsFirstDirSeg value" if self.fsVerbose: print " fsPackClustSize =", self.fsPackClustSize print " fsFirstDirSeg =", self.fsFirstDirSeg print " fsSysVersion =", self.fsSysVersion print " fsVolumeId =", self.fsVolumeId print " fsOwnerName =", self.fsOwnerName print " fsSystemId =", self.fsSystemId
def _fsReadDataBlocks(self, f): """Read the data blocks from the filesystem.""" for entry in self.fsFileList: entry.deSetData(rt11util.readBlocks(f, entry.deStart, entry.deLength))
def _fsReadDirSegs(self, f): """Parse the directory segments. Directory segments are 2 blocks long, start at block number fsFirstDirSeg, and are numbered 1 through 31. We ignore garbage in unused directory segments.""" if self.fsVerbose: print "_fsReadDirSegs():" dsNum = 1 while dsNum > 0: # Read directory segment, convert to 16-bit words bnum = self.fsFirstDirSeg + ((dsNum - 1) * 2) if self.fsVerbose: print " blocks {:d},{:d}".format(bnum, bnum + 1) blk = rt11util.readBlocks(f, bnum, 2) wblk = rt11util.bytesToWords(blk) # Extract fields from directory segment header numDs, nextDs, highDs, xBytes, dStart = wblk[:rtDirSegHdrSize] if self.fsVerbose: print " numDs =", numDs print " nextDs =", nextDs print " highDs =", highDs print " xBytes =", xBytes print " dStart =", dStart rt11util.assertError((xBytes % 2) == 0, "Extra bytes count must be even.") if dsNum == 1: # Initialize stuff from first dir segment header self.fsNumDirSegs = numDs self.fsExtraWords = xBytes / 2 self.fsDirEntSize = rtDirEntSize + self.fsExtraWords self.fsDirEntPerSeg = (rtDirSegSize - rtDirSegHdrSize) / self.fsDirEntSize self.fsDataStart = dStart else: # Sanity checks # Each segment should have matching number of dir segs count in header rt11util.assertWarn( numDs == self.fsNumDirSegs, "Number of directory segments changed in segment " + str(dsNum) ) # Each segment should have matching extra byte count in header rt11util.assertWarn( xBytes / 2 == self.fsExtraWords, "Number of extra entry bytes changed in segment " + str(dsNum) ) # Dir segments should point to contiguous sets of data blocks rt11util.assertWarn(dStart == dsDataBlock, "Non-contiguous data in directory segment " + str(dsNum)) # Unpack remainder of directory segment into list of # directory entry tuples. # This line is so ugly, it ought to be in Perl. # Don't ask me how it works; I barely understood it when I wrote it. dsEntries = zip(*[iter(wblk[rtDirSegHdrSize:])] * self.fsDirEntSize) dsDataBlock = dStart for dsEntry in dsEntries: statWord, fn1, fn2, ext, fileLen, jobChan, fileDate = dsEntry[:7] if statWord & deEEOS: # End of this directory segment break entry = dirEntry( name=[fn1, fn2, ext], length=fileLen, start=dsDataBlock, status=statWord, jobchan=jobChan, date=fileDate, extra=rt11util.wordsToBytes(dsEntry[7:]), ) self.fsFileList.append(entry) self.fsDataBlocks += fileLen dsDataBlock = dsDataBlock + fileLen if nextDs > 0: rt11util.assertWarn(nextDs == dsNum + 1, "Non-sequential directory segments.") dsNum = nextDs
def _fsReadBootBlocks(self, f): """Load the boot blocks""" self.fsBootBlocks = [] for n in [0] + range(2, rtNumBootBlocks + 1): self.fsBootBlocks.append(rt11util.readBlocks(f, n, 1))