mirror of
https://github.com/elliotnunn/machfs.git
synced 2024-09-27 17:56:08 +00:00
Throw clear out-of-space and bad-name exceptions
This commit is contained in:
parent
48e04be236
commit
cd433459d0
@ -35,5 +35,4 @@ def chunkify(b, blksize):
|
|||||||
|
|
||||||
|
|
||||||
def pstring(orig):
|
def pstring(orig):
|
||||||
macroman = orig.encode('mac_roman')
|
return bytes([len(orig)]) + orig
|
||||||
return bytes([len(macroman)]) + macroman
|
|
||||||
|
@ -15,9 +15,6 @@ class AbstractFolder(collections.MutableMapping):
|
|||||||
|
|
||||||
key.encode('mac_roman')
|
key.encode('mac_roman')
|
||||||
|
|
||||||
if not (1 <= len(key) <= 31):
|
|
||||||
raise ValueError('%r: Filename range 1-31 chars' % key)
|
|
||||||
|
|
||||||
lower = key.lower()
|
lower = key.lower()
|
||||||
self._prefdict[lower] = key
|
self._prefdict[lower] = key
|
||||||
self._maindict[lower] = value
|
self._maindict[lower] = value
|
||||||
|
@ -78,12 +78,36 @@ def _get_every_extent(nblocks, firstrecord, cnid, xoflow, fork):
|
|||||||
return extlist
|
return extlist
|
||||||
|
|
||||||
|
|
||||||
|
def _encode_name(name, is_vol_name=False):
|
||||||
|
longest = 27 if is_vol_name else 31
|
||||||
|
|
||||||
|
try:
|
||||||
|
encoded = name.encode('mac_roman')
|
||||||
|
except UnicodeEncodeError:
|
||||||
|
raise BadNameError(name)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not 1 <= len(encoded) <= longest or b':' in encoded:
|
||||||
|
raise BadNameError(name)
|
||||||
|
|
||||||
|
return encoded
|
||||||
|
|
||||||
|
|
||||||
class _TempWrapper:
|
class _TempWrapper:
|
||||||
"""Volume uses this to store metadata while serialising"""
|
"""Volume uses this to store metadata while serialising"""
|
||||||
def __init__(self, of):
|
def __init__(self, of):
|
||||||
self.of = of
|
self.of = of
|
||||||
|
|
||||||
|
|
||||||
|
class OutOfSpaceError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class BadNameError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Folder(directory.AbstractFolder):
|
class Folder(directory.AbstractFolder):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@ -226,6 +250,8 @@ class Volume(directory.AbstractFolder):
|
|||||||
if size < 400 * 1024 or size % 512:
|
if size < 400 * 1024 or size % 512:
|
||||||
raise ValueError('size must be a multiple of 512b and >= 800K')
|
raise ValueError('size must be a multiple of 512b and >= 800K')
|
||||||
|
|
||||||
|
drVN = _encode_name(self.name, is_vol_name=True)
|
||||||
|
|
||||||
# overall layout:
|
# overall layout:
|
||||||
# 1. two boot blocks (offset=0)
|
# 1. two boot blocks (offset=0)
|
||||||
# 2. one volume control block (offset=2)
|
# 2. one volume control block (offset=2)
|
||||||
@ -252,12 +278,17 @@ class Volume(directory.AbstractFolder):
|
|||||||
drNmAlBlks = (size - (5+bitmap_blk_cnt)*512) // drAlBlkSiz
|
drNmAlBlks = (size - (5+bitmap_blk_cnt)*512) // drAlBlkSiz
|
||||||
blkaccum = []
|
blkaccum = []
|
||||||
|
|
||||||
|
def accumulate(x):
|
||||||
|
blkaccum.extend(x)
|
||||||
|
if len(blkaccum) > drNmAlBlks:
|
||||||
|
raise OutOfSpaceError
|
||||||
|
|
||||||
# <<< put the empty extents overflow file in here >>>
|
# <<< put the empty extents overflow file in here >>>
|
||||||
extoflowfile = btree.make_btree([], bthKeyLen=7, blksize=drAlBlkSiz)
|
extoflowfile = btree.make_btree([], bthKeyLen=7, blksize=drAlBlkSiz)
|
||||||
# also need to do some cleverness to ensure that this gets picked up...
|
# also need to do some cleverness to ensure that this gets picked up...
|
||||||
drXTFlSize = len(extoflowfile)
|
drXTFlSize = len(extoflowfile)
|
||||||
drXTExtRec_Start = len(blkaccum)
|
drXTExtRec_Start = len(blkaccum)
|
||||||
blkaccum.extend(bitmanip.chunkify(extoflowfile, drAlBlkSiz))
|
accumulate(bitmanip.chunkify(extoflowfile, drAlBlkSiz))
|
||||||
drXTExtRec_Cnt = len(blkaccum) - drXTExtRec_Start
|
drXTExtRec_Cnt = len(blkaccum) - drXTExtRec_Start
|
||||||
|
|
||||||
# write all the files in the volume
|
# write all the files in the volume
|
||||||
@ -300,11 +331,11 @@ class Volume(directory.AbstractFolder):
|
|||||||
wrap.dfrk = wrap.rfrk = (0, 0)
|
wrap.dfrk = wrap.rfrk = (0, 0)
|
||||||
if obj.data:
|
if obj.data:
|
||||||
pre = len(blkaccum)
|
pre = len(blkaccum)
|
||||||
blkaccum.extend(bitmanip.chunkify(obj.data, drAlBlkSiz))
|
accumulate(bitmanip.chunkify(obj.data, drAlBlkSiz))
|
||||||
wrap.dfrk = (pre, len(blkaccum)-pre)
|
wrap.dfrk = (pre, len(blkaccum)-pre)
|
||||||
if obj.rsrc:
|
if obj.rsrc:
|
||||||
pre = len(blkaccum)
|
pre = len(blkaccum)
|
||||||
blkaccum.extend(bitmanip.chunkify(obj.rsrc, drAlBlkSiz))
|
accumulate(bitmanip.chunkify(obj.rsrc, drAlBlkSiz))
|
||||||
wrap.rfrk = (pre, len(blkaccum)-pre)
|
wrap.rfrk = (pre, len(blkaccum)-pre)
|
||||||
|
|
||||||
self._prefdict = root_dict_backup
|
self._prefdict = root_dict_backup
|
||||||
@ -318,7 +349,7 @@ class Volume(directory.AbstractFolder):
|
|||||||
if wrap.cnid == 1: continue
|
if wrap.cnid == 1: continue
|
||||||
|
|
||||||
obj = wrap.of
|
obj = wrap.of
|
||||||
pstrname = bitmanip.pstring(path[-1])
|
pstrname = bitmanip.pstring(_encode_name(path[-1]))
|
||||||
|
|
||||||
mainrec_key = struct.pack('>L', path2wrap[path[:-1]].cnid) + pstrname
|
mainrec_key = struct.pack('>L', path2wrap[path[:-1]].cnid) + pstrname
|
||||||
|
|
||||||
@ -379,7 +410,7 @@ class Volume(directory.AbstractFolder):
|
|||||||
# also need to do some cleverness to ensure that this gets picked up...
|
# also need to do some cleverness to ensure that this gets picked up...
|
||||||
drCTFlSize = len(catalogfile)
|
drCTFlSize = len(catalogfile)
|
||||||
drCTExtRec_Start = len(blkaccum)
|
drCTExtRec_Start = len(blkaccum)
|
||||||
blkaccum.extend(bitmanip.chunkify(catalogfile, drAlBlkSiz))
|
accumulate(bitmanip.chunkify(catalogfile, drAlBlkSiz))
|
||||||
drCTExtRec_Cnt = len(blkaccum) - drCTExtRec_Start
|
drCTExtRec_Cnt = len(blkaccum) - drCTExtRec_Start
|
||||||
|
|
||||||
if len(blkaccum) > drNmAlBlks:
|
if len(blkaccum) > drNmAlBlks:
|
||||||
@ -400,15 +431,11 @@ class Volume(directory.AbstractFolder):
|
|||||||
drWrCnt = 0 # ????volume write count
|
drWrCnt = 0 # ????volume write count
|
||||||
drVCSize = drVBMCSize = drCtlCSize = 0
|
drVCSize = drVBMCSize = drCtlCSize = 0
|
||||||
drAtrb = 1<<8 # volume attributes (hwlock, swlock, CLEANUNMOUNT, badblocks)
|
drAtrb = 1<<8 # volume attributes (hwlock, swlock, CLEANUNMOUNT, badblocks)
|
||||||
drVN = self.name.encode('mac_roman')
|
|
||||||
drVolBkUp = 0 # date and time of last backup
|
drVolBkUp = 0 # date and time of last backup
|
||||||
drVSeqNum = 0 # volume backup sequence number
|
drVSeqNum = 0 # volume backup sequence number
|
||||||
drFndrInfo = bytes(32) # information used by the Finder
|
drFndrInfo = bytes(32) # information used by the Finder
|
||||||
drCrDate, drLsMod, drVolBkUp = self.crdate, self.mddate, self.bkdate
|
drCrDate, drLsMod, drVolBkUp = self.crdate, self.mddate, self.bkdate
|
||||||
|
|
||||||
if not (1 <= len(drVN) <= 27):
|
|
||||||
raise ValueError('Volume name range 1-27 chars')
|
|
||||||
|
|
||||||
vib = struct.pack('>2sLLHHHHHLLHLH28pLHLLLHLL32sHHHLHHxxxxxxxxLHHxxxxxxxx',
|
vib = struct.pack('>2sLLHHHHHLLHLH28pLHLLLHLL32sHHHLHHxxxxxxxxLHHxxxxxxxx',
|
||||||
drSigWord, drCrDate, drLsMod, drAtrb, drNmFls,
|
drSigWord, drCrDate, drLsMod, drAtrb, drNmFls,
|
||||||
drVBMSt, drAllocPtr, drNmAlBlks, drAlBlkSiz, drClpSiz, drAlBlSt,
|
drVBMSt, drAllocPtr, drNmAlBlks, drAlBlkSiz, drClpSiz, drAlBlSt,
|
||||||
|
Loading…
Reference in New Issue
Block a user