def fsSqueeze(self): """Squeeze the filesystem. Removes tentative files and consolidates unallocated blocks in single empty file at end of filesystem.""" oldFileList = self.fsFileList self.fsFileList = [] dataBlock = self.fsDataStart for de in oldFileList: if de.deStatus & deEPERM: de.deStart = dataBlock dataBlock += de.deLength self.fsFileList.append(de) remainingBlocks = (self.fsDataStart + self.fsDataBlocks) - dataBlock if remainingBlocks > 0: eb = dirEntry( name=rad50.filenameToRad50(" EMPTY.FIL"), length=remainingBlocks, start=dataBlock, status=deEMPTY, date=rt11util.todayWord(self.fsThisYear), ) eb.deEmptyData() self.fsFileList.append(eb) self.fsValidate()
def __init__( self, blocks=512, dirSegs=1, extraWords=0, resBlocks=0, sysVersion="V3A", volId="RT11A", ownerName="", sysId="DECRT11A", bootBlocks=["\000" * rt11util.rtBlockSize] * rtNumBootBlocks, thisYear=None, ): """fileSystem class constructor.""" self.fsSize = blocks self.fsResBlocks = resBlocks self.fsNumDirSegs = dirSegs self.fsExtraWords = extraWords self.fsDirEntSize = rtDirEntSize + self.fsExtraWords self.fsDirEntPerSeg = (rtDirSegSize - rtDirSegHdrSize) / self.fsDirEntSize self.fsSysVersion = rad50.ascToRad50(sysVersion)[0] self.fsVolumeId = volId.ljust(12) self.fsOwnerName = ownerName.ljust(12) self.fsSystemId = sysId.ljust(12) self.fsDataStart = self.fsFirstDirSeg + (self.fsNumDirSegs * 2) self.fsBootBlocks = bootBlocks self.fsThisYear = thisYear self.fsDataBlocks = self.fsSize - self.fsDataStart - self.fsResBlocks if len(self.fsVolumeId) > 12: self.fsVolumeId = self.fsVolumeId[0:12] if len(self.fsOwnerName) > 12: self.fsOwnerName = self.fsOwnerName[0:12] if len(self.fsSystemId) > 12: self.fsSystemId = self.fsSystemId[0:12] dirEnt = dirEntry( name=rad50.filenameToRad50(" EMPTY.FIL"), length=self.fsSize - (self.fsDataStart + self.fsResBlocks), start=self.fsDataStart, status=deEMPTY, date=rt11util.todayWord(self.fsThisYear), ) dirEnt.deEmptyData() self.fsFileList = [dirEnt] self.fsValidate()
def fsDeleteFile(self, filename): """Delete file with specified filename. First permanent file with matching name will be deleted. Not an error if file is not found. Adjacent empty files will be consolidated after deletion.""" fnRad50 = rad50.filenameToRad50(filename) for idx, de in enumerate(self.fsFileList): if fnRad50 == de.deName: de.deStatus = deEMPTY self.fsFileList[idx] = de self._fsConsolidateEmpty()
def fsSaveFile(self, rtFilename, hostFilename=""): """Save permanent file with specified name to host filesystem. If hostFilename is not specified, RT-11 filename will be used and file will be saved in current directory. If host filename is specified, it may include a relative or absolute path.""" r50Name = rad50.filenameToRad50(rtFilename) rtFilename = rad50.rad50ToFilename(r50Name) savedFile = False for de in self.fsFileList: if (de.deStatus & deEPERM) and (de.deName == r50Name): savedFile = True de.deSaveFile(hostFilename) break rt11util.assertWarn(savedFile, "Could not find file " + rtFilename)
def fsAddFile(self, hostFilename, rtFilename="", dateWord=None, statusWord=deEPERM): """Read file and add it to the RT-11 filesystem. hostFilename refers to a local file on the host's filesystem. If rtFilename is not specified, filename on RT-11 filesystem will be derived from hostFilename. If host file size is not a multiple of rtBlockSize, it will be padded with zeroes. Negative dateWord will be replaced with today's date.""" # Use host filename if RT-11 name not specified if rtFilename == "": rtFilename = hostFilename rad50Filename = rad50.filenameToRad50(rtFilename) rtFilename = rad50.rad50ToFilename(rad50Filename) if dateWord is None: dateWord = rt11util.todayWord(self.fsThisYear) # Read host file, pad if necessary f = open(hostFilename, "rb") buf = f.read() f.close pad = rt11util.rtBlockSize - (len(buf) % rt11util.rtBlockSize) if pad != 512: buf += "\000" * pad fileLen = len(buf) / rt11util.rtBlockSize # Delete existing file with same name self.fsDeleteFile(rtFilename) # Search for first empty block large enough to hold file addedFile = False for idx, de in enumerate(self.fsFileList): if (de.deStatus & deEMPTY) and (de.deLength >= fileLen): addedFile = True # If empty block is larger than new file, split it. if de.deLength > fileLen: ede = dirEntry( name=rad50.filenameToRad50(" EMPTY.FIL"), length=de.deLength - fileLen, start=de.deStart + fileLen, status=deEMPTY, date=rt11util.todayWord(self.fsThisYear), ) ede.deEmptyData() self.fsFileList.insert(idx + 1, ede) de.deStatus = statusWord de.deName = rad50Filename de.deLength = fileLen de.deJobChan = 0 de.deDate = dateWord de.deSetData(buf) self.fsFileList[idx] = de break rt11util.assertError(addedFile, "Could not find space for " + rtFilename)