-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathRecoveryTool.command
More file actions
executable file
·282 lines (264 loc) · 10.2 KB
/
RecoveryTool.command
File metadata and controls
executable file
·282 lines (264 loc) · 10.2 KB
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
#!/bin/bash
#STLVNUB
verS="RecoveryTool V1.2"
workingDirectory="`dirname \"$0\"`"
theBS="${workingDirectory}"/com.apple.recovery.boot/BaseSystem.dmg
theTool="${workingDirectory}"/TOOLS/dmtest
appDIR="${workingDirectory}"/Apps
kextDIR="${workingDirectory}"/Kexts
installDIR="${workingDirectory}"/Installation
toolBoxDIR="${workingDirectory}"/ToolBox
preheatDIR="${workingDirectory}"/Files/LML
# files needed to build com.apple.recovery.boot, rest can be copied from OS X
carbDIR="${workingDirectory}"/carb
#files that need to be copied from OS X, boot.efi PlatformSupport.plist SystemVersion.plist
theprogs="boot.efi PlatformSupport.plist SystemVersion.plist"
#files that need to be grabbed from Install OS X Mountain Lion.app, kernelcache BaseSystem.dmg
theOutput="${workingDirectory}"/BaseSystem.dmg
theSystem=$(uname -r)
theSystem="${theSystem:0:2}"
theBaseSystem="Mac OS X Base System"
theESD="Mac OS X Install ESD"
case "${theSystem}" in
[0-10]) rootSystem="unsupported" ;;
11) export rootSystem="Lion" ;;
12) export rootSystem="Mountain Lion" ;;
13) export rootSystem="Mavericks"; theBaseSystem="OS X Base System"; theESD="OS X Install ESD"; preheatDIR="${workingDirectory}"/Files/Mvrks;;
[14-20]) rootSystem="Unknown" ;;
esac
theOutputESD="${workingDirectory}"/Create/Install_${rootSystem}_ESD.dmg
theInputESD="/Applications/Install OS X ${rootSystem}.app/Contents/SharedSupport/InstallESD.dmg"
[ ! -e /Applications/"Install OS X ${rootSystem}.app" ] && [ ! -f "${theBS}" ] && echo "Please download '${theESD} ${rootSystem}.app' from the App store" && exit 1
[ "${rootSystem}" == unsupported ] && echo "For Lion-Mavericks Only!!" && exit 1
[ ! -d "${workingDirectory}"/Create ] && mkdir -p "${workingDirectory}"/Create
b=1
function makeRecovery(){
if [ ! -f "${theOutput}" ]|| [ ! -e /Applications/"Install OS X ${rootSystem}.app" ]; then
if [ ! -f "${theBS}" ]; then
echo "Step 1: Making com.apple.recovery.boot Local Folder"
[ ! -d "${workingDirectory}"/com.apple.recovery.boot ] && mkdir "${workingDirectory}"/com.apple.recovery.boot
echo "Copy some files"
cp -R "${carbDIR}"/ "${workingDirectory}"/com.apple.recovery.boot
echo "open Install OS X ${rootSystem}.app/Contents/SharedSupport/InstallESD.dmg"
open "${theInputESD}"
wait
while [ ! -f /Volumes/"${theESD}"/BaseSystem.dmg ]; do
wait
done
echo "cp BaseSystem.dmg to com.apple.recovery.boot Local Folder"
cp /Volumes/"${theESD}"/BaseSystem.dmg "${workingDirectory}"/com.apple.recovery.boot/
chflags nohidden "${workingDirectory}"/com.apple.recovery.boot/BaseSystem.dmg
if [ -d /Volumes/"${theESD}"/System/Library/CoreServices/ ]; then
for prog in $theprogs; do
if [ -f $prog ]; then
echo "cp $prog to com.apple.recovery.boot Local Folder"
cp /Volumes/"${theESD}"/System/Library/CoreServices/"$prog" "${workingDirectory}"/com.apple.recovery.boot/
fi
done
fi
echo "detach..."
hdiutil detach /Volumes/"${theESD}"
wait
echo "Step $b: Done…"; let b++
else
echo "Local Recovery Folder Found"
echo "Will use "
echo "${theOutput}"
echo "as the source"
if [ $1 == Create ]; then
return
fi
fi
fi
echo "Step $b: BaseSystem.dmg found, attaching with shadow…"; let b++
hdiutil attach -nobrowse -owners on "${theBS}" -shadow
wait
if [ "${rootSystem}" == "Mavericks" ] || [ ! -f "${workingDirectory}"/com.apple.recovery.boot/boot.efi ]; then
echo "cp boot.efi to com.apple.recovery.boot Local Folder"
cp /Volumes/"${theBaseSystem}"/System/Library/CoreServices/boot.efi "${workingDirectory}"/com.apple.recovery.boot/
fi
if [ ! -f "${workingDirectory}"/com.apple.recovery.boot/kernelcache ]; then
echo "cp kernelcache to com.apple.recovery.boot Local Folder"
cp /Volumes/"${theBaseSystem}"/System/Library/Caches/com.apple.kext.caches/Startup/kernelcache "${workingDirectory}"/com.apple.recovery.boot/
fi
[ ! -d /Volumes/"${theBaseSystem}"/ToolBox/ ] && mkdir -p /Volumes/"${theBaseSystem}"/ToolBox/
if [ $1 == Modified ] || [ $1 == Create ]; then
echo "Step $b: Copy some apps and stuff and chown them..."; let b++
sudo cp -R "${appDIR}"/ /Volumes/"${theBaseSystem}"/Applications/
sudo chown -R root:wheel /Volumes/"${theBaseSystem}"/Applications/
sudo cp -R "${toolBoxDIR}" /Volumes/"${theBaseSystem}"/
sudo cp -R "${installDIR}"/ /Volumes/"${theBaseSystem}"/System/Installation/CDIS/
fi
echo "Step $b: Copy preheat.sh, chmod and chown it..."; let b++
sudo cp -R "${preheatDIR}"/preheat.sh /Volumes/"${theBaseSystem}"/System/Installation/CDIS/preheat.sh
sudo chmod +x /Volumes/"${theBaseSystem}"/System/Installation/CDIS/preheat.sh
sudo chown -R root:wheel /Volumes/"${theBaseSystem}"/System/Installation/CDIS/
if [ $a != Vanilla ]; then
echo "Step $b: Copy Kexts,chown them, and detach..."; let b++
sudo cp -R "${kextDIR}" /Volumes/"${theBaseSystem}"/ToolBox/
sudo chown -R root:wheel /Volumes/"${theBaseSystem}"/Toolbox/
fi
echo "Detaching…"
hdiutil detach /Volumes/"${theBaseSystem}"
wait
echo "Step $b: Converting back to readonly..."; let b++
hdiutil convert -format UDZO -o "${theOutput}" "${theBS}" -shadow
echo "Step $b: asr checksumming…"; let b++
asr -imagescan "${theOutput}"
echo "Step $b: remove shadow file..."; let b++
rm -rf "${theBS}".shadow
if [ $1 != Create ]; then # run for Modified OR Vanilla, NOT Create
echo "Step $b: Make Recovery Partiion..."; let b++
sudo ${theTool} ensureRecoveryPartition / "${theOutput}" 0 0 "${workingDirectory}"/com.apple.recovery.boot/BaseSystem.chunklist
echo "Step $b: remove temp files..."
rm -rf "${theOutput}"
else
return
fi
echo "done"
tput bel
}
getBootedHD(){
DEVBooted=`diskutil info / | grep 'Device Identifier:'` # get disk that we booted from
DEVBoot="${DEVBooted:29:8}"
DEVSlice="${DEVBoot:6:1}"
DEVBooted="${DEVBooted:29:5}"
let DEVSlice++
DEVREC="${DEVBooted}s$DEVSlice"
DEVBootedName=`diskutil info / | grep 'Volume Name:'`
DEVBootedName="${DEVBootedName:15:40}"
}
function findRecovery(){
recoveryPart=
DevRecs=`diskutil list | grep Recovery | cut -c 69-75`
for therec in $DevRecs; do
if [ "${DEVREC}" == "$therec" ]; then
DevRoot="${DEVBooted}s" #`diskutil list | grep Recovery | cut -c 69-74`# isolate the last digit of that partition ID
DevID="${DEVSlice}" #`diskutil list | grep Recovery | cut -c 75`
# set the variable which contains the FULL drive ID of the recovery partition
recoveryPart="$DevRoot$DevID"
return
fi
done
}
function deleteRecovery(){
echo "The recovery partition we're erasing is: ${recoveryPart}"
# we know the main partition is one digit LESS on the chain
let mergeID=DevID-1
# set the variable for the drive partition into which we'd like to merge
mergePart="$DevRoot$mergeID"
echo "The partition into which we're merging is: $mergePart"
# find the NAME of the merge partition by setting variable
mergeName=$DEVBootedName # `diskutil list | grep $mergePart | cut -c 34-57`
echo "The name of the merge partition is: $mergeName"
choice=
read -p "Press 'c' key to continue, any other to exit" choice
if [ $choice != c ]; then
exit 1
fi
diskutil eraseVolume HFS+ Blank ${recoveryPart}
echo ""
echo "Now merging the space from ${recoveryPart} into $mergePart"
diskutil mergePartitions HFS+ $mergeName $mergePart ${recoveryPart}
echo ""
echo "Merging is complete. Recovery Partition has been removed."
}
function checkDisks(){
disks=(`diskutil list | grep "GUID_partition_scheme" | awk '{print $5}'`)
if [ "${#disks[@]}" != 1 ]; then
echo -e "\n \n"
echo -e "You have multiple disks attached to your Mac.\nI will assume that $DEVBooted is your Macintosh HD boot volume."
else
echo -e "\n \n"
echo "Preparing to check your hard drive for errors."
fi
diskutil verifyDisk $DEVBooted
RetVal=`echo $?`
if [ $RetVal == 1 ]; then
echo -e "$DEVBootedName needs to be repaired.\nThe easiest way to do this is to boot off another drive or boot disk running Lion or Mountain Lion."
exit 1
else
echo -e "\n \n"
echo "Your disk appears to be OK. The script will now continue."
fi
sleep 2
}
function Vanilla(){
checkDisks
makeRecovery $a # pass argument, Vanilla OR Modified
}
function Modified(){
Vanilla
}
function Delete(){
deleteRecovery
}
function Exit(){
echo "Bye"
exit 1
}
function Create(){
[ -f "${theOutputESD}" ] && rm -rf "${theOutputESD}"
theOutput="${workingDirectory}"/Create/BaseSystem.dmg
if [ ! -f "${theOutput}" ]; then
makeRecovery $a
fi
echo "Step $b: attach"
echo "Install OS X ${rootSystem}.app/Contents/SharedSupport/InstallESD.dmg with shadow"; let b++
hdiutil attach -nobrowse -owners on "${theInputESD}" -shadow "${theOutputESD}".shadow
while [ ! -f /Volumes/"${theESD}"/BaseSystem.dmg ]; do
wait
done
echo "Step $b: cp Modified BaseSystem.dmg To Install ESD"; let b++
sudo cp -R "${theOutput}" /Volumes/"${theESD}"/
wait
hdiutil detach /Volumes/"${theESD}"
wait
echo "Step $b: Converting back to readonly..."; let b++
hdiutil convert -format UDZO -o "${theOutputESD}" "${theInputESD}" -shadow "${theOutputESD}".shadow
wait
echo "Step $b: asr checksumming…"; let b++
asr -imagescan "${theOutput}"
wait
echo "Step $b: remove temp files..."
sudo rm -rf "${theOutputESD}".shadow
tput bel
open "${workingDirectory}"/Create
}
function menu(){
findRecovery
clear
choice3=""
if [ "${recoveryPart}" != "" ]; then
mess="The Following Recovery Partition has been found: ${recoveryPart}"
CHOICE2="Create Vanilla Modified Delete Exit"
choice3="* 'Delete' Removes recovery partition from booted HD '${DEVBooted}' *"
elif [ -f "${theBS}" ]; then
CHOICE2="Vanilla Modified Exit"
else
mess="No Recovery Found…"
CHOICE2="Create Vanilla Modified Exit"
fi
echo -e "Running '${verS}' on '${rootSystem}' with disk '${DEVBooted}'"
echo "$mess"
echo -e "\n******************* This script does one of the following:******************"
echo "* 'Create' Creates an Installation ESD containing FakeSMC and some Tools *"
echo "* 'Vanilla' Installs recovery partition, containing FakeSMC Only *"
echo "* 'Modified' Installs recovery partition, containing FakeSMC and Tools *"
echo -e "$choice3"
echo "******************* Please Select from the following list ******************"
printf '\a'
PS3='Enter your choice as a numeric value: '
select a in $CHOICE2
do
case "$a" in
"") echo "You must select one of the above!";echo "Hit Enter to see menu again!" ;;
"$a" ) break ;;
esac
done
"$a"
wait
menu
}
getBootedHD
menu