Changeset 238

Show
Ignore:
Timestamp:
01/05/07 16:32:29 (2 years ago)
Author:
gbooker
Message:

Install and uninstall (unauthenticated only, sorry).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/CPFPerianPrefPaneController.m

    r236 r238  
    11#import "CPFPerianPrefPaneController.h" 
     2#import <Security/Security.h> 
    23 
    34#define ComponentInfoDictionaryKey      @"Components" 
    45#define BundleVersionKey @"CFBundleVersion" 
    56#define ComponentNameKey @"Name" 
     7#define ComponentArchiveNameKey @"ArchiveName" 
    68#define ComponentTypeKey @"Type" 
    79 
     
    102104} 
    103105 
    104 - (void)mainViewDidLoad 
    105 
    106         /* General */ 
     106- (void)checkForInstallation 
     107
    107108        NSDictionary *infoDict = [[self bundle] infoDictionary]; 
    108109        installStatus = [self installStatusForComponent:@"Perian.component" type:ComponentTypeQuickTime withMyVersion:[infoDict objectForKey:BundleVersionKey]]; 
     
    110111        { 
    111112                [textField_installStatus setStringValue:NSLocalizedString(@"Perian is not Installed", @"")]; 
    112                 [button_install setStringValue:NSLocalizedString(@"Install", @"")]; 
     113                [button_install setTitle:NSLocalizedString(@"Install Perian", @"")]; 
    113114        } 
    114115        else if(installStatus == InstallStatusOutdated) 
    115116        { 
    116117                [textField_installStatus setStringValue:NSLocalizedString(@"Perian is Installed, but Outdated", @"")]; 
    117                 [button_install setStringValue:NSLocalizedString(@"Update", @"")]; 
     118                [button_install setTitle:NSLocalizedString(@"Update Perian", @"")]; 
    118119        } 
    119120        else 
     
    135136                                case InstallStatusNotInstalled: 
    136137                                        [textField_installStatus setStringValue:NSLocalizedString(@"Perian is Installed, but parts are Not Installed", @"")]; 
    137                                         [button_install setStringValue:NSLocalizedString(@"Install", @"")]; 
     138                                        [button_install setTitle:NSLocalizedString(@"Install Perian", @"")]; 
    138139                                        break; 
    139140                                case InstallStatusOutdated: 
    140141                                        [textField_installStatus setStringValue:NSLocalizedString(@"Perian is Installed, but parts are Outdated", @"")]; 
    141                                         [button_install setStringValue:NSLocalizedString(@"Update", @"")]; 
     142                                        [button_install setTitle:NSLocalizedString(@"Update Perian", @"")]; 
    142143                                        break; 
    143144                                case InstallStatusInstalled: 
    144145                                        [textField_installStatus setStringValue:NSLocalizedString(@"Perian is Installed", @"")]; 
    145                                         [button_install setStringValue:NSLocalizedString(@"Uninstall", @"")]; 
     146                                        [button_install setTitle:NSLocalizedString(@"Uninstall Perian", @"")]; 
    146147                                        break; 
    147148                        } 
     
    150151                { 
    151152                        [textField_installStatus setStringValue:NSLocalizedString(@"Perian is Installed", @"")]; 
    152                         [button_install setStringValue:NSLocalizedString(@"Uninstall", @"")]; 
     153                        [button_install setTitle:NSLocalizedString(@"Uninstall Perian", @"")]; 
    153154                } 
    154155                 
    155         } 
     156        }        
     157
     158 
     159- (void)mainViewDidLoad 
     160
     161        /* General */ 
     162        [self checkForInstallation]; 
    156163         
    157164        /* A52 Prefs */ 
     
    174181 
    175182#pragma mark Install/Uninstall 
     183 
     184/* Shamelessly ripped from Sparkle */ 
     185- (BOOL)_extractArchivePath:archivePath toDestination:(NSString *)destination pipingDataToCommand:(NSString *)command 
     186{ 
     187        // Get the file size. 
     188        NSNumber *fs = [[[NSFileManager defaultManager] fileAttributesAtPath:archivePath traverseLink:NO] objectForKey:NSFileSize]; 
     189        if (fs == nil) { return NO; } 
     190         
     191        // Thank you, Allan Odgaard! 
     192        // (who wrote the following extraction alg.) 
     193         
     194        long current = 0; 
     195        FILE *fp, *cmdFP; 
     196        sig_t oldSigPipeHandler = signal(SIGPIPE, SIG_IGN); 
     197        if ((fp = fopen([archivePath UTF8String], "r"))) 
     198        { 
     199                setenv("DESTINATION", [destination fileSystemRepresentation], 1); 
     200                if ((cmdFP = popen([command cString], "w"))) 
     201                { 
     202                        char buf[32*1024]; 
     203                        long len; 
     204                        while((len = fread(buf, 1, 32 * 1024, fp))) 
     205                        {                                
     206                                current += len; 
     207                                 
     208                                fwrite(buf, 1, len, cmdFP); 
     209                                 
     210                        } 
     211                        pclose(cmdFP); 
     212                } 
     213                fclose(fp); 
     214        }        
     215        signal(SIGPIPE, oldSigPipeHandler); 
     216        return YES; 
     217} 
     218 
     219- (BOOL)installArchive:(NSString *)archivePath forPiece:(NSString *)component type:(ComponentType)type withMyVersion:(NSString *)myVersion andAuthorization:(AuthorizationRef *)auth 
     220{ 
     221        NSString *containingDir = nil; 
     222        switch(type) 
     223        { 
     224                case ComponentTypeCoreAudio: 
     225                        containingDir = [self coreAudioComponentDir]; 
     226                        break; 
     227                case ComponentTypeQuickTime: 
     228                        containingDir = [self quickTimeComponentDir]; 
     229                        break; 
     230        } 
     231        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]; 
     238                if(result == NO) 
     239                        return NO; 
     240        } 
     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; 
     248        } 
     249        return YES; 
     250} 
     251 
     252- (void)install:(id)sender 
     253{ 
     254        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
     255        NSDictionary *infoDict = [[self bundle] infoDictionary]; 
     256        NSDictionary *myComponentsInfo = [infoDict objectForKey:ComponentInfoDictionaryKey]; 
     257        NSString *componentPath = [[[self bundle] resourcePath] stringByAppendingPathComponent:@"Components"]; 
     258        NSString *coreAudioComponentPath = [componentPath stringByAppendingPathComponent:@"CoreAudio"]; 
     259        NSString *quickTimeComponentPath = [componentPath stringByAppendingPathComponent:@"QuickTime"]; 
     260         
     261        [self installArchive:[componentPath stringByAppendingPathComponent:@"Perian.zip"] forPiece:@"Perian.component" type:ComponentTypeQuickTime withMyVersion:[infoDict objectForKey:BundleVersionKey] andAuthorization:NULL]; 
     262         
     263        NSEnumerator *componentEnum = [myComponentsInfo objectEnumerator]; 
     264        NSDictionary *myComponent = nil; 
     265        while((myComponent = [componentEnum nextObject]) != nil) 
     266        { 
     267                NSString *archivePath = nil; 
     268                ComponentType type = [[myComponent objectForKey:ComponentTypeKey] intValue]; 
     269                switch(type) 
     270                { 
     271                        case ComponentTypeCoreAudio: 
     272                                archivePath = [coreAudioComponentPath stringByAppendingPathComponent:[myComponent objectForKey:ComponentArchiveNameKey]]; 
     273                                break; 
     274                        case ComponentTypeQuickTime: 
     275                                archivePath = [quickTimeComponentPath stringByAppendingPathComponent:[myComponent objectForKey:ComponentArchiveNameKey]]; 
     276                                break; 
     277                } 
     278                [self installArchive:archivePath forPiece:[myComponent objectForKey:ComponentNameKey] type:type withMyVersion:[myComponent objectForKey:BundleVersionKey] andAuthorization:NULL]; 
     279        } 
     280        [self performSelectorOnMainThread:@selector(installComplete:) withObject:nil waitUntilDone:NO]; 
     281        [pool release]; 
     282} 
     283 
     284- (void)uninstall:(id)sender 
     285{ 
     286        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
     287        NSDictionary *infoDict = [[self bundle] infoDictionary]; 
     288        NSDictionary *myComponentsInfo = [infoDict objectForKey:ComponentInfoDictionaryKey]; 
     289         
     290        //XXX what about authorized 
     291        int tag = 0; 
     292        BOOL result = [[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation source:[self quickTimeComponentDir] destination:@"" files:[NSArray arrayWithObject:@"Perian.component"] tag:&tag]; 
     293         
     294        NSEnumerator *componentEnum = [myComponentsInfo objectEnumerator]; 
     295        NSDictionary *myComponent = nil; 
     296        while((myComponent = [componentEnum nextObject]) != nil) 
     297        { 
     298                ComponentType type = [[myComponent objectForKey:ComponentTypeKey] intValue]; 
     299                NSString *directory = nil; 
     300                switch(type) 
     301                { 
     302                        case ComponentTypeCoreAudio: 
     303                                directory = [self coreAudioComponentDir]; 
     304                                break; 
     305                        case ComponentTypeQuickTime: 
     306                                directory = [self quickTimeComponentDir]; 
     307                                break; 
     308                } 
     309                BOOL result = [[NSWorkspace sharedWorkspace] performFileOperation:NSWorkspaceRecycleOperation source:directory destination:@"" files:[myComponent objectForKey:ComponentNameKey] tag:&tag]; 
     310        } 
     311        [self performSelectorOnMainThread:@selector(installComplete:) withObject:nil waitUntilDone:NO]; 
     312        [pool release]; 
     313} 
     314 
    176315- (IBAction)installUninstall:(id)sender 
    177316{ 
     317        [progress_install startAnimation:sender]; 
     318        if(installStatus == InstallStatusInstalled) 
     319                [NSThread detachNewThreadSelector:@selector(uninstall:) toTarget:self withObject:nil]; 
     320        else 
     321                [NSThread detachNewThreadSelector:@selector(install:) toTarget:self withObject:nil]; 
     322} 
     323 
     324- (void)installComplete:(id)sender 
     325{ 
     326        [progress_install stopAnimation:sender]; 
     327        [self checkForInstallation]; 
    178328} 
    179329