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
)
33 magic
, version
, dummy
, nentry
= struct
.unpack(AS_HEADER_FORMAT
, header
)
34 except ValueError, arg
:
35 raise Error
, "Unpack header error: %s"%arg
37 print 'Magic: 0x%8.8x'%magic
38 print 'Version: 0x%8.8x'%version
39 print 'Entries: %d'%nentry
41 raise Error
, 'Unknown AppleSingle magic number 0x%8.8x'%magic
42 if version
!= AS_VERSION
:
43 raise Error
, 'Unknown AppleSingle version number 0x%8.8x'%version
45 raise Error
, "AppleSingle file contains no forks"
46 headers
= [input.read(AS_ENTRY_LENGTH
) for i
in range(nentry
)]
50 id, offset
, length
= struct
.unpack(AS_ENTRY_FORMAT
, hdr
)
51 except ValueError, arg
:
52 raise Error
, "Unpack entry error: %s"%arg
54 print 'Fork %d, offset %d, length %d'%(id, offset
, length
)
59 data
= input.read(length
)
60 if len(data
) != length
:
61 raise Error
, 'Short read: expected %d bytes got %d'%(length
, len(data
))
67 fp
= open(output
, 'wb')
70 elif id == AS_RESOURCEFORK
:
73 print ' (resource fork)'
75 fp
= open(output
, 'wb')
77 fp
= MacOS
.openrf(output
, 'wb')
84 raise Error
, 'Unknown fork type %d'%id
86 raise Error
, 'No useful forks found'
89 if len(sys
.argv
) < 3 or sys
.argv
[1] == '-r' and len(sys
.argv
) != 4:
90 print 'Usage: applesingle.py [-r] applesinglefile decodedfile'
92 if sys
.argv
[1] == '-r':
97 decode(sys
.argv
[1], sys
.argv
[2], resonly
=resonly
)
99 if __name__
== '__main__':