mirror of
https://github.com/KrisKennaway/pyapple2disk.git
synced 2024-12-26 08:32:23 +00:00
Add some more file types
Fix some anomaly types Add anomalies for corrupted catalog metadata (pointing to out-of-bounds sector) Don't render the entire disk catalog in __str__, it's too verbose. Move it to a dedicated Catalog() method
This commit is contained in:
parent
67683829e4
commit
c57ee58def
@ -12,13 +12,18 @@ class FileType(object):
|
||||
self.long_type = long_type
|
||||
self.parser = parser
|
||||
|
||||
# TODO: add handlers for parsing the rest
|
||||
FILE_TYPES = {
|
||||
0x00: FileType('T', 'TEXT'),
|
||||
0x01: FileType('I', 'INTEGER BASIC'),
|
||||
# TODO: add handler for parsing file content
|
||||
0x02: FileType('A', 'APPLESOFT BASIC', applesoft.AppleSoft),
|
||||
0x04: FileType('B', 'BINARY'),
|
||||
# TODO: others
|
||||
# TODO: add anomalies for these
|
||||
0x08: FileType('S', 'Type S File'),
|
||||
0x10: FileType('R', 'Relocatable object module file'),
|
||||
0x20: FileType('a', 'Type a File'),
|
||||
0x40: FileType('b', 'Type b File'),
|
||||
# TODO: unknown file type
|
||||
}
|
||||
|
||||
class VTOCSector(disklib.Sector):
|
||||
@ -47,7 +52,7 @@ class VTOCSector(disklib.Sector):
|
||||
if tracks_per_disk != disklib.TRACKS_PER_DISK:
|
||||
self.anomalies.append(
|
||||
anomaly.Anomaly(
|
||||
self, anomaly.INTERESTING, 'Disk has %d tracks > %d' % (
|
||||
self, anomaly.UNUSUAL, 'Disk has %d tracks > %d' % (
|
||||
tracks_per_disk, disklib.TRACKS_PER_DISK)
|
||||
)
|
||||
)
|
||||
@ -58,7 +63,7 @@ class VTOCSector(disklib.Sector):
|
||||
if (catalog_track, catalog_sector) != (0x11, 0x0f):
|
||||
self.anomalies.append(
|
||||
anomaly.Anomaly(
|
||||
self, anomaly.INTERESTING, 'Catalog begins in unusual place: T$%02X S$%02X' % (
|
||||
self, anomaly.UNUSUAL, 'Catalog begins in unusual place: T$%02X S$%02X' % (
|
||||
catalog_track, catalog_sector)
|
||||
)
|
||||
)
|
||||
@ -82,7 +87,7 @@ class VTOCSector(disklib.Sector):
|
||||
self.anomalies.append(
|
||||
anomaly.Anomaly(
|
||||
self, anomaly.CORRUPTION,
|
||||
'Freemap claims free sector in track 0: T$%02X S$%02X (cannot be allocated in DOS ' +
|
||||
'Freemap claims free sector in track 0: T$%02X S$%02X (cannot be allocated in DOS '
|
||||
'3.3)' % (track, sector)
|
||||
)
|
||||
)
|
||||
@ -211,8 +216,9 @@ class Dos33Disk(disklib.Disk):
|
||||
# Maps stripped filename to File() object
|
||||
self.files = {}
|
||||
for catalog_entry in self.catalog.itervalues():
|
||||
newfile = self.ReadCatalogEntry(catalog_entry)
|
||||
# TODO: last character has special meaning for deleted files and may legitimately be whitespace. Could collide with a non-deleted file of the same stripped name
|
||||
self.files[catalog_entry.FileName().rstrip()] = self.ReadCatalogEntry(catalog_entry)
|
||||
self.files[catalog_entry.FileName().rstrip()] = newfile
|
||||
|
||||
def _ReadVTOC(self):
|
||||
return VTOCSector.fromSector(self.ReadSector(0x11, 0x0))
|
||||
@ -254,19 +260,26 @@ class Dos33Disk(disklib.Disk):
|
||||
# TODO: add sector type for this. What to do about sectors claimed by this file that are in use by another file? May discover this before or after this entry
|
||||
print "Found deleted file %s" % entry.FileName()
|
||||
break
|
||||
fs = FileMetadataSector.fromSector(self.ReadSector(next_track, next_sector), entry.FileName())
|
||||
(next_track, next_sector) = (fs.next_track, fs.next_sector)
|
||||
|
||||
num_sectors = len(fs.data_track_sectors)
|
||||
sector_list[fs.sector_offset:fs.sector_offset+num_sectors] = fs.data_track_sectors
|
||||
try:
|
||||
fs = FileMetadataSector.fromSector(self.ReadSector(next_track, next_sector), entry.FileName())
|
||||
(next_track, next_sector) = (fs.next_track, fs.next_sector)
|
||||
num_sectors = len(fs.data_track_sectors)
|
||||
sector_list[fs.sector_offset:fs.sector_offset + num_sectors] = fs.data_track_sectors
|
||||
except disklib.IOError, e:
|
||||
# TODO: add a flag indicating truncated file?
|
||||
self.anomalies.append(
|
||||
anomaly.Anomaly(
|
||||
self, anomaly.CORRUPTION, 'File metadata sector out of bounds for file %s: %s' % (
|
||||
entry.FileName(), e)
|
||||
)
|
||||
)
|
||||
(next_track, next_sector) = (None, None)
|
||||
|
||||
# TODO: Assert we didn't have any holes. Or is this fine e.g. for a sparse text file?
|
||||
|
||||
#print track_sector_count
|
||||
# We allocated space up-front for an unknown number of t/s list sectors, trim them from the end
|
||||
sector_list = sector_list[:entry.length - track_sector_count]
|
||||
|
||||
#print sector_list
|
||||
contents = bitstring.BitString()
|
||||
for ts in sector_list:
|
||||
if not ts:
|
||||
@ -276,7 +289,12 @@ class Dos33Disk(disklib.Disk):
|
||||
try:
|
||||
fds = FileDataSector.fromSector(self.ReadSector(t, s), entry.FileName())
|
||||
except disklib.IOError, e:
|
||||
print "%s: Failed to read File data sector: %s" % (entry, e)
|
||||
self.anomalies.append(
|
||||
anomaly.Anomaly(
|
||||
self, anomaly.CORRUPTION, 'File data sector out of bounds for file %s: %s' % (
|
||||
entry.FileName(), e)
|
||||
)
|
||||
)
|
||||
continue
|
||||
contents.append(fds.data)
|
||||
|
||||
@ -284,7 +302,7 @@ class Dos33Disk(disklib.Disk):
|
||||
self.AddChild(newfile)
|
||||
return newfile
|
||||
|
||||
def __str__(self):
|
||||
def Catalog(self):
|
||||
catalog = ['DISK VOLUME %d\n' % self.volume]
|
||||
for filename in self.filenames:
|
||||
entry = self.catalog[filename]
|
||||
@ -298,6 +316,9 @@ class Dos33Disk(disklib.Disk):
|
||||
)
|
||||
return '\n'.join(catalog)
|
||||
|
||||
def __str__(self):
|
||||
return '%s (DOS 3.3 disk)' % (self.name)
|
||||
|
||||
|
||||
class CatalogEntry(container.Container):
|
||||
def __init__(self, track, sector, file_type, file_name, length):
|
||||
|
@ -43,13 +43,13 @@ def main():
|
||||
print data
|
||||
|
||||
|
||||
# Group disks by hash of RWTS sector
|
||||
rwts_hashes = {}
|
||||
# Group disks by hash of boot1 sector
|
||||
boot1_hashes = {}
|
||||
for f, d in disks.iteritems():
|
||||
rwts_hash = d.rwts.hash
|
||||
rwts_hashes.setdefault(rwts_hash, []).append(f)
|
||||
boot1_hash = d.Boot1.hash
|
||||
boot1_hashes.setdefault(boot1_hash, []).append(f)
|
||||
|
||||
for h, disks in rwts_hashes.iteritems():
|
||||
for h, disks in boot1_hashes.iteritems():
|
||||
print h
|
||||
for d in sorted(disks):
|
||||
print " %s" % d
|
||||
|
Loading…
Reference in New Issue
Block a user