88from util import *
99
1010class StubInstaller (PackageInstaller ):
11- def __init__ (self , sysinfo , dutil , osinfo , ipsw_info ):
11+ def __init__ (self , sysinfo , dutil , osinfo ):
1212 super ().__init__ ()
1313 self .dutil = dutil
1414 self .sysinfo = sysinfo
1515 self .osinfo = osinfo
16- self .install_version = ipsw_info .version .split (maxsplit = 1 )[0 ]
1716 self .ucache = None
1817 self .copy_idata = []
1918 self .stub_info = {}
19+ self .ipsw = None
20+ self .pkg = None
21+
22+ def load_ipsw (self , ipsw ):
23+ self .install_version = ipsw_info .version .split (maxsplit = 1 )[0 ]
2024
2125 base = os .environ .get ("IPSW_BASE" , None )
2226 url = ipsw_info .url
@@ -102,6 +106,45 @@ def chflags(self, flags, path):
102106 logging .info (f"chflags { flags } { path } " )
103107 subprocess .run (["chflags" , flags , path ], check = True )
104108
109+ def get_paths (self ):
110+ self .resources = os .path .join (self .osi .system , "Finish Installation.app/Contents/Resources" )
111+ self .step2_sh = os .path .join (self .resources , "step2.sh" )
112+ self .boot_obj_path = os .path .join (self .resources , "boot.bin" )
113+ self .iapm_path = os .path .join (self .osi .system , ".IAPhysicalMedia" )
114+ self .iapm_dis_path = os .path .join (self .osi .system , "IAPhysicalMedia-disabled.plist" )
115+ self .core_services = os .path .join (self .osi .system , "System/Library/CoreServices" )
116+ self .sv_path = os .path .join (self .core_services , "SystemVersion.plist" )
117+ self .sv_dis_path = os .path .join (self .core_services , "SystemVersion-disabled.plist" )
118+
119+ def check_existing_install (self , osi ):
120+ self .osi = osi
121+ self .get_paths ()
122+
123+ if not os .path .exists (self .step2_sh ):
124+ logging .error ("step2.sh is missing" )
125+ return False
126+ if not os .path .exists (self .boot_obj_path ):
127+ logging .error ("boot.bin is missing" )
128+ return False
129+ if not any (os .path .exists (i ) for i in (self .iapm_path , self .iapm_dis_path )):
130+ logging .error (".IAPhysicalMedia is missing" )
131+ return False
132+ if not any (os .path .exists (i ) for i in (self .sv_path , self .sv_dis_path )):
133+ logging .error ("SystemVersion is missing" )
134+ return False
135+
136+ return True
137+
138+ def prepare_for_bless (self ):
139+ if not os .path .exists (self .sv_path ):
140+ os .replace (self .sv_dis_path , self .sv_path )
141+
142+ def prepare_for_step2 (self ):
143+ if os .path .exists (self .sv_path ):
144+ os .replace (self .sv_path , self .sv_dis_path )
145+ if not os .path .exists (self .iapm_path ):
146+ os .replace (self .iapm_dis_path , self .iapm_path )
147+
105148 def install_files (self , cur_os ):
106149 logging .info ("StubInstaller.install_files()" )
107150 logging .info (f"VGID: { self .osi .vgid } " )
@@ -110,6 +153,8 @@ def install_files(self, cur_os):
110153 p_progress ("Beginning stub OS install..." )
111154 ipsw = self .pkg
112155
156+ self .get_paths ()
157+
113158 logging .info ("Parsing metadata..." )
114159
115160 sysver = plistlib .load (ipsw .open ("SystemVersion.plist" ))
@@ -258,32 +303,31 @@ def install_files(self, cur_os):
258303 os .path .join (basesystem_path , "arm64eBaseSystem.dmg" ))
259304 self .flush_progress ()
260305
261- self .systemversion_path = os .path .join (cs , "SystemVersion.plist" )
262-
263306 p_progress ("Wrapping up..." )
264307
265308 logging .info ("Writing SystemVersion.plist" )
266- with open (self .systemversion_path , "wb" ) as fd :
309+ with open (self .sv_path , "wb" ) as fd :
267310 plistlib .dump (sysver , fd )
268- self .copy_idata .append ((self .systemversion_path , "SystemVersion.plist" ))
311+ self .copy_idata .append ((self .sv_path , "SystemVersion.plist" ))
312+
313+ if os .path .exists (self .sv_dis_path ):
314+ os .remove (self .sv_dis_path )
269315
270316 logging .info ("Copying Finish Installation.app" )
271317 shutil .copytree ("step2/Finish Installation.app" ,
272318 os .path .join (self .osi .system , "Finish Installation.app" ))
273319
274320 logging .info ("Writing step2.sh" )
275321 step2_sh = open ("step2/step2.sh" ).read ().replace ("##VGID##" , self .osi .vgid )
276- resources = os .path .join (self .osi .system , "Finish Installation.app/Contents/Resources" )
277- step2_sh_dst = os .path .join (resources , "step2.sh" )
278- with open (step2_sh_dst , "w" ) as fd :
322+ with open (self .step2_sh , "w" ) as fd :
279323 fd .write (step2_sh )
280- os .chmod (step2_sh_dst , 0o755 )
281- self .step2_sh = step2_sh_dst
282- self .boot_obj_path = os .path .join (resources , "boot.bin" )
324+ os .chmod (self .step2_sh , 0o755 )
283325
284326 logging .info ("Copying .IAPhysicalMedia" )
285- shutil .copy ("step2/IAPhysicalMedia.plist" ,
286- os .path .join (self .osi .system , ".IAPhysicalMedia" ))
327+ shutil .copy ("step2/IAPhysicalMedia.plist" , self .iapm_path )
328+
329+ if os .path .exists (self .iapm_dis_path ):
330+ os .remove (self .iapm_dis_path )
287331
288332 print ()
289333 p_success ("Stub OS installation complete." )
0 commit comments