-
Notifications
You must be signed in to change notification settings - Fork 0
/
ab2mb.txt
107 lines (98 loc) · 6.12 KB
/
ab2mb.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import apple_backup
import system.fileIO
import system.magicFixDelimiters
# File names will be "Data File X"
# Note that by default, floppy backups will all be called Apple Backup Data,
# and stored on disks named Hard disk copy X. If someone has made disk images of the disks,
# these can have the first 0x6054 of the disk image cut off/skipped and we should have the data file.
# We can expand this logic in the future to auto-rip backup files from disk images
# When converting this to real code, use the macbinary.ksy to validate the generated files.
inDir = <inputDirectory>
if fileIO.findDir(inDir) is true then continue
outDir = <outputDirectory>
if fileIO.findDir(outDir) is true then continue
inFile = inDir + "Data File "
n = "1"
# Load first archive segment to grab some data:
f = apple_backup.from_file(inFile+n)
outDir = outDir+f.hardDriveName
if not fileIO.findDir(outDir):
fileIO.createDir(outDir)
# Needed to load the first archive to get the number of segments
for n = 1 to f.backupDiskHeader.totalDisks do:
for i = 0 to f.fileData.fileDataContents.fileDataType.size do: # not sure about .size -- must be some way to get the total number
currArchiveFile = f.fileData.fileDataContents.fileDataType[i]
# To do: fullFilePath actually stores the entire path to file with : as delimiter.
# We're going to have to break this out so we can use appropriate path delimiters of the host OS.
realFilePath = magicFixDelimiters(currArchiveFile.fullFilePath)
if not fileIO.findFile(outDir+realFilePath):
if currArchiveFile.folderFlags !== 0:
# we've got a folder, so let's just create it.
fileIO.createDir(outDir+realFilePath)
else:
# If the file doesn't exist, we can just dump data in macBinary format
currFile = fileIO.createFile(outDir+realFilePath)
fileIO.append(currFile,0x0) # unused
fileIO.append(currFile,currArchiveFile.fileNameLen)
fileIO.append(currFile,currArchiveFile.fileName)
fileIO.append(currFile,currArchiveFile.fileNamePadding)
fileIO.append(currFile,currArchiveFile.finfoData.fdType)
fileIO.append(currFile,currArchiveFile.finfoData.fdCreator)
fileIO.append(currFile,currArchiveFile.finfoData.fdFlags_8_f)
fileIO.append(currFile,0x0) # unused
fileIO.append(currFile,0x00) # win_y_pos
fileIO.append(currFile,0x00) # win_x_pos
fileIO.append(currFile,0x00) # win_id
fileIO.append(currFile,0x0) # protected_flag
fileIO.append(currFile,0x0) # unused
fileIO.append(currFile,curArchiveFile.dataForkLength)
fileIO.append(currFile,curArchiveFile.resourceForkLength)
fileIO.append(currFile,curArchiveFile.creationDate)
fileIO.append(currFile,curArchiveFile.modificationDate)
fileIO.append(currFile,curArchiveFile.fxinfoData.fdComment) # getInfoLength
fileIO.append(currFile,currArchiveFile.finfoData.fdFlags_0_7)
fileIO.append(currFile,0x0000) # signature ???
fileIO.append(currFile,curArchiveFile.fxinfoData.fdScript)
fileIO.append(currFile,0x0) # fxInfoData.fdXFlags -- this didn't exist when AppleBackup existed, so it's null
fileIO.append(currFile,0x00000000) # padding
fileIO.append(currFile,0x0000) # totalUnpackedFilesLength - no idea; look into this
fileIO.append(currFile,0x00) # SecondHeaderLength - will always be 0, as we don't have extra headers
fileIO.append(currFile,0x3) # MacBinary Version - we're following 3. Maybe we should use 2, but we haven't.
fileIO.append(currFile,0x2) # minMacBinaryVersionNeeded - we're not adding extended data, so this should be v2 compatible
fileIO.append(currFile,0x0000) # <-- CRC check. This will fail, but eventually I can overwrite this I guess.
# Next part duplicated in the else -- I could probably optimize this in the future.
fileIO.append(currFile,curArchiveFile.dataFork) # if it's empty, we'll just write nothing :)
# if file padding exists, we've got to EOF. There are edge cases where the file record is exactly 0x200 long
# or we've written the entire data fork and padded and written none of the resource fork; those should
# be added to the logic later. Apple Backup shouldn't do the second by default and the first is unlikely.
if curArchiveFile.filePadding:
dfPaddingLength = (128 - (curArchiveFile.dataForkLength % 128))
if dfPaddingLength != 128:
for i = 1 to dfPaddingLength do:
fileIO.append(currFile,0x0)
fileIO.append(currFile,curArchiveFile.resourceFork) # if it's empty, we'll just write nothing :)
if curArchiveFile.filePadding:
rfPaddingLength = (128 - (curArchiveFile.resourceForkLength % 128))
if rfPaddingLength != 128:
for i = 1 to rfPaddingLength do:
fileIO.append(currFile,0x0)
else:
<find data that needs to be appended to the existing file and append it IF this file spans archive segments>
if (f.backupDiskHeader.diskNumber > currArchiveFile.fileStartsOnDisk):
currFile = fileIO.openForAppend(outDir+realFilePath)
fileIO.append(currFile,curArchiveFile.dataFork) # if it's empty, we'll just write nothing :)
# if file padding exists, we've got to EOF. There are edge cases where the file record is exactly 0x200 long
# or we've written the entire data fork and padded and written none of the resource fork; those should
# be added to the logic later. Apple Backup shouldn't do the second by default and the first is unlikely.
if curArchiveFile.filePadding:
dfPaddingLength = (128 - (curArchiveFile.dataForkLength % 128))
if dfPaddingLength != 128:
for i = 1 to dfPaddingLength do:
fileIO.append(currFile,0x0)
fileIO.append(currFile,curArchiveFile.resourceFork) # if it's empty, we'll just write nothing :)
if curArchiveFile.filePadding:
rfPaddingLength = (128 - (curArchiveFile.resourceForkLength % 128))
if rfPaddingLength != 128:
for i = 1 to rfPaddingLength do:
fileIO.append(currFile,0x0)
fileIO.close(currFile)