1 # applesingle - a module to decode AppleSingle files
6 Error
="applesingle.Error"
10 # File header format: magic, version, unused, number of entries
11 AS_HEADER_FORMAT
="ll16sh"
13 # The flag words for AppleSingle
17 # Entry header format: id, offset, length
24 AS_IGNORE
=(3,4,5,6,8,9,10,11,12,13,14,15)
26 def decode(input, output
, resonly
=0):
27 if type(input) == type(''):
28 input = open(input, 'rb')
29 # Should we also test for FSSpecs or FSRefs?
30 header
= input.read(AS_HEADER_LENGTH
)
32 magic
, version
, dummy
, nentry
= struct
.unpack(AS_HEADER_FORMAT
, header
)
33 except ValueError, arg
:
34 raise Error
, "Unpack header error: %s"%arg
36 print 'Magic: 0x%8.8x'%magic
37 print 'Version: 0x%8.8x'%version
38 print 'Entries: %d'%nentry
40 raise Error
, 'Unknown AppleSingle magic number 0x%8.8x'%magic
41 if version
!= AS_VERSION
:
42 raise Error
, 'Unknown AppleSingle version number 0x%8.8x'%version
44 raise Error
, "AppleSingle file contains no forks"
45 headers
= [input.read(AS_ENTRY_LENGTH
) for i
in range(nentry
)]
49 id, offset
, length
= struct
.unpack(AS_ENTRY_FORMAT
, hdr
)
50 except ValueError, arg
:
51 raise Error
, "Unpack entry error: %s"%arg
53 print 'Fork %d, offset %d, length %d'%(id, offset
, length
)
58 data
= input.read(length
)
59 if len(data
) != length
:
60 raise Error
, 'Short read: expected %d bytes got %d'%(length
, len(data
))
66 fp
= open(output
, 'wb')
69 elif id == AS_RESOURCEFORK
:
72 print ' (resource fork)'
74 fp
= open(output
, 'wb')
76 fp
= MacOS
.openrf(output
, 'wb')
83 raise Error
, 'Unknown fork type %d'%id
85 raise Error
, 'No useful forks found'
88 if len(sys
.argv
) < 3 or sys
.argv
[1] == '-r' and len(sys
.argv
) != 4:
89 print 'Usage: applesingle.py [-r] applesinglefile decodedfile'
91 if sys
.argv
[1] == '-r':
96 decode(sys
.argv
[1], sys
.argv
[2], resonly
=resonly
)
98 if __name__
== '__main__':