Changeset 240
- Timestamp:
- 01/05/07 21:17:57 (2 years ago)
- Files:
-
- trunk/CPFPerianPrefPaneController.m (modified) (10 diffs)
- trunk/Perian.xcodeproj/project.pbxproj (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/CPFPerianPrefPaneController.m
r238 r240 1 1 #import "CPFPerianPrefPaneController.h" 2 2 #import <Security/Security.h> 3 #include <sys/stat.h> 3 4 4 5 #define ComponentInfoDictionaryKey @"Components" … … 36 37 } 37 38 39 - (BOOL)systemInstalled 40 { 41 NSString *myPath = [[self bundle] bundlePath]; 42 43 if([myPath hasPrefix:NSHomeDirectory()]) 44 return NO; 45 return YES; 46 } 47 38 48 - (NSString *)quickTimeComponentDir 39 49 { 40 NSString *myPath = [[self bundle] bundlePath];41 50 NSString *basePath = nil; 42 51 43 if( [myPath hasPrefix:NSHomeDirectory()])52 if(![self systemInstalled]) 44 53 basePath = NSHomeDirectory(); 45 54 else … … 51 60 - (NSString *)coreAudioComponentDir 52 61 { 53 NSString *myPath = [[self bundle] bundlePath];54 62 NSString *basePath = nil; 55 63 56 if( [myPath hasPrefix:NSHomeDirectory()])64 if(![self systemInstalled]) 57 65 basePath = NSHomeDirectory(); 58 66 else … … 211 219 pclose(cmdFP); 212 220 } 221 unsetenv("DESTINATION"); 213 222 fclose(fp); 214 223 } … … 217 226 } 218 227 219 - (BOOL)installArchive:(NSString *)archivePath forPiece:(NSString *)component type:(ComponentType)type withMyVersion:(NSString *)myVersion andAuthorization:(AuthorizationRef *)auth 228 - (BOOL)_authenticatedExtractArchivePath:(NSString *)archivePath toDestination:(NSString *)destination finalPath:(NSString *)finalPath authorization:(AuthorizationRef)auth 229 { 230 BOOL ret = NO, oldExist = NO; 231 struct stat sb; 232 if(stat([finalPath fileSystemRepresentation], &sb) == 0) 233 oldExist = YES; 234 235 if(stat([destination fileSystemRepresentation], &sb) != 0) 236 return FALSE; 237 238 char *buf = NULL; 239 if(oldExist) 240 asprintf(&buf, 241 "mv -f \"$DST_COMPONENT\" \"$TMP_PATH\" && " 242 "ditto -x -k --rsrc \"$SRC_ARCHIVE\" \"$DST_PATH\" && " 243 "rm -rf \"$TMP_PATH\" && " 244 "chown -R %d:%d \"$DST_COMPONENT\"", 245 sb.st_uid, sb.st_gid); 246 else 247 asprintf(&buf, 248 "ditto -x -k --rsrc \"$SRC_ARCHIVE\" \"$DST_PATH\" && " 249 "chown -R %d:%d \"$DST_COMPONENT\"", 250 sb.st_uid, sb.st_gid); 251 if(!buf) 252 return FALSE; 253 254 setenv("SRC_ARCHIVE", [archivePath fileSystemRepresentation], 1); 255 setenv("$DST_COMPONENT", [finalPath fileSystemRepresentation], 1); 256 setenv("TMP_PATH", [[finalPath stringByAppendingPathExtension:@"old"] fileSystemRepresentation], 1); 257 setenv("DST_PATH", [destination fileSystemRepresentation], 1); 258 259 char* arguments[] = { "-c", buf, NULL }; 260 if(AuthorizationExecuteWithPrivileges(auth, "/bin/sh", kAuthorizationFlagDefaults, arguments, NULL) == errAuthorizationSuccess) 261 { 262 int status; 263 int pid = wait(&status); 264 if(pid != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0) 265 ret = YES; 266 } 267 free(buf); 268 unsetenv("SRC_ARCHIVE"); 269 unsetenv("$DST_COMPONENT"); 270 unsetenv("TMP_PATH"); 271 unsetenv("DST_PATH"); 272 return ret; 273 } 274 275 - (BOOL)_authenticatedRemove:(NSString *)componentPath authorization:(AuthorizationRef)auth 276 { 277 BOOL ret = NO; 278 struct stat sb; 279 if(stat([componentPath fileSystemRepresentation], &sb) != 0) 280 return FALSE; 281 282 char *buf = NULL; 283 asprintf(&buf, 284 "rm -rf \"$COMP_PATH\" && "); 285 if(!buf) 286 return FALSE; 287 288 setenv("COMP_PATH", [componentPath fileSystemRepresentation], 1); 289 290 char* arguments[] = { "-c", buf, NULL }; 291 if(AuthorizationExecuteWithPrivileges(auth, "/bin/sh", kAuthorizationFlagDefaults, arguments, NULL) == errAuthorizationSuccess) 292 { 293 int status; 294 int pid = wait(&status); 295 if(pid != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0) 296 ret = YES; 297 } 298 free(buf); 299 unsetenv("COMP_PATH"); 300 return ret; 301 } 302 303 304 - (BOOL)installArchive:(NSString *)archivePath forPiece:(NSString *)component type:(ComponentType)type withMyVersion:(NSString *)myVersion andAuthorization:(AuthorizationRef)auth 220 305 { 221 306 NSString *containingDir = nil; … … 230 315 } 231 316 InstallStatus pieceStatus = [self installStatusForComponent:component type:type withMyVersion:myVersion]; 232 if(pieceStatus == InstallStatusOutdated) 233 { 234 //Remove the old one here 235 //XXX what about authorized 236 int tag = 0; 237 BOOL result = [[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation source:containingDir destination:@"" files:[NSArray arrayWithObject:component] tag:&tag]; 317 if(auth != nil && pieceStatus != InstallStatusInstalled) 318 { 319 BOOL result = [self _authenticatedExtractArchivePath:archivePath toDestination:containingDir finalPath:[containingDir stringByAppendingPathComponent:component] authorization:auth]; 238 320 if(result == NO) 239 321 return NO; 240 322 } 241 if(pieceStatus != InstallStatusInstalled) 242 { 243 //Decompress and install new one 244 //XXX Need to do authorized version as well 245 BOOL result = [self _extractArchivePath:archivePath toDestination:containingDir pipingDataToCommand:@"ditto -x -k - \"$DESTINATION\""]; 246 if(result == NO) 247 return NO; 323 else 324 { 325 //Not authenticated 326 if(pieceStatus == InstallStatusOutdated) 327 { 328 //Remove the old one here 329 int tag = 0; 330 BOOL result = [[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation source:containingDir destination:@"" files:[NSArray arrayWithObject:component] tag:&tag]; 331 if(result == NO) 332 return NO; 333 } 334 if(pieceStatus != InstallStatusInstalled) 335 { 336 //Decompress and install new one 337 BOOL result = [self _extractArchivePath:archivePath toDestination:containingDir pipingDataToCommand:@"ditto -x -k - \"$DESTINATION\""]; 338 if(result == NO) 339 return NO; 340 } 248 341 } 249 342 return YES; … … 258 351 NSString *coreAudioComponentPath = [componentPath stringByAppendingPathComponent:@"CoreAudio"]; 259 352 NSString *quickTimeComponentPath = [componentPath stringByAppendingPathComponent:@"QuickTime"]; 260 261 [self installArchive:[componentPath stringByAppendingPathComponent:@"Perian.zip"] forPiece:@"Perian.component" type:ComponentTypeQuickTime withMyVersion:[infoDict objectForKey:BundleVersionKey] andAuthorization:NULL]; 353 AuthorizationRef auth = nil; 354 355 if([self systemInstalled]) 356 { 357 if(!AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &auth) == errAuthorizationSuccess) 358 // Try it anyway, it will likely fail, but who knows what kind of screwed up systems people have 359 auth = nil; 360 } 361 362 [self installArchive:[componentPath stringByAppendingPathComponent:@"Perian.zip"] forPiece:@"Perian.component" type:ComponentTypeQuickTime withMyVersion:[infoDict objectForKey:BundleVersionKey] andAuthorization:auth]; 262 363 263 364 NSEnumerator *componentEnum = [myComponentsInfo objectEnumerator]; … … 276 377 break; 277 378 } 278 [self installArchive:archivePath forPiece:[myComponent objectForKey:ComponentNameKey] type:type withMyVersion:[myComponent objectForKey:BundleVersionKey] andAuthorization:NULL]; 279 } 379 [self installArchive:archivePath forPiece:[myComponent objectForKey:ComponentNameKey] type:type withMyVersion:[myComponent objectForKey:BundleVersionKey] andAuthorization:auth]; 380 } 381 if(auth != nil) 382 AuthorizationFree(auth, 0); 280 383 [self performSelectorOnMainThread:@selector(installComplete:) withObject:nil waitUntilDone:NO]; 281 384 [pool release]; … … 287 390 NSDictionary *infoDict = [[self bundle] infoDictionary]; 288 391 NSDictionary *myComponentsInfo = [infoDict objectForKey:ComponentInfoDictionaryKey]; 289 290 //XXX what about authorized 392 AuthorizationRef auth = nil; 393 394 if([self systemInstalled]) 395 { 396 if(!AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &auth) == errAuthorizationSuccess) 397 // Try it anyway, it will likely fail, but who knows what kind of screwed up systems people have 398 auth = nil; 399 } 400 291 401 int tag = 0; 292 402 BOOL result = [[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation source:[self quickTimeComponentDir] destination:@"" files:[NSArray arrayWithObject:@"Perian.component"] tag:&tag]; … … 309 419 BOOL result = [[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation source:directory destination:@"" files:[myComponent objectForKey:ComponentNameKey] tag:&tag]; 310 420 } 421 if(auth != nil) 422 AuthorizationFree(auth, 0); 423 311 424 [self performSelectorOnMainThread:@selector(installComplete:) withObject:nil waitUntilDone:NO]; 312 425 [pool release]; trunk/Perian.xcodeproj/project.pbxproj
r239 r240 179 179 8F483B5E0A6426C1002CCA73 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8F483B5D0A6426C1002CCA73 /* AudioToolbox.framework */; }; 180 180 8F483B8C0A642886002CCA73 /* PerianAviImporter.r in Rez */ = {isa = PBXBuildFile; fileRef = 8F483B8B0A642886002CCA73 /* PerianAviImporter.r */; }; 181 F53E18E50B4F483C003A0471 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F53E18E40B4F483C003A0471 /* Security.framework */; }; 181 182 F59E09F10A670E570019A3F0 /* Perian.component in CopyFiles */ = {isa = PBXBuildFile; fileRef = 11A70AC10A3D0105002058D4 /* Perian.component */; }; 182 183 /* End PBXBuildFile section */ … … 417 418 8F483BBC0A642B3D002CCA73 /* ff_MovieImportDispatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ff_MovieImportDispatch.h; sourceTree = "<group>"; }; 418 419 F50D440703EAD8DF01B1D299 /* FFusion.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = FFusion.icns; sourceTree = "<group>"; }; 420 F53E18E40B4F483C003A0471 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = "<absolute>"; }; 419 421 F560DECD03D61B6101ABA332 /* Components.k.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Components.k.h; sourceTree = "<group>"; }; 420 422 F560DEFC03D61BE301ABA332 /* FFusionCodec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FFusionCodec.h; sourceTree = "<group>"; }; … … 460 462 files = ( 461 463 83D1D6CF0B4C7AC400E09EC9 /* PreferencePanes.framework in Frameworks */, 464 F53E18E50B4F483C003A0471 /* Security.framework in Frameworks */, 462 465 ); 463 466 runOnlyForDeploymentPostprocessing = 0; … … 492 495 11D4EEFC0A3CE7FA0066D45F /* Carbon.framework */, 493 496 11D4EED50A3CE7EC0066D45F /* QuickTime.framework */, 497 F53E18E40B4F483C003A0471 /* Security.framework */, 494 498 ); 495 499 name = "External Frameworks and Libraries";
